Last active
July 10, 2020 17:56
-
-
Save kilomeow/3e6bcbf92d3297bf80267399e46aa75d to your computer and use it in GitHub Desktop.
Easy dynamic pipes in python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PipeType: | |
def __init__(self, funcs=[]): | |
self.chain = funcs | |
def copy(self): | |
newpipe = type(self)() | |
newpipe.chain = self.chain[:] | |
return newpipe | |
def __rshift__(self, func): | |
newpipe = self.copy() | |
if isinstance(func, PipeType): | |
newpipe.chain.extend(func.chain) | |
elif callable(func): | |
newpipe.chain.append(func) | |
else: | |
raise TypeError(f"Couldn't pass {type(func)} to pipe because it's not Pipe neither callable") | |
return newpipe | |
def __lshift__(self, func): | |
newpipe = self.copy() | |
if isinstance(func, PipeType): | |
newpipe.chain = func.chain + newpipe.chain | |
elif callable(func): | |
newpipe.chain.insert(0, func) | |
else: | |
raise TypeError(f"Couldn't pass {type(func)} to pipe because it's not Pipe neither callable") | |
return newpipe | |
def apply(self, *args, **kwargs): | |
if len(self.chain) == 0: | |
raise TypeError(f"Couldn't apply empty pipe") | |
else: | |
t = self.chain[0](*args, **kwargs) | |
for f in self.chain[1:]: | |
t = f(t) | |
return t | |
__call__ = apply | |
class Apply: | |
def __init__(self, *args, **kwargs): | |
self.args = args | |
self.kwargs = kwargs | |
def to(self, pipe): | |
return pipe.apply(*self.args, **self.kwargs) | |
__or__ = to | |
Pipe = PipeType() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pipe import Pipe, Apply | |
import math | |
# typical use of pipe | |
Apply(3, 4) | Pipe >> (lambda x, y: x**2 + y**2) >> math.sqrt # result is 5.0 | |
# using reverse (normal) order | |
Apply(4, 3) | Pipe << math.sqrt << (lambda x, y: x**2 + y**2) # same | |
# also we can create pipe objects which is callable and could be reused: | |
from functools import partial # go hard | |
cleanWord = Pipe >> partial(filter, str.isalpha) >> "".join | |
pureWords = Pipe >> str.split >> partial(map, cleanWord) >> partial(filter, lambda w: w != "") >> list | |
pureWords("It's okay to be queer!! !") # -> ['Its', 'okay', 'to', 'be', 'queer'] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment