Finish compose.py.
This commit is contained in:
parent
6cd1921102
commit
d6d5adef71
@ -1,30 +1,57 @@
|
|||||||
|
import collections
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
|
from partialable import n_partialable
|
||||||
def compose2(f, g):
|
|
||||||
return lambda x: f(g(x))
|
|
||||||
|
|
||||||
|
|
||||||
def compose(*functions):
|
def _compose2(f, g):
|
||||||
return reduce(compose2, functions)
|
return lambda *args, **kwargs: f(g(*args, **kwargs))
|
||||||
|
|
||||||
|
|
||||||
def extract_args(function):
|
@n_partialable(evaluation_checker=n_partialable.count_evaluation_checker(2))
|
||||||
|
def compose_with_joiner(joiner, *functions):
|
||||||
|
return reduce(joiner, functions)
|
||||||
|
|
||||||
|
|
||||||
|
compose_one_arg = compose_with_joiner(_compose2)
|
||||||
|
|
||||||
|
|
||||||
|
compose = compose_with_joiner(lambda f, g: _compose2(make_single_arity(f),
|
||||||
|
force_args_return(g)))
|
||||||
|
|
||||||
|
|
||||||
|
def make_single_arity(function):
|
||||||
@functools.wraps(function)
|
@functools.wraps(function)
|
||||||
def wrapped(args):
|
def wrapped(args):
|
||||||
return function(*args)
|
return function(*args)
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
def extract_kwargs(function):
|
def kwargs_make_single_arity(function):
|
||||||
@functools.wraps(function)
|
@functools.wraps(function)
|
||||||
def wrapped(kwargs):
|
def wrapped(kwargs):
|
||||||
return function(**kwargs)
|
return function(**kwargs)
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
def extract_args_kwargs(function):
|
def args_kwargs_make_single_arity(function):
|
||||||
@functools.wraps(function)
|
@functools.wraps(function)
|
||||||
def wrapped((args, kwargs)):
|
def wrapped((args, kwargs)):
|
||||||
return function(*args, **kwargs)
|
return function(*args, **kwargs)
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
|
def force_args_return(function):
|
||||||
|
@functools.wraps(function)
|
||||||
|
def wrapped(*args, **kwargs):
|
||||||
|
value = function(*args, **kwargs)
|
||||||
|
if not isinstance(value, collections.Iterable):
|
||||||
|
value = (value,)
|
||||||
|
return value
|
||||||
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
|
def tee(*functions):
|
||||||
|
def wrapped(*args, **kwargs):
|
||||||
|
return tuple(function(*args, **kwargs) for function in functions)
|
||||||
|
return wrapped
|
||||||
|
12
resources/python/compose_test.py
Normal file
12
resources/python/compose_test.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import compose
|
||||||
|
|
||||||
|
|
||||||
|
def test_compose_handles_multiple_argument_output_and_non_iterable_output():
|
||||||
|
assert compose.compose(lambda x: x*2,
|
||||||
|
lambda x, y: x + y,
|
||||||
|
lambda x, y, z: (2*(x - y), z))(1, 2, 3) == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_tee():
|
||||||
|
assert compose.compose(lambda x, y: x + y,
|
||||||
|
compose.tee(lambda x: x + 1, lambda x: x - 1))(2) == 4
|
@ -4,10 +4,13 @@ import inspect
|
|||||||
class n_partialable(object):
|
class n_partialable(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def arity_evaluation_checker(function):
|
def arity_evaluation_checker(function, is_method=False):
|
||||||
|
is_class = inspect.isclass(function)
|
||||||
|
if is_class:
|
||||||
|
function = function.__init__
|
||||||
function_info = inspect.getargspec(function)
|
function_info = inspect.getargspec(function)
|
||||||
function_args = function_info.args
|
function_args = function_info.args
|
||||||
if inspect.isclass(function):
|
if is_class or is_method:
|
||||||
# This is to handle the fact that self will get passed in automatically.
|
# This is to handle the fact that self will get passed in automatically.
|
||||||
function_args = function_args[1:]
|
function_args = function_args[1:]
|
||||||
def evaluation_checker(*args, **kwargs):
|
def evaluation_checker(*args, **kwargs):
|
||||||
@ -21,10 +24,17 @@ class n_partialable(object):
|
|||||||
return not needed_args or kwarg_keys.issuperset(needed_args)
|
return not needed_args or kwarg_keys.issuperset(needed_args)
|
||||||
return evaluation_checker
|
return evaluation_checker
|
||||||
|
|
||||||
def __init__(self, function, evaluation_checker=None, args=None, kwargs=None):
|
@staticmethod
|
||||||
|
def count_evaluation_checker(count):
|
||||||
|
def function(*args, **kwargs):
|
||||||
|
return len(args) >= count
|
||||||
|
return function
|
||||||
|
|
||||||
|
def __init__(self, function, evaluation_checker=None, args=None, kwargs=None,
|
||||||
|
is_method=False):
|
||||||
self.function = function
|
self.function = function
|
||||||
self.evaluation_checker = (evaluation_checker or
|
self.evaluation_checker = (evaluation_checker or
|
||||||
self.arity_evaluation_checker(function))
|
self.arity_evaluation_checker(function, is_method))
|
||||||
self.args = args or ()
|
self.args = args or ()
|
||||||
self.kwargs = kwargs or {}
|
self.kwargs = kwargs or {}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user