fork download
  1. class Node:
  2. def __init__(self, name=None, parent=None, available=True):
  3. self.name = name
  4. self.parent = parent
  5. self.available = available
  6. self.children = []
  7.  
  8. @property
  9. def next_sibling(self):
  10. """Return next node on the same level."""
  11. try:
  12. return self.parent.children[self.parent.children.index(self)+1]
  13. except (AttributeError, IndexError):
  14. return None
  15.  
  16. def next_node(self):
  17. if self.available:
  18. if self.children:
  19. if not self.children[0].available:
  20. return self.children[0].next_node()
  21. else:
  22. return self.children[0]
  23. elif self.parent is not None:
  24. node = self
  25. while True:
  26. if node.parent is not None:
  27. node = node.parent
  28. if node.next_sibling:
  29. if not node.next_sibling.available:
  30. return node.next_sibling.next_node()
  31. else:
  32. return node.next_sibling
  33. else:
  34. break
  35. else:
  36. if self.next_sibling:
  37. if not self.next_sibling.available:
  38. return self.next_sibling.next_node()
  39. else:
  40. return self.next_sibling
  41. elif self.parent is not None:
  42. if self.parent.next_sibling:
  43. if not self.parent.next_sibling.available:
  44. return self.parent.next_sibling.next_node()
  45. else:
  46. return self.parent.next_sibling
  47. return None
  48.  
  49.  
  50. def print_tree(node, only_available=False):
  51. todo = [node]
  52. while todo:
  53. node = todo.pop()
  54. if only_available and not node.available:
  55. continue
  56. todo.extend(reversed(node.children))
  57. print(node.name + (' (unavailable)' if not node.available else ''))
  58.  
  59.  
  60. def traverse(node):
  61. while True:
  62. print(node.name)
  63. node = node.next_node()
  64. if not node:
  65. break
  66.  
  67.  
  68. grandparent = Node(name='grandparent')
  69. parent0 = Node(name=' parent0', parent=grandparent)
  70. parent1 = Node(name=' parent1', parent=grandparent)
  71. parent2 = Node(name=' parent2', parent=grandparent, available=False)
  72. parent3 = Node(name=' parent3', parent=grandparent)
  73. child0 = Node(name=' child0', parent=parent0, available=False)
  74. child1 = Node(name=' child1', parent=parent0, available=False)
  75. child2 = Node(name=' child2', parent=parent1, available=False)
  76. child3 = Node(name=' child3', parent=parent1)
  77. child4 = Node(name=' child4', parent=parent2)
  78. child5 = Node(name=' child5', parent=parent3)
  79. child6 = Node(name=' child6', parent=parent3, available=False)
  80. grandchild0 = Node(name=' grandchild0', parent=child0)
  81. grandchild1 = Node(name=' grandchild1', parent=child0)
  82. grandchild2 = Node(name=' grandchild2', parent=child3)
  83. grandparent.children = [parent0, parent1, parent2, parent3]
  84. parent0.children = [child0, child1]
  85. parent1.children = [child2, child3]
  86. parent2.children = [child4]
  87. parent3.children = [child5, child6]
  88. child0.children = [grandchild0, grandchild1]
  89. child3.children = [grandchild2]
  90. print('Full node tree:\n')
  91. print_tree(grandparent, only_available=False)
  92. print('\n\nGoal sequence:\n')
  93. print_tree(grandparent, only_available=True)
  94. print('\n\nTraverse using Node.next_node() method (must be equal to "Goal sequence"):\n')
  95. traverse(grandparent)
Success #stdin #stdout 0.02s 9060KB
stdin
Standard input is empty
stdout
Full node tree:

grandparent
    parent0
        child0 (unavailable)
            grandchild0
            grandchild1
        child1 (unavailable)
    parent1
        child2 (unavailable)
        child3
            grandchild2
    parent2 (unavailable)
        child4
    parent3
        child5
        child6 (unavailable)


Goal sequence:

grandparent
    parent0
    parent1
        child3
            grandchild2
    parent3
        child5


Traverse using Node.next_node() method (must be equal to "Goal sequence"):

grandparent
    parent0
    parent1
        child3
            grandchild2
    parent3
        child5