]>
git.immae.eu Git - perso/Denise/oms.git/blob - gestion_donnees.py
2 # -*- coding: utf-8 -*-
4 from configuration
import *
5 from gestion_erreurs
import *
6 from gestion_couleurs
import *
12 ### Les données "tournent" selon :
13 ### python -> json -> (export/import) -> formulaire HTML -> données POST -> python etc
15 ############ Fonctions de conversion
17 def convertit_jours_vers_python(chaine
,liste_err
):
18 """ convertit une chaine de type 1a 3m 1s 10j en jours
19 Renvoie un nombre de jours en float
20 Si un des caractères n'est ni un nombre, ni une lettre "autorisée" ni une espace,
21 on affiche un warning et on ignore ce caractère
27 chainenombre
+= lettre
29 if lettre
== 'a' or lettre
== 'A':
30 # On a trouvé l'année, on ajoute tout ce qui est trouvé jusque là
31 agejours
+= int(chainenombre
)*jours_dans_annee
33 elif lettre
== 'm' or lettre
== 'M':
35 agejours
+= int(chainenombre
)*jours_dans_mois
37 elif lettre
== 's' or lettre
== 'S':
39 agejours
+= int(chainenombre
)*jours_dans_semaine
41 elif lettre
== 'j' or lettre
== 'J':
43 agejours
+= int(chainenombre
)
46 # autre caractère : bizarre ?
47 warning("convertit_jour_vers_python : caractère invalide : "+lettre
,liste_err
)
48 # à la fin s'il reste qqch on le garde dans les jours
49 if chainenombre
!= "":
50 agejours
+= int(chainenombre
)
52 warning("L'âge est négatif !",liste_err
)
56 def convertit_age_vers_texte(nombre
):
57 """ convertit un nombre de jours en un truc plus lisible en mois, années, jours
58 et renvoie une chaîne sous la forme 3a2m1j par exemple"""
59 annees
= int(nombre
/ jours_dans_annee
)
60 restant
= nombre
- annees
*jours_dans_annee
61 mois
= int(restant
/jours_dans_mois
)
62 jours
= round(nombre
- mois
*jours_dans_mois
- annees
*jours_dans_annee
)
66 chaine
+= str(annees
)+"a"
68 chaine
+= str(mois
)+"m"
69 if jours
>0 or nombre
==0: # si c'est la naissance, faut beien écrire 0j quand même
70 chaine
+= str(jours
)+"j"
72 ##########################
75 def simplifie_nom(chaine
):
76 """ simplifie le nom chaine afin d'en faire une extension
77 pour le nom du fichier. Met tout en minuscules et vire les caractères spéciaux
78 et max 15 caractères"""
83 chaine2
= unidecode
.unidecode(chaine2
)
86 def convertit_poids_vers_python(chaine
,liste_err
):
87 """ convertit une chaine vers un float qui est le poids.
88 On gère notamment la virgule, et on enlève les espaces
89 Un poids invalide -> on renvoie 0 avec un warning"""
90 chaine2
= chaine
.replace(",",".")
91 chaine2
= chaine2
.replace(" ","")
94 poids
= float(chaine2
)
96 warning("Poids impossible à lire : "+chaine
,liste_err
)
98 if not( 0<=poids
<poids_maxi
):
99 warning("Poids incohérent : "+str(poids
),liste_err
)
103 #def convertit_poids_vers_texte(poids):
104 # """ convertit un poids vers du texte. Rien à dire là pour l'instant """
107 #########################
109 def convertit_date_vers_python(chaine
,liste_err
):
110 """ prend une chaine comme renvoyée par un champ de formulaire date
111 aaaa-mm-jj et en fait une date python
112 renvoie "" si ne marche pas"""
113 liste
= chaine
.split("-")
115 warning("La date : "+chaine
+" est invalide !",liste_err
)
119 date
= datetime
.date(int(liste
[0]),int(liste
[1]),int(liste
[2]))
122 warning("Impossible de lire la date "+chaine
,liste_err
)
125 def convertit_date_vers_texte(date
):
126 """ convertit une date python en format texte aaaa-mm-jj"""
130 return (str(date
.year
)+"-"+str(date
.month
)+"-"+str(date
.day
))
133 def delta_date(date1
,datenaissance
):
134 """ renvoie le nombre de jours (entier) entre date1 et datenaissance format "datetime"
135 datenaissance est supposée antérieure. Erreur sinon."""
136 d
= date1
- datenaissance
139 erreur_continue("La différence entre les dates est négative... :/")
144 ########### Fonctions qui gèretn les données
147 def gere_configuration(data
,liste_err
):
148 """ prend en argument le dictionnaire de requête (configuration imparfaite), et
149 construit le dictionnaire de configuration qui va bien.
150 Vérifie que chaque entrée est cohérente évidemment."""
153 # Pour le nom, osef qu'il soit vide
154 nom
= data
.get("nom","")
155 # Par contre s'il est trop long on le tronque
156 configuration
["nom"] = nom
[:longueur_max_nom_bebe
]
158 sexe
= data
.get("sexe","")
159 if not (sexe
in ["F","M","N"]):
160 warning("Le sexe de l'enfant est invalide ! "+sexe
,liste_err
)
162 configuration
["sexe"] = sexe
164 naissance
= data
.get("naissance","")
166 naissance
= convertit_date_vers_python(naissance
,liste_err
)
167 configuration
["naissance"] = naissance
169 # Type de courbe. Au pire on met P
170 tyc
= data
.get("typecourbe","")
171 if not (tyc
in ["P","Z"]):
173 configuration
["typecourbe"] = tyc
176 unite
= data
.get("unite","")
178 if not (unite
in CONFIG
["liste_unites"]):
180 #warning("L'unité "+unite+" n'est pas reconnue !",liste_err)
181 configuration
["unite"] = unite
184 grille
= data
.get("grille","")
186 configuration
["grille"] = ""
188 configuration
["grille"] = "oui"
190 # maxi. 0 signifie qu'on veut pas de maxi
191 maxi
= data
.get("maxi","")
193 configuration
["maxi"] = 0
195 configuration
["maxi"] = convertit_jours_vers_python(maxi
,liste_err
)
197 # dimensions du graphique
198 largeur
= data
.get("largeur","")
200 largeur
= DEFAUT
["largeur_graphique"]
203 largeur
= int(largeur
)
205 warning("La largeur "+largeur
+"est invalide !",liste_err
)
206 largeur
= DEFAUT
["largeur_graphique"]
207 if largeur
> largeur_graphique_max
:
208 largeur
= largeur_graphique_max
209 warning("Largeur trop grande !",liste_err
)
210 elif largeur
< largeur_graphique_min
:
211 largeur
= largeur_graphique_min
212 warning("Largeur trop petite !",liste_err
)
213 configuration
["largeur"] = largeur
215 hauteur
= data
.get("hauteur","")
217 hauteur
= DEFAUT
["hauteur_graphique"]
220 hauteur
= int(hauteur
)
222 warning("La hauteur "+hauteur
+"est invalide !",liste_err
)
223 hauteur
= DEFAUT
["hauteur_graphique"]
224 if hauteur
> hauteur_graphique_max
:
225 hauteur
= hauteur_graphique_max
226 warning("Hauteur trop grande !",liste_err
)
227 elif hauteur
< hauteur_graphique_min
:
228 hauteur
= hauteur_graphique_min
229 warning("Hauteur trop petite !",liste_err
)
230 configuration
["hauteur"] = hauteur
232 # existence et position de la légende
233 legende
= data
.get("legende","")
240 configuration
["legende"] = legende
242 positionlegende
= data
.get("positionlegende","")
243 if not(positionlegende
in ['upper left','upper right','lower left','lower right']):
244 positionlegende
= "upper left"
245 configuration
["positionlegende"] = positionlegende
248 configuration
["couleurs"] = {}
250 for clecouleur
in DEFAUT
["couleurs"]:
251 coul
= rgb_vers_tuple(data
.get("couleur_"+clecouleur
,""),CONFIG
["couleurs"][clecouleur
],liste_err
)
252 configuration
["couleurs"][clecouleur
] = coul
258 def gere_donneespoids(data
,naissance
,liste_err
):
259 """ prend en argument le dictionnaire de requête, et la date de naissance
260 (éventuellement vide) et construit les deux listes l_jours et l_poids"""
262 # On construit la liste des couples
266 # On va chercher si y'a des données à poids_i
267 while "poids_"+str(i
) in data
.keys():
268 if data
["poids_"+str(i
)] != "":
269 poids
= convertit_poids_vers_python(data
["poids_"+str(i
)],liste_err
)
270 age
= data
.get("age_"+str(i
),"")
272 age
= convertit_jours_vers_python(age
,liste_err
)
273 liste_donnees
.append((age
,poids
))
275 date
= data
.get("date_"+str(i
),"")
276 datep
= convertit_date_vers_python(date
,liste_err
)
279 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
)
280 elif datep
!= "": # la date est valide et on a une date de naissance
281 age
= delta_date(datep
,naissance
)
282 liste_donnees
.append((age
,poids
))
286 liste_donnees
.sort(key
=lambda x
: x
[0])
289 l_jours
= [x
[0] for x
in liste_donnees
]
290 l_poids
= [x
[1] for x
in liste_donnees
]
292 return (l_jours
,l_poids
)
297 def donnees_vers_json(l_jours
,l_poids
,config
):
298 """ retourne le json à renvoyer"""
299 gros_dico
= copy
.deepcopy(config
)
300 l_jours2
= [convertit_age_vers_texte(d
) for d
in l_jours
]
301 gros_dico
["data_j"] = l_jours2
302 gros_dico
["data_p"] = l_poids
303 # gérer la date de naissance
304 if gros_dico
.get("naissance","") != "":
305 gros_dico
["naissance"] = convertit_date_vers_texte(gros_dico
["naissance"])
307 gros_dico
["maxi"] = convertit_age_vers_texte(gros_dico
["maxi"])
309 # for cle in ["couleur1", "couleur2", "couleur3", "couleur_fond","couleur_grille","couleur_cadretxt"]:
310 # gros_dico[cle] = tuple_vers_rgb(gros_dico[cle])
311 for clecouleur
in DEFAUT
["couleurs"]:
312 gros_dico
["couleurs"][clecouleur
] = tuple_vers_rgb(gros_dico
["couleurs"][clecouleur
])
316 return json
.dumps(gros_dico
, indent
=2,ensure_ascii
=False )
319 def fichier_json_vers_configdonnees(fichier
,liste_err
):
320 """ prend le json importé et l'exporte vers les valeurs du formulaire """
321 chaine
= fichier
.read()
322 valform
= json
.loads(chaine
)
323 # Il faut maintenant récupérer les l_jours et l_poids puis les remettre
324 # sous forme de age_i et poids_i
325 l_jours
= valform
.get("data_j",[])
326 l_poids
=valform
.get("data_p",[])
327 if len(l_poids
) != len(l_jours
):
328 warning("Lecture du json : les données sont incohérentes (listes de taille différentes et/ou pb de lecture")
329 long = min(len(l_jours
),len(l_poids
))
332 for i
in range(long):
333 valform
["age_"+str(i
)] = l_jours
[i
]
334 valform
["poids_"+str(i
)] = l_poids
[i
]
336 valform
["nb_data"] = max(long +2,DEFAUT
["nb_data"])