# PrettyPrintTree
This package allows you to print **trees** (the datastructure) and **linked-lists** in a readable fashion.
<br>
It supports trees with any kind of data, as long it can be turned into a string.
<br>
And even supports multi-lined nodes (strings with \n).
![plot](./ExampleImages/one_to_seven.JPG)
![plot](./ExampleImages/json.JPG)
![plot](./ExampleImages/linked_list.JPG)
# Table Of Contents
- [Requirements](#requirements)
- [Install](#install)
- [Import](#import)
- [Documentation](#documentation)
- [Example](#example)
- [Tree](#tree)
- [Linked List](#linked-list)
- [Other Settings](#other-settings)
- [Horizontal](#horizontal)
- [Trim](#trim)
- [Return Instead of Print](#return-instead-of-print)
- [Color](#color)
- [Border](#border)
- [Escape NewLines](#escape-newlines)
- [Max Depth](#max-depth)
- [Start Message](#start-message)
- [Dictionaries \\ JSON](#dictionaries--json)
- [Labels](#labels)
- [Advanced Examples](#advanced-examples)
- [Binary Tree](#binary-tree)
- [Filtering](#filtering)
- [C#](#c)
- [Java](#java)
# Requirements
Python 3.7 and up
# Install
You can easily install **PrettyPrintTree** via **pip**:
```bash
pip install PrettyPrintTree
```
# Import
Once installed, you can import it in your Python script:
```python
from PrettyPrint import PrettyPrintTree
```
# Documentation
To ensure flexibility, PrettyPrintTree requires you to define how to print your specific tree structure. This is achieved by providing two callable functions (lambdas):
1) **get_children:** This function, given a node of your tree type, returns an iterable of all its children, from left to right.
For instance, if your tree implementation looks like this:
```python
class Tree:
def __init__(self, val):
self.val = val
self.children = []
```
Your **get_children** function would be as simple as:
```python
lambda node: node.children
```
2) **get_value:** Given a node of your tree type, this function should return that node's value. <br>For a tree implementation like this:
```python
class Tree:
def __init__(self, val):
self.val = val
```
The **get_value** function would be:
```python
lambda node: node.val
```
*Note: if the value of the tree doesn't implement `__str__`, the **get_value** function should convert it into a string.*
To print the tree, you first need to create a PrettyPrintTree object by providing your lambdas and any additional settings. You can then call this object whenever needed without repeatedly specifying the lambdas.
### Linked Lists
Printing a linked-list is similar, instead of **get_children** you will need:
<br>
**get_next:** This function, given a node of your linked-list type, returns the next node.
And optionally:
<br>
**get_prev:** Given a node of your linked-list type, this function should return the previous node.
# Example
### Tree
```python
from PrettyPrint import PrettyPrintTree
class Tree:
def __init__(self, value):
self.val = value
self.children = []
def add_child(self, child):
self.children.append(child)
return child
pt = PrettyPrintTree(lambda x: x.children, lambda x: x.val)
tree = Tree(1)
child1 = tree.add_child(Tree(2))
child2 = tree.add_child(Tree(3))
child1.add_child(Tree(4))
child1.add_child(Tree(5))
child1.add_child(Tree(6))
child2.add_child(Tree(7))
pt(tree)
```
![plot](./ExampleImages/one_to_seven.JPG)
### Linked List
```python
from PrettyPrint import PrettyPrintLinkedList
class Node:
def __init__(self, val):
self.val = val
self.next_node = None
self.prev_node = None
n1, n2, n3, n4 = Node("Node1"), Node("Node2"), Node("Node\nJs"), Node("Node4")
n1.next_node = n2
n2.next_node = n3
n3.next_node = n4
n3.prev_node = n2
pt = PrettyPrintLinkedList(
lambda x: x.val,
lambda x: x.next_node,
lambda x: x.prev_node,
orientation=PrettyPrintLinkedList.Horizontal,
)
pt(n1)
```
![plot](./ExampleImages/linked_list.JPG)
# Other Settings
***These settings can either be set when initializing the `PrettyPrintTree` object or when calling the function (which will override the initial setting)***
## Horizontal
You can print trees from left to right instead of the default top-to-bottom layout:
```python
pt = PrettyPrintTree(
lambda x: x.children,
lambda x: x.val,
orientation=PrettyPrintTree.Horizontal
)
```
![img.png](ExampleImages/horizontal_animals.JPG)
## Trim
If you want to print only a limited number of characters from each node to keep the tree concise and readable, you can use the **trim** setting:
```python
pt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, trim=5)
```
![plot](./ExampleImages/trim1.JPG)
To use a different trim symbol instead of `...`, you can do this:
```python
pt = PrettyPrintTree(
lambda x: x.children, lambda x: x.val, trim=5,
trim_symbol=' ' + colorama.Back.GREEN
)
```
![plot](./ExampleImages/trim2.JPG)
## Return Instead of Print
If you prefer to get the tree as a string instead of printing it directly, you can enable the **return_instead_of_print** setting:
```python
to_str = PrettyPrintTree(lambda x: x.children, lambda x: x.val, return_instead_of_print=True)
tree_as_str = to_str(tree)
```
## Color
You can change the background color of each node or opt for no color at all:
```python
from colorama import Back
pt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, color=Back.BLACK)
```
![plot](./ExampleImages/black.JPG)
For no color:
```python
pt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, color='')
```
![plot](./ExampleImages/no_color.JPG)
## Border
You can surround each node with a border:
```python
pt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, border=True)
```
![plot](./ExampleImages/border.JPG)
## Escape NewLines
To print each node on one line, you can escape the newline characters:
```python
pt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, show_newline_literal=True)
```
![plot](./ExampleImages/new_line.JPG)
<br>
In order to distinguish between \n and \\n you can highlight the \n's:
```python
PrettyPrintTree(
lambda x: x.children, lambda x: x.val,
show_newline_literal=True,
newline_literal=colorama.Fore.LIGHTGREEN_EX + '\\n' + colorama.Fore.RESET
)
```
![plot](./ExampleImages/new_line2.JPG)
## Max Depth
Limit the depth to control how many levels of nodes are printed:
```python
pt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, max_depth=10)
```
*Note: the head node has a depth of 0*
## Start Message
You can add a message to be printed before the tree. Use a lambda that receives the tree and returns a message:
```python
pt = PrettyPrintTree(
lambda x: x.children,
lambda x: x.val,
start_message=lambda node: f'printing tree of type {node.typ}:'
)
```
![plot](./ExampleImages/msg.JPG)
## Dictionaries \ JSON
**PrettyPrintTree** can also print JSON structures, although they need to be converted into a dictionary, list, or tuple first:
```python
some_json = {'foo': 1, 'bar': ('a', 'b'), 'qux': {'foo': 1, 'bar': ['a', 'b']}}
pt = PrettyPrintTree()
pt.print_json(some_json, name="DICT")
```
![plot](./ExampleImages/json.JPG)
## Labels
You can label the branches in your tree by providing a lambda that returns a label between the node and its parent. Use `None` or `False` if no label is needed:
```python
pt = PrettyPrintTree(
lambda x: x.children,
lambda x: x.val,
lambda x: x.label
)
```
![plot](./ExampleImages/labels_duck.JPG)
You can even apply color to the labels using **label_color**:
```python
from colorama import Back
pt = PrettyPrintTree(
lambda x: x.children,
lambda x: x.val,
lambda x: x.label,
label_color=Back.BLACK
)
```
![plot](./ExampleImages/label_color.JPG)
# Advanced Examples
### Binary Tree
Here's how to print a binary tree:
```python
class Tree:
def __init__(self, val):
self.val = val
self.right = None
self.left = None
```
One approach is to define **get_children** as follows:
```python
PrettyPrintTree(
lambda x: [x for x in [x.prev_node, x.next_node] if x is not None],
lambda x: x.val
)
```
![img.png](ExampleImages/simple_1to6.png)
However, this approach does not preserve the direction of the children when only one child is present. For better results, use this approach:
```python
PrettyPrintTree(
lambda x: [] if x is None or x.prev_node is x.next_node is None else [x.prev_node, x.next_node],
lambda x: x.val if x else (colorama.Back.BLACK + ' ' + colorama.Back.LIGHTBLACK_EX)
)
```
![img_1.png](ExampleImages/binary_tree2.png)
## Filtering
You can easily filter specific nodes by adding a filter in the **get_children** lambda:
```python
PrettyPrintTree(lambda node: filter(lambda n: "to print" in str(n.val), node.children), ...
```
```python
PrettyPrintTree(lambda node: [n for n in node.children if n.val > 3.141], ...
```
# C#
A C# version of PrettyPrintTree is also available:
https://github.com/AharonSambol/PrettyPrintTreeCSharp
# Java
A Java version of PrettyPrintTree is also available:
https://github.com/AharonSambol/PrettyPrintTreeJava
Raw data
{
"_id": null,
"home_page": "https://github.com/AharonSambol/PrettyPrintTree",
"name": "PrettyPrintTree",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "tree, pretty, print, pretty-print, display",
"author": "Aharon Sambol",
"author_email": "email@example.com",
"download_url": "https://files.pythonhosted.org/packages/d4/0b/bb2004917b4f763e00dddd3915f0b26876d4bd6b24368e3cdd191ac23bc2/prettyprinttree-2.0.1.tar.gz",
"platform": null,
"description": "# PrettyPrintTree\n\nThis package allows you to print **trees** (the datastructure) and **linked-lists** in a readable fashion.\n<br>\nIt supports trees with any kind of data, as long it can be turned into a string.\n<br>\nAnd even supports multi-lined nodes (strings with \\n).\n\n![plot](./ExampleImages/one_to_seven.JPG)\n![plot](./ExampleImages/json.JPG)\n![plot](./ExampleImages/linked_list.JPG)\n\n\n# Table Of Contents\n- [Requirements](#requirements)\n- [Install](#install)\n- [Import](#import)\n- [Documentation](#documentation)\n- [Example](#example)\n - [Tree](#tree)\n - [Linked List](#linked-list)\n- [Other Settings](#other-settings)\n - [Horizontal](#horizontal)\n - [Trim](#trim)\n - [Return Instead of Print](#return-instead-of-print)\n - [Color](#color)\n - [Border](#border)\n - [Escape NewLines](#escape-newlines)\n - [Max Depth](#max-depth)\n - [Start Message](#start-message)\n - [Dictionaries \\\\ JSON](#dictionaries--json)\n - [Labels](#labels)\n- [Advanced Examples](#advanced-examples)\n - [Binary Tree](#binary-tree)\n - [Filtering](#filtering)\n- [C#](#c)\n- [Java](#java)\n\n# Requirements\nPython 3.7 and up\n\n# Install\nYou can easily install **PrettyPrintTree** via **pip**:\n\n```bash\npip install PrettyPrintTree\n```\n\n\n# Import\nOnce installed, you can import it in your Python script:\n\n```python\nfrom PrettyPrint import PrettyPrintTree\n```\n\n\n# Documentation\n\nTo ensure flexibility, PrettyPrintTree requires you to define how to print your specific tree structure. This is achieved by providing two callable functions (lambdas):\n\n1) **get_children:** This function, given a node of your tree type, returns an iterable of all its children, from left to right.\nFor instance, if your tree implementation looks like this:\n ```python\n class Tree:\n def __init__(self, val):\n self.val = val\n self.children = []\n ```\n Your **get_children** function would be as simple as:\n ```python\n lambda node: node.children\n ```\n\n2) **get_value:** Given a node of your tree type, this function should return that node's value. <br>For a tree implementation like this:\n\n ```python\n class Tree:\n def __init__(self, val):\n self.val = val\n ```\n \n The **get_value** function would be:\n\n ```python\n lambda node: node.val\n ```\n *Note: if the value of the tree doesn't implement `__str__`, the **get_value** function should convert it into a string.*\n\nTo print the tree, you first need to create a PrettyPrintTree object by providing your lambdas and any additional settings. You can then call this object whenever needed without repeatedly specifying the lambdas.\n\n### Linked Lists\nPrinting a linked-list is similar, instead of **get_children** you will need: \n<br>\n**get_next:** This function, given a node of your linked-list type, returns the next node.\n\nAnd optionally:\n<br>\n**get_prev:** Given a node of your linked-list type, this function should return the previous node.\n\n\n# Example\n### Tree\n```python\nfrom PrettyPrint import PrettyPrintTree\n\n\nclass Tree:\n def __init__(self, value):\n self.val = value\n self.children = []\n\n def add_child(self, child):\n self.children.append(child)\n return child\n\n\npt = PrettyPrintTree(lambda x: x.children, lambda x: x.val)\ntree = Tree(1)\nchild1 = tree.add_child(Tree(2))\nchild2 = tree.add_child(Tree(3))\nchild1.add_child(Tree(4))\nchild1.add_child(Tree(5))\nchild1.add_child(Tree(6))\nchild2.add_child(Tree(7))\npt(tree)\n```\n![plot](./ExampleImages/one_to_seven.JPG)\n\n### Linked List\n```python\nfrom PrettyPrint import PrettyPrintLinkedList\n\nclass Node:\n def __init__(self, val):\n self.val = val\n self.next_node = None\n self.prev_node = None\n\n\nn1, n2, n3, n4 = Node(\"Node1\"), Node(\"Node2\"), Node(\"Node\\nJs\"), Node(\"Node4\")\nn1.next_node = n2\nn2.next_node = n3\nn3.next_node = n4\nn3.prev_node = n2\npt = PrettyPrintLinkedList(\n lambda x: x.val,\n lambda x: x.next_node,\n lambda x: x.prev_node,\n orientation=PrettyPrintLinkedList.Horizontal,\n)\npt(n1)\n```\n![plot](./ExampleImages/linked_list.JPG)\n\n# Other Settings\n\n***These settings can either be set when initializing the `PrettyPrintTree` object or when calling the function (which will override the initial setting)***\n## Horizontal\nYou can print trees from left to right instead of the default top-to-bottom layout:\n```python\npt = PrettyPrintTree(\n lambda x: x.children, \n lambda x: x.val, \n orientation=PrettyPrintTree.Horizontal\n)\n```\n![img.png](ExampleImages/horizontal_animals.JPG)\n\n\n## Trim\nIf you want to print only a limited number of characters from each node to keep the tree concise and readable, you can use the **trim** setting:\n\n```python\npt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, trim=5)\n```\n![plot](./ExampleImages/trim1.JPG)\n\nTo use a different trim symbol instead of `...`, you can do this:\n\n```python\npt = PrettyPrintTree(\n lambda x: x.children, lambda x: x.val, trim=5,\n trim_symbol=' ' + colorama.Back.GREEN\n)\n```\n![plot](./ExampleImages/trim2.JPG)\n\n\n## Return Instead of Print\n\nIf you prefer to get the tree as a string instead of printing it directly, you can enable the **return_instead_of_print** setting:\n\n```python\nto_str = PrettyPrintTree(lambda x: x.children, lambda x: x.val, return_instead_of_print=True)\ntree_as_str = to_str(tree)\n```\n\n\n## Color\nYou can change the background color of each node or opt for no color at all:\n\n```python\nfrom colorama import Back\n\npt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, color=Back.BLACK)\n```\n![plot](./ExampleImages/black.JPG)\n\nFor no color:\n\n```python\npt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, color='')\n```\n![plot](./ExampleImages/no_color.JPG)\n\n\n## Border\nYou can surround each node with a border:\n\n```python\npt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, border=True)\n```\n![plot](./ExampleImages/border.JPG)\n\n\n## Escape NewLines\nTo print each node on one line, you can escape the newline characters:\n\n```python\npt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, show_newline_literal=True)\n```\n![plot](./ExampleImages/new_line.JPG)\n<br>\nIn order to distinguish between \\n and \\\\n you can highlight the \\n's:\n\n```python\nPrettyPrintTree(\n lambda x: x.children, lambda x: x.val,\n show_newline_literal=True,\n newline_literal=colorama.Fore.LIGHTGREEN_EX + '\\\\n' + colorama.Fore.RESET\n)\n```\n![plot](./ExampleImages/new_line2.JPG)\n\n\n## Max Depth\nLimit the depth to control how many levels of nodes are printed:\n\n```python\npt = PrettyPrintTree(lambda x: x.children, lambda x: x.val, max_depth=10)\n```\n*Note: the head node has a depth of 0*\n\n\n## Start Message\nYou can add a message to be printed before the tree. Use a lambda that receives the tree and returns a message:\n\n```python\npt = PrettyPrintTree(\n lambda x: x.children, \n lambda x: x.val, \n start_message=lambda node: f'printing tree of type {node.typ}:'\n)\n```\n![plot](./ExampleImages/msg.JPG)\n\n\n## Dictionaries \\ JSON\n\n**PrettyPrintTree** can also print JSON structures, although they need to be converted into a dictionary, list, or tuple first:\n \n```python\nsome_json = {'foo': 1, 'bar': ('a', 'b'), 'qux': {'foo': 1, 'bar': ['a', 'b']}}\npt = PrettyPrintTree()\npt.print_json(some_json, name=\"DICT\")\n```\n![plot](./ExampleImages/json.JPG)\n\n\n## Labels\n\nYou can label the branches in your tree by providing a lambda that returns a label between the node and its parent. Use `None` or `False` if no label is needed:\n\n```python\npt = PrettyPrintTree(\n lambda x: x.children, \n lambda x: x.val, \n lambda x: x.label\n)\n```\n![plot](./ExampleImages/labels_duck.JPG)\n\nYou can even apply color to the labels using **label_color**:\n\n```python\nfrom colorama import Back\n\npt = PrettyPrintTree(\n lambda x: x.children, \n lambda x: x.val, \n lambda x: x.label,\n label_color=Back.BLACK\n)\n```\n![plot](./ExampleImages/label_color.JPG)\n\n# Advanced Examples\n\n### Binary Tree\nHere's how to print a binary tree:\n\n```python\nclass Tree:\n def __init__(self, val):\n self.val = val\n self.right = None\n self.left = None\n```\nOne approach is to define **get_children** as follows:\n\n```python\nPrettyPrintTree(\n lambda x: [x for x in [x.prev_node, x.next_node] if x is not None],\n lambda x: x.val\n)\n```\n![img.png](ExampleImages/simple_1to6.png)\n\nHowever, this approach does not preserve the direction of the children when only one child is present. For better results, use this approach:\n\n```python\nPrettyPrintTree(\n lambda x: [] if x is None or x.prev_node is x.next_node is None else [x.prev_node, x.next_node],\n lambda x: x.val if x else (colorama.Back.BLACK + ' ' + colorama.Back.LIGHTBLACK_EX)\n)\n```\n\n![img_1.png](ExampleImages/binary_tree2.png)\n\n## Filtering\n\nYou can easily filter specific nodes by adding a filter in the **get_children** lambda:\n\n```python\nPrettyPrintTree(lambda node: filter(lambda n: \"to print\" in str(n.val), node.children), ...\n```\n```python\nPrettyPrintTree(lambda node: [n for n in node.children if n.val > 3.141], ...\n```\n\n# C#\n\nA C# version of PrettyPrintTree is also available: \nhttps://github.com/AharonSambol/PrettyPrintTreeCSharp\n\n\n# Java\n\nA Java version of PrettyPrintTree is also available: \nhttps://github.com/AharonSambol/PrettyPrintTreeJava\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "A tool to print trees to the console",
"version": "2.0.1",
"project_urls": {
"Homepage": "https://github.com/AharonSambol/PrettyPrintTree"
},
"split_keywords": [
"tree",
" pretty",
" print",
" pretty-print",
" display"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6924fa17e12f5f268395f34962e41cc12aec045d5841c9e2c474417ce2811d93",
"md5": "95ab43c51263bd9ea3208d220912ca70",
"sha256": "8b0e92b064731ffc38658a115b3834665a02728f51c5cbabaee32c1ca6b3d306"
},
"downloads": -1,
"filename": "PrettyPrintTree-2.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "95ab43c51263bd9ea3208d220912ca70",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 14941,
"upload_time": "2024-08-15T20:35:30",
"upload_time_iso_8601": "2024-08-15T20:35:30.648780Z",
"url": "https://files.pythonhosted.org/packages/69/24/fa17e12f5f268395f34962e41cc12aec045d5841c9e2c474417ce2811d93/PrettyPrintTree-2.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d40bbb2004917b4f763e00dddd3915f0b26876d4bd6b24368e3cdd191ac23bc2",
"md5": "e0c40c9488503f6ac04c80650a4d3b8a",
"sha256": "c31f9966bfe312feff59aab9022cbceb68de5bf60e13be32c1a8183a5fd45272"
},
"downloads": -1,
"filename": "prettyprinttree-2.0.1.tar.gz",
"has_sig": false,
"md5_digest": "e0c40c9488503f6ac04c80650a4d3b8a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 13077,
"upload_time": "2024-08-15T20:35:32",
"upload_time_iso_8601": "2024-08-15T20:35:32.495934Z",
"url": "https://files.pythonhosted.org/packages/d4/0b/bb2004917b4f763e00dddd3915f0b26876d4bd6b24368e3cdd191ac23bc2/prettyprinttree-2.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-15 20:35:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AharonSambol",
"github_project": "PrettyPrintTree",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "prettyprinttree"
}