From 82cb7cf320c77b7ec0a784b6db5e996858e9dc90 Mon Sep 17 00:00:00 2001 From: ftg Date: Mon, 1 Apr 2024 21:26:38 +0200 Subject: [PATCH] writing the documentation --- docs/build/doctrees/environment.pickle | Bin 67908 -> 92695 bytes docs/build/doctrees/index.doctree | Bin 32005 -> 48293 bytes docs/build/html/_modules/pynodes.html | 82 ++++++++++++++++--------- docs/build/html/_sources/index.rst.txt | 2 + docs/build/html/genindex.html | 41 +++++++++++++ docs/build/html/index.html | 44 +++++++++++++ docs/build/html/objects.inv | Bin 370 -> 401 bytes docs/build/html/searchindex.js | 2 +- docs/source/index.rst | 2 + pynodes.py | 42 +++++++------ 10 files changed, 167 insertions(+), 48 deletions(-) diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index ea57da2d0c705e652172584c803d2c7eda2463f4..e1985910d3493d89fd99e89f2b906f84ff97f74c 100644 GIT binary patch literal 92695 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 kIPEx{zT&4Xboz>)_9SIZD{448=!o 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 diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree index 8a549ee4870c03e2d55e52cd55245a5b3c88b3ba..62b0503b5c38bb9267515e0ec69e89bc97deaaad 100644 GIT binary patch literal 48293 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 F{XZYVq_hA4 literal 32005 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 Czhf@| 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 1e21cd82f2bf93cd5d2ef80da083a3e432395890..a129cf2d2cdf39d8491e3855551ba75a8ed2213d 100644 GIT binary patch delta 292 zcmV+<0o(ra0+9odc7KySZp0uEg?pcZC~0kJ+r2@GL@T98X|XUeDEx_;jY5}e$Wq+5w+nKNW!!jFCI(?Kn4fvlCFG$3mb!XOq)zMt^avQzEz~DDX^B6S8>Q zAA!ck1T;1WVBj50QHSUQL`oa_dT(qZNVUi#5T!9h-4JgCERRo|_NTjkj{m();N}WL zl1IbOIjsJ`uGLw`9?Q1-l}Rs(Xr*`sBfJGho-H1}KfjP=;l<`SIce|iI_u>hvqI{x qje6LVmlp%e)E!lK13RT0io2x|cogauthLI#)cz@d`tApZ%#J%hAd2b$ delta 260 zcmV+f0sH=u1M&ipc7Kw=Y6Bq$*oxxZF0p{+#t|FGbb}DDF6E*;Tb%wor*^0J_GpthpQXA`F5InLW zSTM9f{VAOdsCry)B~*+usQ~2V7_4?3UeFD6OcXJ3S>U5e7=1WDWw3b$Psm(kOg8Z9 zE)r&BnOX7r&a*w$LH7%-^ccp9$P9a@PIXxAPTZ;^CtinbbH{-60L_RaI!zu0leoU& z_xmS{3Z8u(r(#QC(|Ce^?uwTT K*!%%hLlDwZ$$U}( 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):