Demande de conseils ou d'améliorations pour mon code...

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Hello !

Je viens de découvrir ce site en parcourant feu SdZ hier… Je suis en plein apprentissage de python et tk. J'ai réalisé un petit programme, et je souhaiterai avoir un avis d'un oeil (ou plus !) expérimenté à propos de celui-ci. Le programme est supposé aider à compter des sous: il suffit d'y entrer le montant des billets, puis le nombre de chaque sorte de pièce. Le montant total pour chaque sorte de pièce ainsi que le montant total sont calculés à chaque fois qu'un widget Entry reçoit le focus, ou lorsque la touche Entrée est enfonçée. De plus, le texte du widget est sélectionné également lors de ces 2 événements. Le champ 'extra' indique le 'surplus' d'argent lorsque le total est supérieur à ₤50.

Le code paraît un peu long mais il contient pas mal de 'mise en page'… Je n'ai pas encore implémenté l''except' dans le calcul des montants, pour le cas où autre chose qu'un nombre serait entré (seulement 'pass' pour l'instant).

Merci d'avance !

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python3

from tkinter import ttk, Tk, StringVar, Grid, Entry, Label
from tkinter import RIGHT, END, N, E, S, W

coin_number = []
coin_value = []
coin_value_temp = []
entries = []

def calculate(event):
   try:
       # Saving total value of each coin type
       coin_value_temp[0] = int(coin_number[0].get())
       coin_value_temp[1] = int(coin_number[1].get()) * 2
       coin_value_temp[2] = int(coin_number[2].get())
       coin_value_temp[3] = round(float(coin_number[3].get()) * 0.50, 2)
       coin_value_temp[4] = round(float(coin_number[4].get()) * 0.20, 2)
       coin_value_temp[5] = round(float(coin_number[5].get()) * 0.10, 2)
       coin_value_temp[6] = round(float(coin_number[6].get()) * 0.05, 2)
       
       for n in range(0, 7):
           coin_value[n].set(coin_value_temp[n])
           
       # Calculation of the total 
       coin_value_temp[7] = coin_value_temp[0]
       for n in range(1, 7):
           coin_value_temp[7] += coin_value_temp[n]
       coin_value[7].set(round(coin_value_temp[7], 2))
       
       # Calculation of the "Extra"
       coin_value_temp[8] = round(float(coin_value_temp[7]) - 50, 2)
       if(coin_value_temp[8] > 0):
           coin_value[8].set(coin_value_temp[8])
       else:
           coin_value[8].set(0)
   except ValueError:
       pass    # TO DO!!!!!!!!!!!!!!!!!!!!!!!!!!
   
   # Select text on focus
   for n in range(0, 7):
       if(entries[n] == entries[n].focus_get()):
           entries[n].select_range(0, END)

def main():
   root = Tk()
   root.title("Cash up")

   for n in range(0, 7):
       coin_number.append(StringVar())
       coin_number[n].set(0)

   for n in range(0, 9):
       coin_value.append(StringVar())
       coin_value[n].set(0)
       coin_value_temp.append(0)

   # Main Frame
   mainframe = ttk.Frame(root, padding="14 14 15 15")    # left, top, right, bottom
   mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
   mainframe.columnconfigure(0, weight=1)
   mainframe.rowconfigure(0, weight=1)

   # Entries widgets
   entry_width = 6
   for n in range(0, 7):
       entries.append(Entry(mainframe, width=entry_width, textvariable=coin_number[n], justify=RIGHT))
       if(n == 0):
           entries[n].grid(row=1, column=1, sticky=(W, E))
       else:
           entries[n].grid(row=n+3, column=1, sticky=(W, E))

   # Labels Value
   label_value_width = 6
   Label(mainframe, textvariable=coin_value[0], width=label_value_width, anchor=W).grid(row=1, column=3, |sticky=W)
   for n in range(1, 7):
       Label(mainframe, textvariable=coin_value[n], width=label_value_width, anchor=W).grid(row=n+3, column=3, sticky=W)
   Label(mainframe, textvariable=coin_value[7], width=label_value_width, anchor=W, font='bold').grid(row=11, column=3, sticky=W)
   Label(mainframe, textvariable=coin_value[8], width=label_value_width, anchor=W).grid(row=12, column=3, sticky=W)

   # Labels Misc
   Label(mainframe, text="Notes value").grid(row=0, column=0, sticky=E, columnspan=2)
   Label(mainframe, text="₤").grid(row=1, column=0, sticky=E)
   Label(mainframe, text="Coins number").grid(row=3, column=0, columnspan=2, sticky=W)
   Label(mainframe, text="₤2:").grid(row=4, column=0, sticky=E)
   Label(mainframe, text="₤1:").grid(row=5, column=0, sticky=E)
   Label(mainframe, text="₤0.50:").grid(row=6, column=0, sticky=E)
   Label(mainframe, text="₤0.20:").grid(row=7, column=0, sticky=E)
   Label(mainframe, text="₤0.10:").grid(row=8, column=0, sticky=E)
   Label(mainframe, text="₤0.05:").grid(row=9, column=0, sticky=E)
   Label(mainframe, text="Total", font='bold', pady=4).grid(row=11, column=0, sticky=E, columnspan=2)
   Label(mainframe, text="Extra").grid(row=12, column=0, sticky=E, columnspan=2)
   Label(mainframe, text="Total").grid(row=0, column=2, columnspan= 2)
   Label(mainframe, text="= ₤").grid(row=1, column=2, sticky=E)
   for n in range(4, 10):
       Label(mainframe, text="= ₤").grid(row=n, column=2, sticky=E)
   Label(mainframe, text="= ₤", font='bold').grid(row=11, column=2, sticky=E)
   Label(mainframe, text="= ₤").grid(row=12, column=2, sticky=E)

   # Default focus
   entries[0].focus()

   # Events
   for item in entries:
       item.bind('<FocusIn>', calculate)

   root.bind('<Return>', calculate)

   root.mainloop()

if __name__ == '__main__':
   main()

Édité par Nonos

+0 -0

Cette réponse a aidé l'auteur du sujet

'Lut !

Il serait préférable d'inclure ton code au premier message, dans des balises code puis secret : le sujet sera plus pérenne.

Concernant le code, je n'ai pas regardé en détails, mais lorsque tu as un tas de lignes quasiment identiques, c'est généralement pas bon. Plutôt que d'utiliser des préfixes et/ou des suffixes pour distinguer tes noms de variables, passe par un dictionnaire. Tu pourras alors employer des boucles pour effectuer des opérations sur chacune de tes "variables".

+1 -0
Staff

Cette réponse a aidé l'auteur du sujet

Quelques remarques :

  • from tkinter import * : on évite de faire ça car ça peut entraîner des collisions de noms. Soit tu fais comme la ligne suivante, soit tu importe spécifiquement ce que tu souhaite. Mais l'utilisation des * est déconseillé.
  • De plus tout se passe presque dans le scope global. Tu devrais probablement faire des objets ou des fonctions pour organiser ça et minimiser les variables globales. Le lancement devrait être dans un if __name__ == '__main__':.
  • Tu as des tonnes de codes qui se répètent et sont très similaires (ligne 6-12, 25-38, 49-64, etc.). La très grande majorité tu dois pouvoir les factoriser en utilisant des listes et des dict.
  • Dans ta fonction calculate, tu fait des calcules que tu met dans des StringVar pour les récupérer ensuite ligne 13 en refaisant des cast. C'est pas terrible. Tu devrais stoker les valeurs intermédiaires.

Je ne sais pas trop où aller dans les commentaires car je ne sais pas quel est ton niveau actuel d'apprentissage de Python.

NB: je fais des remarques uniquement sur Python car je n'utilise jamais tkinter donc je ne sais pas si ce que tu fais avec est conforme ou pas.

+2 -0
Auteur du sujet

Merci pour vos remarques! J'ai adapté mon code en essayant d'y intégrer tout ceci. Je ne suis pas cependant passé à de l'objet, ne l'ayant pas encore abordé en python…

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python3

from tkinter import ttk, Tk, StringVar, Grid, Entry, Label
from tkinter import RIGHT, END, N, E, S, W

coin_number = []
coin_value = []
coin_value_temp = []
entries = []

def calculate(event):
   try:
       # Saving total value of each coin type
       coin_value_temp[0] = int(coin_number[0].get())
       coin_value_temp[1] = int(coin_number[1].get()) * 2
       coin_value_temp[2] = int(coin_number[2].get())
       coin_value_temp[3] = round(float(coin_number[3].get()) * 0.50, 2)
       coin_value_temp[4] = round(float(coin_number[4].get()) * 0.20, 2)
       coin_value_temp[5] = round(float(coin_number[5].get()) * 0.10, 2)
       coin_value_temp[6] = round(float(coin_number[6].get()) * 0.05, 2)
       
       for n in range(0, 7):
           coin_value[n].set(coin_value_temp[n])
           
       # Calculation of the total 
       coin_value_temp[7] = coin_value_temp[0]
       for n in range(1, 7):
           coin_value_temp[7] += coin_value_temp[n]
       coin_value[7].set(round(coin_value_temp[7], 2))
       
       # Calculation of the "Extra"
       coin_value_temp[8] = round(float(coin_value_temp[7]) - 50, 2)
       if(coin_value_temp[8] > 0):
           coin_value[8].set(coin_value_temp[8])
       else:
           coin_value[8].set(0)
   except ValueError:
       pass    # TO DO!!!!!!!!!!!!!!!!!!!!!!!!!!
   
   # Select text on focus
   for n in range(0, 7):
       if(entries[n] == entries[n].focus_get()):
           entries[n].select_range(0, END)

def main():
   root = Tk()
   root.title("Cash up")

   for n in range(0, 7):
       coin_number.append(StringVar())
       coin_number[n].set(0)

   for n in range(0, 9):
       coin_value.append(StringVar())
       coin_value[n].set(0)
       coin_value_temp.append(0)

   # Main Frame
   mainframe = ttk.Frame(root, padding="14 14 15 15")    # left, top, right, bottom
   mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
   mainframe.columnconfigure(0, weight=1)
   mainframe.rowconfigure(0, weight=1)

   # Entries widgets
   entry_width = 6
   for n in range(0, 7):
       entries.append(Entry(mainframe, width=entry_width, textvariable=coin_number[n], justify=RIGHT))
       if(n == 0):
           entries[n].grid(row=1, column=1, sticky=(W, E))
       else:
           entries[n].grid(row=n+3, column=1, sticky=(W, E))

   # Labels Value
   label_value_width = 6
   Label(mainframe, textvariable=coin_value[0], width=label_value_width, anchor=W).grid(row=1, column=3, |sticky=W)
   for n in range(1, 7):
       Label(mainframe, textvariable=coin_value[n], width=label_value_width, anchor=W).grid(row=n+3, column=3, sticky=W)
   Label(mainframe, textvariable=coin_value[7], width=label_value_width, anchor=W, font='bold').grid(row=11, column=3, sticky=W)
   Label(mainframe, textvariable=coin_value[8], width=label_value_width, anchor=W).grid(row=12, column=3, sticky=W)

   # Labels Misc
   Label(mainframe, text="Notes value").grid(row=0, column=0, sticky=E, columnspan=2)
   Label(mainframe, text="₤").grid(row=1, column=0, sticky=E)
   Label(mainframe, text="Coins number").grid(row=3, column=0, columnspan=2, sticky=W)
   Label(mainframe, text="₤2:").grid(row=4, column=0, sticky=E)
   Label(mainframe, text="₤1:").grid(row=5, column=0, sticky=E)
   Label(mainframe, text="₤0.50:").grid(row=6, column=0, sticky=E)
   Label(mainframe, text="₤0.20:").grid(row=7, column=0, sticky=E)
   Label(mainframe, text="₤0.10:").grid(row=8, column=0, sticky=E)
   Label(mainframe, text="₤0.05:").grid(row=9, column=0, sticky=E)
   Label(mainframe, text="Total", font='bold', pady=4).grid(row=11, column=0, sticky=E, columnspan=2)
   Label(mainframe, text="Extra").grid(row=12, column=0, sticky=E, columnspan=2)
   Label(mainframe, text="Total").grid(row=0, column=2, columnspan= 2)
   Label(mainframe, text="= ₤").grid(row=1, column=2, sticky=E)
   for n in range(4, 10):
       Label(mainframe, text="= ₤").grid(row=n, column=2, sticky=E)
   Label(mainframe, text="= ₤", font='bold').grid(row=11, column=2, sticky=E)
   Label(mainframe, text="= ₤").grid(row=12, column=2, sticky=E)

   # Default focus
   entries[0].focus()

   # Events
   for item in entries:
       item.bind('<FocusIn>', calculate)

   root.bind('<Return>', calculate)

   root.mainloop()

if __name__ == '__main__':
   main()

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte