sauvegarde des dates + version de l'app dans le fichier de sauvegarde
[perso/Denise/oms.git] / calculs_extrapole.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 """
4 Created on Thu Feb 18 18:25:11 2021
5
6 @author: sekhmet
7 """
8
9 from gestion_erreurs import warning, debug
10 from configuration import CONFIG
11 from gestion_donnees import convertit_age_vers_texte
12 import gestion_unites as u
13 from math import ceil
14
15 #### Les fonctions qui permettent de faire les calculs additionnels une fois qu'on a l'extrapolation (ou pas)
16
17 def interpole_lineaire(dates, donnees, t, liste_err):
18 """ simple interpolation linéaire.
19 dates et donnees sont les dates et données de l'enfant.
20 t est le temps (jours) auquel on veut l'interpolation. On renvoie la donnée interpolée.
21 On interpole linéairement entre les deux données. Si ça
22 n'est pas possible parce que t n'est pas dans les bornes, on renvoie -1
23 """
24
25 if t<dates[0] or t>dates[-1]:
26 return -1 # en dehors des bornes
27
28 i=0 # on cherche l'intervalle : entre dates[i] et dates[i+1] on a la donnée t
29 while i<len(dates)-1 and dates[i+1]<t:
30 i+=1
31
32 m = (donnees[i+1] - donnees[i])/(dates[i+1] - dates[i]) # pente de la courbe
33 valeur = m * (t - dates[i]) + donnees[i]
34 return valeur
35
36
37 def interpole_lineaire_ordonnee(dates, donnees, val, liste_err):
38 """ interpolation linéaire des données.
39 dates et donnees sont les dates et données de l'enfant.
40 val est la valeur pour laquelle on veut trouver le temps.
41 On interpole linéairement entre les deux données. Si ça
42 n'est pas possible parce que t n'est pas dans les bornes, on renvoie -1
43
44 Comportement potentiellement foireux si jamais les données ne sont pas
45 croissantes (poids qui chute, etc)..."""
46
47 if val>max(donnees) or val<min(donnees):
48 return -1 # en dehors des maxi et mini
49
50 i = 0 # On cherche dans quel intervalles de données on se situe (donnnes[i]
51 # et donnees [i+1])
52 while i<len(donnees)-1 and donnees[i+1]<val:
53 i+=1
54
55 m = (dates[i+1] - dates[i])/(donnees[i+1] - donnees[i])
56 temps = m * (val - donnees[i]) + dates[i]
57
58 return ceil(temps)
59
60
61 ######################################
62
63
64
65
66
67 def calcule_donnee_extrapolee(dates_extrapole, donnees_extrapole, age_voulu, liste_err):
68 """ prend en argument les données extrapolées, l'âge voulu en jours.
69 Renvoie la donnée, ou -1 si ça n'a pas marché"""
70 age_voulu = int(age_voulu) # pour avoir les choses bien
71 debug("On veut la donnée à l'âge "+str(age_voulu), liste_err)
72 try:
73 i_date_voulue = dates_extrapole.index(age_voulu)
74 donnee_voulue = donnees_extrapole[i_date_voulue]
75
76 return donnee_voulue
77 #return formate_resultat_donnee(age_voulu, donnee_voulue, typedonnee, "", liste_err)
78 except:
79 warning("Impossible de calculer la donnée à l'âge "+age_voulu, liste_err)
80 return -1
81
82
83
84 def calcule_age_extrapole(dates_extrapole, donnees_extrapole, donnee_voulue, liste_err):
85 """ prend en argument les données extrapolées, la donnée voulue (dans l'unité adaptée)
86 Renvoie la donnée, ou -1 si ça n'a pas marché"""
87
88 debug("On veut savoir à quel âge on a "+str(donnee_voulue), liste_err)
89 try:
90 i=0
91 while i<len(donnees_extrapole) and donnees_extrapole[i]<donnee_voulue:
92 i+=1
93
94 return dates_extrapole[i]
95 #return formate_resultat_age(dates_extrapole[i], donnee_voulue, typedonnee, "", liste_err)
96 except:
97 warning("Impossible de calculer l'âge pour la donnée "+str(donnee_voulue), liste_err)
98 return -1
99
100 ######################################
101 ### Formatage du résultat "joli"
102
103 def met_s(chaine):
104 """ renvoie un s si pluriel, rien sinon"""
105 if int(chaine)>1:
106 return "s"
107 else:
108 return ""
109
110 def joliechaine_age(age):
111 """ prend en argument une chaîne du type 6a3m2j et renvoie une chaîne un peu
112 plus jolie à lire genre 6 ans, 3mois, 2 jours"""
113 retour = ""
114 nombre = ""
115 for char in age:
116 if char=="a":
117 retour+=nombre+" an"+met_s(nombre)+", "
118 nombre=""
119 elif char=="m":
120 retour+=nombre+" mois, "
121 nombre=""
122 elif char=="s":
123 retour+=nombre+" semaine"+met_s(nombre)+", "
124 nombre=""
125 elif char=="j":
126 retour+=nombre+" jour"+met_s(nombre)+", "
127 nombre=""
128 else:
129 nombre+=char
130 #print(retour)
131 return retour[:-2]
132
133 def formate_resultat_donnee(age, donnee, typedonnee, extra, liste_err):
134 """ Formate le tout en une zolie phrase
135 age et donnee sont les données,
136 typedonnee est le type de donnée (poids, etc)
137 extra est un truc additionnel à mettre entre parenthèses"""
138
139 donnee_arrondie = u.arrondit_donnee(donnee, typedonnee)
140 chaine = "À "+joliechaine_age(convertit_age_vers_texte(age))
141
142 if typedonnee == "poids":
143 chaine+= ", l'enfant pèsera "+str(donnee_arrondie)+" kg"
144 elif typedonnee == "taille":
145 chaine+= ", l'enfant mesurera "+str(donnee_arrondie)+" cm"
146 else: # phrase générique
147 chaine+= ", la donnée sera : "+str(donnee_arrondie)+" "+CONFIG["unites_typedonnees"][typedonnee]
148
149 if extra!="":
150 ajout=" ("+extra+")"
151 else:
152 ajout=""
153
154 chaine+=ajout+"."
155 return chaine
156
157 def formate_resultat_age(age, donnee, typedonnee, extra, liste_err):
158 """ formate les données en une zolie phrase
159 age et donnee sont les données
160 typedonnee est le type de donnée (poids, etc)
161 extra est un truc additionnel à mettre entre parenthèses"""
162 age_joli = joliechaine_age(convertit_age_vers_texte(age))
163 if typedonnee=="poids":
164 chaine= "L'enfant atteindra un poids de "+str(donnee)+" kg à l'âge de "+age_joli
165 elif typedonnee=="taille":
166 chaine= "L'enfant atteindra la taille "+str(donnee)+ "cm à l'âge de "+age_joli
167 else:# phrase générique
168 chaine= "L'enfant atteindra la donnée "+typedonnee+" "+str(donnee)+" à l'âge de "+age_joli
169
170 if extra!="":
171 ajout=" ("+extra+")"
172 else:
173 ajout=""
174
175 chaine+=ajout+"."
176 return chaine
177
178 def formate_extrapole(nb_extra):
179 """ Renvoie une chaîne qui dit sur cb on a extrapolé"""
180 message="extrapolation à partir "
181 if nb_extra== 0:
182 message+="de l'ensemble des données"
183 elif nb_extra==1:
184 message+="de la donnée la plus récente"
185 else:
186 message+="des "+str(nb_extra)+" dernières données"
187 return message
188
189 def formate_interpole():
190 return "interpolation à partir des données existantes"