@ -1,6 +1,8 @@
import tkinter as tk
from tkinter import messagebox
from Pile import Pile_chaine as Pile
from math import *
from expression import *
class ValeurSaisie :
""" classe d ' une valeur saise par l ' utilisateur """
@ -8,7 +10,7 @@ class ValeurSaisie:
self . valeur = valeur
self . label_valeur = tk . Label ( master , text = valeur )
self . label_valeur . pack ( )
self . label_valeur . pack ( side = " bottom " )
def __del__ ( self ) :
""" suppression du label """
@ -20,48 +22,129 @@ class Interface(tk.Frame):
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 "
self . stack = Pile ( )
self . saisie_expression = tk . Entry ( self . master )
self . saisie_expression . pack ( )
self . create_menu_bar ( )
self . frame_stack = tk . Frame ( self . master )
self . frame_stack . pack ( padx = 10 , pady = 10 )
self . affichage_expression = tk . Label ( self . master , text = " " , bg = " red " )
self . affichage_expression . pack ( )
frame_saisie = tk . Frame ( self . master , padx = 5 , pady = 5 )
frame_saisie . pack ( )
self . saisie_expression = tk . Entry ( frame_saisie )
self . saisie_expression . pack ( side = " left " )
self . saisie_expression . bind ( " <Return> " , lambda e : self . entrer ( ) )
self . saisie_expression . bind ( " <KP_Enter> " , lambda e : self . entrer ( ) )
self . saisie_expression . bind ( " + " , lambda e : self . evaluer ( " + " , 2 ) )
self . saisie_expression . bind ( " - " , lambda e : self . evaluer ( " - " , 2 ) )
self . saisie_expression . bind ( " * " , lambda e : self . evaluer ( " * " , 2 ) )
self . saisie_expression . bind ( " / " , lambda e : self . evaluer ( " / " , 2 ) )
btn_entrer = tk . Button ( frame_saisie , text = ' entrer ' , command = self . entrer )
btn_entrer . pack ( )
commandes = tk . LabelFrame ( self . master , text = " commandes " , padx = 20 , pady = 20 )
commandes = tk . LabelFrame ( self . master , text = " commandes " , padx = 5 , pady = 5 )
commandes . pack ( fill = " both " )
btn_calculer = tk . Button ( commandes , text = ' évaluer ' , command = self . entrer )
btn_calculer . pack ( side = " left " )
btn_effacer = tk . Button ( commandes , text = ' effacer ' , command = self . effacer )
btn_effacer . pack ( side = " left " )
btn_sinus = tk . Button ( commandes , text = ' sin ' , command = lambda : self . evaluer ( " sin " , 1 ) )
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 ( " sin " , 1 ) )
btn_sinus . pack ( side = " left " )
btn_sinus = tk . Button ( commandes , text = ' cos ' , command = lambda : self . evaluer ( " cos " , 1 ) )
btn_sinus = tk . Button ( fon cti ons, text = ' cos ' , command = lambda : self . evaluer ( " cos " , 1 ) )
btn_sinus . pack ( side = " left " )
btn_sinus = tk . Button ( commandes , text = ' tan ' , command = lambda : self . evaluer ( " tan " , 1 ) )
btn_sinus = tk . Button ( fon cti ons, text = ' tan ' , command = lambda : self . evaluer ( " tan " , 1 ) )
btn_sinus . pack ( side = " left " )
btn_pow = tk . Button ( commandes , text = ' ^ ' , command = lambda : self . evaluer ( " ^ " , 2 ) )
btn_pow = tk . Button ( fon cti ons, text = ' ^ ' , command = lambda : self . evaluer ( " ^ " , 2 ) )
btn_pow . pack ( side = " right " )
self . affichage_expression = tk . Label ( self . master )
self . affichage_expression . pack ( )
def create_menu_bar ( self ) :
menu_bar = tk . Menu ( self )
self . frame_stack = tk . Frame ( self . master , bg = " gray " )
self . frame_stack . pack ( padx = 10 , pady = 10 )
menu_file = tk . Menu ( menu_bar , tearoff = 0 )
menu_file . add_command ( label = " Quitter " , command = self . master . destroy )
menu_bar . add_cascade ( label = " Fichier " , menu = menu_file )
menu_affichage = tk . Menu ( menu_bar , tearoff = 0 )
menu_mode = tk . Menu ( menu_bar , tearoff = 0 )
menu_affichage . add_command ( label = " préfixe (polonaise) " , command = lambda : self . change_affichage ( " pre " ) )
menu_affichage . add_command ( label = " infixe " , command = lambda : self . change_affichage ( " inf " ) )
menu_mode . add_command ( label = " mode interactif " , command = lambda : self . change_affichage ( " post-int " ) )
menu_mode . add_command ( label = " mode expression " , command = lambda : self . change_affichage ( " post-expr " ) )
menu_affichage . add_cascade ( label = " postfixe (polonaise inversée) " , menu = menu_mode )
menu_bar . add_cascade ( label = " Notation " , menu = menu_affichage )
menu_help = tk . Menu ( menu_bar , tearoff = 0 )
menu_help . add_command ( label = " Aide " , command = self . aide )
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 . error_log = tk . Label ( self . master , fg = " red " )
self . error_log . pack ( )
def change_affichage ( self , affichage ) :
""" change le mode d ' affichage 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 "
}
self . etat . config ( text = etat_text [ affichage ] )
self . affichage_expression . config ( text = " " )
self . effacer_tt ( )
self . saisie_expression . delete ( 0 , ' end ' )
def do_something ( self ) :
pass
def aide ( self ) :
""" affiche l ' aide """
messagebox . showinfo ( " Aide " , " ... " )
def about ( self ) :
""" à propos de cette application """
messagebox . showinfo ( " À propos " , " Ceci est une calculatrice. " )
def evaluer ( self , op , nb_arg ) :
""" application de l ' operation aux nb_arg dernières valeurs du stack """
self . entrer ( )
""" affiche une erreur s ' il n ' y a pas assez d ' arguments ;
application de l ' operation aux nb_arg dernières valeurs du stack ;
si nb_arg == - 1 alors toutes les valeurs du stack sont utilisées """
if nb_arg == - 1 :
if self . stack . est_vide ( ) :
messagebox . showerror ( " Pas assez d ' arguments " , " Il n ' y a pas d ' arguments " )
return
lst_val = [ ]
while not self . stack . est_vide ( ) :
lst_val . append ( self . stack . depiler ( ) . valeur )
if op == " somme " :
res = 0
for val in lst_val :
res + = val
if op == " produit " :
res = 1
for val in lst_val :
res * = val
if self . stack . taille ( ) < nb_arg :
if nb_arg - self . stack . taille ( ) == 1 :
messagebox . showerror ( " Pas assez d ' arguments " , " Il manque 1 argument " )
else :
messagebox . showerror ( " Pas assez d ' arguments " , " Il manque " + str ( nb_arg - self . stack . taille ( ) ) + " arguments " )
return
if nb_arg == 1 :
val = self . stack . depiler ( ) . valeur
@ -72,13 +155,12 @@ class Interface(tk.Frame):
res = cos ( val )
if op == " tan " :
res = tan ( val )
if op == " ! " :
res = factorial ( val )
elif nb_arg == 2 :
try :
droite = self . stack . depiler ( ) . valeur
gauche = self . stack . depiler ( ) . valeur
except IndexError :
self . error_log . config ( text = " Il manque un argument " )
droite = self . stack . depiler ( ) . valeur
gauche = self . stack . depiler ( ) . valeur
if op == " + " :
res = gauche + droite
@ -91,31 +173,80 @@ class Interface(tk.Frame):
if op == " ^ " :
res = gauche * * droite
self . stack . empiler ( ValeurSaisie ( res , self . frame_stack ) )
elif nb_arg == 3 :
terme3 = self . stack . depiler ( ) . valeur
terme2 = self . stack . depiler ( ) . valeur
terme1 = self . stack . depiler ( ) . valeur
if op == " moy3 " :
res = ( terme1 + terme2 + terme3 ) / 3
#https://stackoverflow.com/questions/11541262/basic-query-regarding-bindtags-in-tkinter/11542200#11542200
return " break "
self . stack . empiler ( ValeurSaisie ( res , self . frame_stack ) )
def entrer ( self ) :
""" ajoute une nouvelle valeur dans le stack
ajoute un label avec cette valeur """
""" si dans mode npi: si dans interactif alors ajoute nv terme
si dans expression alors evalue l ' expression " " "
#completer les différents cas pour les autres notations
if self . etat_affichage == " post-int " :
self . entrer_terme_dans_stack ( )
if self . etat_affichage == " post-expr " :
self . evaluer_prepostfixe ( )
if self . etat_affichage == " pre " :
self . evaluer_prepostfixe ( )
def evaluer_prepostfixe ( self ) :
""" evalue la chaine de caractère dans le champ de saisie
comme une expression en notation polonaise ou npi selon l ' affichage " " "
#simplifier les conditions (plus tard) - ça m'a l'air pas mal
expr = self . saisie_expression . get ( )
if self . etat_affichage == " pre " :
expr = expr [ : : - 1 ]
expr = expr . split ( )
try :
arbre_expr = npi2tree ( expr )
self . affichage_expression . config ( text = str ( arbre_expr ) + " = " + str ( arbre_expr . evalue ( ) ) )
except IndexError :
messagebox . showerror ( " Erreur " , " Erreur " )
def entrer_terme_dans_stack ( self ) :
""" si nombre : ajoute une nouvelle valeur dans le stack
ajoute un label avec cette valeur
si fonction : appelle la fonction évaluer """
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 " , " ! " ] :
self . evaluer ( valeur_a_ajouter , 1 )
elif valeur_a_ajouter in [ " + " , " - " , " / " , " * " , " ^ " ] :
self . evaluer ( valeur_a_ajouter , 2 )
elif valeur_a_ajouter in [ " moy3 " ] :
self . evaluer ( valeur_a_ajouter , 3 )
elif valeur_a_ajouter in [ " somme " , " produit " ] :
self . evaluer ( valeur_a_ajouter , - 1 )
elif valeur_a_ajouter == " pi " :
self . stack . empiler ( ValeurSaisie ( pi , self . frame_stack ) )
else :
valeur_a_ajouter = int ( valeur_a_ajouter )
self . stack . empiler ( ValeurSaisie ( valeur_a_ajouter , self . frame_stack ) )
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 " )
self . saisie_expression . delete ( 0 , ' end ' )
def effacer ( self ) :
""" supprime tout le contenu de la pile et les labels associés """
def effacer_tt ( self ) :
""" supprime tout le contenu de la pile ( et les labels associés) """
while not self . stack . est_vide ( ) :
self . stack . depiler ( )
self . frame_stack . config ( height = 1 )
def effacer_dernier ( self ) :
""" supprime la dernière valeur entrée (et le label associés) """
if not self . stack . est_vide ( ) :
self . stack . depiler ( )
if __name__ == " __main__ " :