X-Git-Url: https://git.immae.eu/?p=perso%2FDenise%2Foms.git;a=blobdiff_plain;f=gestion_donnees.py;h=b508706334e3a7c7797293368b0bf3dfcdd77232;hp=880614de16c1235cd1aba63b6365200202df1e1b;hb=bba98b24fa46099da0cec2b51fa3e0e57434dac9;hpb=b5ac625bdf312851ad3d7acf5dfdc5a94fcbf0be diff --git a/gestion_donnees.py b/gestion_donnees.py index 880614d..b508706 100644 --- a/gestion_donnees.py +++ b/gestion_donnees.py @@ -2,9 +2,9 @@ # -*- coding: utf-8 -*- from configuration import CONFIG,DEFAUT -from gestion_erreurs import * -from gestion_couleurs import * -from gestion_unites import * +from gestion_erreurs import debug, warning, erreur, initialise_erreurs +from gestion_couleurs import rgb_vers_tuple, tuple_vers_rgb +from gestion_unites import choix_unite import datetime import json import unidecode @@ -46,7 +46,7 @@ def convertit_jours_vers_python(chaine,liste_err): chainenombre = "" elif lettre != ' ': # autre caractère : bizarre ? - warning("convertit_jour_vers_python : caractère invalide : "+lettre,liste_err) + warning("problème à la conversion de "+chaine+". Caractère invalide : "+lettre,liste_err) # à la fin s'il reste qqch on le garde dans les jours if chainenombre != "": agejours += int(chainenombre) @@ -63,6 +63,7 @@ def convertit_age_vers_texte(nombre): annees = int(nombre / CONFIG["jours_dans_annee"]) restant = nombre - annees*CONFIG["jours_dans_annee"] mois = int(restant/CONFIG["jours_dans_mois"]) + #print("mois : ",mois, ", restant : ",nombre - mois*CONFIG["jours_dans_mois"]) jours= round(nombre - mois*CONFIG["jours_dans_mois"] - annees*CONFIG["jours_dans_annee"]) chaine = "" @@ -70,9 +71,10 @@ def convertit_age_vers_texte(nombre): chaine += str(annees)+"a" if mois >0: chaine += str(mois)+"m" - if jours>0 or nombre ==0: # si c'est la naissance, faut beien écrire 0j quand même + if jours>0 or nombre ==0: # si c'est la naissance, faut bien écrire 0j quand même chaine += str(jours)+"j" return chaine + ########################## # fonction qui calcule "auto" le maxi du graphique en fonction du max @@ -82,13 +84,13 @@ def calcule_max_graphique(l_jours): return CONFIG["jours_defaut_donneesvides"] else: jour_maxi = max(l_jours)# pas la peine d'aller très au delà du jour max - jour_maxi = int(jour_maxi* 1.1)+3 # on rajoute un peu + jour_maxi = int(jour_maxi* 1.2)+3 # on rajoute un peu return jour_maxi def simplifie_nom(chaine): """ simplifie le nom chaine afin d'en faire une extension - pour le nom du fichier. Met tout en minuscules et vire les caractères spéciaux + pour le nom du fichier. Vire les caractères spéciaux et max 15 caractères""" chaine2 = "" for l in chaine: @@ -100,17 +102,25 @@ def simplifie_nom(chaine): def convertit_donnee_vers_python(chaine,typedonnee,liste_err): """ convertit une chaine vers un float qui est le type donnee voulu. La virgule peut être . ou , et on vire d'éventuels espaces. - Taille invalide : on renvoie 0 avec un warning.""" + Taille invalide : on renvoie 0 avec un warning. + Si la chaine est en fait déjà au format float, on laisse tel quel""" + if type(chaine) == float: + return chaine chaine2 = chaine.replace(",",".") chaine2 = chaine2.replace(" ","") + try: donnee = float(chaine2) except: warning(typedonnee+" impossible à lire : "+chaine,liste_err) donnee = 0 + + # Pour le poids, un cas particulier + if typedonnee == "poids" and donnee > CONFIG["poids_maxi_conversion"]: + donnee = donnee/1000 # conversion en grammes if not( 0<=donnee json @@ -141,28 +157,33 @@ def convertit_date_vers_texte(date): if date == "": return "" else: - return (str(date.year)+"-"+str(date.month)+"-"+str(date.day)) - + #return (str(date.year)+"-"+str(date.month)+"-"+str(date.day)) + return str(date) -def delta_date(date1,datenaissance): +def delta_date(date1,datenaissance, liste_err): """ renvoie le nombre de jours (entier) entre date1 et datenaissance format "datetime" datenaissance est supposée antérieure. Erreur sinon.""" + if type(date1) != datetime.date or type(datenaissance) != datetime.date: + return -1 d = date1 - datenaissance jours = d.days if jours<0: - erreur_continue("La différence entre les dates est négative... :/") + warning("Une des dates saisies ("+str(date1)+") est inférieure à la date de naissance (la donnée est donc ignorée)", liste_err) return -1 return jours + ################### On regroupe tout ce qui gère les données en une fonction -def web_vers_python(data,liste_err): +def web_vers_python(data,liste_err, court=False): """ prend en argument le dictionnaire de requête et renvoie la config, et les - tableaux de donnée""" + tableaux de données + court : si True est précisé, on ne met que le nom dans la config (enfant + additionnel)""" # Régler la configuration - config = gere_configuration(data,liste_err) + config = gere_configuration(data,liste_err, court) # récupérer les données listes_jours = {} @@ -170,16 +191,21 @@ def web_vers_python(data,liste_err): for typed in CONFIG["liste_typedonnees"]: listes_jours[typed],listes_donnees[typed] = gere_donnees(data,config["naissance"],typed,liste_err) + # Si on veut extrapoler au-delà du jour maxi, on adapte + # Si on a choisi la même échelle de données - if config["memechelle"] == "oui": + if config.get("memechelle") == "oui": config["non_sauve"]["maxi"] = calcule_max_graphique([j for lj in listes_jours.values() for j in lj]) + # En cas d'extrapolation, on prend le maxi + if config["non_sauve"]["calculextradata_type"] !="" and config["non_sauve"]["calculextradata_age"]>config["non_sauve"]["maxi"]: + config["non_sauve"]["maxi"] = int(config["non_sauve"]["calculextradata_age"]) +1 config["non_sauve"]["unite"] = choix_unite(config["non_sauve"]["maxi"]) return (config,listes_jours,listes_donnees) -########### Fonctions qui gèretn les données +########### Fonctions qui gèretn les données web vers python def gere_checkbox(chaine): """ prend en arg une chaine, et renvoie "oui" si c'est "on" (sortie de la checkbox) @@ -189,119 +215,209 @@ def gere_checkbox(chaine): else: return "" -def gere_configuration(data,liste_err): +def gere_symbole(chaine): + """ prend en arg une chaîne genre "o", ">" et vérifie si c'est un symbole valide. + Renvoie ce symbole-là ou le défaut""" + if chaine in CONFIG["liste_symboles"]: + return chaine + else: + return DEFAUT["symbole"] + +def gere_configuration(data,liste_err, court=False): """ prend en argument le dictionnaire de requête (configuration imparfaite), et construit le dictionnaire de configuration qui va bien. - Vérifie que chaque entrée est cohérente évidemment.""" - configuration = {} + Vérifie que chaque entrée est cohérente évidemment. + court : si mis à True, on ne met que le nom dans la configuraion, + ainsi que la date de naissance et le sexe""" + # Initialisation + configuration = {"non_sauve": {}} # Pour le nom, osef qu'il soit vide nom = data.get("nom","") # Par contre s'il est trop long on le tronque configuration["nom"] = nom[:CONFIG["longueur_max_nom_bebe"]] - - sexe = data.get("sexe","") - if not (sexe in ["F","M","N"]): - warning("Le sexe de l'enfant est invalide ! "+sexe,liste_err) - sexe = "N" - configuration["sexe"] = sexe - + naissance = data.get("naissance","") if naissance !="": naissance = convertit_date_vers_python(naissance,liste_err) configuration["naissance"] = naissance - prematurite = data.get("prematurite","") - j = convertit_jours_vers_python(prematurite,liste_err) - configuration["prematurite"] = convertit_age_vers_texte(j) + sexe = data.get("sexe","") + if not (sexe in ["F","M","N"]): + warning("Le sexe de l'enfant est invalide. "+sexe,liste_err) + sexe = "N" + configuration["sexe"] = sexe + + if not(court): + + prematurite = data.get("prematurite","") + j = convertit_jours_vers_python(prematurite,liste_err) + configuration["prematurite"] = convertit_age_vers_texte(j) + + configuration["agecorrige"] = gere_checkbox(data.get("agecorrige","")) + + # Type de courbe. Au pire on met P + tyc = data.get("typecourbe","") + if not (tyc in ["P","Z"]): + tyc = "P" + configuration["typecourbe"] = tyc + + # unité + unite = data.get("unite","") + if not (unite in CONFIG["liste_unites"]): + unite = "" + #warning("L'unité "+unite+" n'est pas reconnue !",liste_err) + configuration["unite"] = unite - configuration["agecorrige"] = gere_checkbox(data.get("agecorrige","")) + # grille + configuration["grille"] = gere_checkbox(data.get("grille","")) - # Type de courbe. Au pire on met P - tyc = data.get("typecourbe","") - if not (tyc in ["P","Z"]): - tyc = "P" - configuration["typecourbe"] = tyc + # tracer ou non les courbes vides + configuration["tracevide"] = gere_checkbox(data.get("tracevide","")) + + # Même échelle sur tous les graphiques + configuration["memechelle"] = gere_checkbox(data.get("memechelle","")) - # unité - unite = data.get("unite","") - if not (unite in CONFIG["liste_unites"]): - unite = "" - #warning("L'unité "+unite+" n'est pas reconnue !",liste_err) - configuration["unite"] = unite - - # grille - configuration["grille"] = gere_checkbox(data.get("grille","")) - - # tracer ou non les courbes vides - configuration["tracevide"] = gere_checkbox(data.get("tracevide","")) - # Même échelle sur tous les graphiques - configuration["memechelle"] = gere_checkbox(data.get("memechelle","")) + # maxi. 0 signifie qu'on veut pas de maxi + maxi = data.get("maxi","") + if maxi == "": + configuration["maxi"] = 0 + else: + configuration["maxi"] = int(convertit_jours_vers_python(maxi,liste_err)) + + # dimensions du graphique + largeur = data.get("largeur","") + if largeur == "": + largeur = DEFAUT["largeur_graphique"] + else: + try: + largeur = int(largeur) + except: + warning("La largeur "+largeur+"est invalide !",liste_err) + largeur = DEFAUT["largeur_graphique"] + if largeur > CONFIG["largeur_graphique_max"]: + largeur = CONFIG["largeur_graphique_max"] + warning("Largeur du graphique trop grande !",liste_err) + elif largeur < CONFIG["largeur_graphique_min"]: + largeur = CONFIG["largeur_graphique_min"] + warning("Largeur du graphique trop petite !",liste_err) + configuration["largeur"] = largeur + + hauteur = data.get("hauteur","") + if hauteur == "": + hauteur = DEFAUT["hauteur_graphique"] + else: + try: + hauteur = int(hauteur) + except: + warning("La hauteur "+hauteur+"est invalide !",liste_err) + hauteur = DEFAUT["hauteur_graphique"] + if hauteur > CONFIG["hauteur_graphique_max"]: + hauteur = CONFIG["hauteur_graphique_max"] + warning("Hauteur du graphique trop grande !",liste_err) + elif hauteur < CONFIG["hauteur_graphique_min"]: + hauteur = CONFIG["hauteur_graphique_min"] + warning("Hauteur du graphique trop petite !",liste_err) + configuration["hauteur"] = hauteur + + # existence et position de la légende + configuration["legende"] = gere_checkbox(data.get("legende","")) + + positionlegende = data.get("positionlegende","") + if not(positionlegende in ['upper left','upper right','lower left','lower right']): + positionlegende = "upper left" + configuration["positionlegende"] = positionlegende + + configuration["couleurs"] = {} + # gérer les couleurs + for clecouleur in DEFAUT["couleurs"]: + coul = rgb_vers_tuple(data.get("couleur_"+clecouleur,""),DEFAUT["couleurs"].get(clecouleur, ""),liste_err) + configuration["couleurs"][clecouleur] = coul + + # symbole + configuration["symbole"] = gere_symbole( data.get("symbole", "")) - # maxi. 0 signifie qu'on veut pas de maxi - maxi = data.get("maxi","") - if maxi == "": - configuration["maxi"] = 0 - else: - configuration["maxi"] = int(convertit_jours_vers_python(maxi,liste_err)) + configuration["non_sauve"]["grilleamelio"] = gere_checkbox(data.get("grilleamelio","")) - # dimensions du graphique - largeur = data.get("largeur","") - if largeur == "": - largeur = DEFAUT["largeur_graphique"] - else: - try: - largeur = int(largeur) - except: - warning("La largeur "+largeur+"est invalide !",liste_err) - largeur = DEFAUT["largeur_graphique"] - if largeur > CONFIG["largeur_graphique_max"]: - largeur = CONFIG["largeur_graphique_max"] - warning("Largeur du graphique trop grande !",liste_err) - elif largeur < CONFIG["largeur_graphique_min"]: - largeur = CONFIG["largeur_graphique_min"] - warning("Largeur du graphique trop petite !",liste_err) - configuration["largeur"] = largeur - hauteur = data.get("hauteur","") - if hauteur == "": - hauteur = DEFAUT["hauteur_graphique"] - else: + #### La partie extrapolation n'a pas besoin d'être sauvée + configuration["non_sauve"]["prolongercourbes"] = gere_checkbox(data.get("prolongercourbes","")) + + # Valeur par défaut : 1 + debug(data.get("nbextradata", "aaargh"), liste_err) + nbextradata = data.get("nbextradata",1) try: - hauteur = int(hauteur) + nbextradata = int(nbextradata) except: - warning("La hauteur "+hauteur+"est invalide !",liste_err) - hauteur = DEFAUT["hauteur_graphique"] - if hauteur > CONFIG["hauteur_graphique_max"]: - hauteur = CONFIG["hauteur_graphique_max"] - warning("Hauteur du graphique trop grande !",liste_err) - elif hauteur < CONFIG["hauteur_graphique_min"]: - hauteur = CONFIG["hauteur_graphique_min"] - warning("Hauteur du graphique trop petite !",liste_err) - configuration["hauteur"] = hauteur - - # existence et position de la légende - configuration["legende"] = gere_checkbox(data.get("legende","")) - - positionlegende = data.get("positionlegende","") - if not(positionlegende in ['upper left','upper right','lower left','lower right']): - positionlegende = "upper left" - configuration["positionlegende"] = positionlegende + warning("Le nombre de données sur lequel on extrapole est invalide : "+nbextradata, liste_err) + nbextradata = 1 + configuration["non_sauve"]["nbextradata"] = nbextradata + + if data.get("calculextradata_type","") in CONFIG["liste_typedonnees"]: # Si on a choisi un type de données à calculer + + configuration["non_sauve"]["calculextradata_type"] = data.get("calculextradata_type","") + age = convertit_jours_vers_python(data.get("calculextradata_age","0j"),liste_err) + date = convertit_date_vers_python(data.get("calculextradata_date", ""), liste_err) + agecalcule = delta_date(date, configuration["naissance"], liste_err) + if configuration["naissance"] != "" and agecalcule != -1: # On garde plutôt la date + configuration["non_sauve"]["calculextradata_age"] = agecalcule + configuration["non_sauve"]["calculextradata_date"] = date + else: # On garde l'âge + configuration["non_sauve"]["calculextradata_age"] = age + if type(configuration["naissance"]) == datetime.date: +# print(configuration["naissance"], type(configuration["naissance"])) + configuration["non_sauve"]["calculextradata_date"] = configuration["naissance"] + datetime.timedelta(days=round(age)) + else: + configuration["non_sauve"]["calculextradata_date"] = None + else: + configuration["non_sauve"]["calculextradata_type"] = "" + # On ne met rien dans les autres données, pas la peine + + ctyped = data.get("calculextratemps_type","") + if ctyped in CONFIG["liste_typedonnees"]: + configuration["non_sauve"]["calculextratemps_type"] = ctyped + configuration["non_sauve"]["calculextratemps_val"] = convertit_donnee_vers_python(data.get("calculextratemps_val",""), ctyped, liste_err) + else: + configuration["non_sauve"]["calculextratemps_type"] = "" + + # Tracer les calculs sur la grille + configuration["non_sauve"]["calculextradata_trace"] = gere_checkbox(data.get("calculextradata_trace")) + configuration["non_sauve"]["calculextratemps_trace"] = gere_checkbox(data.get("calculextratemps_trace")) - configuration["couleurs"] = {} - # gérer les couleurs - for clecouleur in DEFAUT["couleurs"]: - coul = rgb_vers_tuple(data.get("couleur_"+clecouleur,""),CONFIG["couleurs"][clecouleur],liste_err) - configuration["couleurs"][clecouleur] = coul - - # On y ajoute la partie "non sauvée" qui servira peut-être plus tard - configuration["non_sauve"] = {} + ### Gestion des repères additionnels + configuration["liste_reperes"] = [] + i=0 + while "repere_texte_"+str(i) in data: # Tant qu'il y a des trucs définis + debug("Repère trouvé", liste_err) + jegardecerepere = False # On va passer à True uniquementsi tout va bien + + age=data.get("repere_age_"+str(i), "") + date=data.get("repere_date_"+str(i), "") + trace=gere_checkbox(data.get("repere_trace_"+str(i), "")) + affichedate=gere_checkbox(data.get("repere_affichedate_"+str(i), "")) + + if date!="" and configuration['naissance'] != "": # Si on a saisi une date (et qu'il y a la date de naissance) + datepython = convertit_date_vers_python(date,liste_err) + if datepython !="": # Si la conversion s'est bien passée + nbjours = delta_date(datepython, configuration['naissance'], liste_err) + if nbjours != -1: # Si tout va bien jusque là + jegardecerepere=True + elif age !="": + nbjours=convertit_jours_vers_python(age, liste_err) + jegardecerepere=True + + if jegardecerepere: + texte = data.get("repere_texte_"+str(i), "") # Même si le texte est vide, osef + configuration["liste_reperes"].append({"typed": "age", "donnee": nbjours, "date": date, "texte": texte, "trace": trace, "affichedate":affichedate}) + i+=1 return configuration + +## web vers python : données def gere_donnees(data,naissance,typedonnee,liste_err): """ prend en argument le dictionnaire de requête, et la date de naissance (éventuellement vide), et construit deux listes : @@ -317,22 +433,28 @@ def gere_donnees(data,naissance,typedonnee,liste_err): i = 0 # On va chercher si y'a des données à donnee_i - while typedonnee+"_"+str(i) in data.keys(): - if data[typedonnee+"_"+str(i)] != "": + while "age_"+str(i) in data.keys(): + if data.get(typedonnee+"_"+str(i), "") != "": # si la donne de ce type existe donnee = convertit_donnee_vers_python(data[typedonnee+"_"+str(i)],typedonnee,liste_err) - age = data.get("age_"+str(i),"") - if age !="": - age = convertit_jours_vers_python(age,liste_err) - liste_donnees.append((age,donnee)) - else: - date = data.get("date_"+str(i),"") + + ## Si une date est saisie, on la prend en priorité car c'est des entiers et les entiers c'est BIEN + date = data.get("date_"+str(i),"") + if date != "": datep = convertit_date_vers_python(date,liste_err) - # on vérifie la date - if naissance == "": - 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) - elif datep != "": # la date est valide et on a une date de naissance - age = delta_date(datep,naissance) - liste_donnees.append((age,donnee)) + else: + datep = "" + + if naissance != "" and datep != "": # On ne peut pas calculer l'âge si on n'a pas ces deux données + age = delta_date(datep,naissance, liste_err) + if age != -1: # -1 signifie une erreur donc on ne garde pas la donnée + liste_donnees.append((age,donnee)) + else: # Sinon, on regarde si on a saisi l'âge + age = data.get("age_"+str(i),"") + if age == "": + warning("gere_donnees : ni l'âge ni la date ne sont saisies... donnée ignorée", liste_err) + else: + age = convertit_jours_vers_python(age,liste_err) + liste_donnees.append((age,donnee)) i+=1 # Trier la liste @@ -344,12 +466,57 @@ def gere_donnees(data,naissance,typedonnee,liste_err): return (l_jours,l_donnee) +# web vers python : enfants additionnels +def gere_enfants_additionnels(data, files, liste_err): + """ data est le dictionnaire de requête. + files est le dictionnaire des fichiers (flask.request.files). + Renvoie les enfants additionnels sous forme de liste de dictionnaires : + {typed: (conf, lj, ldonnees)} + Dans conf y'a les infos qu'il faut pour tracer la courbe additionnelle voulue. + """ + + enfants_add = [] # Enfants additionnels + # Les enfants additionnels commencent à 2 (puis 3, 4, etc) + i=2 + while "couleur_donnees_"+str(i) in data: # Tant qu'il y a des données de ce type + if 'fichier_donnees_'+str(i) in files: # Un enfant à ajouter + fichier = files["fichier_donnees_"+str(i)] + chaine = fichier.read() # On récupère la chaîne + if len(chaine)>=5: # Si elle a une longueur à peu près raisonnable + debug("Un fichier de données additionnel trouvé", liste_err) + formulaire_2 = fichier_json_vers_configdonnees(chaine, liste_err) + if formulaire_2 =={}: + warning("Le fichier de données additionnel est vide ou mal formaté", liste_err) + else: + debug("Form 2 : "+str(formulaire_2), liste_err) + # Récupérer sous forme python + conf2, ljours2, listes_donnees2 = web_vers_python(formulaire_2,liste_err, court=True) + debug("Form 2 données travaillées "+str(ljours2)+str(listes_donnees2), liste_err) + # Le symbole et la couleur + symb2 = gere_symbole(data.get("symbole_donnees_"+str(i))) + coul2 = rgb_vers_tuple(data.get("couleur_donnees_"+str(i),""),CONFIG["couleurs"]["cadretxt"],liste_err) + alias = data.get("alias_"+str(i), "") + if alias != "": # Si l'alias n'est pas vide, il remplace le prénom + print(conf2) + conf2["nom"] = alias + + enfant2 = eclate_donnees_additionnelles(conf2, ljours2, listes_donnees2, symb2, coul2) + enfants_add.append(enfant2) + i+=1 + + return enfants_add + + + + +# python vers Json #### export vers json def donnees_vers_json(l_jours,l_poids,l_jourst,l_taille,config): """ retourne le json à renvoyer""" gros_dico = copy.deepcopy(config) + gros_dico["version"] = CONFIG["version"] l_jours2 = [convertit_age_vers_texte(d) for d in l_jours] l_jourst2 = [convertit_age_vers_texte(d) for d in l_jourst] gros_dico["data_j"] = l_jours2 @@ -359,8 +526,18 @@ def donnees_vers_json(l_jours,l_poids,l_jourst,l_taille,config): # gérer la date de naissance if gros_dico.get("naissance","") != "": gros_dico["naissance"] = convertit_date_vers_texte(gros_dico["naissance"]) + # Calcul de toutes les dates de données + l_dates_poids = [convertit_date_vers_texte( config["naissance"] + datetime.timedelta(days=round(jours)) ) for jours in l_jours] + l_dates_taille = [convertit_date_vers_texte( config["naissance"] + datetime.timedelta(days=round(jours)) ) for jours in l_jourst] + gros_dico["data_dates_poids"]= l_dates_poids + gros_dico["data_dates_taille"] = l_dates_taille + + # gérer l'age maxi gros_dico["maxi"] = convertit_age_vers_texte(gros_dico["maxi"]) + # Gérer les repères + for i in range(len(gros_dico["liste_reperes"])): + gros_dico["liste_reperes"][i]["donnee"] = convertit_age_vers_texte(gros_dico["liste_reperes"][i]["donnee"]) # gérer les couleurs for clecouleur in DEFAUT["couleurs"]: gros_dico["couleurs"][clecouleur] = tuple_vers_rgb(gros_dico["couleurs"][clecouleur]) @@ -371,12 +548,13 @@ def donnees_vers_json(l_jours,l_poids,l_jourst,l_taille,config): return json.dumps(gros_dico, indent=2,ensure_ascii=False ) -def fusionne_donnees(listes_jours,listes_donnees): +def fusionne_donnees(listes_jours,listes_donnees, listes_dates): """ prend en argument deux dicos de listes. Chaque liste de jours est associée à une liste 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 - ("age":truc, "donnee1":truc, "donnee2":truc, ...) triée par ordre de jours. Si jamais une des données est vide, - le champ du dictionnaire n'est pas rempli""" -# nb_donnees = len(listes_jours) + {"age":truc, "donnee1":truc, "donnee2":truc, ...} triée par ordre de jours. Si jamais une des données est vide, + le champ du dictionnaire n'est pas rempli + Le troisième paquet de listes (les dates) peut être vide ou bien simiaire : même clés.""" + def fini(lj): """ teste si les listes sont toutes vides """ for l in lj.values(): @@ -401,18 +579,26 @@ def fusionne_donnees(listes_jours,listes_donnees): # On extrait les données dans les deux listes (jours et données) jour = listes_jours[typedonnee].pop(0) donnee = listes_donnees[typedonnee].pop(0) + if liste_f == [] or jour != liste_f[-1]["age"]: # Si le jour est un "nouveau" jour liste_f.append({"age":jour}) - # On met à jour l'élément + # On met à jour l'élément (ou on l'ajoute) liste_f[-1][typedonnee] = donnee + # Si il y a une date associée, on la met ! + if listes_dates[typedonnee] != []: + date = listes_dates[typedonnee].pop(0) + liste_f[-1]["date"] = convertit_date_vers_texte(date) + + return liste_f - +### COnversion json vers formulaire # Json -> formulaire HTML def fichier_json_vers_configdonnees(chaine,liste_err): - """ prend le json importé (chaine) et l'exporte vers les valeurs du formulaire """ + """ prend le json importé (chaine) et l'exporte vers les valeurs du formulaire + Renvoyé sous forme de dictionnaire (mais adapté au formulaire web)""" debug("json vers config : Prêt à interpréter le json",liste_err) try: valform = json.loads(chaine) @@ -424,16 +610,20 @@ def fichier_json_vers_configdonnees(chaine,liste_err): listes_jours = {} listes_donnees = {} + listes_dates = {} for typed in CONFIG["liste_typedonnees"]: if typed == "poids": # pour la rétrocompatibilité listes_jours[typed] = valform.get("data_j",[]) listes_donnees[typed] = valform.get("data_p",[]) + listes_dates[typed] = valform.get("data_dates_"+typed,[]) else: listes_jours[typed] = valform.get("data_jours_"+typed,[]) listes_donnees[typed] = valform.get("data_"+typed,[]) + listes_dates[typed] = valform.get("data_dates_"+typed,[]) + debug("Avant fusion : listes jours "+str(listes_jours),liste_err) - liste_donnees = fusionne_donnees(listes_jours,listes_donnees) + liste_donnees = fusionne_donnees(listes_jours,listes_donnees, listes_dates) debug("Fusion de listes ok. Liste moche : "+str(liste_donnees),liste_err) for i in range(len(liste_donnees)): for (cle,val) in liste_donnees[i].items(): @@ -444,4 +634,21 @@ def fichier_json_vers_configdonnees(chaine,liste_err): return valform - \ No newline at end of file + +#### Pour l'insertion d'une 2e (ou plus) courbe sur le graphique, ue fonction qui sépare tout ça +def eclate_donnees_additionnelles(conf, ljours, ldonnees, symb, couleur): + """ conf est la config (on ne garde que le nom) pour un enfant additionnel, + ljours et ldonnees les dictionnaires de listes contenant les données. + symb est le symbole choisi pour cette courbe additionnelle (déjà vérifié) + On fabrique un joli dictionnaire typed -> (conf, lj, ldonnee) avec le nom de l'enfant, + et les données pour chaque typed""" + #print("test conf avant "+str(ldonnees)+str(ljours)) + + retour = {} + conf["symbole"] = symb # On ajoute le symbole additionnel + conf["couleurcourbe"] = couleur # la couleur + for typed in CONFIG["liste_typedonnees"]: + retour[typed] = (conf, ljours[typed], ldonnees[typed]) + + #print("test "+str(retour)) + return retour \ No newline at end of file