Wrapper to allow algebraic manipulation and composition of functions. An abstract callable provides methods for chaining and combining functions, and defines an expression syntax for doing the same.
The aims of this package are purely academic; I do not recommend using this if you respect the people who must read your code.
fromfungebraimportFunctionfromexternal_libraryimportother_func@Functiondefmy_func():
...
other_func=Function(other_func)In the following examples:
f,g,hareFunctionwrapped callables.xis an arbitrary argument.
(f+g)(x) ==f.compose(g)(x) ==f(g(x))(f|g)(x) ==f.pipe(g)(x) ==g(f(x))[1, 2, 3] |f==f([1, 2, 3])[1, 2, 3] |f.collect==f(1, 2, 3)(f<< (1, 2, 3))(x) ==f.partial(1, 2, 3)(x) ==f(1, 2, 3, x)(f<< {"opt": "val"})(x) ==f.partial({"opt": "val"})(x) ==f(x, opt="val")(f<<Args(1, 2, opt="val"))(x) ==f.partial(1, 2, opt="val")(x) ==f(1, 2, x, opt="val")(f>> (1, 2, 3))(x) ==f.rpartial(1, 2, 3)(x) ==f(x, 1, 2, 3)(-f)(x) ==f.map(x) ==map(f, x)(f-g)(x) ==f.compose(g.map)(x) ==map(g, f(x))(f<g)(x) ==f.filter(g)() ==filter(g, f(x))(f>g)(x) ==f.reduce(g)(x) ==reduce(g, f(x))(-f>g)(x) == (f>=g)(x) ==f.map.reduce(g)(x) ==reduce(g, map(f, x))(-f<g>h)(x) ==f.map.filter(g).reduce(h)(x) ==reduce(h, filter(g, map(f, x)))(f<=g)(x) ==f.map.filter(g)(x) ==filter(g, map(f, x))A number of compatible Function callables are provided in fungebra.functions. The operator standard library is re-exported as Function objects.
fromfungebraimportFunction, operatorasopfromfungebra.functionsimportless, fnot, itemgettergreater_or_equal=less|fnot@Functiondefget_old_items_sort_by_name_desc(min_age: int):
"""Filter a known schema on old items, and sort by name descending."""returnitemgetter("hits").filter(
itemgetter("age") |greater_or_equal(min_age)
).pipe(
F(sorted) << {"key": itemgetter("name") |ord|op.neg}
).pipe(list)
get_old_items_sort_by_name_desc(2)(
{
"hits": [
{"age": 1, "name": "B"},
{"age": 2, "name": "A"},
{"age": 3, "name": "C"},
]
}
) == [
{"age": 3, "name": "C"},
{"age": 2, "name": "A"},
]fromfungebraimportFunctionfromfungebra.functionsimport (
iffy, less, constantly, caller
)
@Functiondeftruncate_below(minimum: int) ->int: """Truncate arguments below a threshold."""returncaller(minimum).map([less, constantly]) |iffy.expandtruncate_below(0).lmap([-1, 2, 4]) == [0, 2, 4]This package is currently tested for Python 3.6.
This project is not currently packaged and so must be installed manually.
Clone the project with the following command:
git clone https://github.com/jacksmith15/fungebra.git
Package requirements may be installed via pip install -r requirements.txt. Use of a virtualenv is recommended.
- Clone the repository:
git clone git@github.com:jacksmith15/fungebra.git && cd fungebra - Install the requirements:
pip install -r requirements.txt -r requirements-test.txt - Run
pre-commit install - Run the tests:
bash run_test.sh -c -a
This project uses the following QA tools:
- PyTest - for running unit tests.
- PyLint - for enforcing code style.
- MyPy - for static type checking.
- Travis CI - for continuous integration.
- Black - for uniform code formatting.
This project is distributed under the MIT license.