summaryrefslogtreecommitdiff
path: root/calculs_extrapole.py
blob: fdd4c680830cc2315b5bb513673ae9ff512efde6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 18 18:25:11 2021

@author: sekhmet
"""

from gestion_erreurs import warning, debug
from configuration import CONFIG
from gestion_donnees import convertit_age_vers_texte
import gestion_unites as u
from math import ceil

#### Les fonctions qui permettent de faire les calculs additionnels une fois qu'on a l'extrapolation (ou pas)

def interpole_lineaire(dates, donnees, t, liste_err):
    """ simple interpolation linéaire.
    dates et donnees sont les dates et données de l'enfant.
    t est le temps (jours) auquel on veut l'interpolation. On renvoie la donnée interpolée.
    On interpole linéairement entre les deux données. Si ça
    n'est pas possible parce que t n'est pas dans les bornes, on renvoie -1
    """
    
    if t<dates[0] or t>dates[-1]:
        return -1 # en dehors des bornes
    
    i=0 # on cherche l'intervalle : entre dates[i] et dates[i+1] on a la donnée t
    while i<len(dates)-1 and dates[i+1]<t:
        i+=1
    
    m = (donnees[i+1] - donnees[i])/(dates[i+1] - dates[i]) # pente de la courbe
    valeur = m * (t - dates[i]) + donnees[i]
    return valeur


def interpole_lineaire_ordonnee(dates, donnees, val, liste_err):
    """ interpolation linéaire des données.
    dates et donnees sont les dates et données de l'enfant.
    val est la valeur pour laquelle on veut trouver le temps.
    On interpole linéairement entre les deux données. Si ça
    n'est pas possible parce que t n'est pas dans les bornes, on renvoie -1
    
    Comportement potentiellement foireux si jamais les données ne sont pas
    croissantes (poids qui chute, etc)..."""
    
    if val>max(donnees) or val<min(donnees):
        return -1 # en dehors des maxi et mini
    
    i = 0 # On cherche dans quel intervalles de données on se situe (donnnes[i]
    # et donnees [i+1])
    while i<len(donnees)-1 and donnees[i+1]<val:
        i+=1   
        
    m = (dates[i+1] - dates[i])/(donnees[i+1] - donnees[i])
    temps = m * (val - donnees[i]) + dates[i]
    
    return ceil(temps)


######################################


            


def calcule_donnee_extrapolee(dates_extrapole, donnees_extrapole, age_voulu, liste_err):
    """ prend en argument les données extrapolées, l'âge voulu en jours.
    Renvoie la donnée, ou -1 si ça n'a pas marché"""
    age_voulu = int(age_voulu) # pour avoir les choses bien
    debug("On veut la donnée à l'âge "+str(age_voulu), liste_err)
    try:      
        i_date_voulue = dates_extrapole.index(age_voulu)
        donnee_voulue = donnees_extrapole[i_date_voulue]
        
        return donnee_voulue
        #return formate_resultat_donnee(age_voulu, donnee_voulue, typedonnee, "", liste_err)
    except:
        warning("Impossible de calculer la donnée à l'âge "+age_voulu, liste_err)
        return -1
    
 
    
def calcule_age_extrapole(dates_extrapole, donnees_extrapole, donnee_voulue,  liste_err):
    """ prend en argument les données extrapolées, la donnée voulue (dans l'unité adaptée)
    Renvoie la donnée, ou -1 si ça n'a pas marché"""
    
    debug("On veut savoir à quel âge on a "+str(donnee_voulue), liste_err)   
    try:
        i=0
        while i<len(donnees_extrapole) and donnees_extrapole[i]<donnee_voulue:
            i+=1      

        return dates_extrapole[i]
        #return formate_resultat_age(dates_extrapole[i], donnee_voulue, typedonnee, "", liste_err)
    except:
        warning("Impossible de calculer l'âge pour la donnée "+str(donnee_voulue), liste_err)
        return -1

######################################
### Formatage du résultat "joli"

def met_s(chaine):
    """ renvoie un s si pluriel, rien sinon"""
    if int(chaine)>1:
        return "s"
    else:
        return ""

def joliechaine_age(age):
    """ prend en argument une chaîne du type 6a3m2j et renvoie une chaîne un peu
    plus jolie à lire genre 6 ans, 3mois, 2 jours"""
    retour = ""
    nombre = ""
    for char in age:
        if char=="a":
            retour+=nombre+" an"+met_s(nombre)+", "
            nombre=""
        elif char=="m":
            retour+=nombre+" mois, "
            nombre=""
        elif char=="s":
            retour+=nombre+" semaine"+met_s(nombre)+", "
            nombre=""
        elif char=="j":
            retour+=nombre+" jour"+met_s(nombre)+", "
            nombre=""
        else:
            nombre+=char
    #print(retour)
    return retour[:-2]

def formate_resultat_donnee(age, donnee, typedonnee, extra, liste_err):
    """ Formate le tout en une zolie phrase
    age et donnee sont les données,
    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 typedonnee == "poids":
        chaine+= ", l'enfant pèsera "+str(donnee_arrondie)+" kg"
    elif typedonnee == "taille":
        chaine+= ", l'enfant mesurera "+str(donnee_arrondie)+" cm"
    else: # phrase générique
        chaine+= ", la donnée sera : "+str(donnee_arrondie)+" "+CONFIG["unites_typedonnees"][typedonnee]

    if extra!="":
        ajout=" ("+extra+")"
    else:
        ajout=""

    chaine+=ajout+"."
    return chaine

def formate_resultat_age(age, donnee, typedonnee, extra, liste_err):
    """ formate les données en une zolie phrase
    age et donnee sont les données
    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))
    if typedonnee=="poids":
        chaine= "L'enfant atteindra un poids de "+str(donnee)+" kg à l'âge de "+age_joli
    elif typedonnee=="taille":
        chaine= "L'enfant atteindra la taille "+str(donnee)+ "cm à l'âge de "+age_joli
    else:# phrase générique
        chaine= "L'enfant atteindra la donnée "+typedonnee+" "+str(donnee)+" à l'âge de "+age_joli
    
    if extra!="":
        ajout=" ("+extra+")"
    else:
        ajout=""

    chaine+=ajout+"."
    return chaine

def formate_extrapole(nb_extra):
    """ Renvoie une chaîne qui dit sur cb on a extrapolé"""
    message="extrapolation à partir "
    if nb_extra== 0:
        message+="de l'ensemble des données"
    elif nb_extra==1:
        message+="de la donnée la plus récente"
    else:
        message+="des "+str(nb_extra)+" dernières données"
    return message

def formate_interpole():
    return "interpolation à partir des données existantes"