@@ -34,9 +34,9 @@ For **Tree** implementation, there are 9 main components.
3434 2 . `` Node `` , BaseNode with node name attribute
35352 . [ ** ✨ 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
51514 . [ ** 📝 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
57575 . [ ** 🔍 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
157157Nodes can have attributes if they are initialized from ` Node ` , * dictionary* , or * pandas DataFrame* .
158158
159- 1 . ** From ` Node ` **
159+ #### 1. ** From ` Node ` **
160160
161161Nodes 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
231231Construct nodes only.
232232
@@ -256,7 +256,7 @@ root.show()
256256# └── f
257257```
258258
259- 3 . ** From * list***
259+ #### 3. ** From * list***
260260
261261Construct 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
284284Construct nodes using path where ` key ` is path and ` value ` is dict of node attribute names and attribute values.
285285Dictionary 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
331331Construct nodes with attributes, * pandas DataFrame* can contain either path column or parent-child columns,
332332and 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")
474475print_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" ])
545604root.show()
546- # a
547- # ├── b
548- # ├── c
549- # └── d
605+ # Downloads
606+ # ├── Pictures
607+ # ├── photo1.jpg
608+ # └── file1.doc
550609
551610shift_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)
556615root.show()
557- # a
558- # ├── b
559- # │ └── c
560- # └── dummy
561- # └── d
616+ # Downloads
617+ # ├── Pictures
618+ # │ └── photo1.jpg
619+ # └── Files
620+ # └── file1.doc
562621
563622shift_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)
568627root.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" ])
583639root.show()
584- # a
585- # ├── b
586- # ├── c
587- # └── d
640+ # Downloads
641+ # ├── Pictures
642+ # ├── photo1.jpg
643+ # └── file1.doc
588644
589645copy_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)
594650root.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
604660Nodes 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" ])
613666root.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 " )
620673copy_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)
626679root_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)
637690root_other.show()
638- # aa
639- # ├── b
640- # │ └── c
641- # └── d
691+ # Documents
692+ # ├── Pictures
693+ # │ └── photo2.jpg
694+ # └── file2.doc
642695
643696copy_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)
649702root_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