|
|
@ -1,14 +1,15 @@ |
|
|
|
from math import * |
|
|
|
import tkinter as tk |
|
|
|
from tkinter import messagebox |
|
|
|
from Pile import Pile_chaine as Pile |
|
|
|
from math import * |
|
|
|
from expression import * |
|
|
|
from infixe import infixe2npi |
|
|
|
from expression import Expression, toTree |
|
|
|
from infixe import infixe2npi, estUnNombre |
|
|
|
|
|
|
|
|
|
|
|
class ValeurSaisie: |
|
|
|
"""classe d'une valeur saise par l'utilisateur""" |
|
|
|
def __init__(self, valeur, master): |
|
|
|
"""initialisation de la valeur""" |
|
|
|
self.valeur = valeur |
|
|
|
|
|
|
|
self.label_valeur = tk.Label(master, text=valeur) |
|
|
@ -21,6 +22,7 @@ class ValeurSaisie: |
|
|
|
class Interface(tk.Frame): |
|
|
|
"""interface de la calculatrice""" |
|
|
|
def __init__(self, master): |
|
|
|
"""initialisation de l'interface""" |
|
|
|
self.master = master |
|
|
|
tk.Frame.__init__(self, master) |
|
|
|
|
|
|
@ -71,11 +73,13 @@ class Interface(tk.Frame): |
|
|
|
|
|
|
|
|
|
|
|
def ecrire_fx(self, nom): |
|
|
|
"""insère le nom de la fonction dans la barre de saisie""" |
|
|
|
self.saisie_expression.insert(tk.END, " "+nom+" ") |
|
|
|
if self.etat_affichage == "post-int": |
|
|
|
self.entrer() |
|
|
|
|
|
|
|
def dupliquer(self): |
|
|
|
"""duplique la dernière valeur entrée dans le stack""" |
|
|
|
if not self.stack.est_vide(): |
|
|
|
self.stack.empiler(ValeurSaisie(self.stack.sommet().valeur, self.frame_stack)) |
|
|
|
|
|
|
@ -104,27 +108,26 @@ class Interface(tk.Frame): |
|
|
|
menu_help.add_command(label="À propos", command=self.about) |
|
|
|
menu_bar.add_cascade(label="Aide", menu=menu_help) |
|
|
|
|
|
|
|
self.master.config(menu=menu_bar) |
|
|
|
self.master['menu']=menu_bar |
|
|
|
|
|
|
|
def change_affichage(self, affichage): |
|
|
|
"""change le mode d'affichage, |
|
|
|
désactive les opérations de pile si pas dans le mode interactif |
|
|
|
désactive les opérations de pile si l'on est pas dans le mode interactif |
|
|
|
et efface les calculs en cours""" |
|
|
|
self.etat_affichage = affichage |
|
|
|
|
|
|
|
etat_text = {"pre":"notation préfixée (polonaise)", |
|
|
|
"inf":"notation infixée", |
|
|
|
"post-int":"notation postfixée (polonaise inversée) -- mode interactif", |
|
|
|
"post-expr": "notation postfixée (polonaise inversée) -- mode expression" |
|
|
|
} |
|
|
|
"post-expr": "notation postfixée (polonaise inversée) -- mode expression"} |
|
|
|
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') |
|
|
|
child['state']='disable' |
|
|
|
else: |
|
|
|
for child in self.frame_pile.winfo_children(): |
|
|
|
child.configure(state='normal') |
|
|
|
child['state']='normal' |
|
|
|
|
|
|
|
self.affichage_expression.config(text="") |
|
|
|
self.effacer_tt() |
|
|
@ -132,32 +135,37 @@ class Interface(tk.Frame): |
|
|
|
|
|
|
|
def aide(self): |
|
|
|
"""affiche l'aide""" |
|
|
|
messagebox.showinfo("Aide", "...") |
|
|
|
messagebox.showinfo("Aide", "42") |
|
|
|
|
|
|
|
def about(self): |
|
|
|
"""à propos de cette application""" |
|
|
|
messagebox.showinfo("À propos", "Ceci est une calculatrice.") |
|
|
|
|
|
|
|
def entrer(self): |
|
|
|
"""si dans mode interactif alors ajoute nv terme |
|
|
|
si dans autre mode alors evalue l'expression""" |
|
|
|
try: |
|
|
|
if len(self.saisie_expression.get()) > 0: |
|
|
|
"""selon le mode, on évalue l'expression ou on entre la valeur dans le stack""" |
|
|
|
if len(self.saisie_expression.get()) > 0: |
|
|
|
try: |
|
|
|
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.") |
|
|
|
messagebox.showerror("Saisie invalide", "Le résultat de l'opération n'est pas un nombre réel.") |
|
|
|
else: |
|
|
|
self.evaluer_expr() |
|
|
|
except OverflowError: |
|
|
|
messagebox.showerror("OverflowError", "Le résultat est trop élevé.") |
|
|
|
except OverflowError: |
|
|
|
messagebox.showerror("OverflowError", "Le résultat est trop élevé.") |
|
|
|
|
|
|
|
|
|
|
|
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""" |
|
|
|
if "." in terme: |
|
|
|
terme = float(terme) |
|
|
|
"""si c'est un nombre ou une constante: on ajoute une nouvelle valeur dans le stack |
|
|
|
si c'est une fonction : on l'évalue""" |
|
|
|
if estUnNombre(terme): |
|
|
|
if "." in terme: |
|
|
|
terme = float(terme) |
|
|
|
else: |
|
|
|
terme = int(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) |
|
|
@ -166,12 +174,8 @@ class Interface(tk.Frame): |
|
|
|
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 |
|
|
|
messagebox.showerror("Saisie invalide", "La fonction « "+terme+" » est inconnue.") |
|
|
|
return |
|
|
|
|
|
|
|
self.saisie_expression.delete(0 ,'end') |
|
|
|
|
|
|
@ -212,7 +216,7 @@ class Interface(tk.Frame): |
|
|
|
if op == "acos": res = acos(val) |
|
|
|
if op == "atan": res = atan(val) |
|
|
|
if op == "sqrt": res = sqrt(val) |
|
|
|
if op == "!" or op == "factorielle": res = factorial(val) |
|
|
|
if op == "!" or op == "factorielle": res = gamma(val + 1) |
|
|
|
if op == "opp": res = - val |
|
|
|
|
|
|
|
elif nb_arg == 2: |
|
|
@ -246,21 +250,10 @@ class Interface(tk.Frame): |
|
|
|
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 = s.args[0] |
|
|
|
messagebox.showerror("Erreur de syntaxe", explication) |
|
|
|
return |
|
|
|
except ValueError as v: |
|
|
|
message, explication, i_char = v.args |
|
|
|
|
|
|
@ -271,7 +264,7 @@ class Interface(tk.Frame): |
|
|
|
return |
|
|
|
|
|
|
|
try: |
|
|
|
arbre_expr = npi2tree(lst_expr, self.etat_affichage) |
|
|
|
arbre_expr = toTree(lst_expr, self.etat_affichage) |
|
|
|
self.affichage_expression.config(text = str(arbre_expr) + "=" + str(arbre_expr.evalue())) |
|
|
|
except IndexError: |
|
|
|
messagebox.showerror("Erreur","Erreur de syntaxe ici") |
|
|
@ -291,7 +284,7 @@ class Interface(tk.Frame): |
|
|
|
except SyntaxError as s: |
|
|
|
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)""" |
|
|
|
while not self.stack.est_vide(): |
|
|
@ -303,10 +296,9 @@ class Interface(tk.Frame): |
|
|
|
if not self.stack.est_vide(): |
|
|
|
self.stack.depiler() |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
root = tk.Tk() |
|
|
|
root.title("Calculatrice") |
|
|
|
root.geometry("380x500") |
|
|
|
hello_frame = Interface(root) |
|
|
|
hello_frame.mainloop() |
|
|
|
app = Interface(root) |
|
|
|
app.mainloop() |