Hello pipe 2.0.
This commit is contained in:
parent
636647b895
commit
69dd2ec55e
|
@ -0,0 +1,141 @@
|
|||
---
|
||||
Title: Releasing pipe v2.0
|
||||
Date: 2022-05-23 09:31:00
|
||||
Summary: Introducing partially parametrized pipes!
|
||||
---
|
||||
|
||||
# Introducing partially parametrized pipes!
|
||||
|
||||
[pipe](https://github.com/JulienPalard/Pipe) is a very old project of mine, proudly showing 1.3k stars on github!
|
||||
|
||||
I don't maintain it a lot, but today I'm announcing a new release introducing a nice feature: partially parametrized pipes.
|
||||
|
||||
If you're familiar with [currying](https://en.wikipedia.org/wiki/Currying)
|
||||
or
|
||||
[functools.partial](https://docs.python.org/3/library/functools.html#functools.partial)
|
||||
you won't get lost.
|
||||
|
||||
|
||||
## Show me!
|
||||
|
||||
Before `pipe 2`, the following were already valid:
|
||||
|
||||
```python
|
||||
>>> from random import randint
|
||||
>>> from pipe import where, sort
|
||||
>>>
|
||||
>>> negative = where(lambda x: x < 0)
|
||||
>>> positive = where(lambda x: x > 0)
|
||||
>>>
|
||||
>>> numbers = [randint(-10, 10) for _ in range(10)]
|
||||
>>>
|
||||
>>> numbers | positive | sort
|
||||
[7, 10]
|
||||
>>> numbers | negative | sort
|
||||
[-10, -9, -8, -7, -4, -4, -2]
|
||||
```
|
||||
|
||||
It allows to **name things**, naming things make
|
||||
code more readable so I wanted more of it.
|
||||
|
||||
It was probably underrated, I link to do this kind of things:
|
||||
|
||||
```python
|
||||
>>> isort = sort(key=lambda x: x**2)
|
||||
>>> numbers | isort
|
||||
[0, -2, -4, -4, -7, 7, -8, -9, 10, -10]
|
||||
```
|
||||
|
||||
But it failed as soon as you try go deeper:
|
||||
|
||||
```python
|
||||
>>> numbers | isort(reverse=True)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
File "pipe.py", line 100, in __ror__
|
||||
return self.function(other)
|
||||
File "pipe.py", line 103, in <lambda>
|
||||
return Pipe(lambda x: self.function(x, *args, **kwargs))
|
||||
TypeError: Pipe.__call__.<locals>.<lambda>() got an unexpected keyword argument 'reverse'
|
||||
```
|
||||
|
||||
Call it a bug, that's what's pipe 2 fixes:
|
||||
|
||||
```python
|
||||
>>> from pipe import where, sort
|
||||
>>> from random import randint
|
||||
>>> numbers = [randint(-10, 10) for _ in range(10)]
|
||||
>>>
|
||||
>>> isort = sort(key=lambda x: x**2)
|
||||
>>> numbers | isort(reverse=True)
|
||||
[-10, -9, 8, -6, 6, -4, 4, 4, 2, 1]
|
||||
>>>
|
||||
```
|
||||
|
||||
Or in the other way around:
|
||||
|
||||
```python
|
||||
>>> rsort = sort(reverse=True)
|
||||
>>> numbers | rsort
|
||||
[8, 6, 4, 4, 2, 1, -4, -6, -9, -10]
|
||||
>>> numbers | rsort(key=lambda x: x**2)
|
||||
[-10, -9, 8, -6, 6, -4, 4, 4, 2, 1]
|
||||
```
|
||||
|
||||
From here you can build many specialized blocks from a single pipe,
|
||||
here's a better example:
|
||||
|
||||
```python
|
||||
import re
|
||||
|
||||
from pipe import Pipe
|
||||
|
||||
|
||||
@Pipe
|
||||
def grep(iterable, pattern, flags=0, invert=False):
|
||||
"""Mimics grep."""
|
||||
for line in iterable:
|
||||
match = re.match(pattern, line, flags=flags)
|
||||
if (match and not invert) or (not match and invert):
|
||||
yield line
|
||||
```
|
||||
|
||||
Build the small reusable blocks:
|
||||
|
||||
```python
|
||||
igrep = grep(flags=re.I)
|
||||
vgrep = grep(invert=True)
|
||||
vigrep = igrep(invert=True)
|
||||
https = igrep("https://")
|
||||
not_https = https(invert=True)
|
||||
...
|
||||
```
|
||||
|
||||
And they all do what you think they do:
|
||||
|
||||
```python
|
||||
>>> lines = ["https://python.org", "http://detectportal.firefox.com/", "Just no an URL", "HTTPS://afpy.org"]
|
||||
>>> for url in lines | https:
|
||||
... print(url)
|
||||
...
|
||||
https://python.org
|
||||
HTTPS://afpy.org
|
||||
```
|
||||
|
||||
```python
|
||||
>>> for url in lines | not_https:
|
||||
... print(url)
|
||||
...
|
||||
http://detectportal.firefox.com/
|
||||
Just no an URL
|
||||
```
|
||||
|
||||
Remember I said currying? Yes you can abuse the syntax, but please don't:
|
||||
|
||||
```python
|
||||
>>> from pipe import sort
|
||||
>>> lines | grep()(invert=True)()(flags=re.I)()("https://")() | sort
|
||||
['Just no an URL', 'http://detectportal.firefox.com/']
|
||||
```
|
||||
|
||||
As I like to say: « It's not because it's possible than you should do it ».
|
Loading…
Reference in New Issue