sauvegarde des dates + version de l'app dans le fichier de sauvegarde
[perso/Denise/oms.git] / gestion_donnees.py
CommitLineData
5679dfd0
DL
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
d03279e7 4from configuration import CONFIG,DEFAUT
a680b2f7
DL
5from gestion_erreurs import debug, warning, erreur, initialise_erreurs
6from gestion_couleurs import rgb_vers_tuple, tuple_vers_rgb
7from gestion_unites import choix_unite
5679dfd0 8import datetime
be2bf515
DL
9import json
10import unidecode
915e90bb 11import copy
5679dfd0 12
61020126
DL
13### Les données "tournent" selon :
14### python -> json -> (export/import) -> formulaire HTML -> données POST -> python etc
5679dfd0
DL
15
16############ Fonctions de conversion
17
18def convertit_jours_vers_python(chaine,liste_err):
19 """ convertit une chaine de type 1a 3m 1s 10j en jours
be2bf515 20 Renvoie un nombre de jours en float
5679dfd0
DL
21 Si un des caractères n'est ni un nombre, ni une lettre "autorisée" ni une espace,
22 on affiche un warning et on ignore ce caractère
23 """
b5ac625b 24# debug("conversion de "+chaine+" vers un nb de jours",liste_err)
5679dfd0
DL
25 chainenombre = ""
26 agejours = 0.
27 for lettre in chaine:
28 if lettre.isdigit():
29 chainenombre += lettre
30 else:
31 if lettre == 'a' or lettre == 'A':
32 # On a trouvé l'année, on ajoute tout ce qui est trouvé jusque là
d03279e7 33 agejours += int(chainenombre)*CONFIG["jours_dans_annee"]
5679dfd0
DL
34 chainenombre = ""
35 elif lettre == 'm' or lettre == 'M':
36 # On a trouvé le mois
d03279e7 37 agejours += int(chainenombre)*CONFIG["jours_dans_mois"]
5679dfd0
DL
38 chainenombre = ""
39 elif lettre == 's' or lettre == 'S':
40 # la semaine
d03279e7 41 agejours += int(chainenombre)*CONFIG["jours_dans_semaine"]
5679dfd0
DL
42 chainenombre = ""
43 elif lettre == 'j' or lettre == 'J':
44 # On a trouvé le jour
45 agejours += int(chainenombre)
46 chainenombre = ""
47 elif lettre != ' ':
48 # autre caractère : bizarre ?
2dc9eb43 49 warning("problème à la conversion de "+chaine+". Caractère invalide : "+lettre,liste_err)
5679dfd0
DL
50 # à la fin s'il reste qqch on le garde dans les jours
51 if chainenombre != "":
be2bf515 52 agejours += int(chainenombre)
5679dfd0
DL
53 if agejours<0:
54 warning("L'âge est négatif !",liste_err)
55 agejours = 0
b5ac625b 56# debug("On a convertit ! Résultat : "+str(agejours),liste_err)
be2bf515 57 return agejours
5679dfd0 58
8b5845ff 59# python -> json
5679dfd0
DL
60def convertit_age_vers_texte(nombre):
61 """ convertit un nombre de jours en un truc plus lisible en mois, années, jours
62 et renvoie une chaîne sous la forme 3a2m1j par exemple"""
d03279e7
DL
63 annees = int(nombre / CONFIG["jours_dans_annee"])
64 restant = nombre - annees*CONFIG["jours_dans_annee"]
65 mois = int(restant/CONFIG["jours_dans_mois"])
66 jours= round(nombre - mois*CONFIG["jours_dans_mois"] - annees*CONFIG["jours_dans_annee"])
5679dfd0
DL
67
68 chaine = ""
69 if annees >0:
70 chaine += str(annees)+"a"
71 if mois >0:
72 chaine += str(mois)+"m"
73 if jours>0 or nombre ==0: # si c'est la naissance, faut beien écrire 0j quand même
74 chaine += str(jours)+"j"
75 return chaine
a680b2f7 76
5679dfd0 77##########################
be2bf515 78
8b5845ff
DL
79# fonction qui calcule "auto" le maxi du graphique en fonction du max
80def calcule_max_graphique(l_jours):
81 """ calcule l'age maxi sur le graphique"""
82 if l_jours == []:
83 return CONFIG["jours_defaut_donneesvides"]
84 else:
85 jour_maxi = max(l_jours)# pas la peine d'aller très au delà du jour max
c2fe511b 86 jour_maxi = int(jour_maxi* 1.2)+3 # on rajoute un peu
8b5845ff
DL
87 return jour_maxi
88
be2bf515
DL
89
90def simplifie_nom(chaine):
91 """ simplifie le nom chaine afin d'en faire une extension
92 pour le nom du fichier. Met tout en minuscules et vire les caractères spéciaux
93 et max 15 caractères"""
94 chaine2 = ""
95 for l in chaine:
96 if l.isalpha():
97 chaine2+=l
98 chaine2 = unidecode.unidecode(chaine2)
99 return chaine2[:15]
5679dfd0 100
8b5845ff
DL
101def convertit_donnee_vers_python(chaine,typedonnee,liste_err):
102 """ convertit une chaine vers un float qui est le type donnee voulu.
103 La virgule peut être . ou , et on vire d'éventuels espaces.
ca61f310
DL
104 Taille invalide : on renvoie 0 avec un warning.
105 Si la chaine est en fait déjà au format float, on laisse tel quel"""
106 if type(chaine) == float:
107 return chaine
5679dfd0
DL
108 chaine2 = chaine.replace(",",".")
109 chaine2 = chaine2.replace(" ","")
ca61f310 110
5679dfd0
DL
111
112 try:
8b5845ff 113 donnee = float(chaine2)
5679dfd0 114 except:
8b5845ff
DL
115 warning(typedonnee+" impossible à lire : "+chaine,liste_err)
116 donnee = 0
d9eaf2e2
DL
117
118 # Pour le poids, un cas particulier
119 if typedonnee == "poids" and donnee > CONFIG["poids_maxi_conversion"]:
120 donnee = donnee/1000 # conversion en grammes
8b5845ff 121 if not( 0<=donnee<CONFIG[typedonnee+"_maxi"]):
d9eaf2e2 122 warning(typedonnee+" incohérent(e) : "+str(donnee),liste_err)
8b5845ff
DL
123 donnee = 0
124 return donnee
5679dfd0 125
5679dfd0
DL
126
127#########################
128
8b5845ff 129# web -> python
5679dfd0
DL
130def convertit_date_vers_python(chaine,liste_err):
131 """ prend une chaine comme renvoyée par un champ de formulaire date
132 aaaa-mm-jj et en fait une date python
133 renvoie "" si ne marche pas"""
134 liste = chaine.split("-")
135 if len(liste) != 3:
136 warning("La date : "+chaine+" est invalide !",liste_err)
137 return ""
138 else:
30158504 139 debug("Conversion de la date "+chaine+". Découpage : "+str(liste),liste_err)
9cb3c31c
DL
140 try:
141 date = datetime.date(int(liste[0]),int(liste[1]),int(liste[2]))
142 except:
143 date = ""
30158504 144 warning("Impossible de lire la date "+chaine+". Format accepté : aaaa-mm-jj",liste_err)
9cb3c31c 145 return date
8b5845ff
DL
146
147# python -> json
5679dfd0
DL
148def convertit_date_vers_texte(date):
149 """ convertit une date python en format texte aaaa-mm-jj"""
150 if date == "":
151 return ""
152 else:
2dc9eb43
DL
153 #return (str(date.year)+"-"+str(date.month)+"-"+str(date.day))
154 return str(date)
5679dfd0
DL
155
156def delta_date(date1,datenaissance):
157 """ renvoie le nombre de jours (entier) entre date1 et datenaissance format "datetime"
158 datenaissance est supposée antérieure. Erreur sinon."""
159 d = date1 - datenaissance
160 jours = d.days
161 if jours<0:
a680b2f7 162 warning("La différence entre les dates est négative... :/")
5679dfd0
DL
163 return -1
164 return jours
165
166
2dc9eb43 167
8b5845ff
DL
168################### On regroupe tout ce qui gère les données en une fonction
169
ca61f310 170def web_vers_python(data,liste_err, court=False):
8b5845ff 171 """ prend en argument le dictionnaire de requête et renvoie la config, et les
ca61f310
DL
172 tableaux de donnée
173 court : si True est précisé, on ne met que le nom dans la config (enfant
174 additionnel)"""
8b5845ff
DL
175
176 # Régler la configuration
ca61f310 177 config = gere_configuration(data,liste_err, court)
8b5845ff
DL
178
179 # récupérer les données
180 listes_jours = {}
181 listes_donnees = {}
182 for typed in CONFIG["liste_typedonnees"]:
183 listes_jours[typed],listes_donnees[typed] = gere_donnees(data,config["naissance"],typed,liste_err)
184
438ef56d
DL
185 # Si on veut extrapoler au-delà du jour maxi, on adapte
186
8b5845ff 187 # Si on a choisi la même échelle de données
ca61f310 188 if config.get("memechelle") == "oui":
8b5845ff 189 config["non_sauve"]["maxi"] = calcule_max_graphique([j for lj in listes_jours.values() for j in lj])
438ef56d
DL
190 # En cas d'extrapolation, on prend le maxi
191 if config["non_sauve"]["calculextradata_type"] !="" and config["non_sauve"]["calculextradata_age"]>config["non_sauve"]["maxi"]:
192 config["non_sauve"]["maxi"] = int(config["non_sauve"]["calculextradata_age"]) +1
8b5845ff
DL
193 config["non_sauve"]["unite"] = choix_unite(config["non_sauve"]["maxi"])
194
195 return (config,listes_jours,listes_donnees)
196
197
198
a680b2f7 199########### Fonctions qui gèretn les données web vers python
5679dfd0 200
8b5845ff
DL
201def gere_checkbox(chaine):
202 """ prend en arg une chaine, et renvoie "oui" si c'est "on" (sortie de la checkbox)
203 et chaîne vide si n'importe quoi d'autre"""
204 if chaine == "on":
205 return "oui"
206 else:
207 return ""
5679dfd0 208
ca61f310
DL
209def gere_symbole(chaine):
210 """ prend en arg une chaîne genre "o", ">" et vérifie si c'est un symbole valide.
211 Renvoie ce symbole-là ou le défaut"""
212 if chaine in CONFIG["liste_symboles"]:
213 return chaine
214 else:
215 return DEFAUT["symbole"]
216
217def gere_configuration(data,liste_err, court=False):
be2bf515 218 """ prend en argument le dictionnaire de requête (configuration imparfaite), et
5679dfd0 219 construit le dictionnaire de configuration qui va bien.
ca61f310
DL
220 Vérifie que chaque entrée est cohérente évidemment.
221 court : si mis à True, on ne met que le nom dans la configuraion,
222 ainsi que la date de naissance et le sexe"""
a680b2f7 223 # Initialisation
685a5f75 224 configuration = {"non_sauve": {}}
5679dfd0
DL
225
226 # Pour le nom, osef qu'il soit vide
227 nom = data.get("nom","")
228 # Par contre s'il est trop long on le tronque
d03279e7 229 configuration["nom"] = nom[:CONFIG["longueur_max_nom_bebe"]]
ca61f310 230
5679dfd0
DL
231 naissance = data.get("naissance","")
232 if naissance !="":
233 naissance = convertit_date_vers_python(naissance,liste_err)
234 configuration["naissance"] = naissance
235
ca61f310
DL
236 sexe = data.get("sexe","")
237 if not (sexe in ["F","M","N"]):
238 warning("Le sexe de l'enfant est invalide ! "+sexe,liste_err)
239 sexe = "N"
240 configuration["sexe"] = sexe
241
242 if not(court):
243
244 prematurite = data.get("prematurite","")
245 j = convertit_jours_vers_python(prematurite,liste_err)
246 configuration["prematurite"] = convertit_age_vers_texte(j)
5679dfd0 247
ca61f310
DL
248 configuration["agecorrige"] = gere_checkbox(data.get("agecorrige",""))
249
250 # Type de courbe. Au pire on met P
251 tyc = data.get("typecourbe","")
252 if not (tyc in ["P","Z"]):
253 tyc = "P"
254 configuration["typecourbe"] = tyc
255
256 # unité
257 unite = data.get("unite","")
258 if not (unite in CONFIG["liste_unites"]):
259 unite = ""
260 #warning("L'unité "+unite+" n'est pas reconnue !",liste_err)
261 configuration["unite"] = unite
262
263 # grille
264 configuration["grille"] = gere_checkbox(data.get("grille",""))
265
266 # tracer ou non les courbes vides
267 configuration["tracevide"] = gere_checkbox(data.get("tracevide",""))
268
269 # Même échelle sur tous les graphiques
270 configuration["memechelle"] = gere_checkbox(data.get("memechelle",""))
5679dfd0 271
ca61f310
DL
272
273 # maxi. 0 signifie qu'on veut pas de maxi
274 maxi = data.get("maxi","")
275 if maxi == "":
276 configuration["maxi"] = 0
277 else:
278 configuration["maxi"] = int(convertit_jours_vers_python(maxi,liste_err))
279
280 # dimensions du graphique
281 largeur = data.get("largeur","")
282 if largeur == "":
915e90bb 283 largeur = DEFAUT["largeur_graphique"]
ca61f310
DL
284 else:
285 try:
286 largeur = int(largeur)
287 except:
288 warning("La largeur "+largeur+"est invalide !",liste_err)
289 largeur = DEFAUT["largeur_graphique"]
290 if largeur > CONFIG["largeur_graphique_max"]:
291 largeur = CONFIG["largeur_graphique_max"]
292 warning("Largeur du graphique trop grande !",liste_err)
293 elif largeur < CONFIG["largeur_graphique_min"]:
294 largeur = CONFIG["largeur_graphique_min"]
295 warning("Largeur du graphique trop petite !",liste_err)
296 configuration["largeur"] = largeur
297
298 hauteur = data.get("hauteur","")
299 if hauteur == "":
915e90bb 300 hauteur = DEFAUT["hauteur_graphique"]
ca61f310
DL
301 else:
302 try:
303 hauteur = int(hauteur)
304 except:
305 warning("La hauteur "+hauteur+"est invalide !",liste_err)
306 hauteur = DEFAUT["hauteur_graphique"]
307 if hauteur > CONFIG["hauteur_graphique_max"]:
308 hauteur = CONFIG["hauteur_graphique_max"]
309 warning("Hauteur du graphique trop grande !",liste_err)
310 elif hauteur < CONFIG["hauteur_graphique_min"]:
311 hauteur = CONFIG["hauteur_graphique_min"]
312 warning("Hauteur du graphique trop petite !",liste_err)
313 configuration["hauteur"] = hauteur
314
315 # existence et position de la légende
316 configuration["legende"] = gere_checkbox(data.get("legende",""))
317
318 positionlegende = data.get("positionlegende","")
319 if not(positionlegende in ['upper left','upper right','lower left','lower right']):
320 positionlegende = "upper left"
321 configuration["positionlegende"] = positionlegende
322
323 configuration["couleurs"] = {}
324 # gérer les couleurs
325 for clecouleur in DEFAUT["couleurs"]:
38b5e10a 326 coul = rgb_vers_tuple(data.get("couleur_"+clecouleur,""),DEFAUT["couleurs"].get(clecouleur, ""),liste_err)
ca61f310
DL
327 configuration["couleurs"][clecouleur] = coul
328
329 # symbole
330 configuration["symbole"] = gere_symbole( data.get("symbole", ""))
fd69b6b5 331
ca61f310 332 configuration["non_sauve"]["grilleamelio"] = gere_checkbox(data.get("grilleamelio",""))
cf0d4c8c 333
cf0d4c8c 334
ca61f310
DL
335 #### La partie extrapolation n'a pas besoin d'être sauvée
336 configuration["non_sauve"]["prolongercourbes"] = gere_checkbox(data.get("prolongercourbes",""))
fd69b6b5 337
ca61f310
DL
338 # Valeur par défaut : 1
339 debug(data.get("nbextradata", "aaargh"), liste_err)
340 nbextradata = data.get("nbextradata",1)
341 try:
342 nbextradata = int(nbextradata)
343 except:
344 warning("Le nombre de données sur lequel on extrapole est invalide : "+nbextradata, liste_err)
345 nbextradata = 1
346 configuration["non_sauve"]["nbextradata"] = nbextradata
347
348 if data.get("calculextradata_type","") in CONFIG["liste_typedonnees"]:
349 configuration["non_sauve"]["calculextradata_type"] = data.get("calculextradata_type","")
350 configuration["non_sauve"]["calculextradata_age"] = convertit_jours_vers_python(data.get("calculextradata_age","0j"),liste_err)
351 else:
352 configuration["non_sauve"]["calculextradata_type"] = ""
353 # On ne met rien dans l'âge, pas la peine
354
355 ctyped = data.get("calculextratemps_type","")
356 if ctyped in CONFIG["liste_typedonnees"]:
357 configuration["non_sauve"]["calculextratemps_type"] = ctyped
358 configuration["non_sauve"]["calculextratemps_val"] = convertit_donnee_vers_python(data.get("calculextratemps_val",""), ctyped, liste_err)
359 else:
360 configuration["non_sauve"]["calculextratemps_type"] = ""
361
362 # Tracer les calculs sur la grille
363 configuration["non_sauve"]["calculextradata_trace"] = gere_checkbox(data.get("calculextradata_trace"))
364 configuration["non_sauve"]["calculextratemps_trace"] = gere_checkbox(data.get("calculextratemps_trace"))
3d7da80a
DL
365
366
5679dfd0 367 return configuration
5679dfd0 368
cf0d4c8c
DL
369
370
a680b2f7 371## web vers python : données
8b5845ff
DL
372def gere_donnees(data,naissance,typedonnee,liste_err):
373 """ prend en argument le dictionnaire de requête, et la date de
374 naissance (éventuellement vide), et construit deux listes :
375 l_jours et l_data correspondantes.
376 Il faut donner en argument le type de données : voir
377 CONFIG["liste_typedonnees"]"""
378 if typedonnee not in CONFIG["liste_typedonnees"]:
379 warning("gere_donnees : le type de données : "+typedonnee+" est invalide !! Types acceptés : "+str(CONFIG["liste_typedonnees"]),liste_err)
380 return ([],[])
381
382 # On construit une liste de couples d'abord
5679dfd0
DL
383 liste_donnees = []
384
385 i = 0
8b5845ff
DL
386 # On va chercher si y'a des données à donnee_i
387 while typedonnee+"_"+str(i) in data.keys():
388 if data[typedonnee+"_"+str(i)] != "":
389 donnee = convertit_donnee_vers_python(data[typedonnee+"_"+str(i)],typedonnee,liste_err)
5679dfd0
DL
390 age = data.get("age_"+str(i),"")
391 if age !="":
392 age = convertit_jours_vers_python(age,liste_err)
8b5845ff 393 liste_donnees.append((age,donnee))
5679dfd0
DL
394 else:
395 date = data.get("date_"+str(i),"")
396 datep = convertit_date_vers_python(date,liste_err)
397 # on vérifie la date
398 if naissance == "":
399 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)
400 elif datep != "": # la date est valide et on a une date de naissance
401 age = delta_date(datep,naissance)
8b5845ff 402 liste_donnees.append((age,donnee))
5679dfd0
DL
403 i+=1
404
405 # Trier la liste
406 liste_donnees.sort(key=lambda x : x[0])
407
408 # splitter la liste
409 l_jours = [x[0] for x in liste_donnees]
8b5845ff 410 l_donnee = [x[1] for x in liste_donnees]
5679dfd0 411
8b5845ff 412 return (l_jours,l_donnee)
be2bf515
DL
413
414
a680b2f7 415# python vers Json
8b5845ff 416#### export vers json
be2bf515 417
8b5845ff 418def donnees_vers_json(l_jours,l_poids,l_jourst,l_taille,config):
be2bf515 419 """ retourne le json à renvoyer"""
915e90bb 420 gros_dico = copy.deepcopy(config)
2dc9eb43 421 gros_dico["version"] = CONFIG["version"]
be2bf515 422 l_jours2 = [convertit_age_vers_texte(d) for d in l_jours]
8b5845ff 423 l_jourst2 = [convertit_age_vers_texte(d) for d in l_jourst]
be2bf515
DL
424 gros_dico["data_j"] = l_jours2
425 gros_dico["data_p"] = l_poids
8b5845ff
DL
426 gros_dico["data_jours_taille"] = l_jourst2
427 gros_dico["data_taille"] = l_taille
be2bf515
DL
428 # gérer la date de naissance
429 if gros_dico.get("naissance","") != "":
430 gros_dico["naissance"] = convertit_date_vers_texte(gros_dico["naissance"])
2dc9eb43
DL
431 # Calcul de toutes les dates de données
432 l_dates_poids = [convertit_date_vers_texte( config["naissance"] + datetime.timedelta(days=jours) ) for jours in l_jours]
433 l_dates_taille = [convertit_date_vers_texte( config["naissance"] + datetime.timedelta(days=jours) ) for jours in l_jourst]
434 gros_dico["data_dates_poids"]= l_dates_poids
435 gros_dico["data_dates_taille"] = l_dates_taille
436
437
be2bf515
DL
438 # gérer l'age maxi
439 gros_dico["maxi"] = convertit_age_vers_texte(gros_dico["maxi"])
fd69b6b5 440 # gérer les couleurs
915e90bb
DL
441 for clecouleur in DEFAUT["couleurs"]:
442 gros_dico["couleurs"][clecouleur] = tuple_vers_rgb(gros_dico["couleurs"][clecouleur])
fd69b6b5 443
8b5845ff
DL
444 # Enlever ce qui ne se sauvegarde pas si y'a
445 if "non_sauve" in gros_dico:
446 del gros_dico["non_sauve"]
5679dfd0 447
be2bf515 448 return json.dumps(gros_dico, indent=2,ensure_ascii=False )
5679dfd0 449
2dc9eb43 450def fusionne_donnees(listes_jours,listes_donnees, listes_dates):
8b5845ff
DL
451 """ prend en argument deux dicos de listes. Chaque liste de jours est associée à une liste
452 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
2dc9eb43
DL
453 {"age":truc, "donnee1":truc, "donnee2":truc, ...} triée par ordre de jours. Si jamais une des données est vide,
454 le champ du dictionnaire n'est pas rempli
455 Le troisième paquet de listes (les dates) peut être vide ou bien simiaire : même clés."""
a680b2f7 456
8b5845ff
DL
457 def fini(lj):
458 """ teste si les listes sont toutes vides """
459 for l in lj.values():
460 if l!=[]:
461 return False
462 return True
463
464 def mini(lj):
465 """ renvoie la clé de la liste où il y a le min """
466 cle_mini = CONFIG["liste_typedonnees"][0]
467 for (cle,liste) in lj.items():
468 if lj[cle_mini]== []:
469 cle_mini = cle
470 elif lj[cle] != []:
b5ac625b 471 if convertit_jours_vers_python(lj[cle][0],initialise_erreurs())<convertit_jours_vers_python(lj[cle_mini][0],initialise_erreurs()):
8b5845ff
DL
472 cle_mini = cle
473 return cle_mini
474
475 liste_f = []
476 while not(fini(listes_jours)):
477 typedonnee = mini(listes_jours)
478 # On extrait les données dans les deux listes (jours et données)
479 jour = listes_jours[typedonnee].pop(0)
480 donnee = listes_donnees[typedonnee].pop(0)
2dc9eb43 481
8b5845ff
DL
482 if liste_f == [] or jour != liste_f[-1]["age"]: # Si le jour est un "nouveau" jour
483 liste_f.append({"age":jour})
2dc9eb43 484 # On met à jour l'élément (ou on l'ajoute)
8b5845ff
DL
485 liste_f[-1][typedonnee] = donnee
486
2dc9eb43
DL
487 # Si il y a une date associée, on la met !
488 if listes_dates[typedonnee] != []:
489 date = listes_dates[typedonnee].pop(0)
490 liste_f[-1]["date"] = convertit_date_vers_texte(date)
491
492
8b5845ff
DL
493 return liste_f
494
5679dfd0 495
a680b2f7 496### COnversion json vers formulaire
8b5845ff 497# Json -> formulaire HTML
d03279e7 498def fichier_json_vers_configdonnees(chaine,liste_err):
a680b2f7
DL
499 """ prend le json importé (chaine) et l'exporte vers les valeurs du formulaire
500 Renvoyé sous forme de dictionnaire (mais adapté au formulaire web)"""
d03279e7
DL
501 debug("json vers config : Prêt à interpréter le json",liste_err)
502 try:
503 valform = json.loads(chaine)
504 except :
505 erreur("Impossible de lire le fichier json !",liste_err)
506 return {}
be2bf515
DL
507 # Il faut maintenant récupérer les l_jours et l_poids puis les remettre
508 # sous forme de age_i et poids_i
8b5845ff
DL
509
510 listes_jours = {}
511 listes_donnees = {}
2dc9eb43 512 listes_dates = {}
8b5845ff
DL
513 for typed in CONFIG["liste_typedonnees"]:
514 if typed == "poids": # pour la rétrocompatibilité
515 listes_jours[typed] = valform.get("data_j",[])
516 listes_donnees[typed] = valform.get("data_p",[])
2dc9eb43 517 listes_dates[typed] = valform.get("data_dates_"+typed,[])
8b5845ff
DL
518 else:
519 listes_jours[typed] = valform.get("data_jours_"+typed,[])
520 listes_donnees[typed] = valform.get("data_"+typed,[])
2dc9eb43
DL
521 listes_dates[typed] = valform.get("data_dates_"+typed,[])
522
8b5845ff
DL
523
524 debug("Avant fusion : listes jours "+str(listes_jours),liste_err)
2dc9eb43 525 liste_donnees = fusionne_donnees(listes_jours,listes_donnees, listes_dates)
8b5845ff
DL
526 debug("Fusion de listes ok. Liste moche : "+str(liste_donnees),liste_err)
527 for i in range(len(liste_donnees)):
528 for (cle,val) in liste_donnees[i].items():
529 valform[cle+"_"+str(i)] = val
be2bf515 530
8b5845ff 531 valform["nb_data"] = max(len(liste_donnees) +2,DEFAUT["nb_data"])
5679dfd0 532
be2bf515 533 return valform
5679dfd0 534
5679dfd0 535
ca61f310
DL
536
537#### Pour l'insertion d'une 2e (ou plus) courbe sur le graphique, ue fonction qui sépare tout ça
38b5e10a 538def eclate_donnees_additionnelles(conf, ljours, ldonnees, symb, couleur):
ca61f310
DL
539 """ conf est la config (on ne garde que le nom) pour un enfant additionnel,
540 ljours et ldonnees les dictionnaires de listes contenant les données.
541 symb est le symbole choisi pour cette courbe additionnelle (déjà vérifié)
542 On fabrique un joli dictionnaire typed -> (conf lj, ldonnee) avec le nom de l'enfant,
543 et les données pour chaque typed"""
544
545 retour = {}
546 conf["symbole"] = symb # On ajoute le symbole additionnel
38b5e10a 547 conf["couleurcourbe"] = couleur # la couleur
ca61f310
DL
548 for typed in CONFIG["liste_typedonnees"]:
549 retour[typed] = (conf, ljours[typed], ldonnees[typed])
550
551 return retour