{ "info": { "author": "F\u00e1bio Mac\u00eado Mendes", "author_email": "fabiomacedomendes@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "========\nSidekick\n========\n\nSidekick is a library that gives you functional superpowers.\n\n.. image:: https://travis-ci.org/fabiommendes/sidekick.svg?branch=master\n :target: https://travis-ci.org/fabiommendes/sidekick\n.. image:: https://codecov.io/gh/fabiommendes/sidekick/branch/master/graph/badge.svg?\n :target: https://codecov.io/gh/fabiommendes/sidekick\n.. image:: https://codeclimate.com/github/fabiommendes/sidekick/badges/gpa.svg?\n :target: https://codeclimate.com/github/fabiommendes/sidekick\n.. image:: https://codeclimate.com/github/fabiommendes/sidekick/badges/issue_count.svg?\n :target: https://codeclimate.com/github/fabiommendes/sidekick\n\n\nSidekick implements a functional standard library of functions and types designed\nto make functional programming more pleasant in Python. It uses modern Python\nfeatures and requires at least Python 3.6+.\n\nSidekick emphasizes working with immutable types and iterators. It also\nintroduces a special embedded syntax for handling function composition and\neasy creation of new functions.\n\n\n\nQuick start\n===========\n\nInstall it from pip...\n\n::\n\n $ pip install sidekick\n\n... and import a few important names\n\n>>> from sidekick.all import sk, op, X, Y, L, N\n\nThe examples bellow show a taste of what you can do.\n\n\n\nFibonacci numbers\n-----------------\n\nLet us start with the classics. This produces an infinite sequences of\nFibonacci numbers\n\n>>> fibonacci = sk.iterate_past((X + Y), [1, 1])\n>>> fibonacci | L[:10]\n[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n\n**Explanation**\n\n``iterate_past`` creates an infinite iterator that generates each number\nby applying the function in the first argument to the last n elements generated\nby the sequence. ``n`` is given by the size of the initial sequence, which in\nour example is 2. The Fibonacci sequence is obviously created by always adding\nthe last two elements.\n\nWe construct our summation function using the magic objects ``X`` and ``Y``.\nThey are function factories that return lambdas corresponding to the expression\nin which they participate. Hence, ``X + 1`` corresponds to ``lambda x: x +1``\nand ``X + Y`` to ``lambda x, y: x + y``. If you are familiar to any language in the\nHaskell family, it should resemble the `operator section syntax `.\n\nIn a similar vein, the ``L`` magic object that wraps many useful operations on lists.\nIn the example above, L[:10] creates a function that return a list slice\nin the range of 0 to 10 (not included). ``L[0]`` would create a function that fetches\nthe first element, ``L[::2]`` would fetch every two elements, and so on.\n\nFinally, the pipe notation passes the argument on the left to the function on\nthe right. This only works on sidekick enabled functions and mimics\nthe pipe in the unix shell. Maybe someday Python can have a native pipe operator\nlike `other functional languages `.\n\n\n\nGolden ratio\n------------\n\nThe snippet above only consumes the first 10 Fibonacci numbers. Let us continue\nto walk the sequence to find a good approximation to the golden ratio.\n\n>>> ratios = (y / x for (x, y) in sk.window(2, fibonacci))\n>>> sk.until_convergence((X == Y), ratios) | sk.last\n1.618033988749895\n\n**Explanation**\n\n``window`` produces a sliding window of n elements from the\noriginal sequence, e.g., ``sk.window(2, [1, 2, 3, 4])`` ==> ``(1, 2), (2, 3), (3, 4)``.\nThe generator comprehension then compute ratios using those consecutive elements.\n\nFinally, the second line iterate over a sequence until the predicate function\nin the first argument of ``sk.until_convergence`` returns True. Rather than\nsetting up some small interval of variation, we test for equality and wait\nfor the difference between two evaluations be smaller than floating point\nprecision.\n\n\n\nEuler number\n------------\n\nThe following snippet uses Taylor formula for exponentials\n$\\exp(x) = \\sum_{n=0}^{\\infty} \\frac {x^n} {n!}$to compute the Euler number\n\n>>> factorials = sk.iterate_indexed((X * Y), 1, start=1)\n>>> partial_sums = sk.sums(map((1 / X), factorials))\n>>> sk.until_convergence((X == Y), partial_sums) | sk.last\n2.7182818284590455\n\n**Explanation**\n\n``iterate_indexed`` iterates a function ``f(i, x)`` passing both the index\nof iteration and the last evaluation of x to generate the next result. By writing\nwrite down a few examples it is easy to see that the given arguments produce a\nsequence of factorials.\n\nThe second step creates a sequence of partial sums of the reciprocal of each\nfactorial. Finally, we iterate until convergence, testing if two consecutive\nelements are equal.\n\n\n\nSieve of Eratosthenes\n---------------------\n\nThe `Sieve of Eratosthenes `\nis a simple algorithm for selecting all primes in an list of consecutive integers.\nThe list must start with the first prime p (a.k.a., 2), and proceed by excluding\nevery p element. The next valid number will be a prime p'. The\nprocedure is repeated with each new prime until reaching the end of the list.\n\nWe will do it like so, except that the initial list of numbers is infinite.\n\n>>> def sieve(nums):\n... p, nums = sk.uncons(nums)\n... yield p\n... yield from sieve(n for n in nums if n % p != 0)\n>>> primes = sieve(N[2, 3, ...])\n>>> primes | L[:10]\n[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]\n\n**Explanation**\n\nThe fist line in the sieve function uses ``uncons`` to extract the first\nelement and return an iterator over the remaining ones. As we\ndescribed before, the first element is a prime, so we just yield it. The\nlast line of the function applies the sieve to a sequence that excludes every\nmultiple of p.\n\nFinally, we call sieve with the numbers ``2, 3, ...``. The numbers are created\nby the special object `N`, specialized in creating numeric sequences.\nIt is very flexible, and in the example above it\ncreates natural numbers starting from 2 and proceed indefinitely in steps\nof 1. In fact, we could easily make our code operate twice as fast simply\nby initializing the sieve with ``N[2, 3, 5, ...]`` so it would moves in steps\nof two rather than one. This would avoid checking even numbers which we known in\nadvance not be primes.\n\n\nSee also\n========\n\nSidekick is heavily inspired by other libraries and functional programming\nlanguages. Most notably,\n\n* `toolz`_: excellent utility library focused on handling iterators.\n* `placeholder`_, `fn.py`_, `funcy`_, `Pyrsistent`_: other functional programming libraries for Python.\n* `Haskell`_: an essential inspiration to functional programming. You will see many ideas stolen\n directly from Haskell. If you want to learn Haskell, however, I recommend learning `Elm`_ first ;)\n* `Clojure`_ and `Elixir`_: inspiration for many parts of the API.\n* `Lodash`_: a practical functional Javascript library.\n\n\n.. _toolz: https://toolz.readthedocs.io/en/latest/\n.. _placeholder: https://placeholder.readthedocs.io/en/latest/\n.. _fn.py: https://pypi.org/project/fn/\n.. _funcy: https://funcy.readthedocs.io/en/latest/\n.. _Pyrsistent: https://pyrsistent.readthedocs.io/en/latest/\n.. _Haskell: http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Data.html\n.. _Elm: https://elm-lang.org/\n.. _Clojure: https://clojuredocs.org/clojure.core\n.. _Elixir: https://hexdocs.pm/elixir/Kernel.html\n.. _Lodash: https://lodash.com/", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/fabiommendes/sidekick/", "keywords": "functional programming", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "sidekick", "package_url": "https://pypi.org/project/sidekick/", "platform": "", "project_url": "https://pypi.org/project/sidekick/", "project_urls": { "Homepage": "https://github.com/fabiommendes/sidekick/" }, "release_url": "https://pypi.org/project/sidekick/0.5.2/", "requires_dist": null, "requires_python": "", "summary": "The companion that gives you functional superpowers", "version": "0.5.2" }, "last_serial": 5696543, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "0904e48bfac4f08a49e7407661fd862d", "sha256": "ac65705c706dd37bcb37f5f48cc4b1bc82222b31af34449f5bcf3aa5087ac36e" }, "downloads": -1, "filename": "sidekick-0.0.1.tar.gz", "has_sig": false, "md5_digest": "0904e48bfac4f08a49e7407661fd862d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29165, "upload_time": "2017-07-26T04:03:05", "url": "https://files.pythonhosted.org/packages/a9/7f/f71f8d1a5034bd237044da0a289924f1afafe307a61c7da7660251b6f0ac/sidekick-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "580179f0446e331d85fcc1a7f8d87a4b", "sha256": "64ea6f599c5158b63b69188f5d06c2df91480176eb522542314d83e72c8d9673" }, "downloads": -1, "filename": "sidekick-0.0.2.tar.gz", "has_sig": false, "md5_digest": "580179f0446e331d85fcc1a7f8d87a4b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39807, "upload_time": "2017-08-08T01:53:24", "url": "https://files.pythonhosted.org/packages/86/71/8faddce0b403804b941ccfa03c0a64033f811da7b98f7647f0901bd721d7/sidekick-0.0.2.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "1eab0444462b9e64166baf28559e15f8", "sha256": "a28938d2b4a4249df34bab5992ecec4bee202acb64de4e0a35c2b89e7a095ea3" }, "downloads": -1, "filename": "sidekick-0.1.0.tar.gz", "has_sig": false, "md5_digest": "1eab0444462b9e64166baf28559e15f8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39745, "upload_time": "2017-08-24T00:23:55", "url": "https://files.pythonhosted.org/packages/43/ce/f9e8d36f1ef0ac2d29b83f90f4e41856395beed90a91fd6cfe787f5d71ea/sidekick-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "a4600369f3828963e50148f1e5c1f91e", "sha256": "1c7e16dc5519f8ed1139da6fa83ceb864b1dec4154f9bb6282b99149aab4b582" }, "downloads": -1, "filename": "sidekick-0.1.1.tar.gz", "has_sig": false, "md5_digest": "a4600369f3828963e50148f1e5c1f91e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39914, "upload_time": "2017-08-24T01:54:14", "url": "https://files.pythonhosted.org/packages/4b/a4/338203be6c9367922dbd3909a9443438e6f0c805010abe22737d4ef1f74d/sidekick-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "164b804b8aa082b4969f674f93c00372", "sha256": "b556f93bc50bdf8978d115f888f8d662b21b25dc08854d04a00e64139f026e3c" }, "downloads": -1, "filename": "sidekick-0.2.0.tar.gz", "has_sig": false, "md5_digest": "164b804b8aa082b4969f674f93c00372", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 36928, "upload_time": "2018-01-13T19:33:52", "url": "https://files.pythonhosted.org/packages/0f/88/062d0c1421bd3cb6d638e1bc524d303ab85a38140000e26908adfe13a6a5/sidekick-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "ab35eb8bf72f6949f54a1be4e4ee9da3", "sha256": "fc30805f81b41751de9f6866a37529d2cf6b2c43054657634ff7d358a5483a41" }, "downloads": -1, "filename": "sidekick-0.3.0.tar.gz", "has_sig": false, "md5_digest": "ab35eb8bf72f6949f54a1be4e4ee9da3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42141, "upload_time": "2018-05-10T04:09:32", "url": "https://files.pythonhosted.org/packages/b6/53/9bbc6b7c96544acf8ea789ebc2fa43ce5b3ec156b2c1dcb47934aab41395/sidekick-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "5488e931b34aa78de9d9aa8da5b00d5b", "sha256": "97851135e1b9be9f5117bae3d8dff9154fc777ad607f921bf9312e2e658181ff" }, "downloads": -1, "filename": "sidekick-0.3.1.tar.gz", "has_sig": false, "md5_digest": "5488e931b34aa78de9d9aa8da5b00d5b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42316, "upload_time": "2018-05-10T05:10:04", "url": "https://files.pythonhosted.org/packages/39/a4/cf6d1fed65dd209b295d07d506e536e438b86157342e887dc9fbe92fcedc/sidekick-0.3.1.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "0b62f71c6228939b7ef27ad91fdd9d88", "sha256": "ac37bfbdaefe0807d191f6314354d6d8056fb22f09591f6a244cd94ef8370118" }, "downloads": -1, "filename": "sidekick-0.4.0.tar.gz", "has_sig": false, "md5_digest": "0b62f71c6228939b7ef27ad91fdd9d88", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42162, "upload_time": "2018-05-16T21:57:57", "url": "https://files.pythonhosted.org/packages/3f/df/6712ec24e5a75973145f36ff3f56a11561d80d9c7a110fb3d7a0a318e9dc/sidekick-0.4.0.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "c3bdf2d0977eac3e059448dd79262955", "sha256": "67f2f5159be7914783eddc5257e399b03fb9ffe2e8523f1427fa198604aaaf25" }, "downloads": -1, "filename": "sidekick-0.4.1.tar.gz", "has_sig": false, "md5_digest": "c3bdf2d0977eac3e059448dd79262955", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42059, "upload_time": "2018-05-28T19:02:32", "url": "https://files.pythonhosted.org/packages/ea/76/4f02fa28227d4f94ef2b62b9aaf67d55b53e00f835f4cad4aa6a795392cd/sidekick-0.4.1.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "971e8848ab425e1e6e340d497470e92e", "sha256": "e3e29490a4517899c4e3530d61b3997f70ff5e9a28723d76fb4f58e917defc13" }, "downloads": -1, "filename": "sidekick-0.4.2.tar.gz", "has_sig": false, "md5_digest": "971e8848ab425e1e6e340d497470e92e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41941, "upload_time": "2018-06-10T17:45:02", "url": "https://files.pythonhosted.org/packages/b2/6a/214afa2338f1599dc4110e1bb16b0c7e46c8e08798d08979d0bfce4027cb/sidekick-0.4.2.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "60ed7ec9b7f5d848957a306b4bed1561", "sha256": "448f1f95f3362d155a69c58e9f6faad02b8a65b262c0bdcf2a616047fe6457eb" }, "downloads": -1, "filename": "sidekick-0.5.0.tar.gz", "has_sig": false, "md5_digest": "60ed7ec9b7f5d848957a306b4bed1561", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 64415, "upload_time": "2019-04-08T01:06:53", "url": "https://files.pythonhosted.org/packages/8d/9b/3524ebc23e300bf758af418820fec6651e2527e3f64d35a9e07cfe21ae89/sidekick-0.5.0.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "9c76a76761d7c97f50a0c84e44b54c78", "sha256": "e461253bd243061ecda6c04dc70f2d512b6d93caa890c9aa080aaeea8d19ef45" }, "downloads": -1, "filename": "sidekick-0.5.1.tar.gz", "has_sig": false, "md5_digest": "9c76a76761d7c97f50a0c84e44b54c78", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 64408, "upload_time": "2019-04-08T04:40:00", "url": "https://files.pythonhosted.org/packages/36/c6/f6bdf0fc77e8749f0eb4d6302211489f8675640f6971a1b94ea6f286b7fb/sidekick-0.5.1.tar.gz" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "9262a087e82ab981f928af23d3519798", "sha256": "3f1b2c65f2d9cadc4ad06ba57010d7aae0ef3eeff92a94ac3aadb9863b692a6a" }, "downloads": -1, "filename": "sidekick-0.5.2.tar.gz", "has_sig": false, "md5_digest": "9262a087e82ab981f928af23d3519798", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 64901, "upload_time": "2019-08-19T03:45:25", "url": "https://files.pythonhosted.org/packages/58/67/0ae6900774f87d465c48514bc90988edd66550ad65cb8097c3fbfbb59cf5/sidekick-0.5.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9262a087e82ab981f928af23d3519798", "sha256": "3f1b2c65f2d9cadc4ad06ba57010d7aae0ef3eeff92a94ac3aadb9863b692a6a" }, "downloads": -1, "filename": "sidekick-0.5.2.tar.gz", "has_sig": false, "md5_digest": "9262a087e82ab981f928af23d3519798", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 64901, "upload_time": "2019-08-19T03:45:25", "url": "https://files.pythonhosted.org/packages/58/67/0ae6900774f87d465c48514bc90988edd66550ad65cb8097c3fbfbb59cf5/sidekick-0.5.2.tar.gz" } ] }