diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index ea57da2..e198591 100644 Binary files a/docs/build/doctrees/environment.pickle and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree index 8a549ee..62b0503 100644 Binary files a/docs/build/doctrees/index.doctree and b/docs/build/doctrees/index.doctree differ diff --git a/docs/build/html/_modules/pynodes.html b/docs/build/html/_modules/pynodes.html index f88b91f..c1ab604 100644 --- a/docs/build/html/_modules/pynodes.html +++ b/docs/build/html/_modules/pynodes.html @@ -43,7 +43,6 @@ Should be subclassed only """ # Class Var for statistics - total_nodes_number: ClassVar[int] = 0 deepest_level: ClassVar[int] = 0 largest_sibling_number: ClassVar[int] = 0 all_nodes: ClassVar[list[Node]] = [] @@ -52,7 +51,6 @@ """ each subclass must define its own ClassVar """ # TODO to be renamed for clarity super().__init_subclass__() - cls.total_nodes_number: ClassVar[int] = 0 cls.deepest_level: ClassVar[int] = 0 cls.largest_sibling_number: ClassVar[int] = 0 cls.all_nodes: ClassVar[list[Node]] = [] @@ -61,7 +59,7 @@ def __new__(cls, name: str, parent: Node | None = None) -> None: for n in cls.all_nodes: if name == n.name: - raise Exception('Node with this name already exist') + raise AttributeError('Node with this name already exists') else: return super().__new__(cls) @@ -69,9 +67,24 @@ self.name = name self.parent = parent # is set with add_child self.children: list[Node] = [] - type(self).total_nodes_number += 1 type(self).all_nodes.append(self) +
+[docs] + def add_child(self, child: Node) -> None: + """ add new child node to current instance """ + child.parent = self + if child.name not in [c.name for c in self.children]: + self.children.append(child) + if child.level > type(self).deepest_level: + type(self).deepest_level = child.level + if len(self.children) > type(self).largest_sibling_number: + type(self).largest_sibling_number = len(self.children) + else: + raise Exception('Child with same name already exists')
+ + + @property def siblings(self) -> list[Node]: """ returns all the siblings of the Node object """ @@ -109,17 +122,25 @@ path += self.name return path +
+[docs] def is_sibling(self, other: str) -> bool: + """ check if Node object is a sibling of the other Node object """ if other in [s.name for s in self.siblings]: return True else: - return False + return False
+ +
+[docs] def is_child(self, other: str) -> bool: + """ check if Node object is a child of the other Node object """ if other in [s.name for s in self.children]: return True else: - return False + return False
+
[docs] @@ -131,48 +152,54 @@ c.pretty_print()
-
-[docs] - def add_child(self, child: Node) -> None: - """ add new child node to current instance """ - child.parent = self - if child.name not in [c.name for c in self.children]: - self.children.append(child) - if child.level > type(self).deepest_level: - type(self).deepest_level = child.level - if len(self.children) > type(self).largest_sibling_number: - type(self).largest_sibling_number = len(self.children) - else: - raise Exception('Child with same name already exists')
- - +
+[docs] def has_parent(self) -> bool: + """ check if Node object has a parent or not """ if self.parent is not None: return True - return False + return False
+ +
+[docs] def has_children(self) -> bool: + """ check if Node object has one child at least """ if self.children is not None: return True - return False + return False
+ +
+[docs] def has_siblings(self) -> bool: + """ check if Node object has one sibling at least """ if self.has_parent() and self.parent.has_children() \ and len(self.parent.children) > 0: return True - return False + return False
+ +
+[docs] def get_child(self, name: str) -> Node | None: + """ find and returns a child with specified name. None if nothing found """ for c in self.children: if c.name == name: return c - return None + return None
+ +
+[docs] def get_sibling(self, name: str) -> Node | None: + """ find and returns a sibling with specified name. None if nothing + found """ for c in self.siblings: if c.name == name: return c - return None + return None
+ def get_children(self, name: str) -> list[Node]: # refactoring, recursion is not good @@ -207,7 +234,6 @@ """ reset all the ClassVar members """ - cls.total_nodes_number = 0 cls.deepest_level = 0 cls.largest_sibling_number = 0 cls.all_nodes = [] @@ -221,7 +247,7 @@ Creates random tree of nodes for testing purpose """ def create_node(level, i): - id_ = cls.total_nodes_number + 1 + id_ = len(cls.all_nodes) + 1 return cls(f'{type_}_'+str(id_)) def create_node_list(level: int, width: int = 5): diff --git a/docs/build/html/_sources/index.rst.txt b/docs/build/html/_sources/index.rst.txt index c0e1ee1..9f0996b 100644 --- a/docs/build/html/_sources/index.rst.txt +++ b/docs/build/html/_sources/index.rst.txt @@ -13,6 +13,8 @@ A node is an object which is related to other nodes given a tree chart. (venv) $ pip install pynodes +Source code is hosted on my own instance of `gitea `_. + .. toctree:: :maxdepth: 2 :caption: Contents: diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html index f75c586..2ec7f56 100644 --- a/docs/build/html/genindex.html +++ b/docs/build/html/genindex.html @@ -35,6 +35,9 @@
A | C + | G + | H + | I | L | N | P @@ -62,6 +65,44 @@ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+

L

    diff --git a/docs/build/html/index.html b/docs/build/html/index.html index 1848a90..c8f8656 100644 --- a/docs/build/html/index.html +++ b/docs/build/html/index.html @@ -37,6 +37,7 @@ A node is an object which is related to other nodes given a tree chart.

    (venv) $ pip install pynodes
     
    +

    Source code is hosted on my own instance of gitea.

    @@ -72,6 +73,49 @@ children)

    Creates random tree of nodes for testing purpose

    +
    +
    +get_child(name: str) Node | None[source]
    +

    find and returns a child with specified name. None if nothing found

    +
    + +
    +
    +get_sibling(name: str) Node | None[source]
    +

    find and returns a sibling with specified name. None if nothing +found

    +
    + +
    +
    +has_children() bool[source]
    +

    check if Node object has one child at least

    +
    + +
    +
    +has_parent() bool[source]
    +

    check if Node object has a parent or not

    +
    + +
    +
    +has_siblings() bool[source]
    +

    check if Node object has one sibling at least

    +
    + +
    +
    +is_child(other: str) bool[source]
    +

    check if Node object is a child of the other Node object

    +
    + +
    +
    +is_sibling(other: str) bool[source]
    +

    check if Node object is a sibling of the other Node object

    +
    +
    property level: int
    diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv index 1e21cd8..a129cf2 100644 Binary files a/docs/build/html/objects.inv and b/docs/build/html/objects.inv differ diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js index 837627d..52a80d1 100644 --- a/docs/build/html/searchindex.js +++ b/docs/build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["index"], "filenames": ["index.rst"], "titles": ["Welcome to pynodes\u2019s documentation!"], "terms": {"i": 0, "python": 0, "librari": 0, "manag": 0, "node": 0, "class": 0, "A": 0, "an": 0, "object": 0, "which": 0, "relat": 0, "other": 0, "given": 0, "tree": 0, "chart": 0, "venv": 0, "pip": 0, "instal": 0, "import": 0, "name": 0, "str": 0, "parent": 0, "none": 0, "sourc": 0, "should": 0, "subclass": 0, "onli": 0, "add_child": 0, "child": 0, "add": 0, "new": 0, "current": 0, "instanc": 0, "static": 0, "check_lineag": 0, "list": 0, "bool": 0, "check": 0, "straight": 0, "lineag": 0, "1": 0, "ancestor": 0, "2": 0, "3": 0, "n": 0, "grand": 0, "children": 0, "classmethod": 0, "create_random_nod": 0, "type_": 0, "cmd": 0, "depth": 0, "int": 0, "0": 0, "creat": 0, "random": 0, "test": 0, "purpos": 0, "properti": 0, "path": 0, "return": 0, "represent": 0, "self": 0, "pretty_print": 0, "print": 0, "from": 0, "reset_stat": 0, "reset": 0, "all": 0, "classvar": 0, "member": 0, "index": 0, "modul": 0, "search": 0, "page": 0, "level": 0, "sibl": 0}, "objects": {"pynodes": [[0, 0, 1, "", "Node"]], "pynodes.Node": [[0, 1, 1, "", "add_child"], [0, 1, 1, "", "check_lineage"], [0, 1, 1, "", "create_random_nodes"], [0, 2, 1, "", "level"], [0, 2, 1, "", "parents"], [0, 2, 1, "", "path"], [0, 1, 1, "", "pretty_print"], [0, 1, 1, "", "reset_stats"], [0, 2, 1, "", "siblings"]]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:property"}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "property", "Python property"]}, "titleterms": {"welcom": 0, "pynod": 0, "": 0, "document": 0, "basic": 0, "usag": 0, "indic": 0, "tabl": 0}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx": 60}, "alltitles": {"Welcome to pynodes\u2019s documentation!": [[0, "welcome-to-pynodes-s-documentation"]], "Basic Usage": [[0, "basic-usage"]], "Indices and tables": [[0, "indices-and-tables"]]}, "indexentries": {"node (class in pynodes)": [[0, "pynodes.Node"]], "add_child() (pynodes.node method)": [[0, "pynodes.Node.add_child"]], "check_lineage() (pynodes.node static method)": [[0, "pynodes.Node.check_lineage"]], "create_random_nodes() (pynodes.node class method)": [[0, "pynodes.Node.create_random_nodes"]], "level (pynodes.node property)": [[0, "pynodes.Node.level"]], "parents (pynodes.node property)": [[0, "pynodes.Node.parents"]], "path (pynodes.node property)": [[0, "pynodes.Node.path"]], "pretty_print() (pynodes.node method)": [[0, "pynodes.Node.pretty_print"]], "reset_stats() (pynodes.node class method)": [[0, "pynodes.Node.reset_stats"]], "siblings (pynodes.node property)": [[0, "pynodes.Node.siblings"]]}}) \ No newline at end of file +Search.setIndex({"docnames": ["index"], "filenames": ["index.rst"], "titles": ["Welcome to pynodes\u2019s documentation!"], "terms": {"i": 0, "python": 0, "librari": 0, "manag": 0, "node": 0, "class": 0, "A": 0, "an": 0, "object": 0, "which": 0, "relat": 0, "other": 0, "given": 0, "tree": 0, "chart": 0, "venv": 0, "pip": 0, "instal": 0, "import": 0, "name": 0, "str": 0, "parent": 0, "none": 0, "sourc": 0, "should": 0, "subclass": 0, "onli": 0, "add_child": 0, "child": 0, "add": 0, "new": 0, "current": 0, "instanc": 0, "static": 0, "check_lineag": 0, "list": 0, "bool": 0, "check": 0, "straight": 0, "lineag": 0, "1": 0, "ancestor": 0, "2": 0, "3": 0, "n": 0, "grand": 0, "children": 0, "classmethod": 0, "create_random_nod": 0, "type_": 0, "cmd": 0, "depth": 0, "int": 0, "0": 0, "creat": 0, "random": 0, "test": 0, "purpos": 0, "properti": 0, "path": 0, "return": 0, "represent": 0, "self": 0, "pretty_print": 0, "print": 0, "from": 0, "reset_stat": 0, "reset": 0, "all": 0, "classvar": 0, "member": 0, "index": 0, "modul": 0, "search": 0, "page": 0, "level": 0, "sibl": 0, "get_child": 0, "find": 0, "specifi": 0, "noth": 0, "found": 0, "get_sibl": 0, "has_children": 0, "ha": 0, "one": 0, "least": 0, "has_par": 0, "has_sibl": 0, "is_child": 0, "is_sibl": 0, "code": 0, "host": 0, "my": 0, "own": 0, "gitea": 0, "link": [], "text": []}, "objects": {"pynodes": [[0, 0, 1, "", "Node"]], "pynodes.Node": [[0, 1, 1, "", "add_child"], [0, 1, 1, "", "check_lineage"], [0, 1, 1, "", "create_random_nodes"], [0, 1, 1, "", "get_child"], [0, 1, 1, "", "get_sibling"], [0, 1, 1, "", "has_children"], [0, 1, 1, "", "has_parent"], [0, 1, 1, "", "has_siblings"], [0, 1, 1, "", "is_child"], [0, 1, 1, "", "is_sibling"], [0, 2, 1, "", "level"], [0, 2, 1, "", "parents"], [0, 2, 1, "", "path"], [0, 1, 1, "", "pretty_print"], [0, 1, 1, "", "reset_stats"], [0, 2, 1, "", "siblings"]]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:property"}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "property", "Python property"]}, "titleterms": {"welcom": 0, "pynod": 0, "": 0, "document": 0, "basic": 0, "usag": 0, "indic": 0, "tabl": 0}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx": 60}, "alltitles": {"Welcome to pynodes\u2019s documentation!": [[0, "welcome-to-pynodes-s-documentation"]], "Basic Usage": [[0, "basic-usage"]], "Indices and tables": [[0, "indices-and-tables"]]}, "indexentries": {"node (class in pynodes)": [[0, "pynodes.Node"]], "add_child() (pynodes.node method)": [[0, "pynodes.Node.add_child"]], "check_lineage() (pynodes.node static method)": [[0, "pynodes.Node.check_lineage"]], "create_random_nodes() (pynodes.node class method)": [[0, "pynodes.Node.create_random_nodes"]], "get_child() (pynodes.node method)": [[0, "pynodes.Node.get_child"]], "get_sibling() (pynodes.node method)": [[0, "pynodes.Node.get_sibling"]], "has_children() (pynodes.node method)": [[0, "pynodes.Node.has_children"]], "has_parent() (pynodes.node method)": [[0, "pynodes.Node.has_parent"]], "has_siblings() (pynodes.node method)": [[0, "pynodes.Node.has_siblings"]], "is_child() (pynodes.node method)": [[0, "pynodes.Node.is_child"]], "is_sibling() (pynodes.node method)": [[0, "pynodes.Node.is_sibling"]], "level (pynodes.node property)": [[0, "pynodes.Node.level"]], "parents (pynodes.node property)": [[0, "pynodes.Node.parents"]], "path (pynodes.node property)": [[0, "pynodes.Node.path"]], "pretty_print() (pynodes.node method)": [[0, "pynodes.Node.pretty_print"]], "reset_stats() (pynodes.node class method)": [[0, "pynodes.Node.reset_stats"]], "siblings (pynodes.node property)": [[0, "pynodes.Node.siblings"]]}}) \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index c0e1ee1..9f0996b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,6 +13,8 @@ A node is an object which is related to other nodes given a tree chart. (venv) $ pip install pynodes +Source code is hosted on my own instance of `gitea `_. + .. toctree:: :maxdepth: 2 :caption: Contents: diff --git a/pynodes.py b/pynodes.py index b5c7a67..5afe396 100644 --- a/pynodes.py +++ b/pynodes.py @@ -9,7 +9,6 @@ class Node: Should be subclassed only """ # Class Var for statistics - total_nodes_number: ClassVar[int] = 0 deepest_level: ClassVar[int] = 0 largest_sibling_number: ClassVar[int] = 0 all_nodes: ClassVar[list[Node]] = [] @@ -18,7 +17,6 @@ class Node: """ each subclass must define its own ClassVar """ # TODO to be renamed for clarity super().__init_subclass__() - cls.total_nodes_number: ClassVar[int] = 0 cls.deepest_level: ClassVar[int] = 0 cls.largest_sibling_number: ClassVar[int] = 0 cls.all_nodes: ClassVar[list[Node]] = [] @@ -27,7 +25,7 @@ class Node: def __new__(cls, name: str, parent: Node | None = None) -> None: for n in cls.all_nodes: if name == n.name: - raise Exception('Node with this name already exist') + raise AttributeError('Node with this name already exists') else: return super().__new__(cls) @@ -35,9 +33,21 @@ class Node: self.name = name self.parent = parent # is set with add_child self.children: list[Node] = [] - type(self).total_nodes_number += 1 type(self).all_nodes.append(self) + def add_child(self, child: Node) -> None: + """ add new child node to current instance """ + child.parent = self + if child.name not in [c.name for c in self.children]: + self.children.append(child) + if child.level > type(self).deepest_level: + type(self).deepest_level = child.level + if len(self.children) > type(self).largest_sibling_number: + type(self).largest_sibling_number = len(self.children) + else: + raise Exception('Child with same name already exists') + + @property def siblings(self) -> list[Node]: """ returns all the siblings of the Node object """ @@ -76,13 +86,14 @@ class Node: return path def is_sibling(self, other: str) -> bool: - """ test if Node object is sibling with other Node object """ + """ check if Node object is a sibling of the other Node object """ if other in [s.name for s in self.siblings]: return True else: return False def is_child(self, other: str) -> bool: + """ check if Node object is a child of the other Node object """ if other in [s.name for s in self.children]: return True else: @@ -95,41 +106,35 @@ class Node: for c in self.children: c.pretty_print() - def add_child(self, child: Node) -> None: - """ add new child node to current instance """ - child.parent = self - if child.name not in [c.name for c in self.children]: - self.children.append(child) - if child.level > type(self).deepest_level: - type(self).deepest_level = child.level - if len(self.children) > type(self).largest_sibling_number: - type(self).largest_sibling_number = len(self.children) - else: - raise Exception('Child with same name already exists') - def has_parent(self) -> bool: + """ check if Node object has a parent or not """ if self.parent is not None: return True return False def has_children(self) -> bool: + """ check if Node object has one child at least """ if self.children is not None: return True return False def has_siblings(self) -> bool: + """ check if Node object has one sibling at least """ if self.has_parent() and self.parent.has_children() \ and len(self.parent.children) > 0: return True return False def get_child(self, name: str) -> Node | None: + """ find and returns a child with specified name. None if nothing found """ for c in self.children: if c.name == name: return c return None def get_sibling(self, name: str) -> Node | None: + """ find and returns a sibling with specified name. None if nothing + found """ for c in self.siblings: if c.name == name: return c @@ -163,7 +168,6 @@ class Node: """ reset all the ClassVar members """ - cls.total_nodes_number = 0 cls.deepest_level = 0 cls.largest_sibling_number = 0 cls.all_nodes = [] @@ -174,7 +178,7 @@ class Node: Creates random tree of nodes for testing purpose """ def create_node(level, i): - id_ = cls.total_nodes_number + 1 + id_ = len(cls.all_nodes) + 1 return cls(f'{type_}_'+str(id_)) def create_node_list(level: int, width: int = 5):