lenses


Namelenses JSON
Version 1.2.0 PyPI version JSON
download
home_pagehttps://github.com/ingolemo/python-lenses
SummaryA lens library for python
upload_time2023-10-24 17:43:13
maintainer
docs_urlNone
authorAdrian Room
requires_python>=3.7, <4
licenseGPLv3+
keywords lens lenses immutable functional optics
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI
coveralls test coverage
            
Lenses
======

Lenses is a python library that helps you to manipulate large
data-structures without mutating them. It is inspired by the lenses in
Haskell, although it's much less principled and the api is more suitable
for python.


Installation
------------

You can install the latest version from pypi using pip like so::

    pip install lenses

You can uninstall similarly::

    pip uninstall lenses


Documentation
-------------

The lenses library makes liberal use of docstrings, which you can access
as normal with the ``pydoc`` shell command, the ``help`` function in
the repl, or by reading the source yourself.

Most users will only need the docs from ``lenses.UnboundLens``. If you
want to add hooks to allow parts of the library to work with custom
objects then you should check out the ``lenses.hooks`` module. Most of
the fancy lens code is in the ``lenses.optics`` module for those who
are curious how everything works.

Some examples are given in the `examples`_ folder and the `documentation`_
is available on ReadTheDocs.

.. _examples: examples
.. _documentation: https://python-lenses.readthedocs.io/en/latest/


Example
-------

.. code:: pycon

    >>> from pprint import pprint
    >>> from lenses import lens
    >>>
    >>> data = [{'name': 'Jane', 'scores': ['a', 'a', 'b', 'a']},
    ...         {'name': 'Richard', 'scores': ['c', None, 'd', 'c']},
    ...         {'name': 'Zoe', 'scores': ['f', 'f', None, 'f']}]
    ... 
    >>> format_scores = lens.Each()['scores'].Each().Instance(str).call_upper()
    >>> cheat = lens[2]['scores'].Each().set('a')
    >>>
    >>> corrected = format_scores(data)
    >>> pprint(corrected)
    [{'name': 'Jane', 'scores': ['A', 'A', 'B', 'A']},
     {'name': 'Richard', 'scores': ['C', None, 'D', 'C']},
     {'name': 'Zoe', 'scores': ['F', 'F', None, 'F']}]
    >>>
    >>> cheated = format_scores(cheat(data))
    >>> pprint(cheated)
    [{'name': 'Jane', 'scores': ['A', 'A', 'B', 'A']},
     {'name': 'Richard', 'scores': ['C', None, 'D', 'C']},
     {'name': 'Zoe', 'scores': ['A', 'A', 'A', 'A']}]


The definition of ``format_scores`` means "for each item in the data take
the value with the key of ``'scores'`` and then for each item in that list
that is an instance of ``str``, call its ``upper`` method on it". That one
line is the equivalent of this code:

.. code:: python

    def format_scores(data):
        results = []
        for entry in data:
            result = {}
            for key, value in entry.items():
                if key == 'scores':
                    new_value = []
                    for letter in value:
                        if isinstance(letter, str):
                            new_value.append(letter.upper())
                        else:
                            new_value.append(letter)
                    result[key] = new_value
                else:
                    result[key] = value
            results.append(result)
        return results

Now, this code can be simplified using comprehensions. But comprehensions
only work with lists, dictionaries, and sets, whereas the lenses library
can work with arbitrary python objects.

Here's an example that shows off the full power of this library:

.. code:: pycon

    >>> from lenses import lens
    >>> state = (("foo", "bar"), "!", 2, ())
    >>> lens.Recur(str).Each().Filter(lambda c: c <= 'm').Parts().call_mut_reverse()(state)
    (('!oo', 'abr'), 'f', 2, ())

This is an example from the `Putting Lenses to Work`__ talk about the
haskell lenses library by John Wiegley. We extract all the strings inside
of ``state``, extract the characters, filter out any characters that
come after ``'m'`` in the alphabet, treat these characters as if they
were a list, reverse that list, before finally placing these characters
back into the state in their new positions.

.. _putting_lenses_to_work: https://www.youtube.com/watch?v=QZy4Yml3LTY&t=2250

__ putting_lenses_to_work_

This example is obviously very contrived, but I can't even begin to
imagine how you would do this in python code without lenses.


License
-------

python-lenses is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along
with this program. If not, see http://www.gnu.org/licenses/.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ingolemo/python-lenses",
    "name": "lenses",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7, <4",
    "maintainer_email": "",
    "keywords": "lens lenses immutable functional optics",
    "author": "Adrian Room",
    "author_email": "ingolemo@gmail.com",
    "download_url": "",
    "platform": null,
    "description": "\nLenses\n======\n\nLenses is a python library that helps you to manipulate large\ndata-structures without mutating them. It is inspired by the lenses in\nHaskell, although it's much less principled and the api is more suitable\nfor python.\n\n\nInstallation\n------------\n\nYou can install the latest version from pypi using pip like so::\n\n    pip install lenses\n\nYou can uninstall similarly::\n\n    pip uninstall lenses\n\n\nDocumentation\n-------------\n\nThe lenses library makes liberal use of docstrings, which you can access\nas normal with the ``pydoc`` shell command, the ``help`` function in\nthe repl, or by reading the source yourself.\n\nMost users will only need the docs from ``lenses.UnboundLens``. If you\nwant to add hooks to allow parts of the library to work with custom\nobjects then you should check out the ``lenses.hooks`` module. Most of\nthe fancy lens code is in the ``lenses.optics`` module for those who\nare curious how everything works.\n\nSome examples are given in the `examples`_ folder and the `documentation`_\nis available on ReadTheDocs.\n\n.. _examples: examples\n.. _documentation: https://python-lenses.readthedocs.io/en/latest/\n\n\nExample\n-------\n\n.. code:: pycon\n\n    >>> from pprint import pprint\n    >>> from lenses import lens\n    >>>\n    >>> data = [{'name': 'Jane', 'scores': ['a', 'a', 'b', 'a']},\n    ...         {'name': 'Richard', 'scores': ['c', None, 'd', 'c']},\n    ...         {'name': 'Zoe', 'scores': ['f', 'f', None, 'f']}]\n    ... \n    >>> format_scores = lens.Each()['scores'].Each().Instance(str).call_upper()\n    >>> cheat = lens[2]['scores'].Each().set('a')\n    >>>\n    >>> corrected = format_scores(data)\n    >>> pprint(corrected)\n    [{'name': 'Jane', 'scores': ['A', 'A', 'B', 'A']},\n     {'name': 'Richard', 'scores': ['C', None, 'D', 'C']},\n     {'name': 'Zoe', 'scores': ['F', 'F', None, 'F']}]\n    >>>\n    >>> cheated = format_scores(cheat(data))\n    >>> pprint(cheated)\n    [{'name': 'Jane', 'scores': ['A', 'A', 'B', 'A']},\n     {'name': 'Richard', 'scores': ['C', None, 'D', 'C']},\n     {'name': 'Zoe', 'scores': ['A', 'A', 'A', 'A']}]\n\n\nThe definition of ``format_scores`` means \"for each item in the data take\nthe value with the key of ``'scores'`` and then for each item in that list\nthat is an instance of ``str``, call its ``upper`` method on it\". That one\nline is the equivalent of this code:\n\n.. code:: python\n\n    def format_scores(data):\n        results = []\n        for entry in data:\n            result = {}\n            for key, value in entry.items():\n                if key == 'scores':\n                    new_value = []\n                    for letter in value:\n                        if isinstance(letter, str):\n                            new_value.append(letter.upper())\n                        else:\n                            new_value.append(letter)\n                    result[key] = new_value\n                else:\n                    result[key] = value\n            results.append(result)\n        return results\n\nNow, this code can be simplified using comprehensions. But comprehensions\nonly work with lists, dictionaries, and sets, whereas the lenses library\ncan work with arbitrary python objects.\n\nHere's an example that shows off the full power of this library:\n\n.. code:: pycon\n\n    >>> from lenses import lens\n    >>> state = ((\"foo\", \"bar\"), \"!\", 2, ())\n    >>> lens.Recur(str).Each().Filter(lambda c: c <= 'm').Parts().call_mut_reverse()(state)\n    (('!oo', 'abr'), 'f', 2, ())\n\nThis is an example from the `Putting Lenses to Work`__ talk about the\nhaskell lenses library by John Wiegley. We extract all the strings inside\nof ``state``, extract the characters, filter out any characters that\ncome after ``'m'`` in the alphabet, treat these characters as if they\nwere a list, reverse that list, before finally placing these characters\nback into the state in their new positions.\n\n.. _putting_lenses_to_work: https://www.youtube.com/watch?v=QZy4Yml3LTY&t=2250\n\n__ putting_lenses_to_work_\n\nThis example is obviously very contrived, but I can't even begin to\nimagine how you would do this in python code without lenses.\n\n\nLicense\n-------\n\npython-lenses is free software: you can redistribute it and/or modify it\nunder the terms of the GNU General Public License as published by the\nFree Software Foundation, either version 3 of the License, or (at your\noption) any later version.\n\nThis program is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\nPublic License for more details.\n\nYou should have received a copy of the GNU General Public License along\nwith this program. If not, see http://www.gnu.org/licenses/.\n",
    "bugtrack_url": null,
    "license": "GPLv3+",
    "summary": "A lens library for python",
    "version": "1.2.0",
    "project_urls": {
        "Homepage": "https://github.com/ingolemo/python-lenses"
    },
    "split_keywords": [
        "lens",
        "lenses",
        "immutable",
        "functional",
        "optics"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fb066a7c30c3519181263e1bbf0cbea67ef4a43a64443ee16717c7d760214943",
                "md5": "92b27143b0ee2dcc3a4672e69d19510c",
                "sha256": "e03c81e35500e12e1d35504f76c26489c0a4e08b0881e96fc4e8a1b707c53f16"
            },
            "downloads": -1,
            "filename": "lenses-1.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "92b27143b0ee2dcc3a4672e69d19510c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7, <4",
            "size": 51113,
            "upload_time": "2023-10-24T17:43:13",
            "upload_time_iso_8601": "2023-10-24T17:43:13.950321Z",
            "url": "https://files.pythonhosted.org/packages/fb/06/6a7c30c3519181263e1bbf0cbea67ef4a43a64443ee16717c7d760214943/lenses-1.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-24 17:43:13",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ingolemo",
    "github_project": "python-lenses",
    "travis_ci": true,
    "coveralls": true,
    "github_actions": false,
    "tox": true,
    "lcname": "lenses"
}
        
Elapsed time: 0.12780s