{ "info": { "author": "Sam et Max", "author_email": "lesametlemax@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Information Technology", "License :: OSI Approved :: zlib/libpng License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 3.6" ], "description": "***************************************************************************************\nOne-file utility module filled with helper functions for day to day Python programming\n***************************************************************************************\n\nThis is a subset of batbelt, with only the most used features, packed in a tiny file. This new version is Python 3.6+ only.\n\nSo, while you can `pip install minibelt`, you may just drop it in your project and forget about it.\n\nIt's under zlib licence.\n\n\nGet this value from an iterable/indexable or a default\n=======================================================\n\nget(indexable, \\*indices|keys, [default])\n------------------------------------------\n\nYou had a get() method on dict, but not on lists or tuple. Now you do ::\n\n >>> lst = range(10)\n >>> get(lst, 1, default='whatever_you_want')\n 1\n >>> get(lst, 100, default='whatever_you_want')\n 'whatever_you_want'\n\nPlus, you can chain look ups :\n\nThis::\n\n try:\n res = data['key'][0]['other key'][1]\n except (KeyError, IndexError):\n res = \"value\"\n\n\nBecomes::\n\n get(data, 'key', 0, 'other key', 1, default=\"value\")\n\n\nattrs(object, \\*attributes, [default])\n--------------------------------------\n\nAnd for attributes... ::\n\n devise = attr(car, 'insurance', 'expiration_date', 'timezone')\n\n\n\niget(iterable, index, [default])\n--------------------------------------\n\nYou can also get values at indices on any iterable, including generators :\n\n >>> iget(xrange(10), 0)\n 0\n >>> iget(xrange(10), 5)\n 5\n >>> iget(xrange(10), 10000, default='wololo')\n u'wololo'\n\n\n\nIteration tools missing in itertools\n===================================================================================\n\n\nchunks(iterable, size) and window(iterable, size)\n----------------------------------------------------\n\nIteration by chunk or with a sliding window::\n\n >>> l = range(10)\n >>> for chunk in chunks(l, 3):\n ... print list(chunk)\n ...\n [0, 1, 2]\n [3, 4, 5]\n [6, 7, 8]\n [9]\n >>> for slide in window(l, 3):\n ... print list(slide)\n ...\n [0, 1, 2]\n [1, 2, 3]\n [2, 3, 4]\n [3, 4, 5]\n [4, 5, 6]\n [5, 6, 7]\n [6, 7, 8]\n [7, 8, 9]\n\n\nflatten(deeply_nested_iterable)\n--------------------------------\n\nReturns a generator that lazily yield the items and\ndeals with up to hundred of levels of nesting (~800 on my machine,\nand you can control it with sys.setrecursionlimit) ::\n\n\n a = []\n for i in xrange(10):\n a = [a, i]\n print(a)\n\n [[[[[[[[[[[], 0], 1], 2], 3], 4], 5], 6], 7], 8], 9]\n\n print(list(flatten(a)))\n\n [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nIt works with most iterables, even of inifinite or unknown size.\n\n\nSorted Set\n===================================================================================\n\nSlow but useful data structure::\n\n >>> for x in sset((3, 2, 2, 2, 1, 2)):\n ... print x\n ...\n 3\n 2\n 1\n\n\nDictionaries one liners\n===================================================================================\n\n\ndmerge(dict, dict, [merge_function])\n--------------------------------------\n\nI wish '+'' was overloaded for dicts::\n\n >>> dmerge({\"a\": 1, \"b\": 2}, {\"b\": 2, \"c\": 3})\n {'a': 1, 'c': 3, 'b': 2}\n\n\nSometimes you do not want to simply overwrite the values inside the original dict, but merge them in custom fashion::\n\n >>> def my_merge(v1, v2):\n ... if isinstance(v1, dict) and isinstance(v2, dict):\n ... return dmerge(v1, v2)\n ... return v2\n >>> dmerge({\"a\": 1, \"b\": {'ok': 5}}, {\"b\": {'ko': 5 }, \"c\": 3}, my_merge)\n {'a': 1, 'c': 3, 'b': {'ko': 5, 'ok': 5}}\n\n\nsubdict(dict, [include], [exclude])\n-----------------------------------\n\nAnd for lazy people like me ::\n\n >>> subdict({'a': 1, 'b': 2, 'c': 3}, include=('a', 'b'))\n {'a': 1, 'b': 2}\n >>> subdict({'a': 1, 'b': 2, 'c': 3}, exclude=('c',))\n {'a': 1, 'b': 2}\n\n\nWhich is quite nice when you want a dict of some local variables (like in web framework functions returning responses such as Django, Flask or Bottle) ::\n\n\n >>> def test():\n ... a, b, c, d, e = range(5)\n ... return subdict(locals(), exclude=('d',))\n ...\n >>> test()\n {'a': 0, 'c': 2, 'b': 1, 'e': 4}\n\nThis works with any indexable, not just dicts.\n\nString tools\n===================================================================================\n\nnormalize(string)\n----------------------\n\n >>> normalize(u\"H\u00e9lo Whorde\")\n 'Helo Whorde'\n\n\nslugify(string)\n------------------\n\n >>> slugify(u\"H\u00e9lo Whorde\")\n helo-whorde\n\nYou get better slugification if you install the `unidecode` lib, but it's optional. You can specify `separator` if you don't like `-` or call directly `normalize()` (the underlying function) if you wish more control.\n\njson_dumps(struct) and json_loads(string)\n-----------------------------------------\n\nJSON helpers that handle date/time ::\n\n >>> import datetime\n >>> json_dumps({'test': datetime.datetime(2000, 1, 1, 1, 1, 1)})\n '{\"test\": \"2000-01-01 01:01:01.000000\"}'\n >>> json_dumps({'test': datetime.date(2000, 1, 1)})\n '{\"test\": \"2000-01-01\"}'\n >>> json_dumps({'test': datetime.time(1, 1, 1)})\n '{\"test\": \"01:01:01.000000\"}'\n >>> json_dumps({'test': datetime.timedelta(1, 1)})\n '{\"test\": \"timedelta(seconds=\\'86401.0\\')\"}'\n >>> json_dumps({u'test': datetime.timedelta(1, 1), u'a': [1, 2]})\n '{\"test\": \"timedelta(seconds=\\'86401.0\\')\", \"a\": [1, 2]}'\n\n >>> json_loads('{\"test\": \"2000-01-01 01:01:01.000000\"}')\n {u'test': datetime.datetime(2000, 1, 1, 1, 1, 1)}\n >>> json_loads('{\"test\": \"2000-01-01\"}')\n {u'test': datetime.date(2000, 1, 1)}\n >>> json_loads('{\"test\": \"01:01:01.000000\"}')\n {u'test': datetime.time(1, 1, 1)}\n >>> json_loads('{\"test\": \"timedelta(seconds=\\'86401.0\\')\"}')\n {u'test': datetime.timedelta(1, 1)}\n >>> json_loads('{\"test\": \"timedelta(seconds=\\'86401.0\\')\", \"a\": [1, 2]}')\n {u'test': datetime.timedelta(1, 1), u'a': [1, 2]}\n\nwrite(path, \\*args, encoding='utf8', mode='w', errors='replace')\n----------------------------------------------------------------\n\nWrite anything in one row to a file ::\n\n >>> s = '/tmp/test'\n >>> write(s, 'test', '\u00e9', 1, ['fdjskl'])\n >>> print open(s).read()\n test\n \u00e9\n 1\n ['fdjskl']\n\nIt will attempt decoding / encoding and casting automatically each value\nto a string.\n\nThis is an utility function : its slow and doesn't consider edge cases,\nbut allow to do just what you want most of the time in one line.\n\nYou can optionally pass :\n\n- mode : among 'a', 'w', which default to 'w'. Binary mode is forced.\n- encoding : which default to utf8 and will condition decoding AND encoding\n- errors : what to do when en encoding error occurs : 'replace' by default,\n which replace faulty caracters with '?'\n\nYou can pass string or unicode as \\*args, but if you pass strings,\nmake sure you pass them with the same encoding you wish to write to\nthe file.\n\n\nImport this\n===================================================================================\n\n\n`__import__` is weird. Let's abstract that ::\n\n YourClass = import_from_path('foo.bar.YourClass')\n obj = YourClass()\n\n\n\nAdd a any directory to the PYTHON PATH\n===========================================\n\nAccepts shell variables and relative paths :\n\n add_to_pythonpath(\"~/..\")\n\nYou can (and probably wants) specify a starting point if you pass a relative path. The default starting point is the result is `os.getcwd()` while you probably wants the directory containing you script. To to so, pass `__file__`:\n\n add_to_pythonpath(\"../..\", starting_point=__file__)\n\n`starting_point` can be a file path (basename will be stripped) or a directory name. It will be from there that the relative path will be calculated.\n\nYou can also choose where in the `sys.path` list your path will be added by passing `insertion_index`, which default to after the last existing item.\n\n\n\nTo timestamp\n=============\n\ndatetime.fromtimestamp exists but not the other away around, and it's not likely to change anytime soon (see: http://bugs.python.org/issue2736). In the meantime::\n\n >>> from datetime import datetime\n >>> to_timestamp(datetime(2000, 1, 1, 2, 1, 1))\n 946692061\n >>> datetime.fromtimestamp(946688461) # PYTHON, Y U NO HAZ TO_TIMESTAMP ?\n datetime.datetime(2000, 1, 1, 2, 1, 1)\n\n\nRemoving duplicates\n====================\n\nskip_duplicates returns a generator that will yield all objects from an iterable, skipping\nduplicates and preserving order ::\n\n >>> list(skip_duplicates([1, 2, 3, 4, 4, 2, 1, 3 , 4]))\n [1, 2, 3, 4]\n\nDuplicates are identified using the `key` function to calculate a\nunique fingerprint. This does not use natural equality, but the\nresult use a set() to remove duplicates, so defining __eq__\non your objects would have no effect.\n\nBy default the fingerprint is the object itself,\nwhich ensure the functions works as-is with iterable of primitives\nsuch as int, str or tuple.\n\nThe return value of `key` MUST be hashable, which means for\nnon hashable objects such as dict, set or list, you need to specify\na function that returns a hashable fingerprint ::\n\n\n >>> list(skip_duplicates(([], [], (), [1, 2], (1, 2)), lambda x: tuple(x)))\n [[], [1, 2]]\n >>> list(skip_duplicates(([], [], (), [1, 2], (1, 2)), lambda x: (type(x), tuple(x))))\n [[], (), [1, 2], (1, 2)]\n\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/sametmax/minibelt", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "minibelt", "package_url": "https://pypi.org/project/minibelt/", "platform": "", "project_url": "https://pypi.org/project/minibelt/", "project_urls": { "Homepage": "https://github.com/sametmax/minibelt" }, "release_url": "https://pypi.org/project/minibelt/0.2.1/", "requires_dist": null, "requires_python": "", "summary": "One-file utility module filled with helper functions for day to day Python programming", "version": "0.2.1" }, "last_serial": 5835155, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "517e158975e30c938ecf3d989d64ffb0", "sha256": "a47f7d6d0f41cd7e4776cab16bfd7508a7f6a1c4a955acd678adc91f88ba354c" }, "downloads": -1, "filename": "minibelt-0.1.tar.gz", "has_sig": false, "md5_digest": "517e158975e30c938ecf3d989d64ffb0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12336, "upload_time": "2013-10-21T10:31:48", "url": "https://files.pythonhosted.org/packages/d8/73/263ddf4b28c4dfcb753b32ad9a00110dcfa90e585233f0d670f9d211d03e/minibelt-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "fb1e909dea914c3d71dd339251799f37", "sha256": "fad2a7fc16dc5e9b25ee49df8b0c43572789423557c89325c4bdb23ad08ca859" }, "downloads": -1, "filename": "minibelt-0.1.1.tar.gz", "has_sig": false, "md5_digest": "fb1e909dea914c3d71dd339251799f37", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12334, "upload_time": "2013-11-23T21:10:26", "url": "https://files.pythonhosted.org/packages/70/89/b202833ace1d98af86fa893b987c093e652ef5493c5b4c8652f567111f6f/minibelt-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "c891d1b91b45e15db5fac61f1396ffe0", "sha256": "dde8e281bc8ea0c37f4fddd8187eb4ed7674eb85dc75cb7d12c294b09e6e0167" }, "downloads": -1, "filename": "minibelt-0.2.0.tar.gz", "has_sig": false, "md5_digest": "c891d1b91b45e15db5fac61f1396ffe0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13918, "upload_time": "2019-09-16T09:07:58", "url": "https://files.pythonhosted.org/packages/f6/33/f25d87174ab98c591574fb501dc3555c61ff2b6fef6464f35cac704c01d1/minibelt-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "506c98cf6b74754d3030c0700ad4165b", "sha256": "f61da097f2fcf24f1d14f8778d662aa0f15c99f75b4edb981298397c74315845" }, "downloads": -1, "filename": "minibelt-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "506c98cf6b74754d3030c0700ad4165b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12239, "upload_time": "2019-09-16T09:26:14", "url": "https://files.pythonhosted.org/packages/0b/9b/206454545aa8c6cde4eede6b0987da2e22184fde7ea9499839f4ef528d9d/minibelt-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1ff3bf3566b32c0a30eac1db62d791e4", "sha256": "f1f11749c0f02b29ab38aa44f63620509749de2d4e7be9807e090f3a6eac1962" }, "downloads": -1, "filename": "minibelt-0.2.1.tar.gz", "has_sig": false, "md5_digest": "1ff3bf3566b32c0a30eac1db62d791e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13913, "upload_time": "2019-09-16T09:26:18", "url": "https://files.pythonhosted.org/packages/d9/44/4fd5d2b2c22e367b9a7e4db693274c913c08f7bfa3fdd8b4993a459e0c57/minibelt-0.2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "506c98cf6b74754d3030c0700ad4165b", "sha256": "f61da097f2fcf24f1d14f8778d662aa0f15c99f75b4edb981298397c74315845" }, "downloads": -1, "filename": "minibelt-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "506c98cf6b74754d3030c0700ad4165b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12239, "upload_time": "2019-09-16T09:26:14", "url": "https://files.pythonhosted.org/packages/0b/9b/206454545aa8c6cde4eede6b0987da2e22184fde7ea9499839f4ef528d9d/minibelt-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1ff3bf3566b32c0a30eac1db62d791e4", "sha256": "f1f11749c0f02b29ab38aa44f63620509749de2d4e7be9807e090f3a6eac1962" }, "downloads": -1, "filename": "minibelt-0.2.1.tar.gz", "has_sig": false, "md5_digest": "1ff3bf3566b32c0a30eac1db62d791e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13913, "upload_time": "2019-09-16T09:26:18", "url": "https://files.pythonhosted.org/packages/d9/44/4fd5d2b2c22e367b9a7e4db693274c913c08f7bfa3fdd8b4993a459e0c57/minibelt-0.2.1.tar.gz" } ] }