pymaybe


Namepymaybe JSON
Version 0.1.6 PyPI version JSON
download
home_pagehttps://github.com/ekampf/pymaybe
SummaryA Python implementation of the Maybe pattern.
upload_time2015-09-28 21:23:47
maintainerNone
docs_urlNone
authorEran Kampf
requires_pythonNone
licenseBSD
keywords pymaybe
VCS
bugtrack_url
requirements wheel tox coverage flake8 Sphinx
Travis-CI
coveralls test coverage No coveralls.
            ===============================
PyMaybe
===============================

.. image:: https://travis-ci.org/ekampf/pymaybe.svg?branch=master
        :target: https://travis-ci.org/ekampf/pymaybe

.. image:: https://coveralls.io/repos/ekampf/pymaybe/badge.svg?branch=master&service=github
        :target: https://coveralls.io/github/ekampf/pymaybe?branch=master

.. image:: https://img.shields.io/pypi/v/pymaybe.svg
        :target: https://pypi.python.org/pypi/pymaybe

A Python implementation of the Maybe pattern.

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

::

    pip install pymaybe

Getting Started
---------------

::

    from pymaybe import maybe
    first_name = maybe(deep_hash)['account']['user_profile']['first_name'].or_else("<unknown>")

Documentation
-------------
Maybe monad is a programming pattern that allows to treat None values that same way as non-none values.
This is done by wrapping the value, which may or may not be None to, a wrapper class.

The implementation includes two classes: *Maybe* and *Something*.
*Something* represents a value while *Nothing* represents a None value.
There's also a method *maybe* which wraps a regular value and and returns *Something* or *Nothing* instance.

::

    >>> maybe("I'm a value")
    "I'm a value"

    >>> maybe(None);
    None

Both *Something* and *Nothing* implement 4 methods allowing you to test their real value: *is_some*, *is_none*, *get* and *or_else*

::

    >>> maybe("I'm a value").is_some()
    True

    >>> maybe("I'm a value").is_none()
    False

    >>> maybe(None).is_some()
    False

    >>> maybe(None).is_none()
    True

    >>> maybe("I'm a value").get()
    "I'm a value"

    >>> maybe("I'm a value").or_else(lambda: "No value")
    "I'm a value"

    >>> maybe(None).get()
    Traceback (most recent call last):
    ...
    Exception: No such element

    >>> maybe(None).or_else(lambda: "value")
    'value'

    >>> maybe(None).or_else("value")
    'value'

In addition, *Something* and *Nothing* implement the Python magic methods allowing you to treat them as dictionaries:

::
    >>> nested_dict = maybe(nested_dict)
    >>> nested_dict['store']['name']
    'MyStore'

    >>> nested_dict['store']['address']
    None

    >>> nested_dict['store']['address']['street'].or_else('No Address Specified')
    'No Address Specified'

All other method calls on *Something* are forwarded to its real *value*:

::

    >>> maybe('VALUE').lower()
    'value'

    >>> maybe(None).invalid().method().or_else('unknwon')
    'unknwon'

Examples & Use Cases
--------------------

The Maybe pattern helps you avoid nasty try..except blocks.
Consider the following code:

::
    try:
        url = rss.load_feeds()[0].url.domain
    except (TypeError, IndexError, KeyError, AttributeError):
        url = "planetpython.org"

With Maybe you could simply do:

::

    url = maybe(rss).load_feeds()[0]['url'].domain.or_else("planetpython.org")

Getting the current logged in user's name.
Without maybe:

::

    def get_user_zipcode():
        address = getattr(request.user, 'address', None)
        if address:
            return getattr(address, 'zipcode', '')

        return ''

With maybe:

::

    def get_user_zipcode():
        return maybe(request.user).address.zipcode.or_else('')

Further Reading
---------------

* `Option (Scala) <http://www.scala-lang.org/api/current/scala/Option.html>`_
* `Maybe (Java) <https://github.com/npryce/maybe-java>`_
* `Maybe pattern (Python recipe) <http://code.activestate.com/recipes/577248-maybe-pattern/>`_
* `Data.Maybe (Haskell) <http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html>`_
* `Maybe (Ruby) <https://github.com/bhb/maybe>`_

Copyright and License
---------------------
Copyright 2015 - `Eran Kampf <http://www.developerzen.com>`_

* Free software: BSD license
* Documentation: https://pymaybe.readthedocs.org.
* Code is hosted on `GitHub <http://www.github.com/ekampf/pymaybe>`_




History
-------

0.1.0 (2015-01-11)
---------------------

* First release on PyPI.
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ekampf/pymaybe",
    "name": "pymaybe",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "pymaybe",
    "author": "Eran Kampf",
    "author_email": "eran@ekampf.com",
    "download_url": "https://files.pythonhosted.org/packages/fe/86/0bbefee601f7f5ce5fdd11ee59cbae36ce9cb48b96c44f960f38cbfe6d0a/pymaybe-0.1.6.tar.gz",
    "platform": "UNKNOWN",
    "description": "===============================\nPyMaybe\n===============================\n\n.. image:: https://travis-ci.org/ekampf/pymaybe.svg?branch=master\n        :target: https://travis-ci.org/ekampf/pymaybe\n\n.. image:: https://coveralls.io/repos/ekampf/pymaybe/badge.svg?branch=master&service=github\n        :target: https://coveralls.io/github/ekampf/pymaybe?branch=master\n\n.. image:: https://img.shields.io/pypi/v/pymaybe.svg\n        :target: https://pypi.python.org/pypi/pymaybe\n\nA Python implementation of the Maybe pattern.\n\nInstallation\n------------\n\n::\n\n    pip install pymaybe\n\nGetting Started\n---------------\n\n::\n\n    from pymaybe import maybe\n    first_name = maybe(deep_hash)['account']['user_profile']['first_name'].or_else(\"<unknown>\")\n\nDocumentation\n-------------\nMaybe monad is a programming pattern that allows to treat None values that same way as non-none values.\nThis is done by wrapping the value, which may or may not be None to, a wrapper class.\n\nThe implementation includes two classes: *Maybe* and *Something*.\n*Something* represents a value while *Nothing* represents a None value.\nThere's also a method *maybe* which wraps a regular value and and returns *Something* or *Nothing* instance.\n\n::\n\n    >>> maybe(\"I'm a value\")\n    \"I'm a value\"\n\n    >>> maybe(None);\n    None\n\nBoth *Something* and *Nothing* implement 4 methods allowing you to test their real value: *is_some*, *is_none*, *get* and *or_else*\n\n::\n\n    >>> maybe(\"I'm a value\").is_some()\n    True\n\n    >>> maybe(\"I'm a value\").is_none()\n    False\n\n    >>> maybe(None).is_some()\n    False\n\n    >>> maybe(None).is_none()\n    True\n\n    >>> maybe(\"I'm a value\").get()\n    \"I'm a value\"\n\n    >>> maybe(\"I'm a value\").or_else(lambda: \"No value\")\n    \"I'm a value\"\n\n    >>> maybe(None).get()\n    Traceback (most recent call last):\n    ...\n    Exception: No such element\n\n    >>> maybe(None).or_else(lambda: \"value\")\n    'value'\n\n    >>> maybe(None).or_else(\"value\")\n    'value'\n\nIn addition, *Something* and *Nothing* implement the Python magic methods allowing you to treat them as dictionaries:\n\n::\n    >>> nested_dict = maybe(nested_dict)\n    >>> nested_dict['store']['name']\n    'MyStore'\n\n    >>> nested_dict['store']['address']\n    None\n\n    >>> nested_dict['store']['address']['street'].or_else('No Address Specified')\n    'No Address Specified'\n\nAll other method calls on *Something* are forwarded to its real *value*:\n\n::\n\n    >>> maybe('VALUE').lower()\n    'value'\n\n    >>> maybe(None).invalid().method().or_else('unknwon')\n    'unknwon'\n\nExamples & Use Cases\n--------------------\n\nThe Maybe pattern helps you avoid nasty try..except blocks.\nConsider the following code:\n\n::\n    try:\n        url = rss.load_feeds()[0].url.domain\n    except (TypeError, IndexError, KeyError, AttributeError):\n        url = \"planetpython.org\"\n\nWith Maybe you could simply do:\n\n::\n\n    url = maybe(rss).load_feeds()[0]['url'].domain.or_else(\"planetpython.org\")\n\nGetting the current logged in user's name.\nWithout maybe:\n\n::\n\n    def get_user_zipcode():\n        address = getattr(request.user, 'address', None)\n        if address:\n            return getattr(address, 'zipcode', '')\n\n        return ''\n\nWith maybe:\n\n::\n\n    def get_user_zipcode():\n        return maybe(request.user).address.zipcode.or_else('')\n\nFurther Reading\n---------------\n\n* `Option (Scala) <http://www.scala-lang.org/api/current/scala/Option.html>`_\n* `Maybe (Java) <https://github.com/npryce/maybe-java>`_\n* `Maybe pattern (Python recipe) <http://code.activestate.com/recipes/577248-maybe-pattern/>`_\n* `Data.Maybe (Haskell) <http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html>`_\n* `Maybe (Ruby) <https://github.com/bhb/maybe>`_\n\nCopyright and License\n---------------------\nCopyright 2015 - `Eran Kampf <http://www.developerzen.com>`_\n\n* Free software: BSD license\n* Documentation: https://pymaybe.readthedocs.org.\n* Code is hosted on `GitHub <http://www.github.com/ekampf/pymaybe>`_\n\n\n\n\nHistory\n-------\n\n0.1.0 (2015-01-11)\n---------------------\n\n* First release on PyPI.",
    "bugtrack_url": null,
    "license": "BSD",
    "summary": "A Python implementation of the Maybe pattern.",
    "version": "0.1.6",
    "split_keywords": [
        "pymaybe"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "5e37221b3280109ea436700a996ec747",
                "sha256": "01d0f71b98e1c155ecfecd9db44ce49f37ae374b5cb8f1d27c0ee00c3d7aa4dd"
            },
            "downloads": -1,
            "filename": "pymaybe-0.1.6-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5e37221b3280109ea436700a996ec747",
            "packagetype": "bdist_wheel",
            "python_version": "2.7",
            "requires_python": null,
            "size": 7826,
            "upload_time": "2015-09-28T21:23:53",
            "upload_time_iso_8601": "2015-09-28T21:23:53.940342Z",
            "url": "https://files.pythonhosted.org/packages/83/f8/3bd91975bfbed25e453589d079cbf4f8f0b44a9cf6a82bfebbd69506b060/pymaybe-0.1.6-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "30c7a1af361f327abb0e58191072ae01",
                "sha256": "77ed1602e1b9e8b05dccd0d84891ede4ee2004728170e52af7f9c08d4c62378c"
            },
            "downloads": -1,
            "filename": "pymaybe-0.1.6.tar.gz",
            "has_sig": false,
            "md5_digest": "30c7a1af361f327abb0e58191072ae01",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 16670,
            "upload_time": "2015-09-28T21:23:47",
            "upload_time_iso_8601": "2015-09-28T21:23:47.688354Z",
            "url": "https://files.pythonhosted.org/packages/fe/86/0bbefee601f7f5ce5fdd11ee59cbae36ce9cb48b96c44f960f38cbfe6d0a/pymaybe-0.1.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2015-09-28 21:23:47",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "ekampf",
    "github_project": "pymaybe",
    "travis_ci": true,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "wheel",
            "specs": [
                [
                    "==",
                    "0.23.0"
                ]
            ]
        },
        {
            "name": "tox",
            "specs": []
        },
        {
            "name": "coverage",
            "specs": []
        },
        {
            "name": "flake8",
            "specs": []
        },
        {
            "name": "Sphinx",
            "specs": []
        }
    ],
    "tox": true,
    "lcname": "pymaybe"
}
        
Elapsed time: 0.02500s