diff --git a/seminar/treelib.py b/seminar/treelib.py index 95fae9a9..06a710cf 100644 --- a/seminar/treelib.py +++ b/seminar/treelib.py @@ -15,11 +15,14 @@ def print_tree(node,indent=0): # Django je trošku hloupé, takže node.prev nevrací None, ale hází django.core.exceptions.ObjectDoesNotExist def safe_pred(node): + if node is None: + return None try: return node.prev except ObjectDoesNotExist: return None +# FIXME: Proč????? def safe_succ(node): try: return node.succ @@ -27,6 +30,8 @@ def safe_succ(node): return None def safe_father_of_first(node): + if node is None: + return None first = first_brother(node) try: return first.father_of_first @@ -42,6 +47,7 @@ def first_brother(node): return brother ## Rodinné vztahy +# Tohle se teď zrovna k None chová správně, ale je potřeba na to dávat pozor def get_parent(node): # Nejdřív získáme prvního potomka... while safe_pred(node) is not None: @@ -50,6 +56,8 @@ def get_parent(node): return safe_father_of_first(node) def get_last_child(node): + if node is None: + return None first = node.first_child if first is None: return None @@ -73,6 +81,8 @@ def is_orphan(node): # Obecný next: další Node v "the-right-order" pořadí (já, pak potomci, pak sousedé) def general_next(node): + if node is None: + return None # Máme potomka? if node.first_child is not None: return node.first_child @@ -85,6 +95,8 @@ def general_next(node): return node.succ def last_brother(node): + if node is None: + return None while node.succ is not None: node = node.succ return node @@ -92,6 +104,7 @@ def last_brother(node): def general_prev(node): # Předchůdce je buď rekurzivně poslední potomek předchůdce, nebo náš otec. # Otce vyřešíme nejdřív: + # Tady se ošetří node=None samo if safe_pred(node) is None: return safe_father_of_first(node) pred = safe_pred(node) @@ -109,12 +122,16 @@ def me_and_right_brothers(node): current = current.succ def right_brothers(node): + if node is None: + return generator = me_and_right_brothers(node.succ) for item in generator: yield item # Generátor všech sourozenců (vč. sám sebe) def all_brothers(node): + if node is None: + return # Najdeme prvního bratra fb = first_brother(node) marb = me_and_right_brothers(fb) @@ -122,6 +139,8 @@ def all_brothers(node): yield cur def all_proper_brothers(node): + if node is None: + return all = all_brothers(node) for br in all: if br is node: @@ -130,12 +149,16 @@ def all_proper_brothers(node): def all_children(node): """ Generátor všech potomků zadaného Node. """ + if node is None: + return brothers = all_brothers(node.first_child) for br in brothers: yield br def all_children_of_type(node, type): """ Generuje všechny potomky daného Node a daného typu. """ + if node is None: + return brothers = all_brothers(node.first_child) for br in brothers: if isinstance(br, type): @@ -144,6 +167,8 @@ def all_children_of_type(node, type): # Generátor následníků v "the-right-order" # Bez tohoto vrcholu def all_following(node): + if node is None: + return current = general_next(node) while current is not None: yield current @@ -153,12 +178,16 @@ def all_following(node): # Najdi dalšího bratra nějakého typu, nebo None. # hledá i podtřídy, i.e. get_next_brother_of_type(neco, TreeNode) je prostě succ. def get_next_brother_of_type(node, type): + if node is None: + return for current in right_brothers(node): if isinstance(current, type): return current return None def get_prev_brother_of_type(node, type): + if node is None: + return # Na tohle není rozumný generátor, ani ho asi nechceme, prostě to implementujeme cyklem. current = node while safe_pred(current) is not None: @@ -169,6 +198,8 @@ def get_prev_brother_of_type(node, type): # Totéž pro "the-right-order" pořadí def get_next_node_of_type(node, type): + if node is None: + return for cur in all_folowing(node): if isinstance(cur, type): return cur @@ -176,6 +207,8 @@ def get_next_node_of_type(node, type): def get_prev_node_of_type(node, type): # Na tohle není rozumný generátor, ani ho asi nechceme, prostě to implementujeme cyklem. + if node is None: + return current = node while general_prev(current) is not None: current = general_prev(current)