#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Fri Dec 6 11:10:46 2019 @author: andrea """ from rtrace import trace # espressioni algebriche # E = numero # E = variabile # E = (E+E) # E = (E-E) # E = (E*E) # E = (E/E) # E = (E^E) class Numero: def __init__(self, valore): self.valore = valore def __str__(self): return str(self.valore) def calcola(self,variabili): return self.valore def semplifica(self): return self def __eq__(self, other): return type(self)==type(other) and self.valore == other.valore class Variabile: def __init__(self, nome): self.nome = nome def __str__(self): return self.nome def calcola(self,variabili): return variabili[self.nome] def semplifica(self): return self def __eq__(self, other): return type(self)==type(other) and self.nome == other.nome class Operatore: def __init__(self, op, sx, dx): if op not in '+*/-^': raise Exception(f"L'operando {self.op} è sconosciuto.") self.op = op self.sx = sx self.dx = dx def __str__(self): return f"({str(self.sx)}{self.op}{str(self.dx)})" def calcola(self,variabili): sx = self.sx.calcola(variabili) dx = self.dx.calcola(variabili) if self.op == '*': return sx*dx if self.op == '+': return sx+dx if self.op == '-': return sx-dx if self.op == '/': return sx/dx if self.op == '^': return sx**dx def __eq__(self, other): return (type(self)==type(other) and self.op == other.op and self.sx == other.sx and self.dx == other.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.sx == Numero(0): return Numero(0) if self.op == '*' and self.dx == Numero(1): return self.sx if self.op == '*' and self.dx == Numero(0): return Numero(0) 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 == self.dx: return Operatore('*', Numero(2),self.sx) return self cinque = Numero(5) sei = Numero(6) otto = Numero(8) ics = Variabile('x') zero = Numero(0) # (5*(0+x)) espressione = Operatore('*', cinque, Operatore('+', zero, ics)) def parse(stringa, posizione=0): carattere = stringa[posizione] # riconosco le variabili if carattere.isalpha(): return Variabile(carattere), posizione+1 # riconosco i numeri (interi non negativi) if carattere.isdigit(): valore = 0 while posizione < len(stringa) and carattere.isdigit(): cifra = int(carattere) valore *= 10 valore += cifra posizione += 1 carattere = stringa[posizione] return Numero(valore), posizione # altrimenti riconosco una espressione (E op E) if carattere == '(': sx,nuova_posizione = parse(stringa, posizione+1) op = stringa[nuova_posizione] dx, nuova_posizione2 = parse(stringa, nuova_posizione+1) if stringa[nuova_posizione2] != ')': raise Exception(f"mi aspetto una ) al carattere {nuova_posizione2}") return Operatore(op, sx, dx), nuova_posizione2+1 # altrimenti c'è un errore raise Exception(f"carattere sconosciuto in posizione {posizione}")