Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f526c9c
feat: nested_key_dict to tree to support child_key=None
kayjan Sep 9, 2025
0dd54c7
feat: tree to nested_key_dict to support child_key=None
kayjan Sep 9, 2025
e29dc13
Merge branch 'master' of https://github.com/kayjan/bigtree
kayjan Sep 9, 2025
b6cace4
Merge branch 'master' of https://github.com/kayjan/bigtree
kayjan Sep 10, 2025
c85d98a
Merge branch 'master' of https://github.com/kayjan/bigtree
kayjan Sep 11, 2025
084e8bb
Merge branch 'master' of https://github.com/kayjan/bigtree
kayjan Sep 11, 2025
302642c
Merge branch 'master' of https://github.com/kayjan/bigtree
kayjan Sep 12, 2025
5f6ad72
feat: intuitive API with Tree class
kayjan Sep 24, 2025
5829870
docs: add docs
kayjan Sep 24, 2025
664b6aa
feat: Tree WIP, Added BinaryTree
kayjan Sep 25, 2025
ef36c78
feat: Tree completed with helper, query search methods
kayjan Sep 25, 2025
87be2d3
docs: update docs
kayjan Sep 25, 2025
326f02d
feat: Add DAG
kayjan Sep 25, 2025
4567276
docs: update docstring for BinaryTree and DAG
kayjan Sep 25, 2025
2087b39
docs: update doctest to use Tree class
kayjan Sep 25, 2025
34511a6
docs: update doctest to use Tree class
kayjan Sep 25, 2025
d2646bd
docs: update doctest to use Tree class
kayjan Sep 25, 2025
d087ad0
docs: update CHANGELOG
kayjan Sep 25, 2025
792956c
docs: update docstring
kayjan Sep 25, 2025
c31126e
docs: update docs to use new API
kayjan Sep 25, 2025
7d203ed
fix: resolve conflict
kayjan Sep 25, 2025
7d3d937
fix: resolve conflict
kayjan Sep 25, 2025
2a1ef5a
fix: merge conflict
kayjan Sep 25, 2025
485c75a
feat: undo changes for backwards compatibility
kayjan Sep 25, 2025
57bb43e
feat: enhance Tree/BinaryTree/DAG methods
kayjan Sep 25, 2025
794e1d1
refactor: Tree.root is renamed to Tree.node for clarity
kayjan Sep 26, 2025
256695e
docs: update mkdocs and README
kayjan Sep 26, 2025
379cb77
docs: update docstring
kayjan Sep 26, 2025
133058e
docs: update docstring + add plot to Tree
kayjan Sep 26, 2025
48c8fe4
test: save to folder
kayjan Sep 26, 2025
9fdc246
docs: update CHANGELOG
kayjan Sep 26, 2025
7cd95a9
docs: update docs to introduce difference between Tree and Node
kayjan Sep 26, 2025
88c140d
docs: update docs to introduce difference between Tree and Node
kayjan Sep 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ site/

tests/*.html
tests/*.png
tests/files
docs/_static/playground-config.js
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.0.0] - 2025-09-26
### Added:
- Improved API: Introduced BinaryTree, DAG, and Tree classes as a wrapper for all construct, export, helper, iterator
methods instead of calling the various functions.
### Changed:
- Tests: Save images/files to a folder defined in Constants.

## [0.31.2] - 2025-09-25
### Fixed:
- Docs: Upgrade docs to use Python 3.10.
Expand Down Expand Up @@ -830,7 +837,8 @@ ignore null attribute columns.
- Utility Iterator: Tree traversal methods.
- Workflow To Do App: Tree use case with to-do list implementation.

[Unreleased]: https://github.com/kayjan/bigtree/compare/0.31.2...HEAD
[Unreleased]: https://github.com/kayjan/bigtree/compare/1.0.0...HEAD
[1.0.0]: https://github.com/kayjan/bigtree/compare/0.31.2...1.0.0
[0.31.2]: https://github.com/kayjan/bigtree/compare/0.31.1...0.31.2
[0.31.1]: https://github.com/kayjan/bigtree/compare/0.31.0...0.31.1
[0.31.0]: https://github.com/kayjan/bigtree/compare/0.30.1...0.31.0
Expand Down
62 changes: 34 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ Related Links:
## Components
There are 3 segments to Big Tree consisting of Tree, Binary Tree, and Directed Acyclic Graph (DAG) implementation.

For **Tree** implementation, there are 11 main components.
For **Tree** implementation, there are 12 main components.

1. [**🌺 Node**](https://bigtree.readthedocs.io/stable/bigtree/node/node)
1. [**🌺 Node**](https://bigtree.readthedocs.io/stable/bigtree/node/node/)
1. ``BaseNode``, extendable class
2. ``Node``, BaseNode with node name attribute
2. [**✨ Constructing Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/construct/)
2. [**🎄 Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/tree/)
1. ``Tree``, wrapper around ``Node``, providing high-level APIs to build, iterate, query, and export the entire tree structure
3. [**✨ Constructing Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/construct/)
1. From `Node`, using parent and children constructors
2. From *str*, using tree display or Newick string notation
3. From *list*, using paths or parent-child tuples
Expand All @@ -43,74 +45,78 @@ For **Tree** implementation, there are 11 main components.
8. Add nodes to existing tree using path string
9. Add nodes and attributes to existing tree using *dictionary*, *pandas DataFrame*, or *polars DataFrame*, using path
10. Add only attributes to existing tree using *dictionary*, *pandas DataFrame*, or *polars DataFrame*, using node name
3. [**➰ Traversing Tree**](https://bigtree.readthedocs.io/stable/bigtree/utils/iterators/)
4. [**➰ Traversing Tree**](https://bigtree.readthedocs.io/stable/bigtree/utils/iterators/)
1. Pre-Order Traversal
2. Post-Order Traversal
3. Level-Order Traversal
4. Level-Order-Group Traversal
5. ZigZag Traversal
6. ZigZag-Group Traversal
4. [**🧩 Parsing Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/parsing/)
5. [**🧩 Parsing Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/parsing/)
1. Get common ancestors between nodes
2. Get path from one node to another node
5. [**📝 Modifying Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/modify/)
6. [**📝 Modifying Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/modify/)
1. Copy nodes from location to destination
2. Shift nodes from location to destination
3. Shift and replace nodes from location to destination
4. Copy nodes from one tree to another
5. Copy and replace nodes from one tree to another
6. [**📌 Querying Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/query/)
7. [**📌 Querying Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/query/)
1. Filter tree using Tree Query Language
7. [**🔍 Tree Search**](https://bigtree.readthedocs.io/stable/bigtree/tree/search/)
8. [**🔍 Tree Search**](https://bigtree.readthedocs.io/stable/bigtree/tree/search/)
1. Find multiple nodes based on name, partial path, relative path, attribute value, user-defined condition
2. Find single nodes based on name, partial path, relative path, full path, attribute value, user-defined condition
3. Find multiple child nodes based on user-defined condition
4. Find single child node based on name, user-defined condition
8. [**🔧 Helper Function**](https://bigtree.readthedocs.io/stable/bigtree/tree/helper/)
9. [**🔧 Helper Function**](https://bigtree.readthedocs.io/stable/bigtree/tree/helper/)
1. Cloning tree to another `Node` type
2. Get subtree (smaller tree with different root)
3. Prune tree (smaller tree with same root)
4. Get difference between two trees
9. [**📊 Plotting Tree**](https://bigtree.readthedocs.io/stable/bigtree/utils/plot/)
10. [**📊 Plotting Tree**](https://bigtree.readthedocs.io/stable/bigtree/utils/plot/)
1. Enhanced Reingold Tilford Algorithm to retrieve (x, y) coordinates for a tree structure
2. Plot tree using matplotlib (optional dependency)
10. [**🔨 Exporting Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/export/)
1. Print to console, in vertical or horizontal orientation
2. Export to *Newick string notation*, *dictionary*, *nested dictionary*, *pandas DataFrame*, or *polars DataFrame*
3. Export tree to *dot* (can save to .dot, .png, .svg, .jpeg files)
4. Export tree to *Pillow* (can save to .png, .jpg)
5. Export tree to *Mermaid Flowchart* (can display on .md)
6. Export tree to *Pyvis Network* (can display interactive .html)
11. [**✔️ Workflows**](https://bigtree.readthedocs.io/stable/bigtree/workflows/app_todo)
1. Sample workflows for tree demonstration!
11. [**🔨 Exporting Tree**](https://bigtree.readthedocs.io/stable/bigtree/tree/export/)
1. Print to console, in vertical or horizontal orientation
2. Export to *Newick string notation*, *dictionary*, *nested dictionary*, *pandas DataFrame*, or *polars DataFrame*
3. Export tree to *dot* (can save to .dot, .png, .svg, .jpeg files)
4. Export tree to *Pillow* (can save to .png, .jpg)
5. Export tree to *Mermaid Flowchart* (can display on .md)
6. Export tree to *Pyvis Network* (can display interactive .html)
12. [**✔️ Workflows**](https://bigtree.readthedocs.io/stable/bigtree/workflows/app_todo)
1. Sample workflows for tree demonstration!

--------

For **Binary Tree** implementation, there are 3 main components.
For **Binary Tree** implementation, there are 4 main components.
Binary Node inherits from Node, so the components in Tree implementation are also available in Binary Tree.

1. [**🌿 Node**](https://bigtree.readthedocs.io/stable/bigtree/node/binarynode)
1. ``BinaryNode``, Node with binary tree rules
2. [**✨ Constructing Binary Tree**](https://bigtree.readthedocs.io/stable/bigtree/binarytree/construct/)
2. [**🎄 Binary Tree**](https://bigtree.readthedocs.io/stable/bigtree/binarytree/binarytree/)
1. ``BinaryTree``, wrapper around ``BinaryNode``, providing high-level APIs to build, iterate, query, and export the entire tree structure
3. [**✨ Constructing Binary Tree**](https://bigtree.readthedocs.io/stable/bigtree/binarytree/construct/)
1. From *list*, using flattened list structure
3. [**➰ Traversing Binary Tree**](https://bigtree.readthedocs.io/stable/bigtree/utils/iterators/)
4. [**➰ Traversing Binary Tree**](https://bigtree.readthedocs.io/stable/bigtree/utils/iterators/)
1. In-Order Traversal

-----

For **Directed Acyclic Graph (DAG)** implementation, there are 5 main components.
For **Directed Acyclic Graph (DAG)** implementation, there are 6 main components.

1. [**🌼 Node**](https://bigtree.readthedocs.io/stable/bigtree/node/dagnode)
1. [**🌼 Node**](https://bigtree.readthedocs.io/stable/bigtree/node/dagnode/)
1. ``DAGNode``, extendable class for constructing Directed Acyclic Graph (DAG)
2. [**✨ Constructing DAG**](https://bigtree.readthedocs.io/stable/bigtree/dag/construct/)
2. [**🎄 DAG**](https://bigtree.readthedocs.io/stable/bigtree/dag/dag/)
1. ``DAG``, wrapper around ``DAGNode``, providing high-level APIs to build, export, and iterate the entire DAG
3. [**✨ Constructing DAG**](https://bigtree.readthedocs.io/stable/bigtree/dag/construct/)
1. From *list*, containing parent-child tuples
2. From *nested dictionary*
3. From *pandas DataFrame*
3. [**➰ Traversing DAG**](https://bigtree.readthedocs.io/stable/bigtree/utils/iterators/)
4. [**➰ Traversing DAG**](https://bigtree.readthedocs.io/stable/bigtree/utils/iterators/)
1. Generic traversal method
4. [**🧩 Parsing DAG**](https://bigtree.readthedocs.io/stable/bigtree/dag/parsing/)
5. [**🧩 Parsing DAG**](https://bigtree.readthedocs.io/stable/bigtree/dag/parsing/)
1. Get possible paths from one node to another node
5. [**🔨 Exporting DAG**](https://bigtree.readthedocs.io/stable/bigtree/dag/export/)
6. [**🔨 Exporting DAG**](https://bigtree.readthedocs.io/stable/bigtree/dag/export/)
1. Export to *list*, *dictionary*, or *pandas DataFrame*
2. Export DAG to *dot* (can save to .dot, .png, .svg, .jpeg files)

Expand Down
5 changes: 4 additions & 1 deletion bigtree/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
__version__ = "0.31.2"
__version__ = "1.0.0"

from bigtree.binarytree.binarytree import BinaryTree
from bigtree.binarytree.construct import list_to_binarytree
from bigtree.dag.construct import dataframe_to_dag, dict_to_dag, list_to_dag
from bigtree.dag.dag import DAG
from bigtree.dag.export import dag_to_dataframe, dag_to_dict, dag_to_dot, dag_to_list
from bigtree.dag.parsing import get_path_dag
from bigtree.node.basenode import BaseNode
Expand Down Expand Up @@ -83,6 +85,7 @@
find_relative_paths,
findall,
)
from bigtree.tree.tree import Tree
from bigtree.utils.constants import (
ANSIBorderStyle,
ANSIHPrintStyle,
Expand Down
47 changes: 47 additions & 0 deletions bigtree/binarytree/binarytree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from typing import Any, Iterable, Sequence

from bigtree.binarytree import construct
from bigtree.node import binarynode
from bigtree.tree.tree import Tree
from bigtree.utils import iterators


class BinaryTree(Tree):
"""
BinaryTree wraps around BinaryNode class to provide a quick, intuitive, Pythonic API for

* Construction with dataframe, dictionary, list, or string
* Export to dataframe, dictionary, list, string, or images
* Helper methods for cloning, pruning, getting tree diff
* Query and Search methods to find one or more Nodes

Do refer to the various modules respectively on the keyword parameters.
"""

construct_kwargs: dict[str, Any] = dict(node_type=binarynode.BinaryNode)

def __init__(self, root: binarynode.BinaryNode):
super().__init__(root)

@classmethod
def from_heapq_list(
cls, heapq_list: Sequence[int], *args: Any, **kwargs: Any
) -> "BinaryTree":
"""See `list_to_binarytree` for full details.

Accepts the same arguments as `list_to_binarytree`.
"""
construct_kwargs = {**cls.construct_kwargs, **kwargs}
root_node = construct.list_to_binarytree(heapq_list, *args, **construct_kwargs)
return cls(root_node)

# Iterator methods
def inorder_iter(
self, *args: Any, **kwargs: Any
) -> Iterable[binarynode.BinaryNode]:
"""See `inorder_iter` for full details.

Accepts the same arguments as `inorder_iter`.
"""
self.node: binarynode.BinaryNode
return iterators.inorder_iter(self.node, *args, **kwargs)
8 changes: 4 additions & 4 deletions bigtree/binarytree/construct.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ def list_to_binarytree(
"""Construct tree from a list of numbers (int or float) in heapq format.

Examples:
>>> from bigtree import list_to_binarytree, tree_to_dot
>>> from bigtree import BinaryTree
>>> nums_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> root = list_to_binarytree(nums_list)
>>> root.show()
>>> tree = BinaryTree.from_heapq_list(nums_list)
>>> tree.show()
1
├── 2
│ ├── 4
Expand All @@ -29,7 +29,7 @@ def list_to_binarytree(
└── 3
├── 6
└── 7
>>> graph = tree_to_dot(root, node_colour="gold")
>>> graph = tree.to_dot(node_colour="gold")
>>> graph.write_png("assets/construct_binarytree.png")

![Sample Binary Tree](https://github.com/kayjan/bigtree/raw/master/assets/construct_binarytree.png)
Expand Down
18 changes: 9 additions & 9 deletions bigtree/dag/construct.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ def list_to_dag(
"""Construct DAG from list of tuples containing parent-child names. Note that node names must be unique.

Examples:
>>> from bigtree import list_to_dag, dag_iterator
>>> from bigtree import DAG, dag_iterator
>>> relations_list = [("a", "c"), ("a", "d"), ("b", "c"), ("c", "d"), ("d", "e")]
>>> dag = list_to_dag(relations_list)
>>> [(parent.node_name, child.node_name) for parent, child in dag_iterator(dag)]
>>> dag = DAG.from_list(relations_list)
>>> [(parent.node_name, child.node_name) for parent, child in dag.iterate()]
[('a', 'd'), ('c', 'd'), ('d', 'e'), ('a', 'c'), ('b', 'c')]

Args:
Expand Down Expand Up @@ -59,16 +59,16 @@ def dict_to_dag(
Note that node names must be unique.

Examples:
>>> from bigtree import dict_to_dag, dag_iterator
>>> from bigtree import DAG
>>> relation_dict = {
... "a": {"step": 1},
... "b": {"step": 1},
... "c": {"parents": ["a", "b"], "step": 2},
... "d": {"parents": ["a", "c"], "step": 2},
... "e": {"parents": ["d"], "step": 3},
... }
>>> dag = dict_to_dag(relation_dict, parent_key="parents")
>>> [(parent.node_name, child.node_name) for parent, child in dag_iterator(dag)]
>>> dag = DAG.from_dict(relation_dict, parent_key="parents")
>>> [(parent.node_name, child.node_name) for parent, child in dag.iterate()]
[('a', 'd'), ('c', 'd'), ('d', 'e'), ('a', 'c'), ('b', 'c')]

Args:
Expand Down Expand Up @@ -125,7 +125,7 @@ def dataframe_to_dag(

Examples:
>>> import pandas as pd
>>> from bigtree import dataframe_to_dag, dag_iterator
>>> from bigtree import DAG
>>> relation_data = pd.DataFrame([
... ["a", None, 1],
... ["b", None, 1],
Expand All @@ -137,8 +137,8 @@ def dataframe_to_dag(
... ],
... columns=["child", "parent", "step"]
... )
>>> dag = dataframe_to_dag(relation_data)
>>> [(parent.node_name, child.node_name) for parent, child in dag_iterator(dag)]
>>> dag = DAG.from_dataframe(relation_data)
>>> [(parent.node_name, child.node_name) for parent, child in dag.iterate()]
[('a', 'd'), ('c', 'd'), ('d', 'e'), ('a', 'c'), ('b', 'c')]

Args:
Expand Down
Loading