from math import * from Pile import Pile_chaine as Pile from infixe import estUnNombre class Expression: def __init__(self, racine, gauche, droit): """initialisation d'un objet 'Expression'""" self.racine = racine self.gauche = gauche self.droit = droit def evalue(self): """renvoie la valeur de l'expression s'il n'y a qu'un seul argument alors on prend le fils gauche""" #fonctions if self.racine == "sin": return sin(self.gauche.evalue()) if self.racine == "cos": return cos(self.gauche.evalue()) if self.racine == "tan": return tan(self.gauche.evalue()) if self.racine == "asin": return asin(self.gauche.evalue()) if self.racine == "acos": return acos(self.gauche.evalue()) if self.racine == "atan": return atan(self.gauche.evalue()) if self.racine == "opp": return - self.gauche.evalue() if self.racine == "sqrt": return sqrt(self.gauche.evalue()) if self.racine == "factorielle": return gamma(self.gauche.evalue()) #operateurs if self.racine == "+": return self.gauche.evalue() + self.droit.evalue() if self.racine == "-": return self.gauche.evalue() - self.droit.evalue() if self.racine == "*": return self.gauche.evalue() * self.droit.evalue() if self.racine == "/": return self.gauche.evalue() / self.droit.evalue() if self.racine == "^": return self.gauche.evalue() ** self.droit.evalue() #constantes if self.racine == "pi": return pi if self.racine == "e": return exp(1) if "." in self.racine: return float(self.racine) return int(self.racine) def __str__(self): """affiche l'expression""" priorite = {"sin":1, "cos":1, "tan":1, "sqrt":1, "asin":1, "acos":1, "atan":1, "factorielle":1, "opp":1, "^":2, "*":4, "/":4, "+":5, "-":5} associativite = {"opp":"droit", "^":"droit", "*":"gauche", "/":"gauche", "+":"gauche", "-":"gauche"} pas_commutatif = {"^","/","-"} if self.racine in {"!", "^", "*", "/", "+", "-"}: gauche = str(self.gauche) droit = str(self.droit) priorite_racine = priorite[self.racine] priorite_gauche = priorite.get(self.gauche.racine, -1) priorite_droit = priorite.get(self.droit.racine, -1) if (self.gauche.racine == "opp" or (self.gauche.racine != "-" and self.gauche.racine[0] == "-")) and self.racine not in {"+","-"}: gauche = parentheses(gauche) if self.droit.racine == "opp" or (self.droit.racine != "-" and self.droit.racine[0] == "-"): droit = parentheses(droit) if priorite_racine < priorite_gauche: gauche = parentheses(gauche) if priorite_racine < priorite_droit: droit = parentheses(droit) if self.racine in pas_commutatif: if priorite_racine == priorite_droit and associativite[self.racine] == "gauche": droit = parentheses(droit) if priorite_racine == priorite_gauche and associativite[self.racine] == "droit": gauche = parentheses(gauche) return gauche + self.racine + droit if self.racine == "opp": gauche = str(self.gauche) priorite_racine = priorite[self.racine] priorite_gauche = priorite.get(self.gauche.racine, -1) if priorite_racine < priorite_gauche or self.gauche.racine == "opp": gauche = parentheses(gauche) return "-" + gauche if self.racine in {"sin","cos","tan","sqrt","factorielle","asin","acos","atan"}: return self.racine + "(" + str(self.gauche) + ")" return str(self.racine) def parentheses(txt): """ajoute des parentheses à txt""" return "(" + txt + ")" def toTree(liste, etat_affichage): """conversion d'une liste en NPI ou NP (pas en infixe) en un arbre""" pile_expr = Pile() for i,element in enumerate(liste): if element in {"+","-", "*","/", "^"}: fils_gauche = pile_expr.depiler() fils_droit = pile_expr.depiler() if etat_affichage == "post-expr" or etat_affichage == "inf": fils_gauche, fils_droit = fils_droit, fils_gauche pile_expr.empiler(Expression(element, fils_gauche, fils_droit)) elif element in {"opp","sin","cos","tan","sqrt","factorielle","asin","acos","atan"}: pile_expr.empiler(Expression(element, pile_expr.depiler(), None)) elif estUnNombre(element) or element in ["pi","e"]: if "." in element: element = str(float(element)) else: element = str(int(element)) pile_expr.empiler(Expression(element, None, None)) else: raise ValueError("Fonction inconnue","n'est pas une fonction connue, ou il manque des espaces.", i) if pile_expr.taille() == 2: raise SyntaxError("Il manque un opérateur.") if pile_expr.taille() > 2: raise SyntaxError("Il manque " + str(pile_expr.taille() - 1) + " opérateurs.") return pile_expr.sommet()