Skip to content

Commit d6d1f4c

Browse files
authored
Merge pull request #141 from kayjan/enhance-readme
Changed: Updated examples in README
2 parents 46192e3 + fae3bcb commit d6d1f4c

File tree

1 file changed

+147
-94
lines changed

1 file changed

+147
-94
lines changed

README.md

Lines changed: 147 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ For **Tree** implementation, there are 9 main components.
3434
2. ``Node``, BaseNode with node name attribute
3535
2. [**✨ Constructing Tree**](https://bigtree.readthedocs.io/en/latest/bigtree/tree/construct.html)
3636
1. From `Node`, using parent and children constructors
37-
2. From *str*, using tree in string display format
37+
2. From *str*, using tree display
3838
3. From *list*, using paths or parent-child tuples
39-
4. From *nested dictionary*, using path or recursive structure
39+
4. From *nested dictionary*, using path-attribute key-value pairs or recursive structure
4040
5. From *pandas DataFrame*, using paths or parent-child columns
4141
6. Add nodes to existing tree using path string
4242
7. Add nodes and attributes to existing tree using *dictionary* or *pandas DataFrame*, using path
@@ -49,10 +49,10 @@ For **Tree** implementation, there are 9 main components.
4949
5. ZigZag Traversal
5050
6. ZigZag-Group Traversal
5151
4. [**📝 Modifying Tree**](https://bigtree.readthedocs.io/en/latest/bigtree/tree/modify.html)
52-
1. Shift nodes from location to destination
53-
2. Copy nodes from location to destination
54-
3. Copy nodes from one tree to another
55-
4. Shift and replace nodes from location to destination
52+
1. Copy nodes from location to destination
53+
2. Shift nodes from location to destination
54+
3. Shift and replace nodes from location to destination
55+
4. Copy nodes from one tree to another
5656
5. Copy and replace nodes from one tree to another
5757
5. [**🔍 Tree Search**](https://bigtree.readthedocs.io/en/latest/bigtree/tree/search.html)
5858
1. Find multiple nodes based on name, partial path, relative path, attribute value, user-defined condition
@@ -156,7 +156,7 @@ Here are some codes to get started.
156156

157157
Nodes can have attributes if they are initialized from `Node`, *dictionary*, or *pandas DataFrame*.
158158

159-
1. **From `Node`**
159+
#### 1. **From `Node`**
160160

161161
Nodes can be linked to each other in the following ways:
162162
- Using `parent` and `children` setter methods
@@ -226,7 +226,7 @@ root.show(style="ascii")
226226
# +-- c
227227
```
228228

229-
2. **From *str***
229+
#### 2. **From *str***
230230

231231
Construct nodes only.
232232

@@ -256,7 +256,7 @@ root.show()
256256
# └── f
257257
```
258258

259-
3. **From *list***
259+
#### 3. **From *list***
260260

261261
Construct nodes only, list can contain either full paths or tuples of parent-child names.
262262

@@ -279,7 +279,7 @@ root.show()
279279
# └── c
280280
```
281281

282-
4. **From *nested dictionary***
282+
#### 4. **From *nested dictionary***
283283

284284
Construct nodes using path where `key` is path and `value` is dict of node attribute names and attribute values.
285285
Dictionary can also be a recursive structure where `key` is node attribute names and `value` is node attribute values,
@@ -326,7 +326,7 @@ root.show(attr_list=["age"])
326326
# └── c [age=60]
327327
```
328328

329-
5. **From *pandas DataFrame***
329+
#### 5. **From *pandas DataFrame***
330330

331331
Construct nodes with attributes, *pandas DataFrame* can contain either path column or parent-child columns,
332332
and attribute columns.
@@ -372,7 +372,8 @@ root.show(attr_list=["age"])
372372
# └── c [age=60]
373373
```
374374

375-
> If tree is already created, attributes can still be added using a dictionary or pandas DataFrame!
375+
> If tree is already created, nodes can still be added using path string, dictionary, and pandas DataFrame!
376+
> Attributes can be added to existing nodes using a dictionary or pandas DataFrame.
376377
377378
### Print Tree
378379

@@ -474,18 +475,79 @@ print_tree(root, style="double")
474475
print_tree(
475476
root,
476477
style="custom",
477-
custom_style=("| ", "|-- ", "+-- "),
478+
custom_style=("", "├→ ", "╰→ "),
478479
)
479480
# a
480-
# |-- b
481-
# | |-- d
482-
# | +-- e
483-
# +-- c
481+
# ├→ b
482+
# │ ├→ d
483+
# │ ╰→ e
484+
# ╰→ c
484485
```
485486

487+
### Tree Attributes and Operations
488+
489+
Note that using `BaseNode` or `Node` as superclass inherits the default class attributes (properties)
490+
and operations (methods).
491+
492+
```python
493+
from bigtree import str_to_tree
494+
495+
# Initialize tree
496+
tree_str = """
497+
a
498+
├── b
499+
│ ├── d
500+
│ ├── e
501+
│ └── f
502+
│ ├── h
503+
│ └── i
504+
└── c
505+
└── g
506+
"""
507+
root = str_to_tree(tree_str)
508+
509+
# Accessing children
510+
node_b = root["b"]
511+
node_e = root["b"]["e"]
512+
```
513+
514+
Below are the tables of attributes available to `BaseNode` and `Node` classes.
515+
516+
| Attributes wrt self | Code | Returns |
517+
|--------------------------------------|--------------------|----------------------------|
518+
| Check if root | `root.is_root` | True |
519+
| Check if leaf node | `root.is_leaf` | False |
520+
| Check depth of node | `node_b.depth` | 2 |
521+
| Check depth of tree | `node_b.max_depth` | 4 |
522+
| Get node path | `node_b.node_path` | (Node(/a, ), Node(/a/b, )) |
523+
| Get node name (only for `Node`) | `node_b.node_name` | 'b' |
524+
| Get node path name (only for `Node`) | `node_b.path_name` | '/a/b' |
525+
526+
| Attributes wrt structure | Code | Returns |
527+
|-----------------------------------|----------------------------|--------------------------------------------------------------------------------------|
528+
| Get child/children | `root.children` | (Node(/a/b, ), Node(/a/c, )) |
529+
| Get parent | `node_e.parent` | Node(/a/b, ) |
530+
| Get siblings | `node_e.siblings` | (Node(/a/b/d, ), Node(/a/b/f, )) |
531+
| Get left sibling | `node_e.left_sibling` | Node(/a/b/d, ) |
532+
| Get right sibling | `node_e.left_sibling` | Node(/a/b/f, ) |
533+
| Get ancestors (lazy evaluation) | `list(node_e.ancestors)` | [Node(/a/b, ), Node(/a, )] |
534+
| Get descendants (lazy evaluation) | `list(node_b.descendants)` | [Node(/a/b/d, ), Node(/a/b/e, ), Node(/a/b/f, ), Node(/a/b/f/h, ), Node(/a/b/f/i, )] |
535+
| Get leaves (lazy evaluation) | `list(node_b.leaves)` | [Node(/a/b/d, ), Node(/a/b/e, ), Node(/a/b/f/h, ), Node(/a/b/f/i, )] |
536+
537+
Below is the table of operations available to `BaseNode` and `Node` classes.
538+
539+
| Operations | Code | Returns |
540+
|------------------------------------|------------------------------------------------------------|--------------------------------------------|
541+
| Get node information | `root.describe(exclude_prefix="_")` | [('name', 'a')] |
542+
| Find path from one node to another | `root.go_to(node_e)` | [Node(/a, ), Node(/a/b, ), Node(/a/b/e, )] |
543+
| Set attribute(s) | `root.set_attrs({"description": "root-tag"})` | None |
544+
| Get attribute | `root.get_attr("description")` | 'root-tag' |
545+
| Copy tree | `root.copy()` | None |
546+
| Sort children | `root.sort(key=lambda node: node.node_name, reverse=True)` | None |
547+
486548
### Traverse Tree
487549

488-
Tree can be traversed using pre-order, post-order, level-order, level-order-group, zigzag, zigzag-group traversal methods.
550+
Tree can be traversed using the following traversal methods.
489551

490552
{emphasize-lines="23,26,29,32,35,38"}
491553
```python
@@ -532,125 +594,116 @@ root.show()
532594

533595
### Modify Tree
534596

535-
Nodes can be shifted (with or without replacement) or copied from one path to another.
597+
Nodes can be shifted (with or without replacement) or copied from one path to another, changes the tree in-place.
536598

537-
{emphasize-lines="13-17,25-29"}
599+
{emphasize-lines="10-14,22-26"}
538600
```python
539-
from bigtree import Node, shift_nodes, shift_and_replace_nodes
601+
from bigtree import list_to_tree, shift_nodes, shift_and_replace_nodes
540602

541-
root = Node("a")
542-
b = Node("b", parent=root)
543-
c = Node("c", parent=root)
544-
d = Node("d", parent=root)
603+
root = list_to_tree(["Downloads/Pictures", "Downloads/photo1.jpg", "Downloads/file1.doc"])
545604
root.show()
546-
# a
547-
# ├── b
548-
# ├── c
549-
# └── d
605+
# Downloads
606+
# ├── Pictures
607+
# ├── photo1.jpg
608+
# └── file1.doc
550609

551610
shift_nodes(
552611
tree=root,
553-
from_paths=["a/c", "a/d"],
554-
to_paths=["a/b/c", "a/dummy/d"],
612+
from_paths=["photo1.jpg", "Downloads/file1.doc"],
613+
to_paths=["Downloads/Pictures/photo1.jpg", "Downloads/Files/file1.doc"],
555614
)
556615
root.show()
557-
# a
558-
# ├── b
559-
# │ └── c
560-
# └── dummy
561-
# └── d
616+
# Downloads
617+
# ├── Pictures
618+
# │ └── photo1.jpg
619+
# └── Files
620+
# └── file1.doc
562621

563622
shift_and_replace_nodes(
564623
tree=root,
565-
from_paths=["a/dummy"],
566-
to_paths=["a/b/c"],
624+
from_paths=["Downloads/Files"],
625+
to_paths=["Downloads/Pictures/photo1.jpg"],
567626
)
568627
root.show()
569-
# a
570-
# └── b
571-
# └── dummy
572-
# └── d
628+
# Downloads
629+
# └── Pictures
630+
# └── Files
631+
# └── file1.doc
573632
```
574633

575-
{emphasize-lines="13-17"}
634+
{emphasize-lines="10-14"}
576635
```python
577-
from bigtree import Node, copy_nodes
636+
from bigtree import list_to_tree, copy_nodes
578637

579-
root = Node("a")
580-
b = Node("b", parent=root)
581-
c = Node("c", parent=root)
582-
d = Node("d", parent=root)
638+
root = list_to_tree(["Downloads/Pictures", "Downloads/photo1.jpg", "Downloads/file1.doc"])
583639
root.show()
584-
# a
585-
# ├── b
586-
# ├── c
587-
# └── d
640+
# Downloads
641+
# ├── Pictures
642+
# ├── photo1.jpg
643+
# └── file1.doc
588644

589645
copy_nodes(
590646
tree=root,
591-
from_paths=["a/c", "a/d"],
592-
to_paths=["a/b/c", "a/dummy/d"],
647+
from_paths=["photo1.jpg", "Downloads/file1.doc"],
648+
to_paths=["Downloads/Pictures/photo1.jpg", "Downloads/Files/file1.doc"],
593649
)
594650
root.show()
595-
# a
596-
# ├── b
597-
# │ └── c
598-
# ├── c
599-
# ├── d
600-
# └── dummy
601-
# └── d
651+
# Downloads
652+
# ├── Pictures
653+
# │ └── photo1.jpg
654+
# ├── photo1.jpg
655+
# ├── file1.doc
656+
# └── Files
657+
# └── file1.doc
602658
```
603659

604660
Nodes can also be copied (with or without replacement) between two different trees.
605661

606-
{emphasize-lines="13-18,36-41"}
662+
{emphasize-lines="10-15,33-38"}
607663
```python
608-
from bigtree import Node, copy_nodes_from_tree_to_tree, copy_and_replace_nodes_from_tree_to_tree
609-
root = Node("a")
610-
b = Node("b", parent=root)
611-
c = Node("c", parent=root)
612-
d = Node("d", parent=root)
664+
from bigtree import Node, copy_nodes_from_tree_to_tree, copy_and_replace_nodes_from_tree_to_tree, list_to_tree
665+
root = list_to_tree(["Downloads/Pictures", "Downloads/photo1.jpg", "Downloads/file1.doc"])
613666
root.show()
614-
# a
615-
# ├── b
616-
# ├── c
617-
# └── d
667+
# Downloads
668+
# ├── Pictures
669+
# ├── photo1.jpg
670+
# └── file1.doc
618671

619-
root_other = Node("aa")
672+
root_other = Node("Documents")
620673
copy_nodes_from_tree_to_tree(
621674
from_tree=root,
622675
to_tree=root_other,
623-
from_paths=["a/b", "a/c", "a/d"],
624-
to_paths=["aa/b", "aa/b/c", "aa/dummy/d"],
676+
from_paths=["Downloads/Pictures", "photo1.jpg", "file1.doc"],
677+
to_paths=["Documents/Pictures", "Documents/Pictures/photo1.jpg", "Documents/Files/file1.doc"],
625678
)
626679
root_other.show()
627-
# aa
628-
# ├── b
629-
# │ └── c
630-
# └── dummy
631-
# └── d
632-
633-
root_other = Node("aa")
634-
b = Node("b", parent=root_other)
635-
c = Node("c", parent=b)
636-
d = Node("d", parent=root_other)
680+
# Documents
681+
# ├── Pictures
682+
# │ └── photo1.jpg
683+
# └── Files
684+
# └── file1.doc
685+
686+
root_other = Node("Documents")
687+
picture_folder = Node("Pictures", parent=root_other)
688+
photo2 = Node("photo2.jpg", parent=picture_folder)
689+
file2 = Node("file2.doc", parent=root_other)
637690
root_other.show()
638-
# aa
639-
# ├── b
640-
# │ └── c
641-
# └── d
691+
# Documents
692+
# ├── Pictures
693+
# │ └── photo2.jpg
694+
# └── file2.doc
642695

643696
copy_and_replace_nodes_from_tree_to_tree(
644697
from_tree=root,
645698
to_tree=root_other,
646-
from_paths=["a/b", "a/c"],
647-
to_paths=["aa/b/c", "aa/d"],
699+
from_paths=["Downloads/photo1.jpg", "Downloads/file1.doc"],
700+
to_paths=["Documents/Pictures/photo2.jpg", "Documents/file2.doc"],
648701
)
649702
root_other.show()
650-
# aa
651-
# ├── b
652-
# │ └── b
653-
# └── c
703+
# Documents
704+
# ├── Pictures
705+
# │ └── photo1.jpg
706+
# └── file1.doc
654707
```
655708

656709
### Tree Search

0 commit comments

Comments
 (0)