3 changed files with 229 additions and 41 deletions
@ -0,0 +1,74 @@ |
|||||
|
import tkinter as tk |
||||
|
from tkinter import messagebox |
||||
|
from expression import npi2tree |
||||
|
|
||||
|
|
||||
|
def ajouter(val): |
||||
|
entree.insert(tk.END, val + " ") |
||||
|
|
||||
|
|
||||
|
def calculer(): |
||||
|
try: |
||||
|
texte = entree.get() |
||||
|
liste = texte.split() |
||||
|
arbre = npi2tree(liste) |
||||
|
resultat.config(text="Résultat : " + str(arbre.evalue())) |
||||
|
except: |
||||
|
messagebox.showerror("Erreur", "Expression invalide") |
||||
|
|
||||
|
|
||||
|
def effacer(): |
||||
|
entree.delete(0, tk.END) |
||||
|
resultat.config(text="") |
||||
|
|
||||
|
|
||||
|
fenetre = tk.Tk() |
||||
|
fenetre.title("Calculatrice NPI") |
||||
|
fenetre.geometry("500x600") |
||||
|
|
||||
|
entree = tk.Entry(fenetre, width=35, font=("Arial", 18)) |
||||
|
entree.pack(pady=20) |
||||
|
|
||||
|
frame = tk.Frame(fenetre) |
||||
|
frame.pack() |
||||
|
|
||||
|
chiffres = ["7", "8", "9", |
||||
|
"4", "5", "6", |
||||
|
"1", "2", "3", |
||||
|
"0"] |
||||
|
|
||||
|
i = 0 |
||||
|
for c in chiffres: |
||||
|
b = tk.Button(frame, |
||||
|
text=c, |
||||
|
width=6, |
||||
|
height=2, |
||||
|
font=("Arial", 16), |
||||
|
command=lambda x=c: ajouter(x)) |
||||
|
b.grid(row=i//3, column=i%3, padx=5, pady=5) |
||||
|
i += 1 |
||||
|
|
||||
|
plus = tk.Button(frame, text="+", width=6, height=2, |
||||
|
font=("Arial", 16), |
||||
|
command=lambda: ajouter("+")) |
||||
|
plus.grid(row=0, column=3, padx=5, pady=5) |
||||
|
|
||||
|
fois = tk.Button(frame, text="*", width=6, height=2, |
||||
|
font=("Arial", 16), |
||||
|
command=lambda: ajouter("*")) |
||||
|
fois.grid(row=1, column=3, padx=5, pady=5) |
||||
|
|
||||
|
btn_calc = tk.Button(fenetre, text="Calculer", |
||||
|
font=("Arial", 16), height=2, |
||||
|
command=calculer) |
||||
|
btn_calc.pack(pady=10) |
||||
|
|
||||
|
btn_clear = tk.Button(fenetre, text="Effacer", |
||||
|
font=("Arial", 16), height=2, |
||||
|
command=effacer) |
||||
|
btn_clear.pack(pady=5) |
||||
|
|
||||
|
resultat = tk.Label(fenetre, text="", font=("Arial", 16), fg="red") |
||||
|
resultat.pack(pady=20) |
||||
|
|
||||
|
fenetre.mainloop() |
||||
@ -1,60 +1,68 @@ |
|||||
from Pile import Pile_lst as p |
from Pile import Pile_lst |
||||
|
|
||||
|
|
||||
class Expression: |
class Expression: |
||||
def __init__ (self, valeur, gauche, droit): |
""" |
||||
"""Initialise la valeur de la racine (’+’, ’*’ ou un entier) et les fils gauche et |
Représente une expression arithmétique sous forme d’arbre binaire. |
||||
droit (qui seront soit None si la racine est un entier, soit des arbres) ;""" |
""" |
||||
|
|
||||
|
def __init__(self, valeur, gauche=None, droit=None): |
||||
|
""" |
||||
|
Initialise un noeud avec une valeur ('+', '*' ou entier) |
||||
|
et éventuellement deux sous-arbres gauche et droit. |
||||
|
""" |
||||
self.valeur = valeur |
self.valeur = valeur |
||||
self.gauche = gauche |
self.gauche = gauche |
||||
self.droit = droit |
self.droit = droit |
||||
|
|
||||
|
|
||||
def evalue(self): |
def evalue(self): |
||||
"""Renvoie la valeur de l’expression.""" |
""" |
||||
|
Évalue récursivement l'expression et renvoie sa valeur entière. |
||||
|
""" |
||||
|
# Cas feuille (entier) |
||||
if self.gauche is None and self.droit is None: |
if self.gauche is None and self.droit is None: |
||||
return self.valeur |
return self.valeur |
||||
|
|
||||
|
# Cas opérateur |
||||
if self.valeur == "+": |
if self.valeur == "+": |
||||
return self.gauche.evalue() + self.droit.evalue() |
return self.gauche.evalue() + self.droit.evalue() |
||||
elif self.valeur == "*": |
elif self.valeur == "*": |
||||
return self.gauche.evalue() * self.droit.evalue() |
return self.gauche.evalue() * self.droit.evalue() |
||||
|
else: |
||||
|
raise ValueError("Opérateur inconnu") |
||||
|
|
||||
def __str__(self): |
def __str__(self): |
||||
"""Affiche l'expression""" |
""" |
||||
if self.gauche is None and self.droite is None : |
Renvoie une chaîne représentant l’expression avec parenthèses. |
||||
|
""" |
||||
|
# Cas feuille |
||||
|
if self.gauche is None and self.droit is None: |
||||
return str(self.valeur) |
return str(self.valeur) |
||||
|
|
||||
|
# Cas opérateur |
||||
exp = Expression('*', |
return "(" + str(self.gauche) + self.valeur + str(self.droit) + ")" |
||||
Expression(6, None, None), |
|
||||
Expression('+', |
|
||||
Expression(4, None, None), |
|
||||
Expression(3, None, None) |
|
||||
) |
|
||||
) |
|
||||
|
|
||||
exp.evalue() |
|
||||
|
|
||||
|
|
||||
|
|
||||
def npi2tree(liste_npi): |
def npi2tree(liste_npi): |
||||
"""Prends en paramètre une liste correspondant à l’expression en notation |
""" |
||||
polonaise inversée et renvoyant l’arbre (de type Expression) correspondant""" |
Convertit une liste d’éléments en notation polonaise inversée (NPI) |
||||
pile = p() |
en un arbre d’expression de type Expression. |
||||
|
""" |
||||
|
pile = Pile_lst() |
||||
|
|
||||
for elem in liste_npi: |
for elem in liste_npi: |
||||
if elem == "+" : |
|
||||
droit = pile.depiler() |
# Si c'est un opérateur |
||||
gauche = p.depiler() |
if elem == "+" or elem == "*": |
||||
exp = Expression(elem, gauche, droit) |
|
||||
p.empiler(exp) |
|
||||
elif elem == "*" : |
|
||||
droit = pile.depiler() |
droit = pile.depiler() |
||||
gauche = pile.depiler() |
gauche = pile.depiler() |
||||
exp = Expression(elem, gauche, droit) |
exp = Expression(elem, gauche, droit) |
||||
pile.empiler(exp) |
pile.empiler(exp) |
||||
|
|
||||
|
# Sinon c'est un entier |
||||
else: |
else: |
||||
exp = Expression(elem, None, None) |
nombre = int(elem) |
||||
|
exp = Expression(nombre, None, None) |
||||
pile.empiler(exp) |
pile.empiler(exp) |
||||
return p.sommet() |
|
||||
|
|
||||
|
|
||||
|
return pile.sommet() |
||||
@ -0,0 +1,106 @@ |
|||||
|
#!/usr/bin/env python3 |
||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
|
||||
|
class Maillon: |
||||
|
"""Un maillon d'une liste chaînée.""" |
||||
|
def __init__(self, valeur, suivant): |
||||
|
self.valeur = valeur |
||||
|
self.suivant = suivant |
||||
|
|
||||
|
def __str__(self): |
||||
|
"""Renvoie une chane de caractères représentant le maillon.""" |
||||
|
return str(self.valeur) |
||||
|
|
||||
|
|
||||
|
class ListeChaine: |
||||
|
"""Une liste chaînée.""" |
||||
|
def __init__(self, tete=None): |
||||
|
"""Crée une liste vide, ou une liste dont la tete (un maillon) |
||||
|
est donnée.""" |
||||
|
self.__tete = tete |
||||
|
|
||||
|
def est_vide(self): |
||||
|
"""Indique si la liste est vide.""" |
||||
|
return self.__tete is None |
||||
|
|
||||
|
def tete(self): |
||||
|
"""Renvoie la valeur du premier élément de la liste.""" |
||||
|
if self.est_vide(): |
||||
|
raise IndexError("La liste vide n'a pas de tête") |
||||
|
return self.__tete.valeur |
||||
|
|
||||
|
def queue(self): |
||||
|
"""Renvoie la queue de la liste.""" |
||||
|
if self.est_vide(): |
||||
|
raise IndexError("La liste vide n'a pas de queue") |
||||
|
return ListeChaine(self.__tete.suivant) |
||||
|
|
||||
|
def ajoute(self, valeur): |
||||
|
"""ajoute `valeur` en tête de la liste.""" |
||||
|
self.__tete = Maillon(valeur, self.__tete) |
||||
|
|
||||
|
def __str__(self): |
||||
|
"""Renvoie une chaîne de caractères représentant la liste.""" |
||||
|
maillon = self.__tete |
||||
|
s = '' |
||||
|
while maillon is not None: |
||||
|
s = s + str(maillon.valeur) |
||||
|
maillon = maillon.suivant |
||||
|
if maillon is not None: |
||||
|
s += '->' |
||||
|
return s |
||||
|
|
||||
|
def __len__(self): |
||||
|
"""Renvoie la longueur de la liste.""" |
||||
|
maillon = self.__tete |
||||
|
long = 0 |
||||
|
while maillon is not None: |
||||
|
long = long + 1 |
||||
|
maillon = maillon.suivant |
||||
|
return long |
||||
|
|
||||
|
def __getitem__(self, n): |
||||
|
"""Renvoie l'élément d'indice n de la liste.""" |
||||
|
maillon = self.__tete |
||||
|
i = 0 |
||||
|
while i < n and maillon is not None: |
||||
|
i = i + 1 |
||||
|
maillon = maillon.suivant |
||||
|
if maillon is None or n < 0: |
||||
|
raise IndexError("Indice non valide") |
||||
|
return maillon.valeur |
||||
|
|
||||
|
def __add__(self, other): |
||||
|
"""Renvoie la liste correspondant à la concaténation des 2 listes.""" |
||||
|
if self.est_vide(): |
||||
|
return other |
||||
|
v = self.tete() |
||||
|
q = self.queue() |
||||
|
return ListeChaine(Maillon(v, (q + other).__tete)) |
||||
|
|
||||
|
def reverse(self): |
||||
|
"""Renvoie une liste correspondant à la liste renversée.""" |
||||
|
res = ListeChaine() |
||||
|
maillon = self.__tete |
||||
|
while maillon is not None: |
||||
|
res.ajoute(maillon.valeur) |
||||
|
maillon = maillon.suivant |
||||
|
return res |
||||
|
|
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
lst = ListeChaine() |
||||
|
print(lst.est_vide()) |
||||
|
lst.ajoute(306) |
||||
|
lst.ajoute(42) |
||||
|
lst.ajoute(205) |
||||
|
print(lst) |
||||
|
print(lst.est_vide()) |
||||
|
print(lst[0]) |
||||
|
print(lst[1]) |
||||
|
print(len(lst)) |
||||
|
lst2 = ListeChaine() |
||||
|
lst2.ajoute(18) |
||||
|
lst2.ajoute(45) |
||||
|
print(lst + lst2) |
||||
Loading…
Reference in new issue