|
|
@ -2,45 +2,158 @@ |
|
|
|
# GUILLAUMIN-TORRES Ambre |
|
|
|
# COVIN Clara |
|
|
|
|
|
|
|
class Expression : |
|
|
|
"""Permet de représenter et manipuler une expression arithmétique sous la forme d'un arbre""" |
|
|
|
def __init__ (valeur_racine, fils_gauche, fils_droit): |
|
|
|
"""Constructeur""" |
|
|
|
self.valeur = valeur_racine |
|
|
|
from Pile import Pile_lst as Pile |
|
|
|
import tkinter as tk |
|
|
|
|
|
|
|
|
|
|
|
fen = tk.Tk() |
|
|
|
fen.title("Calculatrice") |
|
|
|
|
|
|
|
#taille de la fenetre |
|
|
|
fen.geometry("550x450") |
|
|
|
|
|
|
|
canvas = tk.Canvas(fen, width=500, height=300, bg="pink") |
|
|
|
|
|
|
|
label = tk.Label(canvas, text='Testing') |
|
|
|
# canvas.create_window(50, 50, window.label) |
|
|
|
canvas.grid(column=0,row=0) |
|
|
|
|
|
|
|
|
|
|
|
class Expression: |
|
|
|
"""représente une expression arithmétique sous forme d'un arbre""" |
|
|
|
def __init__ (self, valeur_racine, fils_gauche, fils_droit): |
|
|
|
self.val_racine = valeur_racine |
|
|
|
self.gauche = fils_gauche |
|
|
|
self.droit = fils_droit |
|
|
|
|
|
|
|
def évalue (self): |
|
|
|
"""Renvoie le résultat de l'expression""" |
|
|
|
if self.valeur == '*': |
|
|
|
return multiplication(valeur.gauche, valeur.droit) |
|
|
|
|
|
|
|
def evalue (self) : |
|
|
|
""" Permet de renvoyer la valeur de l’expression""" |
|
|
|
if self.gauche == None and self.droit == None : |
|
|
|
return self.val_racine |
|
|
|
|
|
|
|
elif self.valeur == '+': |
|
|
|
return addition(valeur.gauche, valeur.droit) |
|
|
|
if self.gauche != None: #on ne met pas elif car les cas sont indépendants" |
|
|
|
gauche_val = self.gauche.evalue() |
|
|
|
else: |
|
|
|
gauche_val = 0 |
|
|
|
|
|
|
|
def __str__ (self): |
|
|
|
"""Affiche tous les nœuds de l'arbre a par un parcours DFS préfixé.""" |
|
|
|
if a is None: |
|
|
|
return |
|
|
|
parcours_dfs_infixe(a.gauche) |
|
|
|
print(a.valeur) |
|
|
|
parcours_dfs_infixe(a.droit) |
|
|
|
if self.droit != None: |
|
|
|
droite_val = self.droit.evalue() |
|
|
|
else: |
|
|
|
droite_val = 0 |
|
|
|
|
|
|
|
def multiplication(self): |
|
|
|
"""Multiplie la valeur des fils gauche et droits""" |
|
|
|
if self.gauche == int and self.droit == int : |
|
|
|
return self.gauche * self.droit |
|
|
|
|
|
|
|
def addition(self): |
|
|
|
"""Additionne les valeurs des fils gauche et droits""" |
|
|
|
if self.gauche == int and self.droit == int : |
|
|
|
return self.gauche + self.droit |
|
|
|
|
|
|
|
#test |
|
|
|
exp = Expression('*', |
|
|
|
Expression(6, None, None), |
|
|
|
Expression('+', |
|
|
|
Expression(4, None, None), |
|
|
|
Expression(3, None, None) |
|
|
|
) |
|
|
|
) |
|
|
|
if self.val_racine == '+': |
|
|
|
return gauche_val + droite_val |
|
|
|
elif self.val_racine == '-': |
|
|
|
return gauche_val - droite_val |
|
|
|
elif self.val_racine == '*': |
|
|
|
return gauche_val * droite_val |
|
|
|
elif self.val_racine == '/': |
|
|
|
return gauche_val / droite_val |
|
|
|
else : |
|
|
|
raise ValueError ("Cette commande ne peut pas être effectuer") |
|
|
|
|
|
|
|
def __str__(self): |
|
|
|
"""Permet d'afficher une expression en ligne, représenter par un arbre""" |
|
|
|
result = "" |
|
|
|
if self.droit: |
|
|
|
result = result + str(self.droit) |
|
|
|
result = result + str(self.val_racine) + "\n" #le "/n" c'est pour avoir une nouvelle ligne de l'arbre |
|
|
|
if self.gauche: |
|
|
|
result += str(self.gauche) |
|
|
|
return result |
|
|
|
|
|
|
|
def npi2tree(lst): |
|
|
|
"""Convertit une liste représentant une expression en notation polonaise inversée en un arbre d'expression.""" |
|
|
|
pille = Pile () |
|
|
|
for element in lst: |
|
|
|
# Si c'est un opérateur (+, -, * ou /), on crée un nœud opérateur |
|
|
|
if element in ('+', '-', '*', '/'): |
|
|
|
droit = pille.depiler() |
|
|
|
gauche = pille.depiler() |
|
|
|
pille.empiler(Expression(element, gauche, droit)) # Créer un nouvel arbre et empiler |
|
|
|
else: |
|
|
|
# Sinon, ça veut dire que c'est un nombre donc on le convertit et on l'empile. |
|
|
|
pille.empiler(Expression(int(element), None, None)) |
|
|
|
|
|
|
|
return pille.depiler() # Retourne l'arbre complet |
|
|
|
|
|
|
|
def evaluer_expression(): |
|
|
|
expression = entry.get() |
|
|
|
elements = expression.split() |
|
|
|
if not elements: |
|
|
|
label_2.config(text="Erreur: Expression vide") |
|
|
|
return |
|
|
|
arbre = Expression.npi2tree(elements) |
|
|
|
if arbre is None: |
|
|
|
label_2.config(text="Erreur: Expression incorrecte") |
|
|
|
else: |
|
|
|
resultat = arbre.evalue() |
|
|
|
label_2.config(text=f"Résultat: {resultat}") # si l'expression est incorrecte |
|
|
|
|
|
|
|
# Label pour l'interface |
|
|
|
label_1 = tk.Label(fen, text="Entrez l'expression :") |
|
|
|
label_1.grid() |
|
|
|
|
|
|
|
# Champ de texte pour l'entrée de l'expression |
|
|
|
entry = tk.Entry(fen, width=30) |
|
|
|
entry.grid() |
|
|
|
|
|
|
|
# Bouton pour calculer l'expression |
|
|
|
btn_calculer = tk.Button(fen, text="Calculer", command=evaluer_expression) |
|
|
|
btn_calculer.grid(row=4, column=0, columnspan=2) |
|
|
|
|
|
|
|
# Label pour afficher le résultat |
|
|
|
label_2 = tk.Label(fen, text="Résultat: ") |
|
|
|
label_2.grid(row=5, column=0, columnspan=2) |
|
|
|
|
|
|
|
|
|
|
|
label_2 = tk.Label(fen, text=evaluer_expression().resultat) |
|
|
|
label_2.grid() |
|
|
|
|
|
|
|
# Lancement de l'interface graphique |
|
|
|
fen.mainloop() |
|
|
|
|
|
|
|
|
|
|
|
#test: |
|
|
|
|
|
|
|
exp = Expression(5,None,None) |
|
|
|
assert exp.evalue() == 5 |
|
|
|
|
|
|
|
exp = Expression('+', Expression(8,None,None), Expression(3,None,None))#ça marche comme ça |
|
|
|
assert exp.evalue() == 11 |
|
|
|
|
|
|
|
#exp = Expression('+', 8, 3)#mais ça marche pas comme ça, je sais pas trop comment régler ça |
|
|
|
#assert exp.evalue() == 11 |
|
|
|
|
|
|
|
exp = Expression('*', Expression(8,None,None), Expression(3,None,None))#ça marche comme ça |
|
|
|
assert exp.evalue() == 24 |
|
|
|
|
|
|
|
exp = Expression('-', Expression(45,None,None), Expression(3,None,None))#ça marche comme ça |
|
|
|
assert exp.evalue() == 42 |
|
|
|
|
|
|
|
lst = ["6", "4", "3", "+", "*"] # Correspond à 6 * (4 + 3) |
|
|
|
arbre = Expression.npi2tree(lst) # Convertit la liste en un arbre |
|
|
|
|
|
|
|
print(arbre.evalue()) # Affiche : 42 |
|
|
|
|
|
|
|
# Test: Expression simple de somme |
|
|
|
exp = Expression('+', Expression(8, None, None), Expression(3, None, None)) |
|
|
|
assert exp.evalue() == 11, f"Test échoué: {exp.evalue()}" # Vérifie que 8 + 3 = 11 |
|
|
|
|
|
|
|
# Test: Expression simple de multiplication |
|
|
|
exp = Expression('*', Expression(4, None, None), Expression(5, None, None)) |
|
|
|
assert exp.evalue() == 20, f"Test échoué: {exp.evalue()}" # Vérifie que 4 * 5 = 20 |
|
|
|
|
|
|
|
# Test: Expression avec une soustraction |
|
|
|
exp = Expression('-', Expression(20, None, None), Expression(5, None, None)) |
|
|
|
assert exp.evalue() == 15, f"Test échoué: {exp.evalue()}" # Vérifie que 20 - 5 = 15 |
|
|
|
|
|
|
|
# Test: Test d'une expression valide en NPI (notation polonaise inversée) |
|
|
|
# Correspond à: 6 * (4 + 3) |
|
|
|
lst = ["6", "4", "3", "+", "*"] |
|
|
|
arbre = Expression.npi2tree(lst) |
|
|
|
assert arbre.evalue() == 42, f"Test échoué: {arbre.evalue()}" # Vérifie que 6 * (4 + 3) = 42 |
|
|
|
|
|
|
|
# Test: Expression avec division |
|
|
|
exp = Expression('/', Expression(10, None, None), Expression(2, None, None)) |
|
|
|
assert exp.evalue() == 5, f"Test échoué: {exp.evalue()}" # Vérifie que 10 / 2 = 5 |
|
|
|