diff options
| author | CoprDistGit <infra@openeuler.org> | 2023-04-10 21:39:56 +0000 |
|---|---|---|
| committer | CoprDistGit <infra@openeuler.org> | 2023-04-10 21:39:56 +0000 |
| commit | e973e8df7d78914584e31cc09fc5ffc577c2165b (patch) | |
| tree | e730529062033446334fd0f48c0f7dd2153a4582 /python-pyfunctional.spec | |
| parent | a1b509d9a39ae3c04ddce9b26cbb2e9ee2841b53 (diff) | |
automatic import of python-pyfunctional
Diffstat (limited to 'python-pyfunctional.spec')
| -rw-r--r-- | python-pyfunctional.spec | 510 |
1 files changed, 510 insertions, 0 deletions
diff --git a/python-pyfunctional.spec b/python-pyfunctional.spec new file mode 100644 index 0000000..8cb7607 --- /dev/null +++ b/python-pyfunctional.spec @@ -0,0 +1,510 @@ +%global _empty_manifest_terminate_build 0 +Name: python-pyfunctional +Version: 1.4.3 +Release: 1 +Summary: Package for creating data pipelines with chain functional programming +License: MIT +URL: https://github.com/EntilZha/PyFunctional +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/65/b8/134bf0187d5db42641e93a23c90e0ea20dcda2a8c148147ccc07ecde56e4/PyFunctional-1.4.3.tar.gz +BuildArch: noarch + +Requires: python3-dill +Requires: python3-tabulate +Requires: python3-pandas + +%description +`map(func)/select(func)` | Maps `func` onto elements of sequence | transformation +`starmap(func)/smap(func)` | Apply `func` to sequence with `itertools.starmap` | transformation +`filter(func)/where(func)` | Filters elements of sequence to only those where `func(element)` is `True` | transformation +`filter_not(func)` | Filters elements of sequence to only those where `func(element)` is `False` | transformation +`flatten()` | Flattens sequence of lists to a single sequence | transformation +`flat_map(func)` | `func` must return an iterable. Maps `func` to each element, then merges the result to one flat sequence | transformation +`group_by(func)` | Groups sequence into `(key, value)` pairs where `key=func(element)` and `value` is from the original sequence | transformation +`group_by_key()` | Groups sequence of `(key, value)` pairs by `key` | transformation +`reduce_by_key(func)` | Reduces list of `(key, value)` pairs using `func` | transformation +`count_by_key()` | Counts occurrences of each `key` in list of `(key, value)` pairs | transformation +`count_by_value()` | Counts occurrence of each value in a list | transformation +`union(other)` | Union of unique elements in sequence and `other` | transformation +`intersection(other)` | Intersection of unique elements in sequence and `other` | transformation +`difference(other)` | New sequence with unique elements present in sequence but not in `other` | transformation +`symmetric_difference(other)` | New sequence with unique elements present in sequence or `other`, but not both | transformation +`distinct()` | Returns distinct elements of sequence. Elements must be hashable | transformation +`distinct_by(func)` | Returns distinct elements of sequence using `func` as a key | transformation +`drop(n)` | Drop the first `n` elements of the sequence | transformation +`drop_right(n)` | Drop the last `n` elements of the sequence | transformation +`drop_while(func)` | Drop elements while `func` evaluates to `True`, then returns the rest | transformation +`take(n)` | Returns sequence of first `n` elements | transformation +`take_while(func)` | Take elements while `func` evaluates to `True`, then drops the rest | transformation +`init()` | Returns sequence without the last element | transformation +`tail()` | Returns sequence without the first element | transformation +`inits()` | Returns consecutive inits of sequence | transformation +`tails()` | Returns consecutive tails of sequence | transformation +`zip(other)` | Zips the sequence with `other` | transformation +`zip_with_index(start=0)` | Zips the sequence with the index starting at `start` on the right side | transformation +`enumerate(start=0)` | Zips the sequence with the index starting at `start` on the left side | transformation +`cartesian(*iterables, repeat=1)` | Returns cartesian product from itertools.product | transformation +`inner_join(other)` | Returns inner join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`outer_join(other)` | Returns outer join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`left_join(other)` | Returns left join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`right_join(other)` | Returns right join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`join(other, join_type='inner')` | Returns join of sequence with other as specified by `join_type`. Must be a sequence of `(key, value)` pairs | transformation +`partition(func)` | Partitions the sequence into elements which satisfy `func(element)` and those that don't | transformation +`grouped(size)` | Partitions the elements into groups of size `size` | transformation +`sorted(key=None, reverse=False)/order_by(func)` | Returns elements sorted according to python `sorted` | transformation +`reverse()` | Returns the reversed sequence | transformation +`slice(start, until)` | Sequence starting at `start` and including elements up to `until` | transformation +`head()` / `first()` | Returns first element in sequence | action +`head_option()` | Returns first element in sequence or `None` if its empty | action +`last()` | Returns last element in sequence | action +`last_option()` | Returns last element in sequence or `None` if its empty | action +`len()` / `size()` | Returns length of sequence | action +`count(func)` | Returns count of elements in sequence where `func(element)` is True | action +`empty()` | Returns `True` if the sequence has zero length | action +`non_empty()` | Returns `True` if sequence has non-zero length | action +`all()` | Returns `True` if all elements in sequence are truthy | action +`exists(func)` | Returns `True` if `func(element)` for any element in the sequence is `True` | action +`for_all(func)` | Returns `True` if `func(element)` is `True` for all elements in the sequence | action +`find(func)` | Returns the element that first evaluates `func(element)` to `True` | action +`any()` | Returns `True` if any element in sequence is truthy | action +`max()` | Returns maximal element in sequence | action +`min()` | Returns minimal element in sequence | action +`max_by(func)` | Returns element with maximal value `func(element)` | action +`min_by(func)` | Returns element with minimal value `func(element)` | action +`sum()/sum(projection)` | Returns the sum of elements possibly using a projection | action +`product()/product(projection)` | Returns the product of elements possibly using a projection | action +`average()/average(projection)` | Returns the average of elements possibly using a projection | action +`aggregate(func)/aggregate(seed, func)/aggregate(seed, func, result_map)` | Aggregate using `func` starting with `seed` or first element of list then apply `result_map` to the result | action +`fold_left(zero_value, func)` | Reduces element from left to right using `func` and initial value `zero_value` | action +`fold_right(zero_value, func)` | Reduces element from right to left using `func` and initial value `zero_value` | action +`make_string(separator)` | Returns string with `separator` between each `str(element)` | action +`dict(default=None)` / `to_dict(default=None)` | Converts a sequence of `(Key, Value)` pairs to a `dictionary`. If `default` is not None, it must be a value or zero argument callable which will be used to create a `collections.defaultdict` | action +`list()` / `to_list()` | Converts sequence to a list | action +`set() / to_set()` | Converts sequence to a set | action +`to_file(path)` | Saves the sequence to a file at path with each element on a newline | action +`to_csv(path)` | Saves the sequence to a csv file at path with each element representing a row | action +`to_jsonl(path)` | Saves the sequence to a jsonl file with each element being transformed to json and printed to a new line | action +`to_json(path)` | Saves the sequence to a json file. The contents depend on if the json root is an array or dictionary | action +`to_sqlite3(conn, tablename_or_query, *args, **kwargs)` | Save the sequence to a SQLite3 db. The target table must be created in advance. | action +`to_pandas(columns=None)` | Converts the sequence to a pandas DataFrame | action +`cache()` | Forces evaluation of sequence immediately and caches the result | action +`for_each(func)` | Executes `func` on each element of the sequence | action +### Lazy Execution +Whenever possible, `PyFunctional` will compute lazily. This is accomplished by tracking the list +of transformations that have been applied to the sequence and only evaluating them when an action is +called. In `PyFunctional` this is called tracking lineage. This is also responsible for the +ability for `PyFunctional` to cache results of computation to prevent expensive re-computation. +This is predominantly done to preserve sensible behavior and used sparingly. For example, calling +`size()` will cache the underlying sequence. If this was not done and the input was an iterator, +then further calls would operate on an expired iterator since it was used to compute the length. +Similarly, `repr` also caches since it is most often used during interactive sessions where its +undesirable to keep recomputing the same value. Below are some examples of inspecting lineage. +```python +def times_2(x): + print(x) + return 2 * x +elements = seq(1, 1, 2, 3, 4).map(times_2).distinct() +elements._lineage +# Lineage: sequence -> map(times_2) -> distinct +l_elements = elements.to_list() +# Prints: 1 +# Prints: 1 +# Prints: 2 +# Prints: 3 +# Prints: 4 +elements._lineage +# Lineage: sequence -> map(times_2) -> distinct -> cache +l_elements = elements.to_list() +# The cached result is returned so times_2 is not called and nothing is printed +``` +Files are given special treatment if opened through the `seq.open` and related APIs. +`functional.util.ReusableFile` implements a wrapper around the standard python file to support +multiple iteration over a single file object while correctly handling iteration termination and +file closing. +## Road Map Idea +* SQL based query planner and interpreter +* `_` lambda operator +## Contributing and Bug Fixes +Any contributions or bug reports are welcome. Thus far, there is a 100% acceptance rate for pull +requests and contributors have offered valuable feedback and critique on code. It is great to hear +from users of the package, especially what it is used for, what works well, and what could be +improved. +To contribute, create a fork of `PyFunctional`, make your changes, then make sure that they pass. +In order to be merged, all pull requests must: +* Pass all the unit tests +* Pass all the pylint tests, or ignore warnings with explanation of why its correct to do so +* Not significantly reduce covrage without a good reason [coveralls.io](coveralls.io/github/EntilZha/PyFunctional)) +* Edit the `CHANGELOG.md` file in the `Next Release` heading with changes +## Contact +[Gitter for chat](https://gitter.im/EntilZha/PyFunctional) +## Supported Python Versions +* `PyFunctional` 1.4 and above supports and is tested against Python 3.6, Python 3.7, and PyPy3 +* `PyFunctional` 1.4 and above does not support python 2.7 +* `PyFunctional` 1.4 and above works in Python 3.5, but is not tested against it +* `PyFunctional` 1.4 and above partially works in 3.8, parallel processing currently has issues, but other feature work fine +* `PyFunctional` 1.3 and below supports and was tested against Python 2.7, Python 3.5, Python 3.6, PyPy2, and PyPy3 +## Changelog +[Changelog](https://github.com/EntilZha/PyFunctional/blob/master/CHANGELOG.md) +## About me +To learn more about me (the author) visit my webpage at +[pedro.ai](https://www.pedro.ai). +I created `PyFunctional` while using Python extensivel, and finding that I missed the +ease of use for manipulating data that Spark RDDs and Scala collections have. The project takes the +best ideas from these APIs as well as LINQ to provide an easy way to manipulate data when using +Scala is not an option or PySpark is overkill. +## Contributors +These people have generously contributed their time to improving `PyFunctional` +* [versae](https://github.com/versae) +* [adrian17](https://github.com/adrian17) +* [lucidfrontier45](https://github.com/lucidfrontier45) +* [Digenis](https://github.com/Digenis) +* [ChuyuHsu](https://github.com/ChuyuHsu) +* [jsemric](https://github.com/jsemric) + +%package -n python3-pyfunctional +Summary: Package for creating data pipelines with chain functional programming +Provides: python-pyfunctional +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-pyfunctional +`map(func)/select(func)` | Maps `func` onto elements of sequence | transformation +`starmap(func)/smap(func)` | Apply `func` to sequence with `itertools.starmap` | transformation +`filter(func)/where(func)` | Filters elements of sequence to only those where `func(element)` is `True` | transformation +`filter_not(func)` | Filters elements of sequence to only those where `func(element)` is `False` | transformation +`flatten()` | Flattens sequence of lists to a single sequence | transformation +`flat_map(func)` | `func` must return an iterable. Maps `func` to each element, then merges the result to one flat sequence | transformation +`group_by(func)` | Groups sequence into `(key, value)` pairs where `key=func(element)` and `value` is from the original sequence | transformation +`group_by_key()` | Groups sequence of `(key, value)` pairs by `key` | transformation +`reduce_by_key(func)` | Reduces list of `(key, value)` pairs using `func` | transformation +`count_by_key()` | Counts occurrences of each `key` in list of `(key, value)` pairs | transformation +`count_by_value()` | Counts occurrence of each value in a list | transformation +`union(other)` | Union of unique elements in sequence and `other` | transformation +`intersection(other)` | Intersection of unique elements in sequence and `other` | transformation +`difference(other)` | New sequence with unique elements present in sequence but not in `other` | transformation +`symmetric_difference(other)` | New sequence with unique elements present in sequence or `other`, but not both | transformation +`distinct()` | Returns distinct elements of sequence. Elements must be hashable | transformation +`distinct_by(func)` | Returns distinct elements of sequence using `func` as a key | transformation +`drop(n)` | Drop the first `n` elements of the sequence | transformation +`drop_right(n)` | Drop the last `n` elements of the sequence | transformation +`drop_while(func)` | Drop elements while `func` evaluates to `True`, then returns the rest | transformation +`take(n)` | Returns sequence of first `n` elements | transformation +`take_while(func)` | Take elements while `func` evaluates to `True`, then drops the rest | transformation +`init()` | Returns sequence without the last element | transformation +`tail()` | Returns sequence without the first element | transformation +`inits()` | Returns consecutive inits of sequence | transformation +`tails()` | Returns consecutive tails of sequence | transformation +`zip(other)` | Zips the sequence with `other` | transformation +`zip_with_index(start=0)` | Zips the sequence with the index starting at `start` on the right side | transformation +`enumerate(start=0)` | Zips the sequence with the index starting at `start` on the left side | transformation +`cartesian(*iterables, repeat=1)` | Returns cartesian product from itertools.product | transformation +`inner_join(other)` | Returns inner join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`outer_join(other)` | Returns outer join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`left_join(other)` | Returns left join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`right_join(other)` | Returns right join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`join(other, join_type='inner')` | Returns join of sequence with other as specified by `join_type`. Must be a sequence of `(key, value)` pairs | transformation +`partition(func)` | Partitions the sequence into elements which satisfy `func(element)` and those that don't | transformation +`grouped(size)` | Partitions the elements into groups of size `size` | transformation +`sorted(key=None, reverse=False)/order_by(func)` | Returns elements sorted according to python `sorted` | transformation +`reverse()` | Returns the reversed sequence | transformation +`slice(start, until)` | Sequence starting at `start` and including elements up to `until` | transformation +`head()` / `first()` | Returns first element in sequence | action +`head_option()` | Returns first element in sequence or `None` if its empty | action +`last()` | Returns last element in sequence | action +`last_option()` | Returns last element in sequence or `None` if its empty | action +`len()` / `size()` | Returns length of sequence | action +`count(func)` | Returns count of elements in sequence where `func(element)` is True | action +`empty()` | Returns `True` if the sequence has zero length | action +`non_empty()` | Returns `True` if sequence has non-zero length | action +`all()` | Returns `True` if all elements in sequence are truthy | action +`exists(func)` | Returns `True` if `func(element)` for any element in the sequence is `True` | action +`for_all(func)` | Returns `True` if `func(element)` is `True` for all elements in the sequence | action +`find(func)` | Returns the element that first evaluates `func(element)` to `True` | action +`any()` | Returns `True` if any element in sequence is truthy | action +`max()` | Returns maximal element in sequence | action +`min()` | Returns minimal element in sequence | action +`max_by(func)` | Returns element with maximal value `func(element)` | action +`min_by(func)` | Returns element with minimal value `func(element)` | action +`sum()/sum(projection)` | Returns the sum of elements possibly using a projection | action +`product()/product(projection)` | Returns the product of elements possibly using a projection | action +`average()/average(projection)` | Returns the average of elements possibly using a projection | action +`aggregate(func)/aggregate(seed, func)/aggregate(seed, func, result_map)` | Aggregate using `func` starting with `seed` or first element of list then apply `result_map` to the result | action +`fold_left(zero_value, func)` | Reduces element from left to right using `func` and initial value `zero_value` | action +`fold_right(zero_value, func)` | Reduces element from right to left using `func` and initial value `zero_value` | action +`make_string(separator)` | Returns string with `separator` between each `str(element)` | action +`dict(default=None)` / `to_dict(default=None)` | Converts a sequence of `(Key, Value)` pairs to a `dictionary`. If `default` is not None, it must be a value or zero argument callable which will be used to create a `collections.defaultdict` | action +`list()` / `to_list()` | Converts sequence to a list | action +`set() / to_set()` | Converts sequence to a set | action +`to_file(path)` | Saves the sequence to a file at path with each element on a newline | action +`to_csv(path)` | Saves the sequence to a csv file at path with each element representing a row | action +`to_jsonl(path)` | Saves the sequence to a jsonl file with each element being transformed to json and printed to a new line | action +`to_json(path)` | Saves the sequence to a json file. The contents depend on if the json root is an array or dictionary | action +`to_sqlite3(conn, tablename_or_query, *args, **kwargs)` | Save the sequence to a SQLite3 db. The target table must be created in advance. | action +`to_pandas(columns=None)` | Converts the sequence to a pandas DataFrame | action +`cache()` | Forces evaluation of sequence immediately and caches the result | action +`for_each(func)` | Executes `func` on each element of the sequence | action +### Lazy Execution +Whenever possible, `PyFunctional` will compute lazily. This is accomplished by tracking the list +of transformations that have been applied to the sequence and only evaluating them when an action is +called. In `PyFunctional` this is called tracking lineage. This is also responsible for the +ability for `PyFunctional` to cache results of computation to prevent expensive re-computation. +This is predominantly done to preserve sensible behavior and used sparingly. For example, calling +`size()` will cache the underlying sequence. If this was not done and the input was an iterator, +then further calls would operate on an expired iterator since it was used to compute the length. +Similarly, `repr` also caches since it is most often used during interactive sessions where its +undesirable to keep recomputing the same value. Below are some examples of inspecting lineage. +```python +def times_2(x): + print(x) + return 2 * x +elements = seq(1, 1, 2, 3, 4).map(times_2).distinct() +elements._lineage +# Lineage: sequence -> map(times_2) -> distinct +l_elements = elements.to_list() +# Prints: 1 +# Prints: 1 +# Prints: 2 +# Prints: 3 +# Prints: 4 +elements._lineage +# Lineage: sequence -> map(times_2) -> distinct -> cache +l_elements = elements.to_list() +# The cached result is returned so times_2 is not called and nothing is printed +``` +Files are given special treatment if opened through the `seq.open` and related APIs. +`functional.util.ReusableFile` implements a wrapper around the standard python file to support +multiple iteration over a single file object while correctly handling iteration termination and +file closing. +## Road Map Idea +* SQL based query planner and interpreter +* `_` lambda operator +## Contributing and Bug Fixes +Any contributions or bug reports are welcome. Thus far, there is a 100% acceptance rate for pull +requests and contributors have offered valuable feedback and critique on code. It is great to hear +from users of the package, especially what it is used for, what works well, and what could be +improved. +To contribute, create a fork of `PyFunctional`, make your changes, then make sure that they pass. +In order to be merged, all pull requests must: +* Pass all the unit tests +* Pass all the pylint tests, or ignore warnings with explanation of why its correct to do so +* Not significantly reduce covrage without a good reason [coveralls.io](coveralls.io/github/EntilZha/PyFunctional)) +* Edit the `CHANGELOG.md` file in the `Next Release` heading with changes +## Contact +[Gitter for chat](https://gitter.im/EntilZha/PyFunctional) +## Supported Python Versions +* `PyFunctional` 1.4 and above supports and is tested against Python 3.6, Python 3.7, and PyPy3 +* `PyFunctional` 1.4 and above does not support python 2.7 +* `PyFunctional` 1.4 and above works in Python 3.5, but is not tested against it +* `PyFunctional` 1.4 and above partially works in 3.8, parallel processing currently has issues, but other feature work fine +* `PyFunctional` 1.3 and below supports and was tested against Python 2.7, Python 3.5, Python 3.6, PyPy2, and PyPy3 +## Changelog +[Changelog](https://github.com/EntilZha/PyFunctional/blob/master/CHANGELOG.md) +## About me +To learn more about me (the author) visit my webpage at +[pedro.ai](https://www.pedro.ai). +I created `PyFunctional` while using Python extensivel, and finding that I missed the +ease of use for manipulating data that Spark RDDs and Scala collections have. The project takes the +best ideas from these APIs as well as LINQ to provide an easy way to manipulate data when using +Scala is not an option or PySpark is overkill. +## Contributors +These people have generously contributed their time to improving `PyFunctional` +* [versae](https://github.com/versae) +* [adrian17](https://github.com/adrian17) +* [lucidfrontier45](https://github.com/lucidfrontier45) +* [Digenis](https://github.com/Digenis) +* [ChuyuHsu](https://github.com/ChuyuHsu) +* [jsemric](https://github.com/jsemric) + +%package help +Summary: Development documents and examples for pyfunctional +Provides: python3-pyfunctional-doc +%description help +`map(func)/select(func)` | Maps `func` onto elements of sequence | transformation +`starmap(func)/smap(func)` | Apply `func` to sequence with `itertools.starmap` | transformation +`filter(func)/where(func)` | Filters elements of sequence to only those where `func(element)` is `True` | transformation +`filter_not(func)` | Filters elements of sequence to only those where `func(element)` is `False` | transformation +`flatten()` | Flattens sequence of lists to a single sequence | transformation +`flat_map(func)` | `func` must return an iterable. Maps `func` to each element, then merges the result to one flat sequence | transformation +`group_by(func)` | Groups sequence into `(key, value)` pairs where `key=func(element)` and `value` is from the original sequence | transformation +`group_by_key()` | Groups sequence of `(key, value)` pairs by `key` | transformation +`reduce_by_key(func)` | Reduces list of `(key, value)` pairs using `func` | transformation +`count_by_key()` | Counts occurrences of each `key` in list of `(key, value)` pairs | transformation +`count_by_value()` | Counts occurrence of each value in a list | transformation +`union(other)` | Union of unique elements in sequence and `other` | transformation +`intersection(other)` | Intersection of unique elements in sequence and `other` | transformation +`difference(other)` | New sequence with unique elements present in sequence but not in `other` | transformation +`symmetric_difference(other)` | New sequence with unique elements present in sequence or `other`, but not both | transformation +`distinct()` | Returns distinct elements of sequence. Elements must be hashable | transformation +`distinct_by(func)` | Returns distinct elements of sequence using `func` as a key | transformation +`drop(n)` | Drop the first `n` elements of the sequence | transformation +`drop_right(n)` | Drop the last `n` elements of the sequence | transformation +`drop_while(func)` | Drop elements while `func` evaluates to `True`, then returns the rest | transformation +`take(n)` | Returns sequence of first `n` elements | transformation +`take_while(func)` | Take elements while `func` evaluates to `True`, then drops the rest | transformation +`init()` | Returns sequence without the last element | transformation +`tail()` | Returns sequence without the first element | transformation +`inits()` | Returns consecutive inits of sequence | transformation +`tails()` | Returns consecutive tails of sequence | transformation +`zip(other)` | Zips the sequence with `other` | transformation +`zip_with_index(start=0)` | Zips the sequence with the index starting at `start` on the right side | transformation +`enumerate(start=0)` | Zips the sequence with the index starting at `start` on the left side | transformation +`cartesian(*iterables, repeat=1)` | Returns cartesian product from itertools.product | transformation +`inner_join(other)` | Returns inner join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`outer_join(other)` | Returns outer join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`left_join(other)` | Returns left join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`right_join(other)` | Returns right join of sequence with other. Must be a sequence of `(key, value)` pairs | transformation +`join(other, join_type='inner')` | Returns join of sequence with other as specified by `join_type`. Must be a sequence of `(key, value)` pairs | transformation +`partition(func)` | Partitions the sequence into elements which satisfy `func(element)` and those that don't | transformation +`grouped(size)` | Partitions the elements into groups of size `size` | transformation +`sorted(key=None, reverse=False)/order_by(func)` | Returns elements sorted according to python `sorted` | transformation +`reverse()` | Returns the reversed sequence | transformation +`slice(start, until)` | Sequence starting at `start` and including elements up to `until` | transformation +`head()` / `first()` | Returns first element in sequence | action +`head_option()` | Returns first element in sequence or `None` if its empty | action +`last()` | Returns last element in sequence | action +`last_option()` | Returns last element in sequence or `None` if its empty | action +`len()` / `size()` | Returns length of sequence | action +`count(func)` | Returns count of elements in sequence where `func(element)` is True | action +`empty()` | Returns `True` if the sequence has zero length | action +`non_empty()` | Returns `True` if sequence has non-zero length | action +`all()` | Returns `True` if all elements in sequence are truthy | action +`exists(func)` | Returns `True` if `func(element)` for any element in the sequence is `True` | action +`for_all(func)` | Returns `True` if `func(element)` is `True` for all elements in the sequence | action +`find(func)` | Returns the element that first evaluates `func(element)` to `True` | action +`any()` | Returns `True` if any element in sequence is truthy | action +`max()` | Returns maximal element in sequence | action +`min()` | Returns minimal element in sequence | action +`max_by(func)` | Returns element with maximal value `func(element)` | action +`min_by(func)` | Returns element with minimal value `func(element)` | action +`sum()/sum(projection)` | Returns the sum of elements possibly using a projection | action +`product()/product(projection)` | Returns the product of elements possibly using a projection | action +`average()/average(projection)` | Returns the average of elements possibly using a projection | action +`aggregate(func)/aggregate(seed, func)/aggregate(seed, func, result_map)` | Aggregate using `func` starting with `seed` or first element of list then apply `result_map` to the result | action +`fold_left(zero_value, func)` | Reduces element from left to right using `func` and initial value `zero_value` | action +`fold_right(zero_value, func)` | Reduces element from right to left using `func` and initial value `zero_value` | action +`make_string(separator)` | Returns string with `separator` between each `str(element)` | action +`dict(default=None)` / `to_dict(default=None)` | Converts a sequence of `(Key, Value)` pairs to a `dictionary`. If `default` is not None, it must be a value or zero argument callable which will be used to create a `collections.defaultdict` | action +`list()` / `to_list()` | Converts sequence to a list | action +`set() / to_set()` | Converts sequence to a set | action +`to_file(path)` | Saves the sequence to a file at path with each element on a newline | action +`to_csv(path)` | Saves the sequence to a csv file at path with each element representing a row | action +`to_jsonl(path)` | Saves the sequence to a jsonl file with each element being transformed to json and printed to a new line | action +`to_json(path)` | Saves the sequence to a json file. The contents depend on if the json root is an array or dictionary | action +`to_sqlite3(conn, tablename_or_query, *args, **kwargs)` | Save the sequence to a SQLite3 db. The target table must be created in advance. | action +`to_pandas(columns=None)` | Converts the sequence to a pandas DataFrame | action +`cache()` | Forces evaluation of sequence immediately and caches the result | action +`for_each(func)` | Executes `func` on each element of the sequence | action +### Lazy Execution +Whenever possible, `PyFunctional` will compute lazily. This is accomplished by tracking the list +of transformations that have been applied to the sequence and only evaluating them when an action is +called. In `PyFunctional` this is called tracking lineage. This is also responsible for the +ability for `PyFunctional` to cache results of computation to prevent expensive re-computation. +This is predominantly done to preserve sensible behavior and used sparingly. For example, calling +`size()` will cache the underlying sequence. If this was not done and the input was an iterator, +then further calls would operate on an expired iterator since it was used to compute the length. +Similarly, `repr` also caches since it is most often used during interactive sessions where its +undesirable to keep recomputing the same value. Below are some examples of inspecting lineage. +```python +def times_2(x): + print(x) + return 2 * x +elements = seq(1, 1, 2, 3, 4).map(times_2).distinct() +elements._lineage +# Lineage: sequence -> map(times_2) -> distinct +l_elements = elements.to_list() +# Prints: 1 +# Prints: 1 +# Prints: 2 +# Prints: 3 +# Prints: 4 +elements._lineage +# Lineage: sequence -> map(times_2) -> distinct -> cache +l_elements = elements.to_list() +# The cached result is returned so times_2 is not called and nothing is printed +``` +Files are given special treatment if opened through the `seq.open` and related APIs. +`functional.util.ReusableFile` implements a wrapper around the standard python file to support +multiple iteration over a single file object while correctly handling iteration termination and +file closing. +## Road Map Idea +* SQL based query planner and interpreter +* `_` lambda operator +## Contributing and Bug Fixes +Any contributions or bug reports are welcome. Thus far, there is a 100% acceptance rate for pull +requests and contributors have offered valuable feedback and critique on code. It is great to hear +from users of the package, especially what it is used for, what works well, and what could be +improved. +To contribute, create a fork of `PyFunctional`, make your changes, then make sure that they pass. +In order to be merged, all pull requests must: +* Pass all the unit tests +* Pass all the pylint tests, or ignore warnings with explanation of why its correct to do so +* Not significantly reduce covrage without a good reason [coveralls.io](coveralls.io/github/EntilZha/PyFunctional)) +* Edit the `CHANGELOG.md` file in the `Next Release` heading with changes +## Contact +[Gitter for chat](https://gitter.im/EntilZha/PyFunctional) +## Supported Python Versions +* `PyFunctional` 1.4 and above supports and is tested against Python 3.6, Python 3.7, and PyPy3 +* `PyFunctional` 1.4 and above does not support python 2.7 +* `PyFunctional` 1.4 and above works in Python 3.5, but is not tested against it +* `PyFunctional` 1.4 and above partially works in 3.8, parallel processing currently has issues, but other feature work fine +* `PyFunctional` 1.3 and below supports and was tested against Python 2.7, Python 3.5, Python 3.6, PyPy2, and PyPy3 +## Changelog +[Changelog](https://github.com/EntilZha/PyFunctional/blob/master/CHANGELOG.md) +## About me +To learn more about me (the author) visit my webpage at +[pedro.ai](https://www.pedro.ai). +I created `PyFunctional` while using Python extensivel, and finding that I missed the +ease of use for manipulating data that Spark RDDs and Scala collections have. The project takes the +best ideas from these APIs as well as LINQ to provide an easy way to manipulate data when using +Scala is not an option or PySpark is overkill. +## Contributors +These people have generously contributed their time to improving `PyFunctional` +* [versae](https://github.com/versae) +* [adrian17](https://github.com/adrian17) +* [lucidfrontier45](https://github.com/lucidfrontier45) +* [Digenis](https://github.com/Digenis) +* [ChuyuHsu](https://github.com/ChuyuHsu) +* [jsemric](https://github.com/jsemric) + +%prep +%autosetup -n pyfunctional-1.4.3 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-pyfunctional -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Mon Apr 10 2023 Python_Bot <Python_Bot@openeuler.org> - 1.4.3-1 +- Package Spec generated |
