I used the visitor pattern to visit all the nodes. One visitor visits and runs all the nodes, the other visitor bubbles up the result. The code and output is provided below:
class Node(object):
def __init__(self):
self.children = []
self.result = None
def add(self, node):
self.children.append(node)
def check(self):
self.result = True
print "Node: result:%s" % self.result
return self.result
def accept(self, visitor):
visitor.visit(self)
class Node_A(Node):
def __init__(self):
super(Node_A, self).__init__()
def check(self):
self.result = True
print "Node_A: result:%s" % self.result
return self.result
class Node_A_A(Node_A):
def __init__(self):
super(Node_A_A, self).__init__()
def check(self):
self.result = True
print "Node_A_A: result:%s" % self.result
return self.result
class Node_A_B(Node_A):
def __init__(self):
super(Node_A_B, self).__init__()
def check(self):
self.result = True
print "Node_A_B: result:%s" % self.result
return self.result
class Node_A_A_A(Node_A_A):
def __init__(self):
super(Node_A_A_A, self).__init__()
def check(self):
self.result = True
print "Node_A_A_A: result:%s" % self.result
return self.result
class Node_A_A_B(Node_A_A):
def __init__(self):
super(Node_A_A_B, self).__init__()
def check(self):
self.result = False
print "Node_A_A_B: result:%s" % self.result
return self.result
class Node_A_B_A(Node_A_B):
def __init__(self):
super(Node_A_B_A, self).__init__()
def check(self):
self.result = True
print "Node_A_B_A: result:%s" % self.result
return self.result
class NodeRunner:
def visit(self, node):
if len(node.children) > 0:
for child in node.children:
child.accept(self)
node.check()
class NodeChecker:
def visit(self, node):
results = []
if len(node.children) > 0:
for child in node.children:
child.accept(self)
results.append(child.result)
node.result = all(results)
if __name__ == "__main__":
node = Node()
node_a = Node_A()
node_a_a = Node_A_A()
node_a_b = Node_A_B()
node_a_a_a = Node_A_A_A()
node_a_a_b = Node_A_A_B()
node_a_b_a = Node_A_B_A()
node.add(node_a)
node_a.add(node_a_a)
node_a_a.add(node_a_a_a)
node_a_a.add(node_a_a_b)
node_a.add(node_a_b)
node_a_b.add(node_a_b_a)
print("-------------------")
nVisitor = NodeRunner()
nVisitor.visit(node)
print("-------------------")
nVisitor = NodeChecker()
nVisitor.visit(node)
print("-------------------")
print "node_a_a_a: result: %s" % node_a_a_a.result
print "node_a_a_b: result: %s" % node_a_a_b.result
print "node_a_a: result: %s" % node_a_a.result
print "node_a_b_a: result: %s" % node_a_b_a.result
print "node_a_b: result: %s" % node_a_b.result
print "node_a: result: %s" % node_a.result
print "node: result: %s" % node.result
The output is provided below:
-------------------
Node_A_A_A: result:True
Node_A_A_B: result:False
Node_A_A: result:True
Node_A_B_A: result:True
Node_A_B: result:True
Node_A: result:True
Node: result:True
-------------------
-------------------
node_a_a_a: result: True
node_a_a_b: result: False
node_a_a: result: False
node_a_b_a: result: True
node_a_b: result: True
node_a: result: False
node: result: False