summaryrefslogtreecommitdiff
path: root/gestion_donnees.py
diff options
context:
space:
mode:
Diffstat (limited to 'gestion_donnees.py')
-rw-r--r--gestion_donnees.py209
1 files changed, 151 insertions, 58 deletions
diff --git a/gestion_donnees.py b/gestion_donnees.py
index 6abcd51..3523e7e 100644
--- a/gestion_donnees.py
+++ b/gestion_donnees.py
@@ -4,6 +4,7 @@
4from configuration import CONFIG,DEFAUT 4from configuration import CONFIG,DEFAUT
5from gestion_erreurs import * 5from gestion_erreurs import *
6from gestion_couleurs import * 6from gestion_couleurs import *
7from gestion_unites import *
7import datetime 8import datetime
8import json 9import json
9import unidecode 10import unidecode
@@ -53,6 +54,7 @@ def convertit_jours_vers_python(chaine,liste_err):
53 agejours = 0 54 agejours = 0
54 return agejours 55 return agejours
55 56
57# python -> json
56def convertit_age_vers_texte(nombre): 58def convertit_age_vers_texte(nombre):
57 """ convertit un nombre de jours en un truc plus lisible en mois, années, jours 59 """ convertit un nombre de jours en un truc plus lisible en mois, années, jours
58 et renvoie une chaîne sous la forme 3a2m1j par exemple""" 60 et renvoie une chaîne sous la forme 3a2m1j par exemple"""
@@ -71,6 +73,16 @@ def convertit_age_vers_texte(nombre):
71 return chaine 73 return chaine
72########################## 74##########################
73 75
76# fonction qui calcule "auto" le maxi du graphique en fonction du max
77def calcule_max_graphique(l_jours):
78 """ calcule l'age maxi sur le graphique"""
79 if l_jours == []:
80 return CONFIG["jours_defaut_donneesvides"]
81 else:
82 jour_maxi = max(l_jours)# pas la peine d'aller très au delà du jour max
83 jour_maxi = int(jour_maxi* 1.1)+3 # on rajoute un peu
84 return jour_maxi
85
74 86
75def simplifie_nom(chaine): 87def simplifie_nom(chaine):
76 """ simplifie le nom chaine afin d'en faire une extension 88 """ simplifie le nom chaine afin d'en faire une extension
@@ -83,29 +95,27 @@ def simplifie_nom(chaine):
83 chaine2 = unidecode.unidecode(chaine2) 95 chaine2 = unidecode.unidecode(chaine2)
84 return chaine2[:15] 96 return chaine2[:15]
85 97
86def convertit_poids_vers_python(chaine,liste_err): 98def convertit_donnee_vers_python(chaine,typedonnee,liste_err):
87 """ convertit une chaine vers un float qui est le poids. 99 """ convertit une chaine vers un float qui est le type donnee voulu.
88 On gère notamment la virgule, et on enlève les espaces 100 La virgule peut être . ou , et on vire d'éventuels espaces.
89 Un poids invalide -> on renvoie 0 avec un warning""" 101 Taille invalide : on renvoie 0 avec un warning."""
90 chaine2 = chaine.replace(",",".") 102 chaine2 = chaine.replace(",",".")
91 chaine2 = chaine2.replace(" ","") 103 chaine2 = chaine2.replace(" ","")
92 104
93 try: 105 try:
94 poids = float(chaine2) 106 donnee = float(chaine2)
95 except: 107 except:
96 warning("Poids impossible à lire : "+chaine,liste_err) 108 warning(typedonnee+" impossible à lire : "+chaine,liste_err)
97 poids = 0 109 donnee = 0
98 if not( 0<=poids<CONFIG["poids_maxi"]): 110 if not( 0<=donnee<CONFIG[typedonnee+"_maxi"]):
99 warning("Poids incohérent : "+str(poids),liste_err) 111 warning(typedonnee+"incohérent(e) : "+str(donnee),liste_err)
100 poids = 0 112 donnee = 0
101 return poids 113 return donnee
102 114
103#def convertit_poids_vers_texte(poids):
104# """ convertit un poids vers du texte. Rien à dire là pour l'instant """
105# return str(poids)
106 115
107######################### 116#########################
108 117
118# web -> python
109def convertit_date_vers_python(chaine,liste_err): 119def convertit_date_vers_python(chaine,liste_err):
110 """ prend une chaine comme renvoyée par un champ de formulaire date 120 """ prend une chaine comme renvoyée par un champ de formulaire date
111 aaaa-mm-jj et en fait une date python 121 aaaa-mm-jj et en fait une date python
@@ -122,7 +132,8 @@ def convertit_date_vers_python(chaine,liste_err):
122 date = "" 132 date = ""
123 warning("Impossible de lire la date "+chaine+". Format accepté : aaaa-mm-jj",liste_err) 133 warning("Impossible de lire la date "+chaine+". Format accepté : aaaa-mm-jj",liste_err)
124 return date 134 return date
125 135
136# python -> json
126def convertit_date_vers_texte(date): 137def convertit_date_vers_texte(date):
127 """ convertit une date python en format texte aaaa-mm-jj""" 138 """ convertit une date python en format texte aaaa-mm-jj"""
128 if date == "": 139 if date == "":
@@ -142,8 +153,39 @@ def delta_date(date1,datenaissance):
142 return jours 153 return jours
143 154
144 155
156################### On regroupe tout ce qui gère les données en une fonction
157
158def web_vers_python(data,liste_err):
159 """ prend en argument le dictionnaire de requête et renvoie la config, et les
160 tableaux de donnée"""
161
162 # Régler la configuration
163 config = gere_configuration(data,liste_err)
164
165 # récupérer les données
166 listes_jours = {}
167 listes_donnees = {}
168 for typed in CONFIG["liste_typedonnees"]:
169 listes_jours[typed],listes_donnees[typed] = gere_donnees(data,config["naissance"],typed,liste_err)
170
171 # Si on a choisi la même échelle de données
172 if config["memechelle"] == "oui":
173 config["non_sauve"]["maxi"] = calcule_max_graphique([j for lj in listes_jours.values() for j in lj])
174 config["non_sauve"]["unite"] = choix_unite(config["non_sauve"]["maxi"])
175
176 return (config,listes_jours,listes_donnees)
177
178
179
145########### Fonctions qui gèretn les données 180########### Fonctions qui gèretn les données
146 181
182def gere_checkbox(chaine):
183 """ prend en arg une chaine, et renvoie "oui" si c'est "on" (sortie de la checkbox)
184 et chaîne vide si n'importe quoi d'autre"""
185 if chaine == "on":
186 return "oui"
187 else:
188 return ""
147 189
148def gere_configuration(data,liste_err): 190def gere_configuration(data,liste_err):
149 """ prend en argument le dictionnaire de requête (configuration imparfaite), et 191 """ prend en argument le dictionnaire de requête (configuration imparfaite), et
@@ -175,19 +217,20 @@ def gere_configuration(data,liste_err):
175 217
176 # unité 218 # unité
177 unite = data.get("unite","") 219 unite = data.get("unite","")
178
179 if not (unite in CONFIG["liste_unites"]): 220 if not (unite in CONFIG["liste_unites"]):
180 unite = "" 221 unite = ""
181 #warning("L'unité "+unite+" n'est pas reconnue !",liste_err) 222 #warning("L'unité "+unite+" n'est pas reconnue !",liste_err)
182 configuration["unite"] = unite 223 configuration["unite"] = unite
183 224
184 # grille 225 # grille
185 grille = data.get("grille","") 226 configuration["grille"] = gere_checkbox(data.get("grille",""))
186 if grille != "on": 227
187 configuration["grille"] = "" 228 # tracer ou non les courbes vides
188 else: 229 configuration["tracevide"] = gere_checkbox(data.get("tracevide",""))
189 configuration["grille"] = "oui"
190 230
231 # Même échelle sur tous les graphiques
232 configuration["memechelle"] = gere_checkbox(data.get("memechelle",""))
233
191 # maxi. 0 signifie qu'on veut pas de maxi 234 # maxi. 0 signifie qu'on veut pas de maxi
192 maxi = data.get("maxi","") 235 maxi = data.get("maxi","")
193 if maxi == "": 236 if maxi == "":
@@ -231,14 +274,7 @@ def gere_configuration(data,liste_err):
231 configuration["hauteur"] = hauteur 274 configuration["hauteur"] = hauteur
232 275
233 # existence et position de la légende 276 # existence et position de la légende
234 legende = data.get("legende","") 277 configuration["legende"] = gere_checkbox(data.get("legende",""))
235 if legende =="":
236 legende = "non"
237 elif legende=="on":
238 legende = "oui"
239 else:
240 legende = "oui"
241 configuration["legende"] = legende
242 278
243 positionlegende = data.get("positionlegende","") 279 positionlegende = data.get("positionlegende","")
244 if not(positionlegende in ['upper left','upper right','lower left','lower right']): 280 if not(positionlegende in ['upper left','upper right','lower left','lower right']):
@@ -252,26 +288,34 @@ def gere_configuration(data,liste_err):
252 coul = rgb_vers_tuple(data.get("couleur_"+clecouleur,""),CONFIG["couleurs"][clecouleur],liste_err) 288 coul = rgb_vers_tuple(data.get("couleur_"+clecouleur,""),CONFIG["couleurs"][clecouleur],liste_err)
253 configuration["couleurs"][clecouleur] = coul 289 configuration["couleurs"][clecouleur] = coul
254 290
291 # On y ajoute la partie "non sauvée" qui servira peut-être plus tard
292 configuration["non_sauve"] = {}
255 293
256 return configuration 294 return configuration
257 295
258 296
259def gere_donneespoids(data,naissance,liste_err): 297def gere_donnees(data,naissance,typedonnee,liste_err):
260 """ prend en argument le dictionnaire de requête, et la date de naissance 298 """ prend en argument le dictionnaire de requête, et la date de
261 (éventuellement vide) et construit les deux listes l_jours et l_poids""" 299 naissance (éventuellement vide), et construit deux listes :
262 300 l_jours et l_data correspondantes.
263 # On construit la liste des couples 301 Il faut donner en argument le type de données : voir
302 CONFIG["liste_typedonnees"]"""
303 if typedonnee not in CONFIG["liste_typedonnees"]:
304 warning("gere_donnees : le type de données : "+typedonnee+" est invalide !! Types acceptés : "+str(CONFIG["liste_typedonnees"]),liste_err)
305 return ([],[])
306
307 # On construit une liste de couples d'abord
264 liste_donnees = [] 308 liste_donnees = []
265 309
266 i = 0 310 i = 0
267 # On va chercher si y'a des données à poids_i 311 # On va chercher si y'a des données à donnee_i
268 while "poids_"+str(i) in data.keys(): 312 while typedonnee+"_"+str(i) in data.keys():
269 if data["poids_"+str(i)] != "": 313 if data[typedonnee+"_"+str(i)] != "":
270 poids = convertit_poids_vers_python(data["poids_"+str(i)],liste_err) 314 donnee = convertit_donnee_vers_python(data[typedonnee+"_"+str(i)],typedonnee,liste_err)
271 age = data.get("age_"+str(i),"") 315 age = data.get("age_"+str(i),"")
272 if age !="": 316 if age !="":
273 age = convertit_jours_vers_python(age,liste_err) 317 age = convertit_jours_vers_python(age,liste_err)
274 liste_donnees.append((age,poids)) 318 liste_donnees.append((age,donnee))
275 else: 319 else:
276 date = data.get("date_"+str(i),"") 320 date = data.get("date_"+str(i),"")
277 datep = convertit_date_vers_python(date,liste_err) 321 datep = convertit_date_vers_python(date,liste_err)
@@ -280,7 +324,7 @@ def gere_donneespoids(data,naissance,liste_err):
280 warning("La date de naissance n'a pas été précisée. Du coup on ne peut pas calculer l'âge de l'enfant le "+date,liste_err) 324 warning("La date de naissance n'a pas été précisée. Du coup on ne peut pas calculer l'âge de l'enfant le "+date,liste_err)
281 elif datep != "": # la date est valide et on a une date de naissance 325 elif datep != "": # la date est valide et on a une date de naissance
282 age = delta_date(datep,naissance) 326 age = delta_date(datep,naissance)
283 liste_donnees.append((age,poids)) 327 liste_donnees.append((age,donnee))
284 i+=1 328 i+=1
285 329
286 # Trier la liste 330 # Trier la liste
@@ -288,35 +332,77 @@ def gere_donneespoids(data,naissance,liste_err):
288 332
289 # splitter la liste 333 # splitter la liste
290 l_jours = [x[0] for x in liste_donnees] 334 l_jours = [x[0] for x in liste_donnees]
291 l_poids = [x[1] for x in liste_donnees] 335 l_donnee = [x[1] for x in liste_donnees]
292 336
293 return (l_jours,l_poids) 337 return (l_jours,l_donnee)
294 338
295 339
340#### export vers json
296 341
297 342def donnees_vers_json(l_jours,l_poids,l_jourst,l_taille,config):
298def donnees_vers_json(l_jours,l_poids,config):
299 """ retourne le json à renvoyer""" 343 """ retourne le json à renvoyer"""
300 gros_dico = copy.deepcopy(config) 344 gros_dico = copy.deepcopy(config)
301 l_jours2 = [convertit_age_vers_texte(d) for d in l_jours] 345 l_jours2 = [convertit_age_vers_texte(d) for d in l_jours]
346 l_jourst2 = [convertit_age_vers_texte(d) for d in l_jourst]
302 gros_dico["data_j"] = l_jours2 347 gros_dico["data_j"] = l_jours2
303 gros_dico["data_p"] = l_poids 348 gros_dico["data_p"] = l_poids
349 gros_dico["data_jours_taille"] = l_jourst2
350 gros_dico["data_taille"] = l_taille
304 # gérer la date de naissance 351 # gérer la date de naissance
305 if gros_dico.get("naissance","") != "": 352 if gros_dico.get("naissance","") != "":
306 gros_dico["naissance"] = convertit_date_vers_texte(gros_dico["naissance"]) 353 gros_dico["naissance"] = convertit_date_vers_texte(gros_dico["naissance"])
307 # gérer l'age maxi 354 # gérer l'age maxi
308 gros_dico["maxi"] = convertit_age_vers_texte(gros_dico["maxi"]) 355 gros_dico["maxi"] = convertit_age_vers_texte(gros_dico["maxi"])
309 # gérer les couleurs 356 # gérer les couleurs
310# for cle in ["couleur1", "couleur2", "couleur3", "couleur_fond","couleur_grille","couleur_cadretxt"]:
311# gros_dico[cle] = tuple_vers_rgb(gros_dico[cle])
312 for clecouleur in DEFAUT["couleurs"]: 357 for clecouleur in DEFAUT["couleurs"]:
313 gros_dico["couleurs"][clecouleur] = tuple_vers_rgb(gros_dico["couleurs"][clecouleur]) 358 gros_dico["couleurs"][clecouleur] = tuple_vers_rgb(gros_dico["couleurs"][clecouleur])
314 359
315 360 # Enlever ce qui ne se sauvegarde pas si y'a
361 if "non_sauve" in gros_dico:
362 del gros_dico["non_sauve"]
316 363
317 return json.dumps(gros_dico, indent=2,ensure_ascii=False ) 364 return json.dumps(gros_dico, indent=2,ensure_ascii=False )
318 365
366def fusionne_donnees(listes_jours,listes_donnees):
367 """ prend en argument deux dicos de listes. Chaque liste de jours est associée à une liste
368 de données (par la même clé de type de données). Il faut les fusionner pour avoir une liste de dictionnaires, de type
369 ("age":truc, "donnee1":truc, "donnee2":truc, ...) triée par ordre de jours. Si jamais une des données est vide,
370 le champ du dictionnaire n'est pas rempli"""
371# nb_donnees = len(listes_jours)
372 def fini(lj):
373 """ teste si les listes sont toutes vides """
374 for l in lj.values():
375 if l!=[]:
376 return False
377 return True
378
379 def mini(lj):
380 """ renvoie la clé de la liste où il y a le min """
381 cle_mini = CONFIG["liste_typedonnees"][0]
382 for (cle,liste) in lj.items():
383 if lj[cle_mini]== []:
384 cle_mini = cle
385 elif lj[cle] != []:
386 if convertit_jours_vers_python(lj[cle][0],[])<convertit_jours_vers_python(lj[cle_mini][0],[]):
387 cle_mini = cle
388 return cle_mini
389
390 liste_f = []
391 while not(fini(listes_jours)):
392 typedonnee = mini(listes_jours)
393 # On extrait les données dans les deux listes (jours et données)
394 jour = listes_jours[typedonnee].pop(0)
395 donnee = listes_donnees[typedonnee].pop(0)
396 if liste_f == [] or jour != liste_f[-1]["age"]: # Si le jour est un "nouveau" jour
397 liste_f.append({"age":jour})
398 # On met à jour l'élément
399 liste_f[-1][typedonnee] = donnee
400
401 return liste_f
402
319 403
404
405# Json -> formulaire HTML
320def fichier_json_vers_configdonnees(chaine,liste_err): 406def fichier_json_vers_configdonnees(chaine,liste_err):
321 """ prend le json importé (chaine) et l'exporte vers les valeurs du formulaire """ 407 """ prend le json importé (chaine) et l'exporte vers les valeurs du formulaire """
322 debug("json vers config : Prêt à interpréter le json",liste_err) 408 debug("json vers config : Prêt à interpréter le json",liste_err)
@@ -327,18 +413,25 @@ def fichier_json_vers_configdonnees(chaine,liste_err):
327 return {} 413 return {}
328 # Il faut maintenant récupérer les l_jours et l_poids puis les remettre 414 # Il faut maintenant récupérer les l_jours et l_poids puis les remettre
329 # sous forme de age_i et poids_i 415 # sous forme de age_i et poids_i
330 l_jours= valform.get("data_j",[]) 416
331 l_poids=valform.get("data_p",[]) 417 listes_jours = {}
332 if len(l_poids) != len(l_jours): 418 listes_donnees = {}
333 warning("Lecture du json : les données sont incohérentes (listes de taille différentes et/ou pb de lecture") 419 for typed in CONFIG["liste_typedonnees"]:
334 long = min(len(l_jours),len(l_poids)) 420 if typed == "poids": # pour la rétrocompatibilité
335 else: 421 listes_jours[typed] = valform.get("data_j",[])
336 long = len(l_jours) 422 listes_donnees[typed] = valform.get("data_p",[])
337 for i in range(long): 423 else:
338 valform["age_"+str(i)] = l_jours[i] 424 listes_jours[typed] = valform.get("data_jours_"+typed,[])
339 valform["poids_"+str(i)] = l_poids[i] 425 listes_donnees[typed] = valform.get("data_"+typed,[])
426
427 debug("Avant fusion : listes jours "+str(listes_jours),liste_err)
428 liste_donnees = fusionne_donnees(listes_jours,listes_donnees)
429 debug("Fusion de listes ok. Liste moche : "+str(liste_donnees),liste_err)
430 for i in range(len(liste_donnees)):
431 for (cle,val) in liste_donnees[i].items():
432 valform[cle+"_"+str(i)] = val
340 433
341 valform["nb_data"] = max(long +2,DEFAUT["nb_data"]) 434 valform["nb_data"] = max(len(liste_donnees) +2,DEFAUT["nb_data"])
342 435
343 return valform 436 return valform
344 437