TreeLib: explicitně ošetřené node=None v "získávacích" funkcích
This commit is contained in:
		
							parent
							
								
									e4818d28ea
								
							
						
					
					
						commit
						981cbc8bf1
					
				
					 1 changed files with 33 additions and 0 deletions
				
			
		|  | @ -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 | # Django je trošku hloupé, takže node.prev nevrací None, ale hází django.core.exceptions.ObjectDoesNotExist | ||||||
| def safe_pred(node): | def safe_pred(node): | ||||||
|  | 	if node is None: | ||||||
|  | 		return None | ||||||
| 	try: | 	try: | ||||||
| 		return node.prev | 		return node.prev | ||||||
| 	except ObjectDoesNotExist: | 	except ObjectDoesNotExist: | ||||||
| 		return None | 		return None | ||||||
| 
 | 
 | ||||||
|  | # FIXME: Proč????? | ||||||
| def safe_succ(node): | def safe_succ(node): | ||||||
| 	try: | 	try: | ||||||
| 		return node.succ | 		return node.succ | ||||||
|  | @ -27,6 +30,8 @@ def safe_succ(node): | ||||||
| 		return None | 		return None | ||||||
| 
 | 
 | ||||||
| def safe_father_of_first(node): | def safe_father_of_first(node): | ||||||
|  | 	if node is None: | ||||||
|  | 		return None | ||||||
| 	first = first_brother(node) | 	first = first_brother(node) | ||||||
| 	try: | 	try: | ||||||
| 		return first.father_of_first | 		return first.father_of_first | ||||||
|  | @ -42,6 +47,7 @@ def first_brother(node): | ||||||
| 	return brother | 	return brother | ||||||
| 
 | 
 | ||||||
| ## Rodinné vztahy | ## Rodinné vztahy | ||||||
|  | # Tohle se teď zrovna k None chová správně, ale je potřeba na to dávat pozor | ||||||
| def get_parent(node): | def get_parent(node): | ||||||
| 	# Nejdřív získáme prvního potomka... | 	# Nejdřív získáme prvního potomka... | ||||||
| 	while safe_pred(node) is not None: | 	while safe_pred(node) is not None: | ||||||
|  | @ -50,6 +56,8 @@ def get_parent(node): | ||||||
| 	return safe_father_of_first(node) | 	return safe_father_of_first(node) | ||||||
| 
 | 
 | ||||||
| def get_last_child(node): | def get_last_child(node): | ||||||
|  | 	if node is None: | ||||||
|  | 		return None | ||||||
| 	first = node.first_child | 	first = node.first_child | ||||||
| 	if first is None: | 	if first is None: | ||||||
| 		return 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é) | # Obecný next: další Node v "the-right-order" pořadí (já, pak potomci, pak sousedé) | ||||||
| def general_next(node): | def general_next(node): | ||||||
|  | 	if node is None: | ||||||
|  | 		return None | ||||||
| 	# Máme potomka? | 	# Máme potomka? | ||||||
| 	if node.first_child is not None: | 	if node.first_child is not None: | ||||||
| 		return node.first_child | 		return node.first_child | ||||||
|  | @ -85,6 +95,8 @@ def general_next(node): | ||||||
| 	return node.succ | 	return node.succ | ||||||
| 
 | 
 | ||||||
| def last_brother(node): | def last_brother(node): | ||||||
|  | 	if node is None: | ||||||
|  | 		return None | ||||||
| 	while node.succ is not None: | 	while node.succ is not None: | ||||||
| 		node = node.succ | 		node = node.succ | ||||||
| 	return node | 	return node | ||||||
|  | @ -92,6 +104,7 @@ def last_brother(node): | ||||||
| def general_prev(node): | def general_prev(node): | ||||||
| 	# Předchůdce je buď rekurzivně poslední potomek předchůdce, nebo náš otec. | 	# Předchůdce je buď rekurzivně poslední potomek předchůdce, nebo náš otec. | ||||||
| 	# Otce vyřešíme nejdřív: | 	# Otce vyřešíme nejdřív: | ||||||
|  | 	# Tady se ošetří node=None samo | ||||||
| 	if safe_pred(node) is None: | 	if safe_pred(node) is None: | ||||||
| 		return safe_father_of_first(node) | 		return safe_father_of_first(node) | ||||||
| 	pred = safe_pred(node) | 	pred = safe_pred(node) | ||||||
|  | @ -109,12 +122,16 @@ def me_and_right_brothers(node): | ||||||
| 		current = current.succ | 		current = current.succ | ||||||
| 
 | 
 | ||||||
| def right_brothers(node): | def right_brothers(node): | ||||||
|  | 	if node is None: | ||||||
|  | 		return | ||||||
| 	generator = me_and_right_brothers(node.succ) | 	generator = me_and_right_brothers(node.succ) | ||||||
| 	for item in generator: | 	for item in generator: | ||||||
| 		yield item | 		yield item | ||||||
| 
 | 
 | ||||||
| # Generátor všech sourozenců (vč. sám sebe) | # Generátor všech sourozenců (vč. sám sebe) | ||||||
| def all_brothers(node): | def all_brothers(node): | ||||||
|  | 	if node is None: | ||||||
|  | 		return | ||||||
| 	# Najdeme prvního bratra | 	# Najdeme prvního bratra | ||||||
| 	fb = first_brother(node) | 	fb = first_brother(node) | ||||||
| 	marb = me_and_right_brothers(fb) | 	marb = me_and_right_brothers(fb) | ||||||
|  | @ -122,6 +139,8 @@ def all_brothers(node): | ||||||
| 		yield cur | 		yield cur | ||||||
| 	 | 	 | ||||||
| def all_proper_brothers(node): | def all_proper_brothers(node): | ||||||
|  | 	if node is None: | ||||||
|  | 		return | ||||||
| 	all = all_brothers(node) | 	all = all_brothers(node) | ||||||
| 	for br in all: | 	for br in all: | ||||||
| 		if br is node: | 		if br is node: | ||||||
|  | @ -130,12 +149,16 @@ def all_proper_brothers(node): | ||||||
| 
 | 
 | ||||||
| def all_children(node): | def all_children(node): | ||||||
| 	""" Generátor všech potomků zadaného Node. """ | 	""" Generátor všech potomků zadaného Node. """ | ||||||
|  | 	if node is None: | ||||||
|  | 		return | ||||||
| 	brothers = all_brothers(node.first_child) | 	brothers = all_brothers(node.first_child) | ||||||
| 	for br in brothers: | 	for br in brothers: | ||||||
| 		yield br | 		yield br | ||||||
| 
 | 
 | ||||||
| def all_children_of_type(node, type): | def all_children_of_type(node, type): | ||||||
| 	""" Generuje všechny potomky daného Node a daného typu. """ | 	""" Generuje všechny potomky daného Node a daného typu. """ | ||||||
|  | 	if node is None: | ||||||
|  | 		return | ||||||
| 	brothers = all_brothers(node.first_child) | 	brothers = all_brothers(node.first_child) | ||||||
| 	for br in brothers: | 	for br in brothers: | ||||||
| 		if isinstance(br, type): | 		if isinstance(br, type): | ||||||
|  | @ -144,6 +167,8 @@ def all_children_of_type(node, type): | ||||||
| # Generátor následníků v "the-right-order" | # Generátor následníků v "the-right-order" | ||||||
| # Bez tohoto vrcholu | # Bez tohoto vrcholu | ||||||
| def all_following(node): | def all_following(node): | ||||||
|  | 	if node is None: | ||||||
|  | 		return | ||||||
| 	current = general_next(node) | 	current = general_next(node) | ||||||
| 	while current is not None: | 	while current is not None: | ||||||
| 		yield current | 		yield current | ||||||
|  | @ -153,12 +178,16 @@ def all_following(node): | ||||||
| # Najdi dalšího bratra nějakého typu, nebo None. | # 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. | # hledá i podtřídy, i.e. get_next_brother_of_type(neco, TreeNode) je prostě succ. | ||||||
| def get_next_brother_of_type(node, type): | def get_next_brother_of_type(node, type): | ||||||
|  | 	if node is None: | ||||||
|  | 		return | ||||||
| 	for current in right_brothers(node): | 	for current in right_brothers(node): | ||||||
| 		if isinstance(current, type): | 		if isinstance(current, type): | ||||||
| 			return current | 			return current | ||||||
| 	return None | 	return None | ||||||
| 	 | 	 | ||||||
| def get_prev_brother_of_type(node, type): | 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. | 	# Na tohle není rozumný generátor, ani ho asi nechceme, prostě to implementujeme cyklem. | ||||||
| 	current = node | 	current = node | ||||||
| 	while safe_pred(current) is not None: | 	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í | # Totéž pro "the-right-order" pořadí | ||||||
| def get_next_node_of_type(node, type): | def get_next_node_of_type(node, type): | ||||||
|  | 	if node is None: | ||||||
|  | 		return | ||||||
| 	for cur in all_folowing(node): | 	for cur in all_folowing(node): | ||||||
| 		if isinstance(cur, type): | 		if isinstance(cur, type): | ||||||
| 			return cur | 			return cur | ||||||
|  | @ -176,6 +207,8 @@ def get_next_node_of_type(node, type): | ||||||
| 
 | 
 | ||||||
| def get_prev_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. | 	# Na tohle není rozumný generátor, ani ho asi nechceme, prostě to implementujeme cyklem. | ||||||
|  | 	if node is None: | ||||||
|  | 		return | ||||||
| 	current = node | 	current = node | ||||||
| 	while general_prev(current) is not None: | 	while general_prev(current) is not None: | ||||||
| 		current = general_prev(current) | 		current = general_prev(current) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Pavel 'LEdoian' Turinsky
						Pavel 'LEdoian' Turinsky