-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtkinterface.py
More file actions
206 lines (167 loc) · 6.35 KB
/
tkinterface.py
File metadata and controls
206 lines (167 loc) · 6.35 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# sur GitHub, le fichier s'appelle "project.py"
# donc, dans mon nouveau fichier, je fais :
from project import *
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
# === GLOBAL VARIABLES ===
tps = 1 # compteur de minutes
pax_arret = 0 # nombre de personnes attendant le bus
trains = {} # trains arrivés et passagers en transit vers le bus
# clés = heure d'arrivée du train
# valeur = nombre de passagers cherchant le bus
late_trains = []
savings = []
# pour tkinter
app = None
fig = None
ax = None
graph = None
canvas = None
line = None
frame = None
launch_button = None
parameters = {key:None for key in [
'period_label','period_input','freqtrain_label','freqtrain_input',
'freqbus_label','freqbus_input','seats_label','seats_input',
'stand_label','stand_input','late_label','late_input'
]
}
text_to_display = {
'period_label':'Durée de la simulation',
'freqtrain_label':'Fréquence (train)',
'freqbus_label':'Fréquence (bus)',
'seats_label':"Nombre de places assises (bus)",
'stand_label':'Nombre de "places debout" (bus)',
'late_label':'Taux de retard'
}
# === EVENT MANAGEMENT ===
def clock(values):
global tps,pax_arret,savings,trains,late_trains
global app,ax,graph,line
def step():
global tps,pax_arret,savings,trains,late_trains
global app,ax,graph,line
nonlocal values
# pour éviter de tout modifier (faut avoir la flemme parfois ;)
period = int(values['period_input'])
freq_train = int(values['freqtrain_input'])
freq_bus = int(values['freqbus_input'])
# pour les nouvelles valeurs
seats = int(values['seats_input'])
stand_capacity = int(values['stand_input'])
late_rate = float(values['late_input'])
if tps<=period:
if tps%freq_train==0:
delay = add_late(tps,late_rate)
if delay==0:
trains[tps] = goto_bus(train_arrival())
else:
late_trains.append(tps) # rappelle qu'un train en retard va arriver
# un train en retard arrive ?
if tps in late_trains:
late_trains.pop(late_trains.index(tps)) # nettoyage
trains[tps] = goto_bus(train_arrival()) # passagers arrivent
for arrival,transit_pax in trains.copy().items():
j = arrive_at_bus_stop(transit_pax,arrival,tps)
if j==0: # nettoyer le dictionnaire en enlevant les trop bas
del trains[arrival]
else:
pax_arret += j
if tps%freq_bus==0:
gone, no_more_seats = bus_departure(pax_arret,seats,stand_capacity)
pax_arret -= gone
# enregistre les informations
savings.append((tps,pax_arret))
# classe les informations
times,pax = map(list,zip(*savings))
# met à jour le graphique
line.set_data(times,pax)
ax.relim()
ax.autoscale_view()
graph.draw_idle()
# prochaine minute
tps+=1
app.after(1000,step)
else:
print("Simulation terminée")
return
app.after(0,step)
def reset():
global tps,pax_arret,trains,late_trains,savings
global ax,line
# supprime l'ancien graphe
ax.cla()
line = ax.plot([],[],'r.-')[0]
# remet les paramètres à zéro
tps = 1
pax_arret = 0
trains = {}
late_trains = []
savings = []
def launch():
global parameters
# reset
reset()
# dictionnaire qui contient les valeurs récupérées
values = {}
for key,val in parameters.items():
# on garde uniquement les Entry
if "input" in key:
user_input = val.get() # récupère la valeur
# cas de late_rate
if key=='late_input':
if set(user_input).issubset(set('0123456789.')) and user_input!='' and 0<=float(user_input)<=1:
values[key] = user_input
else:
values[key] = 0.5 # valeur par défaut
# autres cas
else:
if set(user_input).issubset(set('0123456789')) and user_input!='' and int(user_input)>0:
values[key] = user_input
else:
# vérifie si ce n'est pas 0 pour les places
if (key=='seats_input' or key=='stand_input') and user_input!='' and set(user_input)=={0}:
values[key] = user_input
# sinon, c'est que ce n'est pas bon !
else:
values[key] = 50 # valeur par défaut
# lance la simulation
clock(values)
def initialisation():
# initialise l'interface graphique
global app,fig,ax,graph,frame,canvas,line,launch_button
global parameters,text_to_display
# initialisation
if app is None:
app = tk.Tk()
# créer une figure
fig = Figure(figsize=(4,4))
# créer une sous-figure (notre graphique !)
ax = fig.add_subplot(111)
graph = FigureCanvasTkAgg(fig, master=app)
canvas = graph.get_tk_widget()
canvas.grid(row=0, column=0)
line = ax.plot([],[],'r.-')[0]
# créer un espace user-friendly
frame = tk.Frame(app)
frame.grid(row=0, column=1)
# construire les Label et les Entry
i=1
for key in parameters.keys():
if "label" in key: # c'est un Label
t = tk.Label(frame,text=text_to_display[key],font=('Arial',12),foreground='black')
t.grid(row=i,column=2)
parameters[key] = t # sauvegarde
if "input" in key: # c'est un Entry
t = tk.Entry(frame,relief='sunken',borderwidth=2,background='#282828',foreground='white')
t.grid(row=i,column=3)
i+=1
parameters[key] = t # sauvegarde
# construire le bouton
launch_button = tk.Button(frame,text="Lancer la simulation", font=('Arial',12),relief='raised',command=launch)
launch_button.grid(row=i,column=2)
# lance la boucle
app.mainloop()
# appel
initialisation()