From 1424ca2cc6d1cbec961e6e55358b81b1f4c1c457 Mon Sep 17 00:00:00 2001 From: ebonnal Date: Sat, 4 Jan 2025 21:35:19 +0000 Subject: [PATCH] functools: add `running` Co-authored-by: pierrenodet --- README.md | 15 +++++++++++++++ streamable/__init__.py | 2 +- streamable/util/functiontools.py | 14 ++++++++++++++ tests/test_readme.py | 10 ++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4810bb9c..5b5fe242 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,21 @@ zeros: Stream[int] = ( assert list(zeros) == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ``` +### "running map" + +> {TODO: add description} + +```python +from streamable import running + +cumulative_sum: Stream[int] = ( + integers + .map(running(lambda cumsum, i: cumsum + i, initial=0)) +) + +assert list(cumulative_sum) == [0, 1, 3, 6, 10, 15, 21, 28, 36, 45] +``` + ## `.foreach` diff --git a/streamable/__init__.py b/streamable/__init__.py index a51ad250..9266bca0 100644 --- a/streamable/__init__.py +++ b/streamable/__init__.py @@ -1,2 +1,2 @@ from streamable.stream import Stream -from streamable.util.functiontools import star +from streamable.util.functiontools import running, star diff --git a/streamable/util/functiontools.py b/streamable/util/functiontools.py index fdabf049..5c64d1f2 100644 --- a/streamable/util/functiontools.py +++ b/streamable/util/functiontools.py @@ -114,3 +114,17 @@ def add(a: int, b: int) -> int: ``` """ return _Star(func) + + +def running(func: Callable[[R, T], R], initial: R) -> Callable[[T], R]: + """ + TODO + """ + acc = initial + + def _(elem: T) -> R: + nonlocal acc + acc = func(acc, elem) + return acc + + return _ diff --git a/tests/test_readme.py b/tests/test_readme.py index 225401e8..afe281a3 100644 --- a/tests/test_readme.py +++ b/tests/test_readme.py @@ -90,6 +90,16 @@ def test_starmap_example(self) -> None: assert list(zeros) == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + def test_running_map_example(self) -> None: + from streamable import running + + cumulative_sum: Stream[int] = ( + integers + .map(running(lambda cumsum, i: cumsum + i, initial=0)) + ) + + assert list(cumulative_sum) == [0, 1, 3, 6, 10, 15, 21, 28, 36, 45] + def test_foreach_example(self) -> None: state: List[int] = [] appending_integers: Stream[int] = integers.foreach(state.append)