{ "info": { "author": "Ad115", "author_email": "a.garcia230395@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Information Technology", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3 :: Only", "Topic :: Scientific/Engineering :: Artificial Life", "Topic :: Scientific/Engineering :: Bio-Informatics", "Topic :: Scientific/Engineering :: Medical Science Apps.", "Topic :: Software Development", "Topic :: Software Development :: Libraries", "Topic :: Text Processing", "Topic :: Utilities" ], "description": "Generic tree utilities for Python\n=================================\n\nTrees are one of the most ubiquitous data structures. It is amazing how often we \nas programmers tend to reimplement the same algorithms for different tree \nformats and stuctures.\n\nThis module defines generic tree-traverse and tree-reduce algorithms that can be\nused with any tree-like object such as filesystem paths, lists, nested \ndictionaries an expression tree or even specialized tree classes! The only thing \nthat must be provided is a function to get child nodes from a parent node.\n\nAlso, trees are usually represented in some fields (such as bioinformatics) in \nthe newick format, which is nontrivial to parse, so this module includes a \nfunction to do this.\n\n\nUsage and examples\n------------------\n\nInstall from [PyPi](https://pypi.org/project/treet/):\n\n```\npip install treet\n```\n\nImport the basic functions, `traverse`, `reduce` and `parse_newick`:\n\n```python\n\nimport treet\n```\n\n### Use with any kind of structured tree!\n\nAny kind of structured data is supported, in this case, nested dictionaries:\n\n```python\n\ntree = {\n 'label':'A', 'children':[\n {'label':'B', 'children':[]},\n {'label':'C', 'children': [\n {'label':'D', 'children':[]}, \n {'label':'E', 'children':[]}\n ]}\n ]\n}\n\ndef children(node):\n return node['children']\n\n[node['label'] \n for node in treet.traverse(tree, children, mode='inorder')]\n\n# Output --> ['B, 'A', 'D', 'C', 'E']\n\ndef as_list(node, children):\n if not children:\n return node['label']\n else:\n return children\n\ntreet.reduce(tree, children, reduce_fn=as_list)\n\n# Output --> ['B, ['D', 'E']]\n```\n\n### Even with user-defined classes!\n\nDump a tree in a specialized class format to a string in the newick format.\n\n```python\n\nclass Tree:\n def __init__(self, label, children=None):\n self.label = label\n self.children = children if children else []\n\n def is_leaf(self):\n return len(self.children) == 0\n\ntree = Tree('A', [\n Tree('B'),\n Tree('C',[Tree('D'),Tree('E')])\n ]\n)\n\ndef get_children(node):\n return node.children\n\ndef node_to_newick(node, children):\n if node.is_leaf():\n return node.label\n else:\n return f\"({','.join(children)})\"\n\n\ntreet.reduce(tree, get_children, node_to_newick)\n\n# Output --> '(B,(D,E))'\n```\n\n### Parse a newick-formatted tree structure\n\nAssemble the Newick string to a custom data format:\n\n```python\n\ndef parse_node_data(data_string):\n '''\n Example: \n 'data1=xx,data2=yy' \n -> {'data1':'xx', 'data2': 'yy'}\n '''\n items = data_string.split(',')\n key_value_pairs = (item.split('=') for item in items)\n return dict(key_value_pairs)\n\ndef parse_branch_length(length_str):\n return float(length_str) if length_str else 0.0\n\ndef tree_builder(label, children, branch_length, node_data):\n return {\n 'label': label,\n 'length': branch_length,\n 'data': node_data,\n 'children': children}\n\nnewick = \"(A:0.2[dat=23,other=45], B:12.4[dat=122,other=xyz])root[x=y];\"\n\ntreet.parse_newick(\n newick,\n aggregator=tree_builder,\n feature_parser=parse_node_data,\n distance_parser=parse_branch_length\n)\n\n# Output ->\n{'label': 'root', 'length':0.0, 'data': {'x':'y'},\n 'children': [\n {'label': 'A', 'length':0.2, 'data':{'dat':'23','other':'45'}, \n 'children': []},\n {'label': 'B', 'length':12.4, 'data':{'dat':'122','other':'xyz'},\n 'children': []}, \n]}\n```\n\n### Compose to perform complex algorithms\n\nGet the subtree induced by a subset of the leaves:\n\n```python\n\ntree = (('A',('B',('C','D'))),'E')\n\ndef is_leaf(node): \n return isinstance(node, str)\n\ndef get_children(node):\n return node if not is_leaf(node) else []\n\ndef induced_subtree(leafs):\n def induced_subtree_generator(node, children):\n if children:\n return tuple(ch for ch in children if not ch is None)\n else:\n return node if node in leafs else None\n return induced_subtree_generator\n\nleafs = ['B', 'D', 'E']\ninduced = treet.reduce(tree, get_children, induced_subtree(leafs))\nprint(induced)\n\n# Output --> ((('B',('D',)),),'E')\n\n\ndef merge_unary_nodes(node, children):\n if is_leaf(node):\n return node\n\n new_children = [\n ch[0] if (len(ch) == 1) else ch\n for ch in children\n ]\n return tuple(new_children)\n\ntreet.reduce(induced, get_children, merge_unary_nodes)\n\n# Output --> (('B','D'),'E')\n```\n\n### Use even with filesystem paths!\n\nTraverse the `/usr` directory in breadth-first order:\n\n```python\nfrom pathlib import Path\n\ndef enter_folder(path):\n path = Path(path)\n return list(path.iterdir()) if path.is_dir() else []\n\nfor item in treet.traverse('/usr', enter_folder, mode='breadth_first'):\n print(item)\n\n# Output -->\n# /\n# /proc\n# /usr\n# ...\n# /usr/share\n# /usr/bin\n# /usr/sbin\n# ...\n# /usr/bin/jinfo\n# /usr/bin/m2400w\n# ...\n```\n\nMeta\n----\n\n**Author**: [Ad115](https://agargar.wordpress.com/) - \n [Github](https://github.com/Ad115/) \u2013 a.garcia230395@gmail.com\n\nDistributed under the MIT license. See [LICENSE](https://github.com/Ad115/treet/blob/master/LICENSE) more information.\n\n\nContributing\n------------\nTo run tests: `pytest treet/* --hypothesis-show-statistics --verbose`\n\nTo run static type check: `mypy treet/*.py`\n\nTo run coverage analysis: `coverage run --source=. -m pytest treet/* --hypothesis-show-statistics --verbose`\n\n1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.\n2. Fork [the repository](https://github.com/Ad115/treet/) on GitHub to start making your changes to a feature branch, derived from the **master** branch.\n3. Write a test which shows that the bug was fixed or that the feature works as expected.\n4. Send a pull request and bug the maintainer until it gets merged and published.\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Ad115/python-treet", "keywords": "tree hierarchical generic newick traverse reduce", "license": "", "maintainer": "", "maintainer_email": "", "name": "treet", "package_url": "https://pypi.org/project/treet/", "platform": "", "project_url": "https://pypi.org/project/treet/", "project_urls": { "Author": "https://agargar.wordpress.com/", "Documentation": "https://github.com/Ad115/python-treet", "Homepage": "https://github.com/Ad115/python-treet", "Say Thanks!": "https://saythanks.io/to/Ad115" }, "release_url": "https://pypi.org/project/treet/1.0.5/", "requires_dist": [ "pytest ; extra == 'dev'", "hypothesis ; extra == 'dev'", "coverage ; extra == 'dev'", "mypy ; extra == 'dev'" ], "requires_python": "", "summary": "Simple, minimal, but powerful tools to handle any kind of hierarchical (tree) structures", "version": "1.0.5" }, "last_serial": 5982447, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "4e22db68b77dc77582f97762ee63042f", "sha256": "89914ae1e5831a5be8d974795b48663191bd162e8f6576fbeec7b41e1da9e80f" }, "downloads": -1, "filename": "treet-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "4e22db68b77dc77582f97762ee63042f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 14958, "upload_time": "2019-10-16T09:21:32", "url": "https://files.pythonhosted.org/packages/73/8e/5e04c7ba48f8aa2409198e33ddc17bdd4fbb0c65175171a3e34acffe1fa2/treet-1.0.0-py3-none-any.whl" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "e26fca274f65e1b24e6f7471aece8235", "sha256": "6ea58200a6e3fc69438cc15ad01b4c147d780c5e9fda94c762b5312ace5e7f50" }, "downloads": -1, "filename": "treet-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "e26fca274f65e1b24e6f7471aece8235", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15049, "upload_time": "2019-10-16T09:36:55", "url": "https://files.pythonhosted.org/packages/5c/0c/2004dd5d925093d5ddaff36b6e62caf46cf8d73757d1a35de8d942da3cae/treet-1.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6d702c469d03a38cbae868d5a2c6d893", "sha256": "0d1c51d8924eb09387c6ae32db2251ecc245b057e4d4221e852ec82f80132d44" }, "downloads": -1, "filename": "treet-1.0.1.tar.gz", "has_sig": false, "md5_digest": "6d702c469d03a38cbae868d5a2c6d893", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14096, "upload_time": "2019-10-16T09:36:56", "url": "https://files.pythonhosted.org/packages/b0/fc/6edf33ef2cb36e3ae559ca1a694440a7472bc8e736d699b06ab624a990c5/treet-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "8953d8ebaa9208ba338203cd44514869", "sha256": "8c7ec97782165204c14fced6eaadeec0c9d80df05b19765ece8871af75fe16f2" }, "downloads": -1, "filename": "treet-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "8953d8ebaa9208ba338203cd44514869", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15053, "upload_time": "2019-10-16T09:37:56", "url": "https://files.pythonhosted.org/packages/5c/1d/8a6ac7105f4538ec01aecd77674b3277093245dc2c51ccaa5525fb512745/treet-1.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f0031f258a3db6a237f9a61600878bd5", "sha256": "f1f9ce3406f9ab9e3a5d77e31ca0c64cd4bdac8584517d58c77ec8d3d6d06d89" }, "downloads": -1, "filename": "treet-1.0.2.tar.gz", "has_sig": false, "md5_digest": "f0031f258a3db6a237f9a61600878bd5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14083, "upload_time": "2019-10-16T09:37:59", "url": "https://files.pythonhosted.org/packages/b1/55/3e7b18a734b0a229fb5c652675b30b590abadf0553d393ed11bfef99d87a/treet-1.0.2.tar.gz" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "0d072a38c55c2b283e5c8ca97d077eae", "sha256": "eb2f1a0c6ba2dff54190860a8f9ea70e3994216546ed0d90322673899513cc35" }, "downloads": -1, "filename": "treet-1.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "0d072a38c55c2b283e5c8ca97d077eae", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15012, "upload_time": "2019-10-16T09:53:06", "url": "https://files.pythonhosted.org/packages/73/53/7ad48270a08042686487f9abd3588ce4265677b61629cadcd0e93542371b/treet-1.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "be14a3dfa41268620dadc3e40011bffa", "sha256": "3f1108ee3ec88e6a0bc1cc4bf2ddda36fb7e2506908af81b745abd95afbbf0c2" }, "downloads": -1, "filename": "treet-1.0.3.tar.gz", "has_sig": false, "md5_digest": "be14a3dfa41268620dadc3e40011bffa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14220, "upload_time": "2019-10-16T09:53:08", "url": "https://files.pythonhosted.org/packages/f0/5f/ce9356939e28b4974b77a15413201d3f57fc6de78ffa7b725c1045d90d96/treet-1.0.3.tar.gz" } ], "1.0.4": [ { "comment_text": "", "digests": { "md5": "b63e57cd8c10a8f007393d5379035ade", "sha256": "07007315f0b619a6fffaffd2912476e1c2711d107fae474466196a71f14f2ae0" }, "downloads": -1, "filename": "treet-1.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "b63e57cd8c10a8f007393d5379035ade", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15438, "upload_time": "2019-10-16T10:24:59", "url": "https://files.pythonhosted.org/packages/51/9e/5b4351f6628916a64dc1093a6ba0dbaac5e560d454287fb9d436737dc5fb/treet-1.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "05037d9d82e2f5ff41c16a1c916edd2e", "sha256": "c17fa8833c044c72795c0f34d2c7609515d83592a6757a0d2dd35ba9338c37b0" }, "downloads": -1, "filename": "treet-1.0.4.tar.gz", "has_sig": false, "md5_digest": "05037d9d82e2f5ff41c16a1c916edd2e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15018, "upload_time": "2019-10-16T10:25:02", "url": "https://files.pythonhosted.org/packages/86/43/f5b084e4a6c70dd9ecff359cd16eeab55f1a1a0228cbc7e4d8e6b1f5b512/treet-1.0.4.tar.gz" } ], "1.0.5": [ { "comment_text": "", "digests": { "md5": "92498ac2fd87bf6557b3461113a61554", "sha256": "f6e9d7f0ae92b2b502dea1dcf400206d58c55b42e4370c382283a9bd2a95366f" }, "downloads": -1, "filename": "treet-1.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "92498ac2fd87bf6557b3461113a61554", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15438, "upload_time": "2019-10-16T10:28:45", "url": "https://files.pythonhosted.org/packages/1a/04/3f01f958ee13e64a86b9cea611f02bca6584c59bf05e04e5ad3c9db98cc0/treet-1.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9ccb185cfec6f659bc9b10c0d3abf38e", "sha256": "11f72f8b66120ab57317b138f587a296d41338a50178cf6469ffb701a4a29877" }, "downloads": -1, "filename": "treet-1.0.5.tar.gz", "has_sig": false, "md5_digest": "9ccb185cfec6f659bc9b10c0d3abf38e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15023, "upload_time": "2019-10-16T10:28:47", "url": "https://files.pythonhosted.org/packages/59/e8/84cb731c2c0a736de73dc98d8a22cb90afaa6535f0ece54ec4cf348c0880/treet-1.0.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "92498ac2fd87bf6557b3461113a61554", "sha256": "f6e9d7f0ae92b2b502dea1dcf400206d58c55b42e4370c382283a9bd2a95366f" }, "downloads": -1, "filename": "treet-1.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "92498ac2fd87bf6557b3461113a61554", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15438, "upload_time": "2019-10-16T10:28:45", "url": "https://files.pythonhosted.org/packages/1a/04/3f01f958ee13e64a86b9cea611f02bca6584c59bf05e04e5ad3c9db98cc0/treet-1.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9ccb185cfec6f659bc9b10c0d3abf38e", "sha256": "11f72f8b66120ab57317b138f587a296d41338a50178cf6469ffb701a4a29877" }, "downloads": -1, "filename": "treet-1.0.5.tar.gz", "has_sig": false, "md5_digest": "9ccb185cfec6f659bc9b10c0d3abf38e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15023, "upload_time": "2019-10-16T10:28:47", "url": "https://files.pythonhosted.org/packages/59/e8/84cb731c2c0a736de73dc98d8a22cb90afaa6535f0ece54ec4cf348c0880/treet-1.0.5.tar.gz" } ] }