From ec6d89b84ba9782197a3fb7aec32219c38795bfb Mon Sep 17 00:00:00 2001 From: "bollet.c" <> Date: Thu, 22 Feb 2024 22:54:36 +0100 Subject: [PATCH] =?UTF-8?q?gestion=20de=20certaines=20erreurs(overflow..);?= =?UTF-8?q?am=C3=A9lioration=20interface(boutons);ajout=20fx(factorielle,a?= =?UTF-8?q?sin,acos,atan);ajout=20cste(pi=20et=20e);=20r=C3=A9ecriture=20d?= =?UTF-8?q?e=20cleanFx;correction=20mineure=20sur=20parenth=C3=A9sage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- expression.py | 98 +++++++++++-------------- infixe.py | 103 ++++++++++++++++---------- test_interface.py | 180 +++++++++++++++++++++++++++------------------- 3 files changed, 212 insertions(+), 169 deletions(-) diff --git a/expression.py b/expression.py index ff42224..8db045e 100644 --- a/expression.py +++ b/expression.py @@ -16,15 +16,22 @@ class Expression: 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 == "sqrt": return sqrt(self.gauche.evalue()) + if self.racine == "factorielle": return factorial(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) @@ -32,25 +39,26 @@ class Expression: def __str__(self): """affiche l'expression""" - priorite = {"opp":1, - "!":1, - "^":2, - "sin":3, - "cos":3, - "tan":3, - "sqrt":3, - "*":4, - "/":4, - "+":5, - "-":5 - } + 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" - } + "^":"droit", + "*":"gauche", + "/":"gauche", + "+":"gauche", + "-":"gauche"} pas_commutatif = ["^","/","-"] if self.racine in ["opp","!", "^", "*", "/", "+", "-"]: gauche = str(self.gauche) @@ -73,9 +81,9 @@ class Expression: 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] == "-": + 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] == "-": + if self.droit.racine == "opp" or (self.droit.racine != "-" and self.droit.racine[0] == "-"): droit = parentheses(droit) if priorite_racine < priorite_gauche: @@ -90,7 +98,7 @@ class Expression: return gauche + self.racine + droit - if self.racine in ["sin","cos","tan","sqrt"]: + if self.racine in ["asin","acos","atan","sin","cos","tan","sqrt","factorielle"]: return self.racine + "(" + str(self.gauche) + ")" return str(self.racine) @@ -99,6 +107,7 @@ def parentheses(txt): """ajoute des parentheses à txt""" return "(" + txt + ")" def npi2tree_original(liste_en_npi): + #obsolète (il faudrait mettre à jour la liste de fonctions) """conversion d'une liste en NPI en un arbre""" pile_expr = Pile() for element in liste_en_npi: @@ -116,7 +125,7 @@ def npi2tree_original(liste_en_npi): def npi2tree(liste, etat_affichage): """conversion d'une liste en NPI ou NP en un arbre""" pile_expr = Pile() - for element in liste: + for i,element in enumerate(liste): if element in ["+","-", "*","/", "^"]: fils_gauche = pile_expr.depiler() fils_droit = pile_expr.depiler() @@ -126,42 +135,15 @@ def npi2tree(liste, etat_affichage): pile_expr.empiler(Expression(element, fils_gauche, fils_droit)) - elif element in ["sin","cos","tan", "opp", "sqrt"]: + elif element in ["asin","acos","atan","sin","cos","tan", "opp", "sqrt","factorielle"]: pile_expr.empiler(Expression(element, pile_expr.depiler(), None)) - elif estUnNombre(element): + elif estUnNombre(element) or element in ["pi","e"]: pile_expr.empiler(Expression(element, None, None)) else: - #à compléter - raise ValueError("Fonction inconnue","n'est pas une fonction connue, ou il manque des espaces.", element) - print("Taille de pile_expr à la fin de la boucle : " , pile_expr.taille()) + 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. L'étoile ( « ★ » ) indique la position de l'opérateur manquant dans l'expression.", pile_expr)) + raise SyntaxError("Il manque un opérateur.") if pile_expr.taille() > 2: - raise SyntaxError(("Il manque " + str(pile_expr.taille() - 1) + " opérateurs. L'étoile ( « ★ » ) indique la position des opérateurs manquants dans l'expression.", pile_expr)) - return pile_expr.sommet() - -def fonctionsAvecArgument(lst_expr): - #la clarifier un peu, peut-être ? - """vérifie que les fonctions aient des arguments, mêmes incorrects - ex : `sin ) 2 +` est OK.Plus tard l'expression sera vérifiée - par d'autres fonctions qui verront les erreurs (parenthèses..) - Le but est d'éviter que les expression comme `2 sin` soit vues justes - par shunting-yard""" - fonctions = ["sin","cos","tan", "sqrt"] - lst_expr_stripped = list(filter(lambda x: x != "+" and x != "-", lst_expr)) - if lst_expr_stripped[-1] in fonctions: return False - #si à droite, pas un nombre ou une parenthèse fermante - fx_a_gauche = False - for terme in lst_expr_stripped: - if fx_a_gauche == True: - if terme in [")", "*", "/"]: return False - - if terme in fonctions: - fx_a_gauche = True - - #return not in fonctions - -def inserer_dans_liste(element, lst, indice): - """insère l'item `element` dans la liste `lst` à l'indice `indice`""" - return - \ No newline at end of file + raise SyntaxError("Il manque " + str(pile_expr.taille() - 1) + " opérateurs.") + return pile_expr.sommet() \ No newline at end of file diff --git a/infixe.py b/infixe.py index 76abbcc..fdece50 100644 --- a/infixe.py +++ b/infixe.py @@ -7,30 +7,36 @@ def infixe2npi(liste_en_infixe): pile_op = Pile() sortie = [] - fonctions = ["sin","cos","tan","sqrt"] + fonctions = ["asin","acos","atan","sin","cos","tan","sqrt","factorielle"] operateurs = ["+", "-", "*", "/", "^","opp"] priorite = {"sin":1, + "cos":1, + "tan":1, + "asin":1, + "acos":1, + "atan":1, + "sqrt":1, + "factorielle":1, "opp":1, "^":1, "*":2, "/":2, "+":3, - "-":3 - } + "-":3} associativite = {"opp": "droit", "^":"droit", "*":"gauche", "/":"gauche", "+":"gauche", - "-":"gauche" - } + "-":"gauche"} + last_token = None print(40*"=") for index_token, token in enumerate(liste_en_infixe): print(20*"-") print("token", token) - #nombre - if estUnNombre(token): + + if estUnNombre(token) or token in ["pi","e"]: if sortie != []: if pile_op.est_vide(): #mul. implicite @@ -39,20 +45,23 @@ def infixe2npi(liste_en_infixe): print("c'est un nombre et il est dans le cas pile_op.est_vide()") else: print(last_token, pile_op.sommet()) - if last_token == pile_op.sommet() or pile_op.sommet() == "opp": + if last_token == pile_op.sommet(): #opération binaire normale ou fonction (avec avant elle ultimement une opération binaire) sortie.append(token) print("c'est un nombre et il est dans le cas last_token == pile_op.sommet()") if last_token == sortie[-1]: print("c'est un nombre et il est dans le cas last_token == sortie[-1]") #on a affaire à une expression (chiffre (... 2), opération (... +), fonction (... fx)) qui est in fine un nombre - cleanFx(pile_op, sortie) + cleanFx(pile_op, sortie, token) + sortie.append(token) + sortie.append("*") + if last_token == ")": sortie.append(token) sortie.append("*") else: sortie.append(token) print("c'est un nombre et il est dans le cas sortie == []") - #fonction + elif token in fonctions: if sortie != []: if pile_op.est_vide(): @@ -60,27 +69,34 @@ def infixe2npi(liste_en_infixe): pile_op.empiler("*") pile_op.empiler(token) else: - if last_token == pile_op.sommet() or pile_op.sommet() == "opp": + if last_token == pile_op.sommet(): #composition de fonctions, ou fonction qui suit un opérateur pile_op.empiler(token) #normal if last_token == sortie[-1]: #le dernier element est l'argument de la fonction (ou #des fonctions, composées) sur la pile - s'il y a des fonctions - cleanFx(pile_op, sortie) + cleanFx(pile_op, sortie, token) + pile_op.empiler("*") + pile_op.empiler(token) + if last_token == ")": pile_op.empiler("*") pile_op.empiler(token) else: pile_op.empiler(token) - - #operateur + elif token in operateurs: if not (estUnNombre(last_token) or last_token == ")"): #opérations unaires if token == "-" : #opposé pile_op.empiler("opp") + print("'-' qui devient 'opp'") elif token == "+": #identité + if last_token in fonctions: + print("'+' identité juste après une fonction") + #raise ValueError("Opérateur mal utilisé","est ici ambigu ; addition ou identité ?",index_token) + print("le plus est identité") pass else: raise ValueError("Opérateur mal utilisé","n'a ici qu'un seul opérande, quand il devrait en avoir deux.",index_token) @@ -91,44 +107,44 @@ def infixe2npi(liste_en_infixe): except IndexError: pass pile_op.empiler(token) - # "(" + elif token == "(": if sortie != []: if pile_op.est_vide(): #mul. implicite pile_op.empiler("*") pile_op.empiler(token) + print("parenthèse insérée dans la pile AVEC une multiplication -- pile_op.est_vide()") else: - if last_token == pile_op.sommet() or pile_op.sommet() == "opp": + if last_token == pile_op.sommet(): #parenthèse qui suit une fonction ou parenthèse normale pile_op.empiler(token) #normal + print("parenthèse insérée dans la pile SANS une multiplication -- last_token == pile_op.sommet()") if last_token == sortie[-1]: #le dernier element est l'argument de la fonction (ou #des fonctions, composées) sur la pile - s'il y a des fonctions - cleanFx(pile_op, sortie) + cleanFx(pile_op, sortie, token) pile_op.empiler("*") pile_op.empiler(token) + print("parenthèse insérée dans la pile AVEC une multiplication -- last_token == sortie[-1]") else: pile_op.empiler(token) - # ")" + print("parenthèse insérée dans la pile SANS une multiplication -- il n'y a rien en sortie") + elif token == ")": - try: - while pile_op.sommet() != "(": - if pile_op.est_vide(): - raise SyntaxError(("Mauvais () detail", index_token)) - else: - sortie.append(pile_op.depiler()) - except IndexError: - raise SyntaxError(("Mauvais parenthésage.", index_token)) - if pile_op.sommet() == "(": - pile_op.depiler() - if not pile_op.est_vide(): - if pile_op.sommet() in fonctions: - sortie.append(pile_op.depiler()) + cleanFx(pile_op, sortie, ")") + else: raise ValueError("Fonction inconnue","n'est pas une fonction connue, ou il manque des espaces.", index_token) - last_token = token - + + if token == "-" and pile_op.sommet() == "opp": + last_token = "opp" + elif token == "+" and pile_op.sommet() != "+": + pass + else: + last_token = token + print("état de la sortie après le token : ", sortie) + while not pile_op.est_vide(): if pile_op.sommet() != "(": sortie.append(pile_op.depiler()) @@ -137,12 +153,23 @@ def infixe2npi(liste_en_infixe): print("infixe2npi : ",sortie) return sortie -def cleanFx(pile, sortie): - #doc bof - """sort toutes les fonctions et opérateurs de la pile""" - while not pile.est_vide(): +def cleanFx(pile, sortie, token): + """dépile tous les tokens dans la sortie + - pas d'erreur de parenthésage si token != ")" + car on veut garder la multipication implicite""" + while not pile.est_vide() and pile.sommet() != "(": sortie.append(pile.depiler()) - return sortie + if not pile.est_vide() and pile.sommet() == "(": + pile.depiler() + else: + if token == ")": + raise SyntaxError("Mauvais parenthésage. Il manque une parenthèse gauche.") + + if not pile.est_vide(): + if pile.sommet() in ["asin","acos","atan","sin","cos","tan","sqrt", "opp","factorielle"]: + sortie.append(pile.depiler()) + # ↓ sert à quelque chose ?? + #return sortie def estUnNombre(txt): """indique si la chaine de caractères txt est un nombre (entier (négatif) ou flottant)""" diff --git a/test_interface.py b/test_interface.py index 0d29d4e..9e3a7ad 100644 --- a/test_interface.py +++ b/test_interface.py @@ -1,11 +1,10 @@ import tkinter as tk -from tkinter import messagebox, font +from tkinter import messagebox from Pile import Pile_chaine as Pile from math import * from expression import * from infixe import infixe2npi -from popup import MsgBox class ValeurSaisie: """classe d'une valeur saise par l'utilisateur""" @@ -24,7 +23,7 @@ class Interface(tk.Frame): def __init__(self, master): self.master = master tk.Frame.__init__(self, master) - + self.etat = tk.Label(self.master, text="notation postfixée (polonaise inversée) -- mode interactif", fg="gray42") self.etat.pack() self.etat_affichage = "post-int" @@ -40,9 +39,9 @@ class Interface(tk.Frame): self.affichage_expression.pack() frame_saisie = tk.Frame(self.master, padx=5, pady=5) - frame_saisie.pack() + frame_saisie.pack(fill="both") self.saisie_expression = tk.Entry(frame_saisie) - self.saisie_expression.pack(side="left") + self.saisie_expression.pack(fill="both",expand=True,side="left") self.saisie_expression.bind("", lambda e : self.entrer()) self.saisie_expression.bind("", lambda e : self.entrer()) @@ -50,29 +49,39 @@ class Interface(tk.Frame): btn_entrer.pack() commandes = tk.LabelFrame(self.master, text="commandes", padx=5, pady=5) - commandes.pack(fill="both") + commandes.pack(fill="both", padx=5) + self.frame_pile = tk.LabelFrame(commandes, text="pile", padx=5, pady=5) + self.frame_pile.pack(fill="both") + tk.Button(self.frame_pile, text='tout supprimer', command=self.effacer_tt).pack(side="left") + tk.Button(self.frame_pile, text='supprimer sommet', command=self.effacer_dernier).pack(side="left") + tk.Button(self.frame_pile, text='dupliquer sommet', command=self.dupliquer).pack(side="left") - effacer = tk.LabelFrame(commandes, text="effacer", padx=5, pady=5) - effacer.pack(fill="both") - btn_effacer_tt = tk.Button(effacer, text='tout effacer', command=self.effacer_tt) - btn_effacer_tt.pack(side="left") - btn_effacer_dernier = tk.Button(effacer, text='effacer la dernière valeur', command=self.effacer_dernier) - btn_effacer_dernier.pack(side="left") fonctions = tk.LabelFrame(commandes, text="fonctions", padx=5, pady=5) fonctions.pack(fill="both") - btn_sinus = tk.Button(fonctions, text='sin', command=lambda : self.evaluer_stack("sin",1)) - btn_sinus.pack(side="left") - btn_sinus = tk.Button(fonctions, text='cos', command=lambda : self.evaluer_stack("cos",1)) - btn_sinus.pack(side="left") - btn_sinus = tk.Button(fonctions, text='tan', command=lambda : self.evaluer_stack("tan",1)) - btn_sinus.pack(side="left") - btn_pow = tk.Button(fonctions, text='^', command=lambda : self.evaluer_stack("^",2)) - btn_pow.pack(side="right") + + for i, text in enumerate(("+", "-", "/","*","^")): + tk.Button(fonctions, text=text, command=lambda x=text: self.ecrire_fx(x)).grid(row=0, column=i, sticky="ew") + for i, text in enumerate(("sin","cos","tan","factorielle")): + tk.Button(fonctions, text=text, command=lambda x=text: self.ecrire_fx(x)).grid(row=1, column=i, sticky="ew") + for i, text in enumerate(("asin","acos","atan")): + tk.Button(fonctions, text=text, command=lambda x=text: self.ecrire_fx(x)).grid(row=2, column=i, sticky="ew") + + + def ecrire_fx(self, nom): + self.saisie_expression.insert(tk.END, " "+nom+" ") + if self.etat_affichage == "post-int": + self.entrer() + + def dupliquer(self): + if not self.stack.est_vide(): + self.stack.empiler(ValeurSaisie(self.stack.sommet().valeur, self.frame_stack)) + def create_menu_bar(self): + """crée la barre de menu de la calculatrice""" menu_bar = tk.Menu(self) menu_file = tk.Menu(menu_bar, tearoff=0) @@ -98,7 +107,9 @@ class Interface(tk.Frame): self.master.config(menu=menu_bar) def change_affichage(self, affichage): - """change le mode d'affichage et efface les calculs en cours""" + """change le mode d'affichage, + désactive les opérations de pile si pas dans le mode interactif + et efface les calculs en cours""" self.etat_affichage = affichage etat_text = {"pre":"notation préfixée (polonaise)", @@ -108,6 +119,13 @@ class Interface(tk.Frame): } self.etat.config(text=etat_text[affichage]) + if self.etat_affichage != "post-int": + for child in self.frame_pile.winfo_children(): + child.configure(state='disable') + else: + for child in self.frame_pile.winfo_children(): + child.configure(state='normal') + self.affichage_expression.config(text="") self.effacer_tt() self.saisie_expression.delete(0 ,'end') @@ -121,31 +139,39 @@ class Interface(tk.Frame): def entrer(self): """si dans mode interactif alors ajoute nv terme si dans autre mode alors evalue l'expression""" - if self.etat_affichage == "post-int": - self.entrer_terme_dans_stack() - if len(self.saisie_expression.get()) > 0: - self.evaluer_expr() + try: + if len(self.saisie_expression.get()) > 0: + if self.etat_affichage == "post-int": + try: self.entrer_terme_dans_stack(self.saisie_expression.get().replace(" ","")) + except ValueError: + messagebox.showerror("Saisie invalide", "Le résultat n'est pas un nombre réel.") + else: + self.evaluer_expr() + except OverflowError: + messagebox.showerror("OverflowError", "Le résultat est trop élevé.") + - def entrer_terme_dans_stack(self): + def entrer_terme_dans_stack(self, terme): """si nombre : ajoute une nouvelle valeur dans le stack ajoute un label avec cette valeur si fonction : on l'évalue""" - valeur_a_ajouter = self.saisie_expression.get().replace(" ", "") - if valeur_a_ajouter != "": - if "." in valeur_a_ajouter: - valeur_a_ajouter = float(valeur_a_ajouter) - self.stack.empiler(ValeurSaisie(valeur_a_ajouter, self.frame_stack)) - elif valeur_a_ajouter in ["sin","cos","tan","sqrt","!","opp"]: self.evaluer_stack(valeur_a_ajouter,1) - elif valeur_a_ajouter in ["+","-","/","*","^"]: self.evaluer_stack(valeur_a_ajouter,2) - elif valeur_a_ajouter in ["moy3"]: self.evaluer_stack(valeur_a_ajouter,3) - elif valeur_a_ajouter in ["somme","produit"]: self.evaluer_stack(valeur_a_ajouter,-1) - elif valeur_a_ajouter == "pi": self.stack.empiler(ValeurSaisie(pi, self.frame_stack)) - else: - try: - valeur_a_ajouter = int(valeur_a_ajouter) - self.stack.empiler(ValeurSaisie(valeur_a_ajouter, self.frame_stack)) - except ValueError: - messagebox.showerror("Saisie invalide", "Vous n'avez pas entré un nombre, ou la fonction est inconnue") + if "." in terme: + terme = float(terme) + self.stack.empiler(ValeurSaisie(terme, self.frame_stack)) + elif terme in ["asin","acos","atan","sin","cos","tan","sqrt","!","factorielle","opp"]: self.evaluer_stack(terme,1) + elif terme in ["+","-","/","*","^"]: self.evaluer_stack(terme,2) + elif terme in ["moy3"]: self.evaluer_stack(terme,3) + elif terme in ["somme","produit"]: self.evaluer_stack(terme,-1) + elif terme == "pi": self.stack.empiler(ValeurSaisie(pi, self.frame_stack)) + elif terme == "e": self.stack.empiler(ValeurSaisie(exp(1), self.frame_stack)) + + else: + try: + terme = int(terme) + self.stack.empiler(ValeurSaisie(terme, self.frame_stack)) + except ValueError: + messagebox.showerror("Saisie invalide", "Vous n'avez pas entré un nombre, ou la fonction est inconnue") + return self.saisie_expression.delete(0 ,'end') @@ -182,8 +208,11 @@ class Interface(tk.Frame): if op == "sin": res = sin(val) if op == "cos": res = cos(val) if op == "tan": res = tan(val) + if op == "asin": res = asin(val) + if op == "acos": res = acos(val) + if op == "atan": res = atan(val) if op == "sqrt": res = sqrt(val) - if op == "!": res = factorial(val) + if op == "!" or op == "factorielle": res = factorial(val) if op == "opp": res = - val elif nb_arg == 2: @@ -212,26 +241,29 @@ class Interface(tk.Frame): if self.etat_affichage == "pre": lst_expr.reverse() if self.etat_affichage == "inf": + if "opp" in lst_expr: + messagebox.showerror("Erreur", "Vous ne pouvez pas utiliser la fonction 'opp' ici ; veuillez utiliser le signe '-' à la place.\n(Vous pouvez par contre utiliser 'opp' quand vous êtes en notation préfixée ou infixée.)") + return try: lst_expr = infixe2npi(lst_expr) - except SyntaxError as s: - explication, i_char = s.args[0] - if explication == "manque op": - messagebox.showerror("Erreur de syntaxe", - "Il manque un opérateur. L'étoile ( « ★ » ) indique la position de l'opérateur manquant dans l'expression." - + "\nL'expression : \n\n(" - + " ".join(lst_expr[:i_char]) + ") ★ (" + " ".join(lst_expr[i_char:]) + ")") - elif explication == "Mauvais () detail": - messagebox.showerror("Erreur de syntaxe", explication - + "\nLa parenthèse fautive entre 【 crochet 】: \n\n" - + " ".join(lst_expr[:i_char]) - + " 【 " + str(lst_expr[i_char]) + " 】 " + " ".join(lst_expr[i_char+1:])) - else: - messagebox.showerror("Erreur de syntaxe", explication) - return + #except SyntaxError as s: + # explication, i_char = s.args[0] + # if explication == "manque op": + # messagebox.showerror("Erreur de syntaxe", + # "Il manque un opérateur. L'étoile ( « ★ » ) indique la position de l'opérateur manquant dans l'expression." + # + "\nL'expression : \n\n(" + # + " ".join(lst_expr[:i_char]) + ") ★ (" + " ".join(lst_expr[i_char:]) + ")") + # elif explication == "Mauvais () detail": + # messagebox.showerror("Erreur de syntaxe", explication + # + "\nLa parenthèse fautive entre 【 crochet 】: \n\n" + # + " ".join(lst_expr[:i_char]) + # + " 【 " + str(lst_expr[i_char]) + " 】 " + " ".join(lst_expr[i_char+1:])) + # else: + # messagebox.showerror("Erreur de syntaxe", explication) + # return except ValueError as v: message, explication, i_char = v.args - + messagebox.showerror(message,"Le terme « " + lst_expr[i_char] + " » " + explication + "\n\n" + "Dans l'expression, entre 【 crochet 】 :\n" + " ".join(lst_expr[:i_char]) @@ -243,20 +275,22 @@ class Interface(tk.Frame): self.affichage_expression.config(text = str(arbre_expr) + "=" + str(arbre_expr.evalue())) except IndexError: messagebox.showerror("Erreur","Erreur de syntaxe ici") - except ValueError: - #faire un truc plus beau - messagebox.showerror("Saisie invalide", "Vous n'avez pas entré un nombre, ou la fonction est inconnue.") + except ValueError as v: + explication = v.args[0] + if v.args[0] == "math domain error": + messagebox.showerror("Saisie invalide", "Le résultat n'est pas un nombre réel.") + else: + message, explication, i_char = v.args + if self.etat_affichage == "pre": + lst_expr.reverse() + i_char = len(lst_expr) - i_char - 1 + messagebox.showerror(message,"Le terme « " + lst_expr[i_char] + " » " + + explication + "\n\n" + + "Dans l'expression, entre 【 crochet 】 :\n" + " ".join(lst_expr[:i_char]) + + " 【 " + str(lst_expr[i_char]) + " 】 " + " ".join(lst_expr[i_char+1:])) except SyntaxError as s: - explication, pile_expr = s.args[0] - print("pile_expr depuis evaluer_expr",pile_expr) - lst_pile_expr = [] - while not pile_expr.est_vide(): - lst_pile_expr.append(str(pile_expr.depiler())) - lst_pile_expr.reverse() - print(lst_pile_expr) - messagebox.showerror("Erreur de syntaxe", explication - +"\nL'expression : \n\n(" - + ") ★ (".join(lst_pile_expr) + ")") + explication = s.args[0] + messagebox.showerror("Erreur de syntaxe", explication) def effacer_tt(self): """supprime tout le contenu de la pile (et les labels associés)""" @@ -273,6 +307,6 @@ class Interface(tk.Frame): if __name__ == "__main__": root = tk.Tk() root.title("Calculatrice") - root.geometry("350x500") + root.geometry("380x500") hello_frame = Interface(root) hello_frame.mainloop() \ No newline at end of file