]>
git.immae.eu Git - perso/Denise/oms.git/blob - gestion_donnees.py
2 # -*- coding: utf-8 -*-
4 from configuration
import CONFIG
,DEFAUT
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
)*CONFIG
["jours_dans_annee"]
33 elif lettre
== 'm' or lettre
== 'M':
35 agejours
+= int(chainenombre
)*CONFIG
["jours_dans_mois"]
37 elif lettre
== 's' or lettre
== 'S':
39 agejours
+= int(chainenombre
)*CONFIG
["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
/ CONFIG
["jours_dans_annee"])
60 restant
= nombre
- annees
*CONFIG
["jours_dans_annee"]
61 mois
= int(restant
/CONFIG
["jours_dans_mois"])
62 jours
= round(nombre
- mois
*CONFIG
["jours_dans_mois"] - annees
*CONFIG
["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
<CONFIG
["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
)
118 debug("Conversion de la date "+chaine
+". Découpage : "+str(liste
),liste_err
)
120 date
= datetime
.date(int(liste
[0]),int(liste
[1]),int(liste
[2]))
123 warning("Impossible de lire la date "+chaine
+". Format accepté : aaaa-mm-jj",liste_err
)
126 def convertit_date_vers_texte(date
):
127 """ convertit une date python en format texte aaaa-mm-jj"""
131 return (str(date
.year
)+"-"+str(date
.month
)+"-"+str(date
.day
))
134 def delta_date(date1
,datenaissance
):
135 """ renvoie le nombre de jours (entier) entre date1 et datenaissance format "datetime"
136 datenaissance est supposée antérieure. Erreur sinon."""
137 d
= date1
- datenaissance
140 erreur_continue("La différence entre les dates est négative... :/")
145 ########### Fonctions qui gèretn les données
148 def gere_configuration(data
,liste_err
):
149 """ prend en argument le dictionnaire de requête (configuration imparfaite), et
150 construit le dictionnaire de configuration qui va bien.
151 Vérifie que chaque entrée est cohérente évidemment."""
154 # Pour le nom, osef qu'il soit vide
155 nom
= data
.get("nom","")
156 # Par contre s'il est trop long on le tronque
157 configuration
["nom"] = nom
[:CONFIG
["longueur_max_nom_bebe"]]
159 sexe
= data
.get("sexe","")
160 if not (sexe
in ["F","M","N"]):
161 warning("Le sexe de l'enfant est invalide ! "+sexe
,liste_err
)
163 configuration
["sexe"] = sexe
165 naissance
= data
.get("naissance","")
167 naissance
= convertit_date_vers_python(naissance
,liste_err
)
168 configuration
["naissance"] = naissance
170 # Type de courbe. Au pire on met P
171 tyc
= data
.get("typecourbe","")
172 if not (tyc
in ["P","Z"]):
174 configuration
["typecourbe"] = tyc
177 unite
= data
.get("unite","")
179 if not (unite
in CONFIG
["liste_unites"]):
181 #warning("L'unité "+unite+" n'est pas reconnue !",liste_err)
182 configuration
["unite"] = unite
185 grille
= data
.get("grille","")
187 configuration
["grille"] = ""
189 configuration
["grille"] = "oui"
191 # maxi. 0 signifie qu'on veut pas de maxi
192 maxi
= data
.get("maxi","")
194 configuration
["maxi"] = 0
196 configuration
["maxi"] = int(convertit_jours_vers_python(maxi
,liste_err
))
198 # dimensions du graphique
199 largeur
= data
.get("largeur","")
201 largeur
= DEFAUT
["largeur_graphique"]
204 largeur
= int(largeur
)
206 warning("La largeur "+largeur
+"est invalide !",liste_err
)
207 largeur
= DEFAUT
["largeur_graphique"]
208 if largeur
> CONFIG
["largeur_graphique_max"]:
209 largeur
= CONFIG
["largeur_graphique_max"]
210 warning("Largeur du graphique trop grande !",liste_err
)
211 elif largeur
< CONFIG
["largeur_graphique_min"]:
212 largeur
= CONFIG
["largeur_graphique_min"]
213 warning("Largeur du graphique trop petite !",liste_err
)
214 configuration
["largeur"] = largeur
216 hauteur
= data
.get("hauteur","")
218 hauteur
= DEFAUT
["hauteur_graphique"]
221 hauteur
= int(hauteur
)
223 warning("La hauteur "+hauteur
+"est invalide !",liste_err
)
224 hauteur
= DEFAUT
["hauteur_graphique"]
225 if hauteur
> CONFIG
["hauteur_graphique_max"]:
226 hauteur
= CONFIG
["hauteur_graphique_max"]
227 warning("Hauteur du graphique trop grande !",liste_err
)
228 elif hauteur
< CONFIG
["hauteur_graphique_min"]:
229 hauteur
= CONFIG
["hauteur_graphique_min"]
230 warning("Hauteur du graphique trop petite !",liste_err
)
231 configuration
["hauteur"] = hauteur
233 # existence et position de la légende
234 legende
= data
.get("legende","")
241 configuration
["legende"] = legende
243 positionlegende
= data
.get("positionlegende","")
244 if not(positionlegende
in ['upper left','upper right','lower left','lower right']):
245 positionlegende
= "upper left"
246 configuration
["positionlegende"] = positionlegende
249 configuration
["couleurs"] = {}
251 for clecouleur
in DEFAUT
["couleurs"]:
252 coul
= rgb_vers_tuple(data
.get("couleur_"+clecouleur
,""),CONFIG
["couleurs"][clecouleur
],liste_err
)
253 configuration
["couleurs"][clecouleur
] = coul
259 def gere_donneespoids(data
,naissance
,liste_err
):
260 """ prend en argument le dictionnaire de requête, et la date de naissance
261 (éventuellement vide) et construit les deux listes l_jours et l_poids"""
263 # On construit la liste des couples
267 # On va chercher si y'a des données à poids_i
268 while "poids_"+str(i
) in data
.keys():
269 if data
["poids_"+str(i
)] != "":
270 poids
= convertit_poids_vers_python(data
["poids_"+str(i
)],liste_err
)
271 age
= data
.get("age_"+str(i
),"")
273 age
= convertit_jours_vers_python(age
,liste_err
)
274 liste_donnees
.append((age
,poids
))
276 date
= data
.get("date_"+str(i
),"")
277 datep
= convertit_date_vers_python(date
,liste_err
)
280 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
)
281 elif datep
!= "": # la date est valide et on a une date de naissance
282 age
= delta_date(datep
,naissance
)
283 liste_donnees
.append((age
,poids
))
287 liste_donnees
.sort(key
=lambda x
: x
[0])
290 l_jours
= [x
[0] for x
in liste_donnees
]
291 l_poids
= [x
[1] for x
in liste_donnees
]
293 return (l_jours
,l_poids
)
298 def donnees_vers_json(l_jours
,l_poids
,config
):
299 """ retourne le json à renvoyer"""
300 gros_dico
= copy
.deepcopy(config
)
301 l_jours2
= [convertit_age_vers_texte(d
) for d
in l_jours
]
302 gros_dico
["data_j"] = l_jours2
303 gros_dico
["data_p"] = l_poids
304 # gérer la date de naissance
305 if gros_dico
.get("naissance","") != "":
306 gros_dico
["naissance"] = convertit_date_vers_texte(gros_dico
["naissance"])
308 gros_dico
["maxi"] = convertit_age_vers_texte(gros_dico
["maxi"])
310 # for cle in ["couleur1", "couleur2", "couleur3", "couleur_fond","couleur_grille","couleur_cadretxt"]:
311 # gros_dico[cle] = tuple_vers_rgb(gros_dico[cle])
312 for clecouleur
in DEFAUT
["couleurs"]:
313 gros_dico
["couleurs"][clecouleur
] = tuple_vers_rgb(gros_dico
["couleurs"][clecouleur
])
317 return json
.dumps(gros_dico
, indent
=2,ensure_ascii
=False )
320 def fichier_json_vers_configdonnees(chaine
,liste_err
):
321 """ prend le json importé (chaine) et l'exporte vers les valeurs du formulaire """
322 debug("json vers config : Prêt à interpréter le json",liste_err
)
324 valform
= json
.loads(chaine
)
326 erreur("Impossible de lire le fichier json !",liste_err
)
328 # Il faut maintenant récupérer les l_jours et l_poids puis les remettre
329 # sous forme de age_i et poids_i
330 l_jours
= valform
.get("data_j",[])
331 l_poids
=valform
.get("data_p",[])
332 if len(l_poids
) != len(l_jours
):
333 warning("Lecture du json : les données sont incohérentes (listes de taille différentes et/ou pb de lecture")
334 long = min(len(l_jours
),len(l_poids
))
337 for i
in range(long):
338 valform
["age_"+str(i
)] = l_jours
[i
]
339 valform
["poids_"+str(i
)] = l_poids
[i
]
341 valform
["nb_data"] = max(long +2,DEFAUT
["nb_data"])