#!/usr/bin/python3 # # Naše objektové řešení obsahovalo spoustu duplicitního kódu: speciálně # všechny binární operátory měly identické metody __init__ a velmi podobné # metody __str__ a eval. # # Zde se duplicit zbavíme tím, že je přesuneme do společného předka: # třídy BinaryNode, která popisuje chování obecného binárního operátoru. # Každý konkrétní operátor si pak pouze dodefinuje, jak se jmenuje a jaké # funkci odpovídá. # class Node: def eval(self): raise NotImplementedError() def depth(self): raise NotImplementedError() def to_postfix(self, dest): raise NotImplementedError() class NumNode(Node): def __init__(self, x): self.value = x def __str__(self): return str(self.value) def eval(self): return self.value def depth(self): return 0 def to_postfix(self, dest): dest.append(str(self.value)) class BinaryNode(Node): op_name = '?' def __init__(self, left, right): self.left = left self.right = right def __str__(self): return '(' + str(self.left) + self.op_name + str(self.right) + ')' def eval(self): return self.eval_op(self.left.eval(), self.right.eval()) def eval_op(self, x, y): raise NotImplementedError() def depth(self): return max(self.left.depth(), self.right.depth()) + 1 def to_postfix(self, dest): self.left.to_postfix(dest) self.right.to_postfix(dest) dest.append(self.op_name) class UnaryNode(Node): op_name = '?' def __init__(self, arg): self.arg = arg def __str__(self): return '(' + self.op_name + str(self.arg) + ')' def eval(self): return self.eval_op(self.arg.eval()) def eval_op(self, x): raise NotImplementedError() def depth(self): return self.arg.depth() + 1 def to_postfix(self, dest): self.arg.to_postfix(dest) dest.append(self.op_name) class NegNode(UnaryNode): op_name = 'N' def eval_op(self, x): return -x class AddNode(BinaryNode): op_name = '+' def eval_op(self, x, y): return x + y class SubNode(BinaryNode): op_name = '-' def eval_op(self, x, y): return x - y class MulNode(BinaryNode): op_name = '*' def eval_op(self, x, y): return x * y class DivNode(BinaryNode): op_name = '/' def eval_op(self, x, y): return x // y x = AddNode(NegNode(MulNode(NumNode(3), NumNode(4))), SubNode(NumNode(5), NumNode(6))) print(x) print(x.eval()) print(x.depth()) dest = [] x.to_postfix(dest) print(" ".join(dest))