--- /dev/null
+"Utilisation","Comment tracer la courbe ?","Remplissez le formulaire (vous pouvez laisser par défaut tous les champs qui ne vous « parlent » pas), puis cliquez sur ""Je veux la courbe !"". La courbe s'affiche plus bas. Si vous modifiez les données du formulaire, vous pouvez re-cliquer sur ce bouton pour la mettre à jour. Et c'est tout !"
+
+"Utilisation","Comment sauvegarder mes données pour une prochaine fois ?","L'outil ne propose pas de sauvegarde en ligne, car il ne garde aucune donnée personnelle. Quand vous demandez à tracer la courbe, il s'affiche en bas un champ de texte. Si vous copiez-collez ce contenu et le gardez dans un fichier, vous n'aurez pas à re-saisir les données. Utilisez la partie ""Importer le fichier de données"" puis ""Charger les données"" : les champs seront alors pré-remplis et vous pourrez les modifier ou ajouter des données (par exemple une pesée récente)."
+
+"Utilisation","Je ne comprends pas comment saisir les données âge/poids !","Pour chaque pesée, vous avez le choix entre donner son âge, ou donner la date de la pesée. Pour la date de la pesée, il faut que vous ayiez rempli la date de naissance (sinon l'outil ne peut pas calculer l'âge !). Pour l'âge, vous pouvez indiquer en années, mois, semaines, jours, et mélanger plusieurs unités. Par exemple 2m3j pour « 2 mois 3 jours ». Ne remplissez qu'un des deux champs : âge ou date. Puis saisissez le poids en kilogrammes dans la colonne de droite. <br>
+Si vous manquez de lignes, vous pouvez cliquer sur ""Ajouter des lignes"" pour avoir plus de champs de données. Il n'y a pas de problème à laisser des champs vides, ils seront simplement ignorés."
+
+"Courbe","À quoi sert ce site ?","Il sert à tracer la courbe de poids des bébés et jeunes enfants en fonction de leur âge, comme sur le carnet de santé, et la compare aux courbes de références de l'Organisation Mondiale de la Santé."
+
+"Courbe","Pourquoi des courbes OMS et pas des courbes françaises ?","Les particularités de ces données sont les suivantes : bébés et enfants choisis dans différents pays du monde (et non dans un seul pays), dans des familles raisonnablement aisées (pour éviter les problèmes liés à la malnutrition), et des bébés allaités. Plus d'infos <a href=""https://www.who.int/childgrowth/standards/technical_report/en/"">ici</a> (en anglais). L'idée générale était de donner une « référence » de croissance de l'enfant de l'espèce humaine. Cela ne veut pas dire que les courbes du carnet de santé français sont mauvaises (si vous avez celles datant d'avant 2018, elles sont un peu anciennes par contre), de fait, elles sont très peu différentes. Pour les autres pays je ne sais pas, je n'ai pas comparé."
+
+"Courbe","Mon enfant doit-il être dans la moyenne ?","Il y a des petits bébés, des gros bébés, des bébés moyens. En général, un bébé en bonne santé ""suit"" un couloir de courbe, que ce soit la courbe des « bébés crevettes » ou des « bébés dodus ». Un changement de couloir (poids en baisse le plus souvent) peut éventuellement être signe d'un problème. Ou pas. Dans tous les cas, référez vous à des professionnels de santé et/ou de la petite enfance."
+
+"Divers","Pourquoi cet outil ?","Tout a commencé sur le <a href=""https://forum.lllfrance.org/"">forum de La Leche League</a>, où de nombreuses mamans (et parfois quelques papas) viennent poser des questions sur l'allaitement. Souvent, se pose la question de la prise de poids du bébé, qui est un bon indicateur de si le bébé reçoit assez de lait. Le poids dans l'absolu étant peu pertinent, il est utile de « tracer » la courbe de poids. Il n'existe actuellement que peu d'outils qui permettent de le faire (l'OMS en fournit un qui ne fonctionne que sous windows), en voici un."
+
+"Divers","Mais qui es tu donc ?","Je suis une de ces nombreuses mamans qui s'est posée un jour (et un autre jour aussi) la question de la prise de poids de son enfant. Adepte de solutions libres et multi-plateforme, je n'ai rien trouvée qui me permette de tracer cette courbe, que ce soit pour mon enfant ou celui des autres. Je suis par ailleurs férue de programmation (et je l'enseigne d'ailleurs), et donc... voilà."
+
+"Technique","Quelle est la technologie utilisée derrière ?","Il s'agit de <a href=""https://flask.palletsprojects.com/en/1.1.x/"">flask</a>, un petit framework de développement web en <a href=""https://www.python.org/"">python</a>. Il y a une petite dose de <a href=""https://developer.mozilla.org/fr/docs/Web/JavaScript"">JavaScript</a> pour assaisonner le tout, et voilà."
from gestion_donnees import *
from gestion_unites import *
from trace_courbe import *
+from faq import *
+
import matplotlib.pyplot as plt
import base64
liste_err = initialise_erreurs()
data = flask.request.form
- config = gere_configuration(data,liste_err)
-
+ # Régler la configuration et les données
+ config = gere_configuration(data,liste_err)
l_jours,l_poids = gere_donneespoids(data,config["naissance"],liste_err)
+
+ # préparer l'export
+ texte = configuration_vers_texte(config)
+ texte += donnees_poids_vers_texte(l_jours,l_poids)
+
+ # créer la figure
fig = cree_figure(config,l_jours,l_poids,liste_err)
-
output = io.BytesIO()
FigureCanvas(fig).print_png(output)
-
plt.close(fig)
+
if ext == "b64":
- return flask.Response(base64.b64encode(output.getvalue()), mimetype='text/plain')
+ reponse = flask.jsonify({ "result":"success",
+ "messages": liste_err[1],
+ "image": base64.b64encode(output.getvalue()).decode("ascii"),
+ "export_txt": texte})
+ return reponse
+ #return flask.Response(base64.b64encode(output.getvalue()), mimetype='text/plain')
elif ext == "png":
return flask.Response(output.getvalue(), mimetype='image/png')
else:
return flask.Response(texte,mimetype="text/plain")
+@app.route("/faq")
+def faq():
+
+ table_faq = lire_fichier_csv_simple(fichier_FAQ)
+ l_categ,table_qr = extraire_tables_par_cat(table_faq)
+
+ return flask.render_template("faq.html",lcateg=l_categ,tableqr=table_qr,err=[])
+
+
if __name__ == "__main__":
app.run(host='0.0.0.0',debug=True)
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+### Les fonctions et données pour la FAQ
+
+import csv
+fichier_FAQ = "FAQ_data.txt"
+
+# Les questions seront dans une database sous la forme (categorie,question,reponse)
+
+def lire_fichier_csv_simple(fichier):
+ """ lire un fichier csv et le renvoyer en table"""
+ table=[]
+ with open(fichier, "r") as fichier_csv:
+ reader_notes = csv.reader(fichier_csv,delimiter=",",dialect="unix")
+ for ligne in reader_notes:
+ if ligne != []:
+ table.append(ligne)
+ return table
+
+
+
+
+
+# On trie par catégorie
+#table_faq.sort(key=(lambda x: x[0]))
+
+def extraire_categories(table):
+ """ extrait les catégories (1ere colonne du tableau de tableau)
+ renvoie sous forme de liste"""
+ liste_cat = []
+ for ligne in table:
+ if not (ligne[0] in liste_cat):
+ liste_cat.append(ligne[0])
+ return liste_cat
+
+def extraire_tables_par_cat(table):
+ """ construit deux tables : une de catégories, une de tables de (q,r)
+ categ[i] va correspondre à tableqr[i] en terme de catégorie"""
+ categ = extraire_categories(table)
+ tableqr = [ [] for i in range(len(categ)) ]
+
+ for ligne in table:
+ try:
+ cat = ligne[0]
+ (q,r) = [ligne[1],ligne[2]]
+ ind = categ.index(cat)
+ tableqr[ind].append((q,r))
+ except:
+ print("Impossible de lire la ligne : "+str(ligne))
+
+ return (categ,tableqr)
chaine2 = chaine2.replace(" ","")
try:
- poids = float(chaine)
+ poids = float(chaine2)
except:
warning("Poids impossible à lire : "+chaine,liste_err)
poids = 0
- if not( 0<poids<poids_maxi):
- warning("Poids incohérent : "+poids)
+ if not( 0<=poids<poids_maxi):
+ warning("Poids incohérent : "+str(poids),liste_err)
poids = 0
return poids
#le nb max du formulaire
valform["nb_data"] = indice_formulaire +2
- return valform
\ No newline at end of file
+ return valform
var formData = new FormData( document.getElementById("donnees_enfant") );
var requete = new XMLHttpRequest();
+ requete.responseType = "json";
requete.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200) {
- document.getElementById('courbe').src = 'data:image/png;base64,'+(this.response);
+ // on récupère les différents champs de la réponse
+ var image = this.response.image ;
+ var liste_warnings = this.response.messages
+ var texte = this.response.export_txt;
+ // On affiche l'image
+ document.getElementById('courbe').src = 'data:image/png;base64,'+(image);
document.getElementById('sectioncourbe').style.display = "block";
+
+ // on affiche l'export des données
+ document.getElementById('export').innerHTML = texte;
+ document.getElementById('sectionexport').style.display = "block";
+
+ // Si y'a eu des warnings, faut les afficher
+ if(liste_warnings.length != 0)
+ {
+ // afficher la liste des warnings
+ var elem_div = document.getElementById('courbe_warnings') ;
+ elem_div.style.display = "block" ;
+ var ul = elem_div.children[1] ;
+ for(i=0; i<liste_warnings.length; i++) {
+ var li = document.createElement("li");
+ li.appendChild(document.createTextNode(liste_warnings[i]));
+ ul.appendChild(li);
+ }
+
+
+ }
}
}
requete.open("POST","courbe/b64",true)
requete.send(formData)
}
-
-function exporte_donnees()
-{
- var formData = new FormData( document.getElementById("donnees_enfant") );
-
- var requete = new XMLHttpRequest();
- requete.onreadystatechange = function()
- {
- if (this.readyState == 4 && this.status == 200) {
- document.getElementById('export').innerHTML = this.responseText;
- document.getElementById('sectionexport').style.display = "block";
- }
- }
- requete.open("POST","export_donnees",true)
- requete.send(formData)
-
-
-}
width: 25em;
height: 20em;
}
+
+#courbe_warnings {
+ display: none;
+}
<nav><a href="/">Accueil et saisie des données</a> |
<a href="/apropos">À propos</a> |
+ <a href="faq">Foire Aux Questions</a>
</nav>
</body>
--- /dev/null
+{% extends "base.html" %}
+{% block contenu %}
+<h2>Foire Aux Questions</h2>
+
+<div id="sommaire">
+<ul>{% for cat in lcateg %}
+<li><a href="#{{ cat }}">{{ cat }}</a></li>
+{% endfor %}
+</ul>
+</div>
+
+<div id="questionsreponses">
+{% for i in range(lcateg|length) %}
+{% set qr = tableqr[i] %}
+
+<h3 id="{{ lcateg[i] }}">{{ lcateg[i] }}</h3>
+<ul>
+ {% for (q,r) in qr %}
+ <li><p><strong>Q : </strong>{{ q|safe }}</p>
+ <p><strong>R : </strong>{{ r|safe }}</p>
+ </li>
+ {% endfor %}
+</ul>
+
+
+{% endfor %}
+</div>
+
+
+{% endblock %}
<h3>Données de poids</h3>
<p>Syntaxe pour l'âge : utiliser j, s, m, a comme des "unités" (jours, semaines, mois, années). Vous pouvez mixer les unités, par exemple "3a2m5j" pour 3 ans, 2 mois et 5 jours. Les espaces sont ignorées, et il faut saisir des nombres entiers.</p>
-<p>Saisir le poids en kilogrammes (le point et la virgule comptent comme le séparateur virgule).</p>
+<p>Saisir le poids en kilogrammes (par exemple "2.62" ou "2,62" pour 2 kilogrammes et 620 grammes).</p>
<p>Il faut saisir la date ou l'âge. Si les deux sont saisis, seul l'âge comptera.</p>
<p>Si le tableau est laissé vide, cela génère une courbe "vide" de référence.</p>
<hr>
-<button onclick="appelle_image(); exporte_donnees()">Je veux la courbe !</button>
+<button onclick="appelle_image()">Je veux la courbe !</button>
<div id="sectioncourbe">
<h2>Courbe</h2>
<img id="courbe">
</div>
+<div id="courbe_warnings">
+<p><strong>Alerte :</strong> la courbe a eu quelques soucis à se générer. Voici la liste des erreurs.</p>
+<ul></ul>
+</div>
<div id="sectionexport">
<h2>Export des données</h2>