from abc import ABC, abstractmethod

class Exp (ABC):
    @abstractmethod
    def valuta(self) -> int:
        pass

class ExpNumero(Exp):
    def __init__ (self, i:int):
        self._i = i

    def valuta(self) -> int:
        return self._i
    
    def __str__ (self) ->str:
        return str(self._i)

class ExpSomma (Exp):
    def __init__ (self, a:Exp, b:Exp):
        self._a:Exp = a
        self._b:Exp = b
    
    def valuta(self) -> int:
        return self._a.valuta() + self._b.valuta()

    def __str__ (self) ->str:
        return "(" + str(self._a) + " + " + str(self._b) +")"
    
class ExpDifferenza (Exp):
    def __init__ (self, a:Exp, b:Exp):
        self._a:Exp = a
        self._b:Exp = b
    
    def valuta(self) -> int:
        return self._a.valuta() - self._b.valuta()
    
    def __str__ (self) ->str:
        return "(" + str(self._a) + " - " + str(self._b) +")"
    
class ExpProdotto (Exp):
    def __init__ (self, a:Exp, b:Exp):
        self._a:Exp = a
        self._b:Exp = b
    
    def valuta(self) -> int:
        return self._a.valuta() * self._b.valuta()
    
    def __str__ (self) ->str:
        return "(" + str(self._a) + " * " + str(self._b) +")"


e:Exp = ExpDifferenza (   
    ExpProdotto(ExpSomma(ExpNumero(3), 
                         ExpNumero(5)), 
                           ExpNumero(2)),   
    ExpSomma (
        ExpNumero(4),
        ExpProdotto(ExpNumero(7), 
                         ExpNumero(9))
    )
        )

print (str(e) + " = " + str(e.valuta()))



 
