# récupérer les données du formulaire proprement
config,listes_jours,listes_donnees = donnees.web_vers_python(data,liste_err)
- debug(" * On a récupéré et traité les données du formulaire web",liste_err)
+ debug(" * On a récupéré et traité les données du formulaire web, "+str(listes_jours)+str(listes_donnees),liste_err)
# Gérer les enfants additionnels
enfants_add = donnees.gere_enfants_additionnels(data, flask.request.files, liste_err)
#print(retour)
return retour[:-2]
-def formate_resultat_donnee(age, donnee, typedonnee, extra, liste_err):
+def formate_resultat_donnee(age, date, donnee, typedonnee, extra, liste_err):
""" Formate le tout en une zolie phrase
- age et donnee sont les données,
+ age date et donnee sont les données. date peut être None (sinon donnée de date)
typedonnee est le type de donnée (poids, etc)
extra est un truc additionnel à mettre entre parenthèses"""
donnee_arrondie = u.arrondit_donnee(donnee, typedonnee)
chaine = "À "+joliechaine_age(convertit_age_vers_texte(age))
+ if date != None:
+ chaine += ", le "+date.strftime("%d/%m/%Y")
+
if typedonnee == "poids":
chaine+= ", l'enfant pèsera "+str(donnee_arrondie)+" kg"
elif typedonnee == "taille":
chaine+=ajout+"."
return chaine
-def formate_resultat_age(age, donnee, typedonnee, extra, liste_err):
+def formate_resultat_age(age, date, donnee, typedonnee, extra, liste_err):
""" formate les données en une zolie phrase
- age et donnee sont les données
+ age, date et donnee sont les données. date est une donnée de date qui peut être vide.
typedonnee est le type de donnée (poids, etc)
extra est un truc additionnel à mettre entre parenthèses"""
age_joli = joliechaine_age(convertit_age_vers_texte(age))
else:# phrase générique
chaine= "L'enfant atteindra la donnée "+typedonnee+" "+str(donnee)+" à l'âge de "+age_joli
+ if date != None:
+ chaine += ", le "+date.strftime("%d/%m/%Y")
+
if extra!="":
ajout=" ("+extra+")"
else:
CONFIG = {}
### La version de l'app
-CONFIG["version"] = 2.5
+CONFIG["version"] = 2.6
# Nombre de versions anciennes dans le changelog
CONFIG["nb_lignes_changelog"] = 4
-"Version 2.51","26/25/2022","<p>Un test à faire : les dates sont prioritaires sur les âges pour éviter les soucis d'arrondis. À tester, et d'autres trucs arrivent.</p>"
+"Version 2.6","28/05/2022","<p>Des petites nouveautés :</p>
+<ul>
+ <li>Les dates sont désormais prioritaires sur les âges pour éviter les soucis d'arrondis.</li>
+ <li>Il est également possible de mettre une date sur un repère (et de repérer une date précise).</li>
+ <li>On peut également utiliser les dates pour les extrapolations (telle date l'enfant pèsera tant...)</li>
+ <li>Un bug corrigé : si on demande une taille de graphique supérieure à l'âge max des données OMS (5 ans), ça ne fait pas planter l'extrapolation (le tracé d'extrapolation s'arrêtera juste à 5 ans).</li>
+</ul>"
"Version 2.501","14/05/2022","<p>Petit bug mineur corrigé : si on met une donnée avec une date inférieure à la date de naissance, elle est ignorée et un petit message s'affiche.</p>"
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 = ""
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:
nbextradata = 1
configuration["non_sauve"]["nbextradata"] = nbextradata
- if data.get("calculextradata_type","") in CONFIG["liste_typedonnees"]:
+ 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","")
- configuration["non_sauve"]["calculextradata_age"] = convertit_jours_vers_python(data.get("calculextradata_age","0j"),liste_err)
+ age = convertit_jours_vers_python(data.get("calculextradata_age","0j"),liste_err)
+ date = convertit_date_vers_python(data.get("calculextradata_date", ""), [[],[]])
+ 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 l'âge, pas la peine
+ # On ne met rien dans les autres données, pas la peine
ctyped = data.get("calculextratemps_type","")
if ctyped in CONFIG["liste_typedonnees"]:
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), ""))
- if age !="":
- agec=convertit_jours_vers_python(age, liste_err)
+ 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": agec, "texte": texte, "trace": trace})
+ configuration["liste_reperes"].append({"typed": "age", "donnee": nbjours, "date": date, "texte": texte, "trace": trace, "affichedate":affichedate})
i+=1
return configuration
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=jours) ) for jours in l_jours]
- l_dates_taille = [convertit_date_vers_texte( config["naissance"] + datetime.timedelta(days=jours) ) for jours in l_jourst]
+ 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
for(var i=nblignes; i<nblignes+nb_additionnel ; i++)
{
var elt = document.createElement("li") ;
- elt.innerHTML = 'Âge : <input class="data" type="text" name="repere_age_'+i+'" value=""> Texte associé : <input class="texte" type="text" name="repere_texte_'+i+'" value=""> Tracer : <input type="checkbox" name="repere_trace_'+i+'">' ;
+ elt.innerHTML = 'Âge : <input class="data" type="text" name="repere_age_'+i+'" value=""> \
+ ou date : <input type="date" name="repere_date_{{ i }}" value=""> \
+ Texte associé : <input class="texte" type="text" name="repere_texte_'+i+'" value=""> \
+ Tracer : <input type="checkbox" name="repere_trace_'+i+'">\
+ Afficher la date : <input type="checkbox" name="repere_affichedate_{{ i }}">' ;
eltul.appendChild(elt) ;
}
document.getElementById('sectioncourbe').style.display = "block";
document.getElementById('section_courbe_poids').style.display = "block" ;
document.getElementById('courbe_poids').src = 'data:image/png;base64,'+(image_poids);
+ document.getElementById('courbe_poids').alt = 'Courbe de poids de '+nomenfant ;
boutondl = document.getElementById("courbe_dl_poids") ;
boutondl.setAttribute('onclick',"download_file('courbe_poids_"+nomenfant+".png', 'image/png;base64','"+image_poids +"')")
}
document.getElementById('sectioncourbe').style.display = "block";
document.getElementById('section_courbe_taille').style.display = "block" ;
document.getElementById('courbe_taille').src = 'data:image/png;base64,'+(image_taille);
+ document.getElementById('courbe_taille').alt = 'Courbe de taille de '+nomenfant ;
boutondl = document.getElementById("courbe_dl_taille") ;
boutondl.setAttribute('onclick',"download_file('courbe_taille_"+nomenfant+".png', 'image/png;base64','"+image_taille +"')")
}
<label for="fichier_donnees" class="icon_button">
- <img src="static/icons/import.png">
+ <img src="static/icons/import.png" alt="Importer">
<span class="icon_legend">Importer un fichier</span>
</label>
<input type="file" name="fichier_donnees" id="fichier_donnees" oninput="upload_file('form_import_donnees')">
<h3>Informations sur l'enfant</h3>
<div>
<label for="reset_donnees" class="icon_button">
- <img src="static/icons/trash.png">
+ <img src="static/icons/trash.png" alt="Effacer">
<span class="icon_legend">Effacer les données du formulaire</span>
</label>
<input type="reset" id="reset_donnees" value="Effacer les données du formulaire">
<ul id="ajoutereperecourbe">
{% for i in range(valform.liste_reperes | length) %}
<li>Âge : <input class="data" type="text" name="repere_age_{{ i }}" value="{{ valform.liste_reperes[i].donnee }}">
+ ou date : <input type="date" name="repere_date_{{ i }}" value="{{ valform.liste_reperes[i].date }}">
Texte associé : <input class="texte" type="text" name="repere_texte_{{ i }}" value="{{ valform.liste_reperes[i].texte }}">
- Tracer : <input type="checkbox" name="repere_trace_{{ i }}" {% if valform.liste_reperes[i].trace %} checked {% endif %}></li>
+ Tracer : <input type="checkbox" name="repere_trace_{{ i }}" {% if valform.liste_reperes[i].trace %} checked {% endif %}>
+ Afficher la date : <input type="checkbox" name="repere_affichedate_{{ i }}" {% if valform.liste_reperes[i].affichedate %} checked {% endif %}>
+ </li>
{% endfor %}
{% for j in range(valform.liste_reperes | length, valform.nb_reperes_mini) %}
<li>Âge : <input class="data" type="text" name="repere_age_{{ j }}" value="">
+ ou date : <input type="date" name="repere_date_{{ i }}" value="">
Texte associé : <input class="texte" type="text" name="repere_texte_{{ j }}" value="">
- Tracer : <input type="checkbox" name="repere_trace_{{ j }}"></li>
+ Tracer : <input type="checkbox" name="repere_trace_{{ j }}">
+ Afficher la date : <input type="checkbox" name="repere_affichedate_{{ i }}"></li>
+
{% endfor %}
</ul>
{% for val in CONFIG.liste_typedonnees %}
<option value="{{val}}">{{val}}</option>
{% endfor %}
- </select> à l'âge <input type="text" class="data" name="calculextradata_age" value="6m">
+ </select> à l'âge <input type="text" class="data" name="calculextradata_age">
+ ou à la date <input type="date" name="calculextradata_date">
<input type="checkbox" name="calculextradata_trace"> ... et le voir sur le graphique.</li>
<li>Calculer l'âge auquel l'enfant aura <input type="text" class="data" name="calculextratemps_val">
<!--- Le grobouton -->
<div>
<span onclick="appelle_image()" class="icon_button">
- <img src="static/icons/courbe.png">
+ <img src="static/icons/courbe.png" alt="Tracer les courbes">
<span class="icon_legend">Je veux les courbes !</span></span>
<span id="statut_courbes"></span>
</div>
<h2>Courbes</h2>
<div id="section_courbe_poids">
- <img id="courbe_poids">
+ <img id="courbe_poids" src="" alt="">
<div id="courbe_dl_poids" class="icon_button">
- <img src="static/icons/export.png">
+ <img src="static/icons/export.png" alt="Exporter la courbe de poids">
<span class="icon_legend">Télécharger la courbe de poids</span>
</div>
</div>
<div id="section_courbe_taille">
- <img id="courbe_taille">
+ <img id="courbe_taille" src="" alt="">
<div id="courbe_dl_taille" class="icon_button">
- <img src="static/icons/export.png">
+ <img src="static/icons/export.png" alt="Exporter la courbe de taille">
<span class="icon_legend">Télécharger la courbe de taille</span>
</div>
</div>
<p>Vous pouvez télécharger les données afin de ne pas avoir à les re-saisir la prochaine fois.</p>
<div id="export_dl" class="icon_button">
- <img src="static/icons/export.png">
+ <img src="static/icons/export.png" alt="Exporter les données">
<span class="icon_legend">Télécharger les données</span>
</div>
- <p>Si vous n'arrivez pas à télécharger les données, <a href='#export' onclick="affiche_export()">cliquez ici</a> pour les voir en texte clair : il vous suffira de les copier/coller dans un fichier texte.</p>
+ <p>Si vous n'arrivez pas à télécharger les données, <a href='#export' onclick="affiche_export()">cliquez ici</a> pour les voir en texte clair : il vous suffira de les copier/coller dans un fichier texte.</p>
<div id="export">
<textarea readonly id="export_texte">
</textarea>
from gestion_donnees import calcule_max_graphique, convertit_jours_vers_python
from gestion_erreurs import debug, erreur, warning
from calculs_extrapole import calcule_donnee_extrapolee, calcule_age_extrapole, interpole_lineaire, interpole_lineaire_ordonnee, formate_resultat_donnee, formate_resultat_age, formate_interpole, formate_extrapole
+import datetime
from numpy import arange
# On va prendre les extrapolations de la dernière donnée jusqu'à l fin du graphe
debut_extr = int(l_jours[-conf["non_sauve"]["nbextradata"]])
i_debut_extr = dates_extrapole.index(debut_extr)
- i_fin_extr = dates_extrapole.index(jour_maxi)
+ if jour_maxi >= dates_extrapole[-1]:
+ i_fin_extr = len(dates_extrapole) -1
+ else:
+ i_fin_extr = dates_extrapole.index(jour_maxi)
+ print("bla", i_debut_extr, i_fin_extr)
# Voilà ce qu'on veut tracer
dates_extrapole_trace = dates_extrapole[i_debut_extr:i_fin_extr+1]
donnees_extrapole_trace = donnees_extrapole[i_debut_extr:i_fin_extr+1]
else:
message=formate_interpole()
- texte = formate_resultat_donnee(conf["non_sauve"]["calculextradata_age"], r, typedonnee, message, liste_err)
+ texte = formate_resultat_donnee(conf["non_sauve"]["calculextradata_age"], conf["non_sauve"]["calculextradata_date"], r, typedonnee, message, liste_err)
debug("calcul de la donnée extrapolée : "+texte, liste_err)
if texte!="":
liste_extracalculs.append(texte)
- print(liste_extracalculs)
+ #print(liste_extracalculs)
# Ajouter le trait ?
if conf["non_sauve"]["calculextradata_trace"] == "oui":
dessine_guides(conf["non_sauve"]["calculextradata_age"], r, conf["couleurs"]["cadretxt"], unite, ax, liste_err)
if conf["non_sauve"]["calculextratemps_type"] == typedonnee:
# interpolation
r = interpole_lineaire_ordonnee(l_jours,l_poids,conf["non_sauve"]["calculextratemps_val"], liste_err)
+ if type(conf["naissance"]) == datetime.date:
+ rdate = conf["naissance"] + datetime.timedelta(days=r)
+ else:
+ rdate = None
+
if r==-1:
# ça sera donc une extrapolation
- r = calcule_age_extrapole(dates_extrapole, donnees_extrapole, conf["non_sauve"]["calculextratemps_val"], liste_err)
+ r = calcule_age_extrapole(dates_extrapole, donnees_extrapole, conf["non_sauve"]["calculextratemps_val"], liste_err)
+ if type(conf["naissance"]) == datetime.date:
+ rdate = conf["naissance"] + datetime.timedelta(days=round(r))
+ else:
+ rdate = None
message=formate_extrapole(conf["non_sauve"]["nbextradata"])
else:
message=formate_interpole()
-
- texte = formate_resultat_age(r, conf["non_sauve"]["calculextratemps_val"], typedonnee, message, liste_err)
+ print(r, rdate)
+ texte = formate_resultat_age(r, rdate, conf["non_sauve"]["calculextratemps_val"], typedonnee, message, liste_err)
#r = calcule_age_extrapole(dates_extrapole, donnees_extrapole, conf["non_sauve"]["calculextratemps_val"], typedonnee, liste_err)
if texte!="":
agec = u.convertitunite(rep["donnee"], unite, liste_err)
# Tracé de la ligne verticale
ax.vlines(agec, poids_min, poids_max, linestyles="dashed", color=conf["couleurs"]["cadretxt"])
- # Tracé éventuel du texte
+ # date à afficher ?
+ if rep["affichedate"] == "oui" and rep["date"] != "":
+ ax.text(agec, poids_min,rep["date"]+" ", rotation=90, verticalalignment='top', horizontalalignment='center', color=conf["couleurs"]["cadretxt"], fontstyle="italic")
+ # Si y'a un texte à afficher
if rep["texte"] != "":
ax.text(agec, poids_min, " "+rep["texte"], rotation=90, verticalalignment='bottom', horizontalalignment='right', color=conf["couleurs"]["cadretxt"])