Ao executar o código do exercício 02, percebi que as expressões não eram impressas corretamente.
Percebi que isso ocorre porque os métodos "aceita" das expressões "Subtração", "Soma" e "Número" percorrem a sub-árvore (se houver) mas não retorna seu valor avaliado, fazendo com que o método que chamou o "aceita" (Impressora.visitar_soma, Impressora.visitar_subtração ou Impressora.visitar_numero) salvem None como um dos termos da expressão.
A solução é fazer com o que os referidos métodos retornem o valor avaliado na sub-árvore, como no código abaixo:
expressoes.py
class Sub(object):
def __init__(self, left_expr, right_expr):
self.__expressao_esquerda = left_expr
self.__expressao_direita = right_expr
def avaliar(self):
return self.__expressao_esquerda.avaliar() - self.__expressao_direita.avaliar()
@property
def expressao_esquerda(self):
return self.__expressao_esquerda
@property
def expressao_direita(self):
return self.__expressao_direita
def aceitar(self, visitor):
return visitor.visitar_subtracao(self)
class Soma(object):
def __init__(self, left_expr, right_expr):
self.__expressao_esquerda = left_expr
self.__expressao_direita = right_expr
def avaliar(self):
return self.__expressao_esquerda.avaliar() + self.__expressao_direita.avaliar()
def aceitar(self, visitor):
return visitor.visitar_soma(self)
@property
def expressao_esquerda(self):
return self.__expressao_esquerda
@property
def expressao_direita(self):
return self.__expressao_direita
class Numero(object):
def __init__(self, numero):
self.__numero = numero
def avaliar(self):
return self.__numero
def aceitar(self, visitor):
return visitor.visitar_numero(self)
Impressora.py
class Impressora(object):
def visitar_soma(self, soma):
output = "({}+{})".format(soma.expressao_esquerda.aceitar(self), soma.expressao_direita.aceitar(self))
return output
def visitar_subtracao(self, sub):
output = "({}-{})".format(sub.expressao_esquerda.aceitar(self), sub.expressao_direita.aceitar(self))
return output
def visitar_numero(self, numero):
output = numero.avaliar()
return output
No arquivo main.py:
if __name__ == '__main__':
expressao_esquerda = Sub(Numero(10), Numero(5))
expressao_direita = Soma(Numero(2), Numero(10))
expressao_conta = Soma(expressao_esquerda, expressao_direita)
expressao_conta = Sub(expressao_conta, Numero(3.2))
visitor = Impressora()
print (expressao_conta.aceitar(visitor))
Saída: (((10-5)+(2+10))-3.2) :)