2 # -*- coding: utf-8 -*-
4 from configuration
import CONFIG
,DEFAUT
5 from gestion_erreurs
import debug
, warning
, erreur
, initialise_erreurs
6 from gestion_couleurs
import rgb_vers_tuple
, tuple_vers_rgb
7 from gestion_unites
import choix_unite
13 ### Les données "tournent" selon :
14 ### python -> json -> (export/import) -> formulaire HTML -> données POST -> python etc
16 ############ Fonctions de conversion
18 def convertit_jours_vers_python(chaine
,liste_err
):
19 """ convertit une chaine de type 1a 3m 1s 10j en jours
20 Renvoie un nombre de jours en float
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
24 # debug("conversion de "+chaine+" vers un nb de jours",liste_err)
29 chainenombre
+= lettre
31 if lettre
== 'a' or lettre
== 'A':
32 # On a trouvé l'année, on ajoute tout ce qui est trouvé jusque là
33 agejours
+= int(chainenombre
)*CONFIG
["jours_dans_annee"]
35 elif lettre
== 'm' or lettre
== 'M':
37 agejours
+= int(chainenombre
)*CONFIG
["jours_dans_mois"]
39 elif lettre
== 's' or lettre
== 'S':
41 agejours
+= int(chainenombre
)*CONFIG
["jours_dans_semaine"]
43 elif lettre
== 'j' or lettre
== 'J':
45 agejours
+= int(chainenombre
)
48 # autre caractère : bizarre ?
49 warning("problème à la conversion de "+chaine
+". Caractère invalide : "+lettre
,liste_err
)
50 # à la fin s'il reste qqch on le garde dans les jours
51 if chainenombre
!= "":
52 agejours
+= int(chainenombre
)
54 warning("L'âge est négatif !",liste_err
)
56 # debug("On a convertit ! Résultat : "+str(agejours),liste_err)
60 def 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"""
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 #print("mois : ",mois, ", restant : ",nombre - mois*CONFIG["jours_dans_mois"])
67 jours
= round(nombre
- mois
*CONFIG
["jours_dans_mois"] - annees
*CONFIG
["jours_dans_annee"])
71 chaine
+= str(annees
)+"a"
73 chaine
+= str(mois
)+"m"
74 if jours
>0 or nombre
==0: # si c'est la naissance, faut bien écrire 0j quand même
75 chaine
+= str(jours
)+"j"
78 ##########################
80 # fonction qui calcule "auto" le maxi du graphique en fonction du max
81 def calcule_max_graphique(l_jours
):
82 """ calcule l'age maxi sur le graphique"""
84 return CONFIG
["jours_defaut_donneesvides"]
86 jour_maxi
= max(l_jours
)# pas la peine d'aller très au delà du jour max
87 jour_maxi
= int(jour_maxi
* 1.2)+3 # on rajoute un peu
91 def simplifie_nom(chaine
):
92 """ simplifie le nom chaine afin d'en faire une extension
93 pour le nom du fichier. Vire les caractères spéciaux
94 et max 15 caractères"""
99 chaine2
= unidecode
.unidecode(chaine2
)
102 def convertit_donnee_vers_python(chaine
,typedonnee
,liste_err
):
103 """ convertit une chaine vers un float qui est le type donnee voulu.
104 La virgule peut être . ou , et on vire d'éventuels espaces.
105 Taille invalide : on renvoie 0 avec un warning.
106 Si la chaine est en fait déjà au format float, on laisse tel quel"""
107 if type(chaine
) == float:
109 chaine2
= chaine
.replace(",",".")
110 chaine2
= chaine2
.replace(" ","")
114 donnee
= float(chaine2
)
116 warning(typedonnee
+" impossible à lire : "+chaine
,liste_err
)
119 # Pour le poids, un cas particulier
120 if typedonnee
== "poids" and donnee
> CONFIG
["poids_maxi_conversion"]:
121 donnee
= donnee
/1000 # conversion en grammes
122 if not( 0<=donnee
<CONFIG
[typedonnee
+"_maxi"]):
123 warning(typedonnee
+" incohérent(e) : "+str(donnee
),liste_err
)
128 #########################
131 def convertit_date_vers_python(chaine
,liste_err
):
132 """ prend une chaine comme renvoyée par un champ de formulaire date
133 aaaa-mm-jj et en fait une date python
134 renvoie "" si ne marche pas.
135 Si jamais la date est au format avec des / ça devrait passer aussi."""
137 liste
= chaine
.split("/")
139 liste
= chaine
.split("-")
141 warning("La date : "+chaine
+" est invalide !",liste_err
)
146 debug("Conversion de la date "+chaine
+". Découpage : "+str(liste
),liste_err
)
148 date
= datetime
.date(int(liste
[0]),int(liste
[1]),int(liste
[2]))
151 warning("Impossible de lire la date "+chaine
+". Format accepté : aaaa-mm-jj ou aaaa/mm/jj",liste_err
)
155 def convertit_date_vers_texte(date
):
156 """ convertit une date python en format texte aaaa-mm-jj"""
160 #return (str(date.year)+"-"+str(date.month)+"-"+str(date.day))
163 def delta_date(date1
,datenaissance
, liste_err
):
164 """ renvoie le nombre de jours (entier) entre date1 et datenaissance format "datetime"
165 datenaissance est supposée antérieure. Erreur sinon."""
166 if type(date1
) != datetime
.date
or type(datenaissance
) != datetime
.date
:
168 d
= date1
- datenaissance
171 warning("Une des dates saisies ("+str(date1
)+") est inférieure à la date de naissance (la donnée est donc ignorée)", liste_err
)
177 ################### On regroupe tout ce qui gère les données en une fonction
179 def web_vers_python(data
,liste_err
, court
=False):
180 """ prend en argument le dictionnaire de requête et renvoie la config, et les
182 court : si True est précisé, on ne met que le nom dans la config (enfant
185 # Régler la configuration
186 config
= gere_configuration(data
,liste_err
, court
)
188 # récupérer les données
191 for typed
in CONFIG
["liste_typedonnees"]:
192 listes_jours
[typed
],listes_donnees
[typed
] = gere_donnees(data
,config
["naissance"],typed
,liste_err
)
194 # Si on veut extrapoler au-delà du jour maxi, on adapte
196 # Si on a choisi la même échelle de données
197 if config
.get("memechelle") == "oui":
198 config
["non_sauve"]["maxi"] = calcule_max_graphique([j
for lj
in listes_jours
.values() for j
in lj
])
199 # En cas d'extrapolation, on prend le maxi
200 if config
["non_sauve"]["calculextradata_type"] !="" and config
["non_sauve"]["calculextradata_age"]>config
["non_sauve"]["maxi"]:
201 config
["non_sauve"]["maxi"] = int(config
["non_sauve"]["calculextradata_age"]) +1
202 config
["non_sauve"]["unite"] = choix_unite(config
["non_sauve"]["maxi"])
204 return (config
,listes_jours
,listes_donnees
)
208 ########### Fonctions qui gèretn les données web vers python
210 def gere_checkbox(chaine
):
211 """ prend en arg une chaine, et renvoie "oui" si c'est "on" (sortie de la checkbox)
212 et chaîne vide si n'importe quoi d'autre"""
218 def gere_symbole(chaine
):
219 """ prend en arg une chaîne genre "o", ">" et vérifie si c'est un symbole valide.
220 Renvoie ce symbole-là ou le défaut"""
221 if chaine
in CONFIG
["liste_symboles"]:
224 return DEFAUT
["symbole"]
226 def gere_configuration(data
,liste_err
, court
=False):
227 """ prend en argument le dictionnaire de requête (configuration imparfaite), et
228 construit le dictionnaire de configuration qui va bien.
229 Vérifie que chaque entrée est cohérente évidemment.
230 court : si mis à True, on ne met que le nom dans la configuraion,
231 ainsi que la date de naissance et le sexe"""
233 configuration
= {"non_sauve": {}
}
235 # Pour le nom, osef qu'il soit vide
236 nom
= data
.get("nom","")
237 # Par contre s'il est trop long on le tronque
238 configuration
["nom"] = nom
[:CONFIG
["longueur_max_nom_bebe"]]
240 naissance
= data
.get("naissance","")
242 naissance
= convertit_date_vers_python(naissance
,liste_err
)
243 configuration
["naissance"] = naissance
245 sexe
= data
.get("sexe","")
246 if not (sexe
in ["F","M","N"]):
247 warning("Le sexe de l'enfant est invalide. "+sexe
,liste_err
)
249 configuration
["sexe"] = sexe
253 prematurite
= data
.get("prematurite","")
254 j
= convertit_jours_vers_python(prematurite
,liste_err
)
255 configuration
["prematurite"] = convertit_age_vers_texte(j
)
257 configuration
["agecorrige"] = gere_checkbox(data
.get("agecorrige",""))
259 # Type de courbe. Au pire on met P
260 tyc
= data
.get("typecourbe","")
261 if not (tyc
in ["P","Z"]):
263 configuration
["typecourbe"] = tyc
266 unite
= data
.get("unite","")
267 if not (unite
in CONFIG
["liste_unites"]):
269 #warning("L'unité "+unite+" n'est pas reconnue !",liste_err)
270 configuration
["unite"] = unite
273 configuration
["grille"] = gere_checkbox(data
.get("grille",""))
275 # tracer ou non les courbes vides
276 configuration
["tracevide"] = gere_checkbox(data
.get("tracevide",""))
278 # Même échelle sur tous les graphiques
279 configuration
["memechelle"] = gere_checkbox(data
.get("memechelle",""))
282 # maxi. 0 signifie qu'on veut pas de maxi
283 maxi
= data
.get("maxi","")
285 configuration
["maxi"] = 0
287 configuration
["maxi"] = int(convertit_jours_vers_python(maxi
,liste_err
))
289 # dimensions du graphique
290 largeur
= data
.get("largeur","")
292 largeur
= DEFAUT
["largeur_graphique"]
295 largeur
= int(largeur
)
297 warning("La largeur "+largeur
+"est invalide !",liste_err
)
298 largeur
= DEFAUT
["largeur_graphique"]
299 if largeur
> CONFIG
["largeur_graphique_max"]:
300 largeur
= CONFIG
["largeur_graphique_max"]
301 warning("Largeur du graphique trop grande !",liste_err
)
302 elif largeur
< CONFIG
["largeur_graphique_min"]:
303 largeur
= CONFIG
["largeur_graphique_min"]
304 warning("Largeur du graphique trop petite !",liste_err
)
305 configuration
["largeur"] = largeur
307 hauteur
= data
.get("hauteur","")
309 hauteur
= DEFAUT
["hauteur_graphique"]
312 hauteur
= int(hauteur
)
314 warning("La hauteur "+hauteur
+"est invalide !",liste_err
)
315 hauteur
= DEFAUT
["hauteur_graphique"]
316 if hauteur
> CONFIG
["hauteur_graphique_max"]:
317 hauteur
= CONFIG
["hauteur_graphique_max"]
318 warning("Hauteur du graphique trop grande !",liste_err
)
319 elif hauteur
< CONFIG
["hauteur_graphique_min"]:
320 hauteur
= CONFIG
["hauteur_graphique_min"]
321 warning("Hauteur du graphique trop petite !",liste_err
)
322 configuration
["hauteur"] = hauteur
324 # existence et position de la légende
325 configuration
["legende"] = gere_checkbox(data
.get("legende",""))
327 positionlegende
= data
.get("positionlegende","")
328 if not(positionlegende
in ['upper left','upper right','lower left','lower right']):
329 positionlegende
= "upper left"
330 configuration
["positionlegende"] = positionlegende
332 configuration
["couleurs"] = {}
334 for clecouleur
in DEFAUT
["couleurs"]:
335 coul
= rgb_vers_tuple(data
.get("couleur_"+clecouleur
,""),DEFAUT
["couleurs"].get(clecouleur
, ""),liste_err
)
336 configuration
["couleurs"][clecouleur
] = coul
339 configuration
["symbole"] = gere_symbole( data
.get("symbole", ""))
341 configuration
["non_sauve"]["grilleamelio"] = gere_checkbox(data
.get("grilleamelio",""))
344 #### La partie extrapolation n'a pas besoin d'être sauvée
345 configuration
["non_sauve"]["prolongercourbes"] = gere_checkbox(data
.get("prolongercourbes",""))
347 # Valeur par défaut : 1
348 debug(data
.get("nbextradata", "aaargh"), liste_err
)
349 nbextradata
= data
.get("nbextradata",1)
351 nbextradata
= int(nbextradata
)
353 warning("Le nombre de données sur lequel on extrapole est invalide : "+nbextradata
, liste_err
)
355 configuration
["non_sauve"]["nbextradata"] = nbextradata
357 if data
.get("calculextradata_type","") in CONFIG
["liste_typedonnees"]: # Si on a choisi un type de données à calculer
359 configuration
["non_sauve"]["calculextradata_type"] = data
.get("calculextradata_type","")
360 age
= convertit_jours_vers_python(data
.get("calculextradata_age","0j"),liste_err
)
361 date
= convertit_date_vers_python(data
.get("calculextradata_date", ""), liste_err
)
362 agecalcule
= delta_date(date
, configuration
["naissance"], liste_err
)
363 if configuration
["naissance"] != "" and agecalcule
!= -1: # On garde plutôt la date
364 configuration
["non_sauve"]["calculextradata_age"] = agecalcule
365 configuration
["non_sauve"]["calculextradata_date"] = date
366 else: # On garde l'âge
367 configuration
["non_sauve"]["calculextradata_age"] = age
368 if type(configuration
["naissance"]) == datetime
.date
:
369 # print(configuration["naissance"], type(configuration["naissance"]))
370 configuration
["non_sauve"]["calculextradata_date"] = configuration
["naissance"] + datetime
.timedelta(days
=round(age
))
372 configuration
["non_sauve"]["calculextradata_date"] = None
374 configuration
["non_sauve"]["calculextradata_type"] = ""
375 # On ne met rien dans les autres données, pas la peine
377 ctyped
= data
.get("calculextratemps_type","")
378 if ctyped
in CONFIG
["liste_typedonnees"]:
379 configuration
["non_sauve"]["calculextratemps_type"] = ctyped
380 configuration
["non_sauve"]["calculextratemps_val"] = convertit_donnee_vers_python(data
.get("calculextratemps_val",""), ctyped
, liste_err
)
382 configuration
["non_sauve"]["calculextratemps_type"] = ""
384 # Tracer les calculs sur la grille
385 configuration
["non_sauve"]["calculextradata_trace"] = gere_checkbox(data
.get("calculextradata_trace"))
386 configuration
["non_sauve"]["calculextratemps_trace"] = gere_checkbox(data
.get("calculextratemps_trace"))
389 ### Gestion des repères additionnels
390 configuration
["liste_reperes"] = []
392 while "repere_texte_"+str(i
) in data
: # Tant qu'il y a des trucs définis
393 debug("Repère trouvé", liste_err
)
394 jegardecerepere
= False # On va passer à True uniquementsi tout va bien
396 age
=data
.get("repere_age_"+str(i
), "")
397 date
=data
.get("repere_date_"+str(i
), "")
398 trace
=gere_checkbox(data
.get("repere_trace_"+str(i
), ""))
399 affichedate
=gere_checkbox(data
.get("repere_affichedate_"+str(i
), ""))
401 if date
!="" and configuration
['naissance'] != "": # Si on a saisi une date (et qu'il y a la date de naissance)
402 datepython
= convertit_date_vers_python(date
,liste_err
)
403 if datepython
!="": # Si la conversion s'est bien passée
404 nbjours
= delta_date(datepython
, configuration
['naissance'], liste_err
)
405 if nbjours
!= -1: # Si tout va bien jusque là
408 nbjours
=convertit_jours_vers_python(age
, liste_err
)
412 texte
= data
.get("repere_texte_"+str(i
), "") # Même si le texte est vide, osef
413 configuration
["liste_reperes"].append({"typed": "age", "donnee": nbjours, "date": date, "texte": texte, "trace": trace, "affichedate":affichedate}
)
420 ## web vers python : données
421 def gere_donnees(data
,naissance
,typedonnee
,liste_err
):
422 """ prend en argument le dictionnaire de requête, et la date de
423 naissance (éventuellement vide), et construit deux listes :
424 l_jours et l_data correspondantes.
425 Il faut donner en argument le type de données : voir
426 CONFIG["liste_typedonnees"]"""
427 if typedonnee
not in CONFIG
["liste_typedonnees"]:
428 warning("gere_donnees : le type de données : "+typedonnee
+" est invalide !! Types acceptés : "+str(CONFIG
["liste_typedonnees"]),liste_err
)
431 # On construit une liste de couples d'abord
435 # On va chercher si y'a des données à donnee_i
436 while "age_"+str(i
) in data
.keys():
437 if data
.get(typedonnee
+"_"+str(i
), "") != "": # si la donne de ce type existe
438 donnee
= convertit_donnee_vers_python(data
[typedonnee
+"_"+str(i
)],typedonnee
,liste_err
)
440 ## Si une date est saisie, on la prend en priorité car c'est des entiers et les entiers c'est BIEN
441 date
= data
.get("date_"+str(i
),"")
443 datep
= convertit_date_vers_python(date
,liste_err
)
447 if naissance
!= "" and datep
!= "": # On ne peut pas calculer l'âge si on n'a pas ces deux données
448 age
= delta_date(datep
,naissance
, liste_err
)
449 if age
!= -1: # -1 signifie une erreur donc on ne garde pas la donnée
450 liste_donnees
.append((age
,donnee
))
451 else: # Sinon, on regarde si on a saisi l'âge
452 age
= data
.get("age_"+str(i
),"")
454 warning("gere_donnees : ni l'âge ni la date ne sont saisies... donnée ignorée", liste_err
)
456 age
= convertit_jours_vers_python(age
,liste_err
)
457 liste_donnees
.append((age
,donnee
))
461 liste_donnees
.sort(key
=lambda x
: x
[0])
464 l_jours
= [x
[0] for x
in liste_donnees
]
465 l_donnee
= [x
[1] for x
in liste_donnees
]
467 return (l_jours
,l_donnee
)
469 # web vers python : enfants additionnels
470 def gere_enfants_additionnels(data
, files
, liste_err
):
471 """ data est le dictionnaire de requête.
472 files est le dictionnaire des fichiers (flask.request.files).
473 Renvoie les enfants additionnels sous forme de liste de dictionnaires :
474 {typed: (conf, lj, ldonnees)}
475 Dans conf y'a les infos qu'il faut pour tracer la courbe additionnelle voulue.
478 enfants_add
= [] # Enfants additionnels
479 # Les enfants additionnels commencent à 2 (puis 3, 4, etc)
481 while "couleur_donnees_"+str(i
) in data
: # Tant qu'il y a des données de ce type
482 if 'fichier_donnees_'+str(i
) in files
: # Un enfant à ajouter
483 fichier
= files
["fichier_donnees_"+str(i
)]
484 chaine
= fichier
.read() # On récupère la chaîne
485 if len(chaine
)>=5: # Si elle a une longueur à peu près raisonnable
486 debug("Un fichier de données additionnel trouvé", liste_err
)
487 formulaire_2
= fichier_json_vers_configdonnees(chaine
, liste_err
)
488 if formulaire_2
=={}:
489 warning("Le fichier de données additionnel est vide ou mal formaté", liste_err
)
491 debug("Form 2 : "+str(formulaire_2
), liste_err
)
492 # Récupérer sous forme python
493 conf2
, ljours2
, listes_donnees2
= web_vers_python(formulaire_2
,liste_err
, court
=True)
494 debug("Form 2 données travaillées "+str(ljours2
)+str(listes_donnees2
), liste_err
)
495 # Le symbole et la couleur
496 symb2
= gere_symbole(data
.get("symbole_donnees_"+str(i
)))
497 coul2
= rgb_vers_tuple(data
.get("couleur_donnees_"+str(i
),""),CONFIG
["couleurs"]["cadretxt"],liste_err
)
498 alias
= data
.get("alias_"+str(i
), "")
499 if alias
!= "": # Si l'alias n'est pas vide, il remplace le prénom
503 enfant2
= eclate_donnees_additionnelles(conf2
, ljours2
, listes_donnees2
, symb2
, coul2
)
504 enfants_add
.append(enfant2
)
514 #### export vers json
516 def donnees_vers_json(l_jours
,l_poids
,l_jourst
,l_taille
,config
):
517 """ retourne le json à renvoyer"""
518 gros_dico
= copy
.deepcopy(config
)
519 gros_dico
["version"] = CONFIG
["version"]
520 l_jours2
= [convertit_age_vers_texte(d
) for d
in l_jours
]
521 l_jourst2
= [convertit_age_vers_texte(d
) for d
in l_jourst
]
522 gros_dico
["data_j"] = l_jours2
523 gros_dico
["data_p"] = l_poids
524 gros_dico
["data_jours_taille"] = l_jourst2
525 gros_dico
["data_taille"] = l_taille
526 # gérer la date de naissance
527 if gros_dico
.get("naissance","") != "":
528 gros_dico
["naissance"] = convertit_date_vers_texte(gros_dico
["naissance"])
529 # Calcul de toutes les dates de données
530 l_dates_poids
= [convertit_date_vers_texte( config
["naissance"] + datetime
.timedelta(days
=round(jours
)) ) for jours
in l_jours
]
531 l_dates_taille
= [convertit_date_vers_texte( config
["naissance"] + datetime
.timedelta(days
=round(jours
)) ) for jours
in l_jourst
]
532 gros_dico
["data_dates_poids"]= l_dates_poids
533 gros_dico
["data_dates_taille"] = l_dates_taille
537 gros_dico
["maxi"] = convertit_age_vers_texte(gros_dico
["maxi"])
539 for i
in range(len(gros_dico
["liste_reperes"])):
540 gros_dico
["liste_reperes"][i
]["donnee"] = convertit_age_vers_texte(gros_dico
["liste_reperes"][i
]["donnee"])
542 for clecouleur
in DEFAUT
["couleurs"]:
543 gros_dico
["couleurs"][clecouleur
] = tuple_vers_rgb(gros_dico
["couleurs"][clecouleur
])
545 # Enlever ce qui ne se sauvegarde pas si y'a
546 if "non_sauve" in gros_dico
:
547 del gros_dico
["non_sauve"]
549 return json
.dumps(gros_dico
, indent
=2,ensure_ascii
=False )
551 def fusionne_donnees(listes_jours
,listes_donnees
, listes_dates
):
552 """ prend en argument deux dicos de listes. Chaque liste de jours est associée à une liste
553 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
554 {"age":truc, "donnee1":truc, "donnee2":truc, ...} triée par ordre de jours. Si jamais une des données est vide,
555 le champ du dictionnaire n'est pas rempli
556 Le troisième paquet de listes (les dates) peut être vide ou bien simiaire : même clés."""
559 """ teste si les listes sont toutes vides """
560 for l
in lj
.values():
566 """ renvoie la clé de la liste où il y a le min """
567 cle_mini
= CONFIG
["liste_typedonnees"][0]
568 for (cle
,liste
) in lj
.items():
569 if lj
[cle_mini
]== []:
572 if convertit_jours_vers_python(lj
[cle
][0],initialise_erreurs())<convertit_jours_vers_python(lj
[cle_mini
][0],initialise_erreurs()):
577 while not(fini(listes_jours
)):
578 typedonnee
= mini(listes_jours
)
579 # On extrait les données dans les deux listes (jours et données)
580 jour
= listes_jours
[typedonnee
].pop(0)
581 donnee
= listes_donnees
[typedonnee
].pop(0)
583 if liste_f
== [] or jour
!= liste_f
[-1]["age"]: # Si le jour est un "nouveau" jour
584 liste_f
.append({"age":jour}
)
585 # On met à jour l'élément (ou on l'ajoute)
586 liste_f
[-1][typedonnee
] = donnee
588 # Si il y a une date associée, on la met !
589 if listes_dates
[typedonnee
] != []:
590 date
= listes_dates
[typedonnee
].pop(0)
591 liste_f
[-1]["date"] = convertit_date_vers_texte(date
)
597 ### COnversion json vers formulaire
598 # Json -> formulaire HTML
599 def fichier_json_vers_configdonnees(chaine
,liste_err
):
600 """ prend le json importé (chaine) et l'exporte vers les valeurs du formulaire
601 Renvoyé sous forme de dictionnaire (mais adapté au formulaire web)"""
602 debug("json vers config : Prêt à interpréter le json",liste_err
)
604 valform
= json
.loads(chaine
)
606 erreur("Impossible de lire le fichier json !",liste_err
)
608 # Il faut maintenant récupérer les l_jours et l_poids puis les remettre
609 # sous forme de age_i et poids_i
614 for typed
in CONFIG
["liste_typedonnees"]:
615 if typed
== "poids": # pour la rétrocompatibilité
616 listes_jours
[typed
] = valform
.get("data_j",[])
617 listes_donnees
[typed
] = valform
.get("data_p",[])
618 listes_dates
[typed
] = valform
.get("data_dates_"+typed
,[])
620 listes_jours
[typed
] = valform
.get("data_jours_"+typed
,[])
621 listes_donnees
[typed
] = valform
.get("data_"+typed
,[])
622 listes_dates
[typed
] = valform
.get("data_dates_"+typed
,[])
625 debug("Avant fusion : listes jours "+str(listes_jours
),liste_err
)
626 liste_donnees
= fusionne_donnees(listes_jours
,listes_donnees
, listes_dates
)
627 debug("Fusion de listes ok. Liste moche : "+str(liste_donnees
),liste_err
)
628 for i
in range(len(liste_donnees
)):
629 for (cle
,val
) in liste_donnees
[i
].items():
630 valform
[cle
+"_"+str(i
)] = val
632 valform
["nb_data"] = max(len(liste_donnees
) +2,DEFAUT
["nb_data"])
638 #### Pour l'insertion d'une 2e (ou plus) courbe sur le graphique, ue fonction qui sépare tout ça
639 def eclate_donnees_additionnelles(conf
, ljours
, ldonnees
, symb
, couleur
):
640 """ conf est la config (on ne garde que le nom) pour un enfant additionnel,
641 ljours et ldonnees les dictionnaires de listes contenant les données.
642 symb est le symbole choisi pour cette courbe additionnelle (déjà vérifié)
643 On fabrique un joli dictionnaire typed -> (conf, lj, ldonnee) avec le nom de l'enfant,
644 et les données pour chaque typed"""
645 #print("test conf avant "+str(ldonnees)+str(ljours))
648 conf
["symbole"] = symb
# On ajoute le symbole additionnel
649 conf
["couleurcourbe"] = couleur
# la couleur
650 for typed
in CONFIG
["liste_typedonnees"]:
651 retour
[typed
] = (conf
, ljours
[typed
], ldonnees
[typed
])
653 #print("test "+str(retour))