Functional programming in Python: implementation of missing features to enjoy FP

Overview

Fn.py: enjoy FP in Python

Despite the fact that Python is not pure-functional programming language, it's multi-paradigm PL and it gives you enough freedom to take credits from functional programming approach. There are theoretical and practical advantages to the functional style:

  • Formal provability
  • Modularity
  • Composability
  • Ease of debugging and testing

Fn.py library provides you with missing "batteries" to get maximum from functional approach even in mostly-imperative program.

More about functional approach from my Pycon UA 2012 talks: Functional Programming with Python.

Scala-style lambdas definition

from fn import _
from fn.op import zipwith
from itertools import repeat

assert list(map(_ * 2, range(5))) == [0,2,4,6,8]
assert list(filter(_ < 10, [9,10,11])) == [9]
assert list(zipwith(_ + _)([0,1,2], repeat(10))) == [10,11,12]

More examples of using _ you can find in test cases declaration (attributes resolving, method calling, slicing).

Attention! If you work in interactive python shell, your should remember that _ means "latest output" and you'll get unpredictable results. In this case, you can do something like from fn import _ as X (and then write functions like X * 2).

If you are not sure, what your function is going to do, you can print it:

from fn import _

print (_ + 2) # "(x1) => (x1 + 2)"
print (_ + _ * _) # "(x1, x2, x3) => (x1 + (x2 * x3))"

_ will fail with ArityError (TypeError subclass) on inaccurate number of passed arguments. This is one more restrictions to ensure that you did everything right:

>>> from fn import _
>>> (_ + _)(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "fn/underscore.py", line 82, in __call__
    raise ArityError(self, self._arity, len(args))
fn.underscore.ArityError: (_ + _) expected 2 arguments, got 1

Persistent data structures

Attention: Persistent data structures are under active development.

Persistent data structure is a data structure that always preserves the previous version of itself when it is modified (more formal information on Wikipedia). Each operation with such data structure yields a new updated structure instead of in-place modification (all previous versions are potentially available or GC-ed when possible).

Lets take a quick look:

>>> from fn.immutable import SkewHeap
>>> s1 = SkewHeap(10)
>>> s2 = s1.insert(20)
>>> s2
<fn.immutable.heap.SkewHeap object at 0x10b14c050>
>>> s3 = s2.insert(30)
>>> s3
<fn.immutable.heap.SkewHeap object at 0x10b14c158> # <-- other object
>>> s3.extract()
(10, <fn.immutable.heap.SkewHeap object at 0x10b14c050>)
>>> s3.extract() # <-- s3 isn't changed
(10, <fn.immutable.heap.SkewHeap object at 0x10b11c052>)

If you think I'm totally crazy and it will work despairingly slow, just give it 5 minutes. Relax, take a deep breath and read about few techniques that make persistent data structures fast and efficient: structural sharing and path copying.

To see how it works in "pictures", you can check great slides from Zach Allaun's talk (StrangeLoop 2013): "Functional Vectors, Maps And Sets In Julia".

And, if you are brave enough, go and read:

  • Chris Okasaki, "Purely Functional Data Structures" (Amazon)
  • Fethi Rabhi and Guy Lapalme, "Algorithms: A Functional Programming Approach" (Amazon)

Available immutable data structures in fn.immutable module:

  • LinkedList: most "obvious" persistent data structure, used as building block for other list-based structures (stack, queue)
  • Stack: wraps linked list implementation with well-known pop/push API
  • Queue: uses two linked lists and lazy copy to provide O(1) enqueue and dequeue operations
  • Deque (in progress): "Confluently Persistent Deques via Data Structural Bootstrapping"
  • Deque based on FingerTree data structure (see more information below)
  • Vector: O(log32(n)) access to elements by index (which is near-O(1) for reasonable vector size), implementation is based on BitmappedTrie, almost drop-in replacement for built-in Python list
  • SkewHeap: self-adjusting heap implemented as a binary tree with specific branching model, uses heap merge as basic operation, more information - "Self-adjusting heaps"
  • PairingHeap: "The Pairing-Heap: A New Form of Self-Adjusting Heap"
  • Dict (in progress): persistent hash map implementation based on BitmappedTrie
  • FingerTree (in progress): "Finger Trees: A Simple General-purpose Data Structure"

Use appropriate doc strings to get more information about each data structure as well as sample code.

To get more clear vision of how persistent heaps work (SkewHeap and PairingHeap), you can look at slides from my talk "Union-based heaps" (with analyzed data structures definitions in Python and Haskell).

Note. Most functional languages use persistent data structures as basic building blocks, well-known examples are Clojure, Haskell and Scala. Clojure community puts much effort to popularize programming based on the idea of data immutability. There are few amazing talk given by Rich Hickey (creator of Clojure), you can check them to find answers on both questions "How?" and "Why?":

Streams and infinite sequences declaration

Lazy-evaluated Scala-style streams. Basic idea: evaluate each new element "on demand" and share calculated elements between all created iterators. Stream object supports << operator that means pushing new elements when it's necessary.

Simplest cases:

from fn import Stream

s = Stream() << [1,2,3,4,5]
assert list(s) == [1,2,3,4,5]
assert s[1] == 2
assert list(s[0:2]) == [1,2]

s = Stream() << range(6) << [6,7]
assert list(s) == [0,1,2,3,4,5,6,7]

def gen():
    yield 1
    yield 2
    yield 3

s = Stream() << gen << (4,5)
assert list(s) == [1,2,3,4,5]

Lazy-evaluated stream is useful for infinite sequences, i.e. fibonacci sequence can be calculated as:

from fn import Stream
from fn.iters import take, drop, map
from operator import add

f = Stream()
fib = f << [0, 1] << map(add, f, drop(1, f))

assert list(take(10, fib)) == [0,1,1,2,3,5,8,13,21,34]
assert fib[20] == 6765
assert list(fib[30:35]) == [832040,1346269,2178309,3524578,5702887]

Trampolines decorator

fn.recur.tco is a workaround for dealing with TCO without heavy stack utilization. Let's start from simple example of recursive factorial calculation:

def fact(n):
    if n == 0: return 1
    return n * fact(n-1)

This variant works, but it's really ugly. Why? It will utilize memory too heavy cause of recursive storing all previous values to calculate final result. If you will execute this function with big n (more than sys.getrecursionlimit()) CPython will fail with

>>> import sys
>>> fact(sys.getrecursionlimit() * 2)
... many many lines of stacktrace ...
RuntimeError: maximum recursion depth exceeded

Which is good, cause it prevents you from terrible mistakes in your code.

How can we optimize this solution? Answer is simple, lets transform function to use tail call:

def fact(n, acc=1):
    if n == 0: return acc
    return fact(n-1, acc*n)

Why this variant is better? Cause you don't need to remember previous values to calculate final result. More about tail call optimization on Wikipedia. But... Python interpreter will execute this function the same way as previous one, so you won't win anything.

fn.recur.tco gives you mechanism to write "optimized a bit" tail call recursion (using "trampoline" approach):

from fn import recur

@recur.tco
def fact(n, acc=1):
    if n == 0: return False, acc
    return True, (n-1, acc*n)

@recur.tco is a decorator that execute your function in while loop and check output:

  • (False, result) means that we finished
  • (True, args, kwargs) means that we need to call function again with other arguments
  • (func, args, kwargs) to switch function to be executed inside while loop

The last variant is really useful, when you need to switch callable inside evaluation loop. Good example for such situation is recursive detection if given number is odd or even:

>>> from fn import recur
>>> @recur.tco
... def even(x):
...     if x == 0: return False, True
...     return odd, (x-1,)
...
>>> @recur.tco
... def odd(x):
...     if x == 0: return False, False
...     return even, (x-1,)
...
>>> print even(100000)
True

Attention: be careful with mutable/immutable data structures processing.

Itertools recipes

fn.uniform provides you with "unification" of lazy functionality for few functions to work the same way in Python 2+/3+:

  • map (returns itertools.imap in Python 2+)
  • filter (returns itertools.ifilter in Python 2+)
  • reduce (returns functools.reduce in Python 3+)
  • zip (returns itertools.izip in Python 2+)
  • range (returns xrange in Python 2+)
  • filterfalse (returns itertools.ifilterfalse in Python 2+)
  • zip_longest (returns itertools.izip_longest in Python 2+)
  • accumulate (backported to Python < 3.3)

fn.iters is high-level recipes to work with iterators. Most of them taken from Python docs and adopted to work both with Python 2+/3+. Such recipes as drop, takelast, droplast, splitat, splitby I have already submitted as docs patch which is review status just now.

  • take, drop
  • takelast, droplast
  • head (alias: first), tail (alias: rest)
  • second, ffirst
  • compact, reject
  • every, some
  • iterate
  • consume
  • nth
  • padnone, ncycles
  • repeatfunc
  • grouper, powerset, pairwise
  • roundrobin
  • partition, splitat, splitby
  • flatten
  • iter_except
  • first_true

More information about use cases you can find in docstrings for each function in source code and in test cases.

High-level operations with functions

fn.F is a useful function wrapper to provide easy-to-use partial application and functions composition.

from fn import F, _
from operator import add, mul

# F(f, *args) means partial application
# same as functools.partial but returns fn.F instance
assert F(add, 1)(10) == 11

# F << F means functions composition,
# so (F(f) << g)(x) == f(g(x))
f = F(add, 1) << F(mul, 100)
assert list(map(f, [0, 1, 2])) == [1, 101, 201]
assert list(map(F() << str << (_ ** 2) << (_ + 1), range(3))) == ["1", "4", "9"]

It also give you move readable in many cases "pipe" notation to deal with functions composition:

from fn import F, _
from fn.iters import filter, range

func = F() >> (filter, _ < 6) >> sum
assert func(range(10)) == 15

You can find more examples for compositions usage in fn._ implementation source code.

fn.op.apply executes given function with given positional arguments in list (or any other iterable). fn.op.flip returns you function that will reverse arguments order before apply.

from fn.op import apply, flip
from operator import add, sub

assert apply(add, [1, 2]) == 3
assert flip(sub)(20,10) == -10
assert list(map(apply, [add, mul], [(1,2), (10,20)])) == [3, 200]

fn.op.foldl and fn.op.foldr are folding operators. Each accepts function with arity 2 and returns function that can be used to reduce iterable to scalar: from left-to-right and from right-to-left in case of foldl and foldr respectively.

from fn import op, _

folder = op.foldr(_ * _, 1)
assert 6 == op.foldl(_ + _)([1,2,3])
assert 6 == folder([1,2,3])

Use case specific for right-side folding is:

from fn.op import foldr, call

assert 100 == foldr(call, 0 )([lambda s: s**2, lambda k: k+10])
assert 400 == foldr(call, 10)([lambda s: s**2, lambda k: k+10])

Function currying

fn.func.curried is a decorator for building curried functions, for example:

>>> from fn.func import curried
>>> @curried
... def sum5(a, b, c, d, e):
...     return a + b + c + d + e
...
>>> sum5(1)(2)(3)(4)(5)
15
>>> sum5(1, 2, 3)(4, 5)
15

Functional style for error-handling

fn.monad.Option represents optional values, each instance of Option can be either instance of Full or Empty. It provides you with simple way to write long computation sequences and get rid of many if/else blocks. See usage examples below.

Assume that you have Request class that gives you parameter value by its name. To get uppercase notation for non-empty striped value:

class Request(dict):
    def parameter(self, name):
        return self.get(name, None)

r = Request(testing="Fixed", empty="   ")
param = r.parameter("testing")
if param is None:
    fixed = ""
else:
    param = param.strip()
    if len(param) == 0:
        fixed = ""
    else:
        fixed = param.upper()

Hmm, looks ugly.. Update code with fn.monad.Option:

from operator import methodcaller
from fn.monad import optionable

class Request(dict):
    @optionable
    def parameter(self, name):
        return self.get(name, None)

r = Request(testing="Fixed", empty="   ")
fixed = r.parameter("testing")
         .map(methodcaller("strip"))
         .filter(len)
         .map(methodcaller("upper"))
         .get_or("")

fn.monad.Option.or_call is good method for trying several variant to end computation. I.e. use have Request class with optional attributes type, mimetype, url. You need to evaluate "request type" using at least one attribute:

from fn.monad import Option

request = dict(url="face.png", mimetype="PNG")
tp = Option \
        .from_value(request.get("type", None)) \ # check "type" key first
        .or_call(from_mimetype, request) \ # or.. check "mimetype" key
        .or_call(from_extension, request) \ # or... get "url" and check extension
        .get_or("application/undefined")

Installation

To install fn.py, simply:

$ pip install fn

Or, if you absolutely must:

$ easy_install fn

You can also build library from source

$ git clone https://github.com/kachayev/fn.py.git
$ cd fn.py
$ python setup.py install

Work in progress

"Roadmap":

  • fn.monad.Either to deal with error logging
  • C-accelerator for most modules

Ideas to think about:

  • Scala-style for-yield loop to simplify long map/filter blocks

Contribute

  1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
  2. Fork the repository on Github to start making your changes to the master branch (or branch off of it).
  3. Write a test which shows that the bug was fixed or that the feature works as expected.

How to find me

  • Twitter: @kachayev
  • Email: kachayev <at> gmail.com
Comments
  • Additional functions in fn.iters

    Additional functions in fn.iters

    Additional functions to be added to fn.iters (influenced by Underscore.js):

    • compact: filter out falsey items from iterable
    • reject: the opposite of filter
    • groupby: saner approach to itertools.groupby
    • countby: similar to groupby, but instead of sub-iterator, it yields a count for the number of items in each group

    Unit tests added. Tested with Python 2 (2.7) and Python 3 (3.3).

    Thanks for reviewing in advance. Any feedback, positive or negative, would be highly appreciated.

    Cheers, James

    opened by microamp 10
  • Scala-style partial operator binding fails on 3+ underscores.

    Scala-style partial operator binding fails on 3+ underscores.

    The current implementation of underscore.py fails with some scary-looking error messages if more than one underscore per operator is used. For example:

    > (_ + _ * _)(1, 2)
    TypeError: unsupported operand type(s) for +: 'int' and 'function'
    
      in <stdin> line 1, `<module>`: None
      in ./fn/underscore.py line 64, `__call__`: return curry(self._callback, *args)
      in ./fn/op.py line 27, `curry`: return curry(f(arg), *rest) if rest else f(arg)
      in ./fn/op.py line 27, `curry`: return curry(f(arg), *rest) if rest else f(arg)
      in ./fn/underscore.py line 18, `<lambda>`: call = lambda arg1: lambda arg2: f(self(arg1), other(arg2))
    

    Unfortunately, the current underscore implementation was too cryptic for me to understand :) That's why the attached commits rewrite it completely. But hey, at least it works now! :)

    > (_ + _ * _)(1, 2)
    <lambda>
    > (_ + _ * _)(1, 2, 3)
    7
    

    (As a side note, I took the liberty of changing the string representations so that the eval(repr(x)) == x rule holds.) (EDIT: Sorry if I messed up the pull request. I hope it won't be too hard to merge it. :)

    opened by pyos 8
  • how to use _ in a function

    how to use _ in a function

    I've try : print math.sin(_) it turn out to be wrong, but it works for: lambda x: math.sin(x)

    Does _ always be same as lambda caluse? any limitation? thx ~~

    opened by laocan 4
  • Fix #45 and #47

    Fix #45 and #47

    This should fix #45 and #47.

    The latter appears to be a bug in the PyPy version on Traivs (PyPy 2.2.1 with GCC 4.6.3) which seems to have been addressed in a later version. I could not reproduce the error with PyPy 2.3.0-alpha0 running locally. The alternative solution in the pull request is not as elegant as collections.namedtuple, but it would help us move on without having to wait for the next stable release of PyPy.

    In addition to the above two, I've

    • fixed a naming conflict issue between immutable.list.Deque and immutable.finger.Deque, and
    • added Python 3.4 to the Traivs config
    opened by microamp 4
  • about rock tail recursion

    about rock tail recursion


    @tail_call_optimized def even(x): if x == 0: return True return odd(x-1)

    @tail_call_optimized def odd(x): if x == 0: return False return even(x-1)

    print even(100000)

    can recur.tco resolve rock tail recursion?


    question 
    opened by pyloque 4
  • Made iters.flatten flatten nested iterables of any kind, not just lists

    Made iters.flatten flatten nested iterables of any kind, not just lists

    First off, thank you for fn.py.

    I feel like I've implemented flatten() or something like it on several projects. I thought I would contribute a version that doesn't require the input to be nested lists, but nested iterables of any sort (not including strings).

    I kept the original tests and added some for the additional behavior. I also changed the docstring to match the new behavior.

    I've tried to match my contribution to the existing style, but just let me know if I've missed anything.

    opened by calebsmith 4
  • (question) Folds implementation and reduce()

    (question) Folds implementation and reduce()

    I want to add foldl and foldr tomorrow, but I feel like this needs some discussion. CPython's builtin reduce() is a left-fold. Can/should we rely on this or should it be replaced with a custom left-fold implementation? reduce() should be faster, but the actual result of it is up to the implementation if I understand correctly.

    opened by K900 4
  • Strange _ behavior

    Strange _ behavior

    Hi! I ran your example and got this:

    In [1]: from fn.iters import map
    In [2]: from fn import _
    In [3]: list(map(_ * 2, range(5)))
    Out[3]: [0, 2, 4, 6, 8]
    In [4]: list(map(_ * 2, range(5)))
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-4-448bfa47eeda> in <module>()
    ----> 1 list(map(_ * 2, range(5)))
    TypeError: 'list' object is not callable
    

    python 2.7.3 windows 7 x64

    question 
    opened by pavlenko-volodymyr 4
  • Create aliases for iters.head (first) and iters.tail (rest)

    Create aliases for iters.head (first) and iters.tail (rest)

    iters.first and iters.rest as aliases for iters.head and iters.tail respectively, as used in programming languages like Clojure.

    first is already in use inside iters.iter_except, but the function is already complete and tested, hence such conflict wouldn't cause any harm in my opinion. Optionally, a trailing _ can be added to make it obvious, provided that it conforms to PEP 8 (http://www.python.org/dev/peps/pep-0008/). For example,

    if first_ is not None:
        ...
    
    opened by microamp 3
  • Fix error with __repl__ calculation for _ with getattr

    Fix error with __repl__ calculation for _ with getattr

    >>> from fn import _ as XXX
    >>> from fn.op import flip
    >>> print flip(XXX + XXX)
    (x1, x2, x3, x4, x5, x6) => getattr((x1 + x2), x3x4flipbackx5x6)
    
    bug 
    opened by kachayev 3
  • Lazily evaluate Stream slices

    Lazily evaluate Stream slices

    This pull request is meant to resolve #6. Right now I've just added a test for the behavior we want to accomplish (which may not even be entirely accurate, but is at least a start).

    Right now slicing a Stream seems to return a slice of the underlying collection, which you have implemented as a list. In order to make this lazily evaluated, I was wondering what you thought should be the return type. We could either return a new Stream based off the parameters of the index, or simply a generator. My inclination is to do the former, but I'm open to other suggestions.

    Your presentation on Functional Programming totally changed the way I write Python, and I'm a big Scala fan to begin with - I'm very excited to help on this package however I can :)

    opened by danielhfrank 3
  • There are wrong comments here

    There are wrong comments here

    class F(object):
        def __rshift__(self, g):
            """Overload << operator for F instances"""
            return self.__class__.__compose(self.__ensure_callable(g), self.f)
    
        def __lshift__(self, g):
            """Overload >> operator for F instances"""
            return self.__class__.__compose(self.f, self.__ensure_callable(g))
    

    the operator >> is right shift and << is left shift respectively

    opened by pppppkun 0
  • fix: import failure on Python >=3.10

    fix: import failure on Python >=3.10

    My worry is that this breaks backward compatibility because the typing module was added on Python 3.5 [1], so it would only work on Python 3.5 and above.

    We realized this because the nixpkgs CI [2] fails to package this library to be used by other dependents. It's not that a huge problem because basically all of the stuff depends on the version based on Python 3.9, that works fine [3].

    [1] https://docs.python.org/3/library/typing.html

    [2] https://hydra.nixos.org/job/nixpkgs/trunk/python310Packages.fn.x86_64-linux

    [3] https://hydra.nixos.org/job/nixpkgs/trunk/python39Packages.fn.x86_64-linux

    Closes https://github.com/kachayev/fn.py/issues/91 https://github.com/kachayev/fn.py/issues/86

    opened by lucasew 0
  • ImportError: cannot import name Iterable from collections on Python 3.10

    ImportError: cannot import name Iterable from collections on Python 3.10

    It just doesn't work. It expects Iterable from collections but this is not available.

    This log is from building python310Packages.fn with nix but should be reproducible on any python 3.10 out there

    Sourcing python-remove-tests-dir-hook
    Sourcing python-catch-conflicts-hook.sh
    Sourcing python-remove-bin-bytecode-hook.sh
    Sourcing setuptools-build-hook
    Using setuptoolsBuildPhase
    Using setuptoolsShellHook
    Sourcing pip-install-hook
    Using pipInstallPhase
    Sourcing python-imports-check-hook.sh
    Using pythonImportsCheckPhase
    Sourcing python-namespaces-hook
    Sourcing setuptools-check-hook
    Using setuptoolsCheckPhase
    @nix { "action": "setPhase", "phase": "unpackPhase" }
    unpacking sources
    unpacking source archive /nix/store/bhfhqwy9y6x63h4dq2lpimzkl0b2b29i-fn-0.4.3.tar.gz
    source root is fn-0.4.3
    setting SOURCE_DATE_EPOCH to timestamp 1407495729 of file fn-0.4.3/setup.cfg
    @nix { "action": "setPhase", "phase": "patchPhase" }
    patching sources
    @nix { "action": "setPhase", "phase": "configurePhase" }
    configuring
    no configure script, doing nothing
    @nix { "action": "setPhase", "phase": "buildPhase" }
    building
    Executing setuptoolsBuildPhase
    Traceback (most recent call last):
      File "/build/fn-0.4.3/nix_run_setup", line 8, in <module>
        exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))
      File "setup.py", line 6, in <module>
        import fn
      File "/build/fn-0.4.3/fn/__init__.py", line 1, in <module>
        from .stream import Stream
      File "/build/fn-0.4.3/fn/stream.py", line 9, in <module>
        from .iters import map, range
      File "/build/fn-0.4.3/fn/iters.py", line 2, in <module>
        from collections import deque, Iterable
    ImportError: cannot import name 'Iterable' from 'collections' (/nix/store/443qk9752l44kfp8pzsrp0m9jyq6jz2p-python3-3.10.3/lib/python3.10/collections/__init__.py)
    
    

    Backlinks: https://github.com/NixOS/nixpkgs/pull/167402

    opened by lucasew 1
  • API Documentation

    API Documentation

    Hi, interesting library!

    Do you have a function to use-case reference? Something similar to https://ramdajs.com/docs

    Coming back to Python from javascript and it's a difficulty curve for new users if they have to dig through the source to find use cases.

    If you don't have one, perhaps we could setup a Github action to generate the docs using pydoc or other, whenever a merge to master happens?

    opened by tavurth 1
Owner
Oleksii Kachaiev
Principal Software Engineer @ Riot Games. Tech Lead on League of Legends Data/ML/AI. Hobbies: algebras, theory of computation and symbolic reasoning.
Oleksii Kachaiev
Cython implementation of Toolz: High performance functional utilities

CyToolz Cython implementation of the toolz package, which provides high performance utility functions for iterables, functions, and dictionaries. tool

null 894 Jan 2, 2023
A functional standard library for Python.

Toolz A set of utility functions for iterators, functions, and dictionaries. See the PyToolz documentation at https://toolz.readthedocs.io LICENSE New

null 4.1k Jan 3, 2023
A fancy and practical functional tools

Funcy A collection of fancy functional tools focused on practicality. Inspired by clojure, underscore and my own abstractions. Keep reading to get an

Alexander Schepanovski 2.9k Dec 29, 2022
粤语编程语言.The Cantonese programming language.

粤语编程语言.The Cantonese programming language.

Stepfen Shawn 895 Dec 24, 2022
missing-pixel-filler is a python package that, given images that may contain missing data regions (like satellite imagery with swath gaps), returns these images with the regions filled.

Missing Pixel Filler This is the official code repository for the Missing Pixel Filler by SpaceML. missing-pixel-filler is a python package that, give

SpaceML 11 Jul 19, 2022
a simple functional programming language compiler written in python

Functional Programming Language A compiler for my small functional language. Written in python with SLY lexer/parser generator library. Requirements p

Ashkan Laei 3 Nov 5, 2021
This is a library to do functional programming in Python.

Fpylib This is a library to do functional programming in Python. Index Fpylib Index Features Intelligents Ranges with irange Lazyness to functions Com

Fabián Vega Alcota 4 Jul 17, 2022
Python library for creating data pipelines with chain functional programming

PyFunctional Features PyFunctional makes creating data pipelines easy by using chained functional operators. Here are a few examples of what it can do

Pedro Rodriguez 2.1k Jan 5, 2023
Used python functional programming to make this Ai assistant

Python-based-AI-Assistant I have used python functional programming to make this Ai assistant. Inspiration of project : we have seen in our daily life

Durgesh Kumar 2 Dec 26, 2021
Simple, elegant, Pythonic functional programming.

Coconut Coconut (coconut-lang.org) is a variant of Python that adds on top of Python syntax new features for simple, elegant, Pythonic functional prog

Evan Hubinger 3.6k Jan 3, 2023
Functional tensors for probabilistic programming

Funsor Funsor is a tensor-like library for functions and distributions. See Functional tensors for probabilistic programming for a system description.

null 208 Dec 29, 2022
Your own movie streaming service. Easy to install, easy to use. Download, manage and watch your favorite movies conveniently from your browser or phone. Install it on your server, access it anywhere and enjoy.

Vigilio Your own movie streaming service. Easy to install, easy to use. Download, manage and watch your favorite movies conveniently from your browser

Tugcan Olgun 141 Jan 6, 2023
Add Me To Your Group Enjoy With Me. Pyrogram bot. https://t.me/TamilSupport

SongPlayRoBot 3X Fast Telethon Based Bot ⚜ Open Source Bot ????‍?? Demo : SongPlayRoBot ???? Easy To Deploy ?? Click Below Image to Deploy DEPLOY Grou

IMVETRI 850 Dec 30, 2022
Tune in is a Collaborative Music Playing Systems where multiple guests can join a room and enjoy the song being played

✨A collaborative music playing systems?? where multiple guests can join a room ➡?? and enjoy the song?? being played.

Vedansh Vijaywargiya 8 Nov 5, 2022
This is a bot which you can use in telegram to spam without flooding and enjoy being in the leaderboard

Telegram-Count-spamming-Bot This is a bot which you can use in telegram to spam without flooding and enjoy being in the leaderboard You can avoid the

Lalan Kumar 1 Oct 23, 2021
These data visualizations were created as homework for my CS40 class. I hope you enjoy!

Data Visualizations These data visualizations were created as homework for my CS40 class. I hope you enjoy! Nobel Laureates by their Country of Birth

null 9 Sep 2, 2022
An 8D music player made to enjoy Halloween this year!🤘

HAPPY HALLOWEEN buddy! Split Player Hello There! Welcome to SplitPlayer... Supposed To Be A 8DPlayer.... You Decide.... It can play the ordinary audio

Akshat Kumar Singh 1 Nov 4, 2021
Enjoy Discords Unlimited Storage

Discord Storage V.3.5 (Beta) Made by BoKa Enjoy Discords free and unlimited storage... Prepare: Clone this from Github, make sure there either a folde

null 0 Dec 16, 2021
A static website generator for people who enjoy the simpler things in life.

A static website generator for people who enjoy the simpler things in life.

Darren Mulholland 93 Dec 22, 2022
You want to uto-update your private minecraft client? Give this to developer and enjoy!

minecraft-hack-installer You want to uto-update your private minecraft client? Give this to developer and enjoy! Steps to do: Install libraries: pip i

EuropeStudio 1 Jun 3, 2022