diff --git a/CHANGELOG.md b/CHANGELOG.md index d7d4ec9f..a6a27afb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Work In Progress - Node: WeightedNode for weighted edge tree implementation. +## [0.4.5] - 2022-11-08 +### Changed +- Tree Exporter: Printing tree with added ability to omit null attributes. + ## [0.4.4] - 2022-11-08 ### Fixed - Tree Constructors: Handle adding attributes that are array-like - add array even when one of the items is null @@ -71,7 +75,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Utility Iterators: Tree traversal methods. - Workflow To Do App: Tree use case with to-do list implementation. -[0.4.3]: https://github.com/kayjan/bigtree/compare/v0.4.3...v0.4.4 +[0.4.5]: https://github.com/kayjan/bigtree/compare/v0.4.4...v0.4.5 +[0.4.4]: https://github.com/kayjan/bigtree/compare/v0.4.3...v0.4.4 [0.4.3]: https://github.com/kayjan/bigtree/compare/v0.4.2...v0.4.3 [0.4.2]: https://github.com/kayjan/bigtree/compare/v0.4.1...v0.4.2 [0.4.1]: https://github.com/kayjan/bigtree/compare/v0.4.0...v0.4.1 diff --git a/bigtree/__init__.py b/bigtree/__init__.py index 36c4d590..e8ba5723 100644 --- a/bigtree/__init__.py +++ b/bigtree/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.4.4" +__version__ = "0.4.5" from bigtree.dag.construct import dataframe_to_dag, dict_to_dag, list_to_dag from bigtree.dag.export import dag_to_dataframe, dag_to_dict, dag_to_dot, dag_to_list diff --git a/bigtree/tree/export.py b/bigtree/tree/export.py index b669025a..c0dc0444 100644 --- a/bigtree/tree/export.py +++ b/bigtree/tree/export.py @@ -34,6 +34,7 @@ def print_tree( max_depth: int = None, all_attrs: bool = False, attr_list: List[str] = None, + attr_omit_null: bool = True, attr_bracket_open: str = "[", attr_bracket_close: str = "]", style: str = "ansi", @@ -46,6 +47,7 @@ def print_tree( - Able to select which node to print from, resulting in a subtree, using `node_name` - Able to customize for maximum depth to print, using `max_depth` - Able to choose which attributes to show or show all attributes, using `attr_name_filter` and `all_attrs` + - Able to omit showing of attributes if it is null, using `attr_omit_null` - Able to customize open and close brackets if attributes are shown - Able to customize style, to choose from `ansi`, `ascii`, `const`, `rounded`, `double`, and `custom` style - Default style is `ansi` style @@ -145,6 +147,7 @@ def print_tree( max_depth (int): maximum depth of tree to print, based on `depth` attribute, optional all_attrs (bool): indicator to show all attributes, overrides `attr_list` attr_list (list): list of node attributes to print, optional + attr_omit_null (bool): indicator whether to omit showing of null attributes, defaults to True attr_bracket_open (str): open bracket for `attr_list` attr_bracket_close (str): close bracket for `attr_list` style (str): style of print, defaults to abstract style @@ -169,10 +172,23 @@ def print_tree( attr_str = ", ".join([f"{k}={v}" for k, v in attrs]) attr_str = f" {attr_bracket_open}{attr_str}{attr_bracket_close}" elif attr_list: - attr_str = ", ".join( - [f"{attr_name}={_node.get_attr(attr_name)}" for attr_name in attr_list] - ) - attr_str = f" {attr_bracket_open}{attr_str}{attr_bracket_close}" + if attr_omit_null: + attr_str = ", ".join( + [ + f"{attr_name}={_node.get_attr(attr_name)}" + for attr_name in attr_list + if _node.get_attr(attr_name) + ] + ) + else: + attr_str = ", ".join( + [ + f"{attr_name}={_node.get_attr(attr_name)}" + for attr_name in attr_list + ] + ) + if attr_str: + attr_str = f" {attr_bracket_open}{attr_str}{attr_bracket_close}" node_str = f"{_node.node_name}{attr_str}" print(f"{pre_str}{fill_str}{node_str}") diff --git a/tests/tree/test_export.py b/tests/tree/test_export.py index f4a608a2..744e5087 100644 --- a/tests/tree/test_export.py +++ b/tests/tree/test_export.py @@ -62,6 +62,13 @@ def test_print_tree_unknown_style(tree_node): with pytest.raises(ValueError): print_tree(tree_node, style="something") + @staticmethod + def test_print_tree_no_attr(tree_node): + expected_str = """a\n|-- b\n| |-- d\n| `-- e\n| |-- g\n| `-- h\n`-- c\n `-- f\n""" + assert_print_statement( + print_tree, expected_str, tree=tree_node, attr_list=["random"], style="ansi" + ) + @staticmethod def test_print_tree_child_node(tree_node): expected_str = """b\n|-- d\n`-- e\n |-- g\n `-- h\n""" @@ -82,7 +89,11 @@ def test_print_tree_unequal_char(tree_node): def test_print_tree_attr(tree_node): expected_str = """a [age=90]\n|-- b [age=65]\n| |-- d [age=40]\n| `-- e [age=35]\n| |-- g [age=10]\n| `-- h [age=6]\n`-- c [age=60]\n `-- f [age=38]\n""" assert_print_statement( - print_tree, expected_str, tree=tree_node, attr_list=["age"] + print_tree, + expected_str, + tree=tree_node, + attr_list=["age"], + attr_omit_null=False, ) @staticmethod