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

pypi-AgEIcHlwaS5vcmcCJDRlYmRmOTA3LTk0NmQtNGNkNS05NTVlLTJjYjhmMzBmODdmYwACKlszLCI1YThjM2VlNi0yNTE3LTRhMjktYmFmZS03MGVlYzdjYmUzODQiXQAABiDECjlqB8MRizOvcmEUQBEhVNljktnp5-ZY6WIAyVgR_Q

CHANGELOG
Added, Changed, Fixed, Removed

STEPS
Check function name and order
Check docstrings
Check type hint
Check test cases
Write documentation
---------------------------------------------------------
Tests

import doctest
doctest.testmod()

Tree should have structure
a (age=90)
|-- b (age=65)
|   |-- d (age=40)
|   +-- e (age=35)
|       |-- g (age=10)
|       +-- h (age=6)
+-- c (age=60)
    +-- f (age=38)

root = Node("a", age=90)
b = Node("b", age=65, parent=root)
c = Node("c", age=60, parent=root)
d = Node("d", age=40, parent=b)
e = Node("e", age=35, parent=b)

from bigtree.node.node import Node
def tree_node():
    """
    Tree should have structure
    a
    |-- b
    |   |-- d
    |   +-- e
    |       |-- g
    |       +-- h
    +-- c
        +-- f
    """
    a = Node("a", age=90)
    b = Node("b", age=65)
    c = Node("c", age=60)
    d = Node("d", age=40)
    e = Node("e", age=35)
    f = Node("f", age=38)
    g = Node("g", age=10)
    h = Node("h", age=6)

    b.parent = a
    c.parent = a
    d.parent = b
    e.parent = b
    f.parent = c
    g.parent = e
    h.parent = e
    return a

def tree_node_plot():
    z = Node("z")
    y = Node("y")
    y.parent = z
    return z

def tree_node_style():
    """
    Tree should have structure
    a (age=90)
    |-- b (age=65)
    |   |-- d (age=40)
    |       |-- g (age=10)
    |   +-- e (age=35)
    |       +-- h (age=6)
    +-- c (age=60)
        +-- f (age=38)
    """
    a = Node("a", node_style={"style": "filled", "fillcolor": "gold"})
    b = Node("b", node_style={"style": "filled", "fillcolor": "blue"})
    c = Node("c", node_style={"style": "filled", "fillcolor": "blue"})
    d = Node("d", node_style={"style": "filled", "fillcolor": "green"})
    e = Node("e", node_style={"style": "filled", "fillcolor": "green"})
    f = Node("f", node_style={"style": "filled", "fillcolor": "green"})
    g = Node("g", node_style={"style": "filled", "fillcolor": "red"})
    h = Node("h", node_style={"style": "filled", "fillcolor": "red"})

    b.parent = a
    c.parent = a
    d.parent = b
    e.parent = b
    f.parent = c
    g.parent = d
    h.parent = e
    return a

tree_node = tree_node()
tree_node_style = tree_node_style()
tree_node_plot = tree_node_plot()

from bigtree import DAGNode, dag_to_dot, dag_iterator, tree_to_dot
def dag_node():
    a = DAGNode("a")
    b = DAGNode("b")
    c = DAGNode("c")
    d = DAGNode("d")
    e = DAGNode("e")
    f = DAGNode("f")
    g = DAGNode("g")
    h = DAGNode("h")

    c.parents = [a, b]
    d.parents = [a, c]
    e.parents = [d]
    f.parents = [c, d]
    g.parents = [c]
    h.parents = [g]
    return a

def dag_node_child():
    a = DAGNode("a")
    b = DAGNode("b")
    c = DAGNode("c")
    d = DAGNode("d")
    e = DAGNode("e")
    f = DAGNode("f")
    g = DAGNode("g")
    h = DAGNode("h")

    c.parents = [a, b]
    d.parents = [a, c]
    e.parents = [d]
    f.parents = [c, d]
    g.parents = [c]
    h.parents = [g]
    return f


def dag_node_style():
    a = DAGNode("a", node_style={"style": "filled", "fillcolor": "gold"})
    b = DAGNode("b", node_style={"style": "filled", "fillcolor": "blue"})
    c = DAGNode("c", node_style={"style": "filled", "fillcolor": "blue"})
    d = DAGNode("d", node_style={"style": "filled", "fillcolor": "green"})
    e = DAGNode("e", node_style={"style": "filled", "fillcolor": "green"})
    f = DAGNode("f", node_style={"style": "filled", "fillcolor": "green"})
    g = DAGNode("g", node_style={"style": "filled", "fillcolor": "red"})
    h = DAGNode("h", node_style={"style": "filled", "fillcolor": "red"})

    c.parents = [a, b]
    d.parents = [a, c]
    e.parents = [d]
    f.parents = [c, d]
    g.parents = [c]
    h.parents = [g]
    return a

dag_node = dag_node()
dag_node_child = dag_node_child()
dag_node_style = dag_node_style()

a = DAGNode("a", step=1)
b = DAGNode("b", step=1)
c = DAGNode("c", step=2, parents=[a, b])
d = DAGNode("d", step=2, parents=[a, c])
e = DAGNode("e", step=3, parents=[d])
list(dag_iterator(a))

tree = a
bgcolor = None
fillcolor = None
node_attr = None
dag_graph = dag_to_dot(a)
node = tree
node_from = None
direction = 1

assert_tree_structure_basenode_root_generic (tree structure)
assert_tree_structure_basenode_root_attr (tree structure with age attr)
assert_tree_structure_basenode_self (tree structure with age attr)

assert_tree_structure_node_root_generic (path)
assert_tree_structure_node_self (path)
assert_tree_structure_node_self_sep (sep \\)
assert_tree_structure_node_root_sep (sep \\)

*******************************
TestBaseNode
test_from_dict
test_set_parent_error
test_set_parent
test_set_parents_rshift
test_set_parent_lshift
test_set_parent_constructor
test_set_parent_null_parent
test_set_parent_duplicate
test_set_parent_duplicate_constructor //
test_set_children
test_set_children_constructor
test_set_children_null_children
test_set_children_duplicate
test_set_children_duplicate_constructor //
test_deep_copy_set_children
test_shallow_copy_set_children
test_error_set_parent_type_error
test_error_set_parent_loop_error
test_error_set_children_type_error
test_error_set_children_loop_error
test_error_set_children_exception

*******************************
TestDAGNode
test_from_dict
test_set_parent_error
test_set_parents
test_set_parents_rshift
test_set_parents_lshift
test_set_parents_constructor
test_set_parents_none_parent
test_set_parent_duplicate
test_set_parent_duplicate_constructor //
test_set_children
test_set_children_constructor
test_set_children_none_children
test_set_children_duplicate
test_set_children_duplicate_constructor //
test_deep_copy_set_children
test_shallow_copy_set_children
test_set_children_constructor //
test_error_set_parent_type_error
test_error_set_parent_loop_error
test_error_set_parent_exception
test_error_set_children_type_error
test_error_set_children_loop_error
test_error_set_children_exception

*******************************
TestNode
test_set_parent
test_set_parent_constructor
test_set_parent_duplicate
test_set_parent_duplicate_constructor //
test_set_parent_sep_root
test_set_parent_sep_child //
test_set_children
test_set_children_constructor
test_set_children_duplicate
test_set_children_duplicate_constructor //
test_error_set_parent_same_path
test_error_set_parent_constructor_same_path
test_error_set_children_same_path
test_error_set_children_constructor_same_path
test_error_set_children_multiple_same_path //
test_error_set_parent
test_error_set_children

*******************************
TestConstruct
test_add_path_to_tree
test_add_path_to_tree_leaves
test_add_path_to_tree_empty
test_add_path_to_tree_sep_leading
test_add_path_to_tree_sep_trailing
test_add_path_to_tree_sep_undefined
test_add_path_to_tree_sep
test_add_path_to_tree_sep_tree
test_add_path_to_tree_duplicate_node
test_add_path_to_tree_node_type
test_add_path_to_tree_different_root //

test_add_dict_to_tree_by_path
test_add_dict_to_tree_by_path_empty
test_add_dict_to_tree_by_path_sep_leading
test_add_dict_to_tree_by_path_sep_trailing
test_add_dict_to_tree_by_path_sep_undefined
test_add_dict_to_tree_by_path_sep
test_add_dict_to_tree_by_path_sep_tree
test_add_dict_to_tree_by_path_duplicate_node
test_add_dict_to_tree_by_path_node_type
test_add_dict_to_tree_by_path_different_root //

test_add_dict_to_tree_by_name
test_add_dict_to_tree_by_name_empty
test_add_dict_to_tree_by_name_duplicate_in_tree
test_add_dict_to_tree_by_name_inner_join_tree
test_add_dict_to_tree_by_name_inner_join_dict
test_add_dict_to_tree_by_name_left_join
test_add_dict_to_tree_by_name_invalid_join
test_add_dict_to_tree_by_name_sep_tree
test_add_dict_to_tree_by_name_node_type //

test_add_dataframe_to_tree_by_path
test_add_dataframe_to_tree_by_path_col_name
test_add_dataframe_to_tree_by_path_empty_row
test_add_dataframe_to_tree_by_path_empty_col
test_add_dataframe_to_tree_by_path_no_attribute
test_add_dataframe_to_tree_by_path_sep_leading
test_add_dataframe_to_tree_by_path_sep_trailing
test_add_dataframe_to_tree_by_path_sep_undefined
test_add_dataframe_to_tree_by_path_sep
test_add_dataframe_to_tree_by_path_sep_tree
test_add_dataframe_to_tree_by_path_node_type
test_add_dataframe_to_tree_by_path_different_root
test_add_dataframe_to_tree_by_path_duplicate
test_add_dataframe_to_tree_by_path_duplicate_node //

test_add_dataframe_to_tree_by_name
test_add_dataframe_to_tree_by_name_duplicate_in_tree
test_add_dataframe_to_tree_by_name_col_name
test_add_dataframe_to_tree_by_name_empty
test_add_dataframe_to_tree_by_name_empty_row
test_add_dataframe_to_tree_by_name_inner_join_tree
test_add_dataframe_to_tree_by_name_inner_join_data
test_add_dataframe_to_tree_by_name_left_join
test_add_dataframe_to_tree_by_name_invalid_join
test_add_dataframe_to_tree_by_name_sep_tree
test_add_dataframe_to_tree_by_name_node_type
test_add_dataframe_to_tree_by_name_duplicate
test_add_dataframe_to_tree_by_name_duplicate_node //

test_list_to_tree
test_list_to_tree_leaves
test_list_to_tree_empty
test_list_to_tree_sep_leading
test_list_to_tree_sep_trailing
test_list_to_tree_sep_undefined
test_list_to_tree_sep
test_list_to_tree_duplicate_node
test_list_to_tree_node_type
test_list_to_tree_different_root //

test_dict_to_tree
test_dict_to_tree_empty
test_dict_to_tree_sep_leading
test_dict_to_tree_sep_trailing
test_dict_to_tree_sep_undefined
test_dict_to_tree_sep
test_dict_to_tree_duplicate_node
test_dict_to_tree_node_type
test_dict_to_tree_different_root //

test_nested_dict_to_tree
test_nested_dict_to_tree_key_name
test_nested_dict_to_tree_node_type //

test_dataframe_to_tree
test_dataframe_to_tree_col_name
test_dataframe_to_tree_no_attribute
test_dataframe_to_tree_empty_row
test_dataframe_to_tree_empty_col
test_dataframe_to_tree_sep_leading
test_dataframe_to_tree_sep_trailing
test_dataframe_to_tree_sep_undefined
test_dataframe_to_tree_sep
test_dataframe_to_tree_node_type
test_dataframe_to_tree_different_root
test_dataframe_to_tree_duplicate
test_dataframe_to_tree_duplicate_node

*******************************
TestPrintTree
test_print_tree_ansi
test_print_tree_ascii
test_print_tree_const
test_print_tree_const_bold
test_print_tree_rounded
test_print_tree_double
test_print_tree_custom
test_print_tree_unknown_style
test_print_tree_unequal_char
test_print_tree_attr

TestTreeToDataFrame
test_tree_to_dataframe
test_tree_to_dataframe_path_col
test_tree_to_dataframe_path_col_missing
test_tree_to_dataframe_name_col
test_tree_to_dataframe_name_col_missing
test_tree_to_dataframe_name_path_col_missing
test_tree_to_dataframe_parent_col
test_tree_to_dataframe_attr_dict
test_tree_to_dataframe_all_attr
test_tree_to_dataframe_max_depth
test_tree_to_dataframe_skip_depth
test_tree_to_dataframe_leaf_only
test_tree_to_dataframe_multiple_columns
test_tree_to_dataframe_multiple_cols_subset_tree
test_tree_to_dataframe_to_tree

TestTreeToDict
test_tree_to_dict
test_tree_to_dict_name_key
test_tree_to_dict_parent_key
test_tree_to_dict_attr_dict
test_tree_to_dict_all_attr
test_tree_to_dict_max_depth
test_tree_to_dict_skip_depth
test_tree_to_dict_leaf_only
test_tree_to_dict_multiple_keys
test_tree_to_dict_multiple_keys_subset_tree
test_tree_to_dict_to_tree

TestTreeToNestedDict
test_tree_to_nested_dict
test_tree_to_nested_dict_name_key
test_tree_to_nested_dict_child_key
test_tree_to_nested_dict_attr_dict
test_tree_to_nested_dict_all_attr
test_tree_to_nested_dict_max_depth
test_tree_to_nested_dict_skip_depth
test_tree_to_nested_dict_multiple_keys
test_tree_to_nested_dict_multiple_keys_subset_tree
test_tree_to_nested_dict_to_tree

TestTreeToDot
test_tree_to_dot
test_tree_to_dot_type_error
test_tree_to_dot_directed
test_tree_to_dot_bg_color
test_tree_to_dot_fill_color
test_tree_to_dot_edge_colour
test_tree_to_dot_node_attr

TestDAGToDot
test_dag_to_dot
test_dag_to_dot_from_child
test_dag_to_dot_type_error
test_dag_to_dot_bg_color
test_dag_to_dot_fill_color
test_dag_to_dot_node_attr

*******************************
TestCloneTree
test_clone_tree_wrong_type
test_clone_tree_basenode_node
test_clone_tree_node_basenode
test_clone_tree_basenode_custom

TestPruneTree
test_prune_tree
test_prune_tree_multiple_path
test_prune_tree_nonexistant_path
test_prune_tree_sep
test_prune_tree_sep_wrong

TestTreeDiff
test_tree_diff
test_tree_diff_all_diff
test_tree_diff_same_tree

*******************************
TestCopyOrShiftNodes
test_copy_or_shift_nodes
test_copy_or_shift_nodes_invalid_type
test_copy_or_shift_nodes_unequal_length
test_copy_or_shift_nodes_invalid_paths
test_copy_or_shift_nodes_invalid_from_paths
test_copy_or_shift_nodes_invalid_to_paths
test_copy_or_shift_nodes_create_intermediate_path
test_copy_or_shift_nodes_sep
test_copy_or_shift_nodes_copy_node
test_copy_or_shift_nodes_skippable
test_copy_or_shift_nodes_delete_and_overriding
test_copy_or_shift_nodes_merge_children_change_levels
test_copy_or_shift_nodes_merge_children_same_level
test_copy_or_shift_nodes_shift_same_node
test_copy_or_shift_nodes_tree_to_tree

*******************************
TestSearch
test_find_all
test_find_all_descendant
test_find_all_max_depth
test_exception_find_all_max_count
test_exception_find_all_min_count
test_find
test_find_descendant
test_exception_find
test_find_name
test_find_names
test_find_full_path
test_find_full_path_sep_leading
test_find_full_path_sep_trailing
test_find_full_wrong_path
test_find_full_wrong_root
test_find_path
test_find_path_partial
test_find_path_sep_leading
test_find_path_sep_trailing
test_find_paths
test_find_paths_partial
test_find_paths_sep_leading
test_find_paths_sep_trailing
test_find_attr
test_find_attrs

*******************************
TestPreOrderIter
test_preorder_iter
test_preorder_iter2
test_preorder_iter_filter_condition
test_preorder_iter_filter_condition_skip_level
test_preorder_iter_stop_condition
test_preorder_iter_max_depth

TestPostOrderIter
test_postorder_iter
test_postorder_iter2
test_postorder_iter_filter_condition
test_postorder_iter_filter_condition_skip_level
test_postorder_iter_stop_condition
test_postorder_iter_max_depth

TestLevelOrderIter
test_levelorder_iter
test_levelorder_iter2
test_levelorder_iter_filter_condition
test_levelorder_iter_filter_condition_skip_level
test_levelorder_iter_stop_condition
test_levelorder_iter_max_depth

TestLevelOrderGroupIter
test_levelordergroup_iter
test_levelordergroup_iter2
test_levelordergroup_iter_filter_condition
test_levelordergroup_iter_filter_condition_skip_level
test_levelordergroup_iter_stop_condition
test_levelordergroup_iter_max_depth

*******************************
test_creation
test_add_list
test_add_list_duplicate
test_prioritize_list
test_prioritize_list_error //
test_add_item_single
test_add_item_single_list
test_add_item_multiple
test_add_item_multiple_list
test_add_item_type_error //
test_remove_item_single
test_remove_item_single_list
test_remove_duplicate_item
test_remove_duplicate_item_error
test_remove_item_multiple
test_remove_item_multiple_list
test_remove_item_error //
test_prioritize_item
test_prioritize_item_error //

test_add_list_verbose
test_add_list_duplicate_verbose
test_add_item_single_verbose
---------------------------------------------------------
LEARNINGS
type hinting (same type?) Self (python 3.11), Type[A] vs A
pre commit hook
toml file, coverage, flake8, isort
hatch vs poetry
inherit and override private methods
doctest, importing clashes when running file with -m
yield and yield from
logging for libraries
pytest for print and stdout and dataframes
add image to md files