Package: pytoolz
[![Build Status](https://travis-ci.com/andrea-lascola/Pytoolz.svg?branch=master)](https://travis-ci.com/andrea-lascola/Pytoolz)[![PyPI version](https://badge.fury.io/py/pytoolz.svg)](https://badge.fury.io/py/pytoolz)[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/2441/badge)](https://bestpractices.coreinfrastructure.org/projects/2441)# Pytoolz 🚀Module containing some python utilities/abstractionspython >= 3.7 compatible## Prerequisitespython >= 3.7## Installingpip install pytoolz## Sections* [Functional](#functional) λ* [Data Structures](#data-structures) 📂* [Cache](#cache) 🚀* [Design](#design) 🏛* [Logs](#logs) 📖* [Multiprocess](#multiprocess) 👯* [Serialization](#serialization) 🤖#### FunctionalA set of utilities oriented to functional programming.##### compose(f1: Callable, f2: Callable) -> CallableCompose two functions: return the fn composition of the two```pythonfrom pytoolz.functional import composeif __name__ == "__main__":f = compose(lambda x: x * 2,lambda x: x * 3)f(10)# 60```##### pipe(functions: List[Callable], obj)Recursively apply a list of morphism to an input value```pythonfrom pytoolz.functional import pipeif __name__ == "__main__":pipe([lambda x: x * 3,lambda x: x * 2,lambda x: x / 3], 10)# 20.0```##### flat_map(fn: Callable, collection: Iterable)Apply the input function to every element in iterable and flatten the result lists```pythonfrom pytoolz.functional import flat_mapif __name__ == "__main__":flat_map(lambda x: [x, x], [1, 2, 3])# [1, 1, 2, 2, 3, 3]flat_map(lambda x: (x, x), [1, 2, 3])# [1, 1, 2, 2, 3, 3]```##### iflat_map(fn: Callable, collection: Iterable)Apply the input function to every element in iterable and flatten the result list **lazily**```pythonfrom pytoolz.functional import iflat_mapif __name__ == "__main__":iflat_map(lambda x: [x, x], [1, 2, 3])# [1, 1, 2, 2, 3, 3]iflat_map(lambda x: (x, x), [1, 2, 3])# [1, 1, 2, 2, 3, 3]```##### for_each(fn: Callable, collection: Iterable)Create side effect applying the input function for every element in iterable```pythonfrom pytoolz.functional import iflat_mapif __name__ == "__main__":iflat_map(lambda x: [x, x], [1, 2, 3])# [1, 1, 2, 2, 3, 3]iflat_map(lambda x: (x, x), [1, 2, 3])# [1, 1, 2, 2, 3, 3]```##### Stream(iterable: Iterable) -> Stream[Experiment] Emulate the Java Stream API to create pipelines of transformations unsing function composition```pythonfrom pytoolz.functional import Streamif __name__ == "__main__":Stream([1, 2, 3]).map(lambda x: x * 3).to_list()# [3, 6, 9]Stream([1, 2, 3]).sum().to_int()# 6Stream([1, 2, 3]).map(lambda x: x * 3).filter(lambda x: x >= 6).to_tuple()# (6, 9)Stream(["a", "b", "c"]).map(lambda x: x + "a").to_set() == {'aa', 'ba', 'ca'}# TrueStream([1, 4, 3]) \.map(lambda x: x + 3) \.map(lambda x: x * x) \.filter(lambda x: x > 3) \.sum() \.to_float()# 101.0#Alternative constructorStream.of([1, 2, 3], [(Stream.map, lambda x: x * 3),(Stream.map, lambda x: x * 3)]).to_list()# [9, 18, 27]```#### SerializationSerialization and deSerialization of objects:different engine are built-in: Json/Pickle/Dict```pythonfrom pytoolz.serialization import Dict, Json, Pickleif __name__ == "__main__":original = '{"users": ["bob", "foo", "bar"], "companies": {}}'data = Json(original).deserialize()print(type(data))# '<class 'dict'>'string_data = Json(data).serialize()print(type(string_data))# '<class 'str'>'```#### Data structuresUtilities related to data structures (missing data structures or customization of existing ones)##### LinkedList```pythonfrom pytooolz.ds import LinkedList, Nodeif __name__ == "__main__":ll = LinkedList()ll.add(Node(3))ll.add(Node(4))ll.add(Node(5))ll.add(Node(6))print(ll)#$ LinkedList(head=Node(value=6, next=Node(value=5, next=Node(value=4, next=Node(value=3, next=None)))))```##### DoublyLinkedListTODO complete#### CacheUtilities related to **caching**. Different backend will be implemented:ex:* Redis* Memcache* LRU in-memory* Filesystem```pythonfrom pytooolz.cache import memoize # memoize decoratorfrom pytooolz.cache import FileEngine # Disk cache enginefrom pytooolz.cache import InMemoryEngine # LRU in memory enginefrom pytooolz.cache import MemcachedEngine # Memcache enginefrom pytooolz.cache import RedisEngine # Redis engineif __name__ == "__main__":@memoize(InMemoryEngine(limit=10, expiration=10))def fn(*args):return argsfn(1, 2, 3, 4, 5) # fn evaluatedfn(1, 2, 3, 4, 5) # got from cachefn(1, 2, 3, 4, 5) # got from cachefn(1, 2, 3, 4, 5) # got from cache```#### DesignUtilities related to application design**Singleton decorator** - Examples:```pythonfrom pytooolz.design import singletonif __name__ == "__main__":@singleton.singletonclass MyClass:passassert id(MyClass()) == id(MyClass())```**Traits**Attach a specific trait to an instance.This should enable polimorphism using composition instead of classic inheritanceTo use this feature:* decorate your class with ```@extendable``` decorator* implement your custom class that implements ```Trait``` interface* choose one (or more) traits during the class init using ```.with_trait(...)```Example:```pythonfrom pytooolz.design import Traitfrom pytooolz.design import extendableif __name__ == "__main__":class UserRenderHtml(Trait):def render(self):print("""<h1>{0!s}</h1><p>{1!s}</p>""".format(self.name, self.surname))class UserRenderText(Trait):def render(self):print(self.name, self.surname)@extendableclass User:def __init__(self, name, surname):self.name = nameself.surname = surnameusr = User("Andrea", "La Scola").with_trait(UserRenderHtml)print(usr.render())```#### Logs**log decorators**- multiple backends## Authors* **Andrea La Scola** - *Initial work* - [PurpleBooth](https://github.com/andrea-lascola)