Browse Source

gestion de certaines erreurs(overflow..);amélioration interface(boutons);ajout fx(factorielle,asin,acos,atan);ajout cste(pi et e); réecriture de cleanFx;correction mineure sur parenthésage

master
bollet.c 9 months ago
parent
commit
ec6d89b84b
  1. 78
      expression.py
  2. 97
      infixe.py
  3. 164
      test_interface.py

78
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 == "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,
priorite = {"sin":1,
"cos":1,
"tan":1,
"sqrt":1,
"asin":1,
"acos":1,
"atan":1,
"factorielle":1,
"opp":1,
"^":2,
"sin":3,
"cos":3,
"tan":3,
"sqrt":3,
"*":4,
"/":4,
"+":5,
"-":5
}
"-":5}
associativite = {"opp":"droit",
"^":"droit",
"*":"gauche",
"/":"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))
raise SyntaxError("Il manque " + str(pile_expr.taille() - 1) + " opérateurs.")
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

97
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,43 +107,43 @@ 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)
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() != "(":
@ -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)"""

164
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"""
@ -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("<Return>", lambda e : self.entrer())
self.saisie_expression.bind("<KP_Enter>", 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()
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))
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:
valeur_a_ajouter = int(valeur_a_ajouter)
self.stack.empiler(ValeurSaisie(valeur_a_ajouter, self.frame_stack))
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,23 +241,26 @@ 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
@ -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()
Loading…
Cancel
Save