From 07ec938759e7fffe16a0886e8860c9c523bc34cb Mon Sep 17 00:00:00 2001 From: Evgeny Fomin Date: Fri, 4 Aug 2017 18:32:40 +0300 Subject: [PATCH 1/2] add thread_some function --- toolz/functoolz.py | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/toolz/functoolz.py b/toolz/functoolz.py index 2bd80a4d..451a9f31 100644 --- a/toolz/functoolz.py +++ b/toolz/functoolz.py @@ -8,8 +8,9 @@ from .utils import no_default -__all__ = ('identity', 'thread_first', 'thread_last', 'memoize', 'compose', - 'pipe', 'complement', 'juxt', 'do', 'curry', 'flip', 'excepts') +__all__ = ('identity', 'thread_first', 'thread_last', 'thread_some', 'memoize', + 'compose', 'pipe', 'complement', 'juxt', 'do', 'curry', 'flip', + 'excepts') def identity(x): @@ -93,6 +94,45 @@ def evalform_back(val, form): return func(*args) return reduce(evalform_back, forms, val) +def thread_some(val, *forms): + """ Thread value through a sequence of functions/forms + with early termination if None occurred + + >>> def double(x): return 2*x + >>> def inc(x): return x + 1 + >>> thread_some(1, inc, double) + 4 + + If the function expects more than one input you can specify those inputs + in a tuple. The value is used as the first input. + + >>> def add(x, y): return x + y + >>> def pow(x, y): return x**y + >>> thread_some(1, (add, 4), (pow, 2)) # pow(add(1, 4), 2) + 25 + + If some function return None, all computation will + fail, returning None. + + >>> def div(x, y): (x / y) if y != 0 else None + >>> def double(x): return 2 * x + >>> def inc(x): return x + 1 + >>> thread_some(-1, inc, (div, 10), double) is None + True + + """ + next_val = val + for f in forms: + if next_val is None: + return None + if callable(f): + next_val = f(next_val) + elif isinstance(f, tuple): + func, args = f[0], f[1:] + args = (next_val,) + args + next_val = func(*args) + return next_val + def instanceproperty(fget=None, fset=None, fdel=None, doc=None, classval=None): """ Like @property, but returns ``classval`` when used as a class attribute From 567f03678ea580e755eb64e86c6f469ec1a343f9 Mon Sep 17 00:00:00 2001 From: Evgeny Fomin Date: Fri, 4 Aug 2017 19:02:08 +0300 Subject: [PATCH 2/2] make Travis feel good --- toolz/curried/__init__.py | 1 + toolz/functoolz.py | 1 + 2 files changed, 2 insertions(+) diff --git a/toolz/curried/__init__.py b/toolz/curried/__init__.py index 43aeffd4..4af0f2b5 100644 --- a/toolz/curried/__init__.py +++ b/toolz/curried/__init__.py @@ -51,6 +51,7 @@ second, thread_first, thread_last, + thread_some, ) from .exceptions import merge, merge_with diff --git a/toolz/functoolz.py b/toolz/functoolz.py index 451a9f31..f3e1352d 100644 --- a/toolz/functoolz.py +++ b/toolz/functoolz.py @@ -94,6 +94,7 @@ def evalform_back(val, form): return func(*args) return reduce(evalform_back, forms, val) + def thread_some(val, *forms): """ Thread value through a sequence of functions/forms with early termination if None occurred