#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue Dec 11 12:27:32 2018 @author: andrea """ ''' Espressioni algebriche ''' class numero: def __init__(self, valore): self.valore = valore def __str__(self): return str(self.valore) def semplifica(self): return self def calcola(self, _valori): return self.valore def __eq__(self, other): return type(other) == type(self) and self.valore == other.valore class variabile: def __init__(self, nome): self.nome = nome def __str__(self): return self.nome def semplifica(self): return self def calcola(self, valori): return valori[self.nome] def __eq__(self, other): return type(other) == type(self) and self.nome == other.nome class operatore: funzioni = { '*' : lambda x, y: x*y, '+' : lambda x, y: x+y, '/' : lambda x, y: x/y, '-' : lambda x, y: x-y, '^' : lambda x, y: x**y, } def __init__(self, op, sx, dx): self.op = op self.sx = sx self.dx = dx def __str__(self): return f"({self.sx.__str__()}{self.op}{self.dx.__str__()})" def calcola(self, valori=None): if valori == None: valori = {} sx = self.sx.calcola(valori) dx = self.dx.calcola(valori) return self.funzioni[self.op](sx, dx) def semplifica(self): self.sx = self.sx.semplifica() self.dx = self.dx.semplifica() if self.op == '*' and self.sx == numero(1): return self.dx if self.op == '*' and self.dx == numero(1): return self.sx if self.op == '*' and self.sx == numero(0): return numero(0) if self.op == '*' and self.dx == numero(0): return numero(0) if self.op == '-' and self.sx == self.dx: return numero(0) if self.op == '-' and self.dx == numero(0): return self.sx if self.op == '/' and self.sx == self.dx: return numero(1) if self.op == '/' and self.dx == numero(1): return self.sx if self.op == '+' and self.sx == numero(0): return self.dx if self.op == '+' and self.dx == numero(0): return self.sx if self.op == '^' and self.sx == numero(0): return numero(0) if self.op == '^' and self.sx == numero(1): return numero(1) if self.op == '^' and self.dx == numero(0): return numero(1) if self.op == '^' and self.dx == numero(1): return self.sx # e così via per tutte le semplificazioni che vengono in mente # x+x = 2*x # x*x = x^2 # x*(x^n) = x^(n+1) # x+(x^n) = x*(n+1) # (x*y)+(x*z) = x*(y+z) # (x+y)*(x-y) = (x-y)^2 # (x/y)+(z/y) = (x+z)/y # ... return self def __eq__(self, other): return type(other) == type(self) \ and self.op == other.op \ and self.sx == other.sx \ and self.dx == other.dx \ def parse(espressione, inizio=0): carattere = espressione[inizio] if carattere == '(': # Espressione1 e1, fine = parse(espressione, inizio+1) # operatore op = espressione[fine] # espressione2 e2, fine2 = parse(espressione, fine+1) # parentesi chiusa if espressione[fine2] == ')': return operatore(op, e1, e2), fine2+1 else: raise Exception(") expected" + espressione[:fine2]) elif carattere.isdigit() : # numero # tutte le cifre n = ord(carattere) - ord('0') i = inizio + 1 # raccolgo i caratteri numerici while i