TD F3 : exploiter un fichier texte avec des données numérique (correction)¶
L'objectif de ce TD est de récupérer les données numériques contenues dans un texte et de faire quelques opérations sur celles-ci.
Dans nos activités, le plus souvent, les fichiers contiendront des données numériques que l'on devra étudier. Par exemple, dans ce travail on va étudier les données (issues d'un fichier GPS) relevées lors d'une sortie d'un cycliste. Voici le début du fichier (il est lié à ce TD):
txt
# time(s), distance(km), elevation(m)
0 0 780.4
1 0.005619584185703101 780.6
2 0.013857605826860752 780.9
3 0.020495868631472042 781.1
...
On rappelle la fonction python read_datas(nomfich : str) -> list qui lit ligne par ligne le contenu d'un fichier et qui renvoie la liste de chaque ligne contenant des données numériques.
def read_datas(nomfich : str) -> list:
""" renvoie la liste constituée par les lignes
du fichier nomfich"""
lst = []
with open(nomfich,mode="r") as f :
for line in f:
if line[0] not in ['\n', '#'] :
lst.append(line)
return lst
# test :
print(read_datas('data_cycle.txt')[:10])
['0\t0\t780.4\n', '1\t0.005619584185703101\t780.6\n', '2\t0.013857605826860752\t780.9\n', '3\t0.020495868631472042\t781.1\n', '4\t0.026106630314283865\t781.2\n', '5\t0.0316834089922878\t781.2\n', '6\t0.03712030885730648\t781.2\n', '7\t0.04356730294189649\t781.1\n', '8\t0.049778524036890495\t781.1\n', '9\t0.05673365615708354\t781.0\n']
Q1. Compléter la fonction python parse(lst : list) -> dict dont le but est d'analyser le fichier datas_cycle.txt et de renvoyer les données des trois colonnes stockées sous forme d'un dictionnaire dont la structure est la suivante :
datas_dict = {
'time' : .... , # liste des temps (colonne 1)
'distance' : .... , # liste des distances (colonne 2)
'elevation' : .... # liste des altitudes (colonne 3)
}
(On pourra se reporter au TD04A et notamment penser à utiliser la fonction split...)
def parse(lst : list) -> list :
""" récupère une liste de str contenant chacune 3 valeurs (time/dist/elev),
récupère ces données et les stocke dans un dictionnaire du type :
datas_dict = {
'time' : .... , # liste des temps (colonne 1)
'distance' : .... , # liste des distances (colonne 2)
'elevation' : .... # liste des altitudes (colonne 3)
}
"""
datas_dic = {
'time' : [],
'distance' : [],
'elevation' : []
}
for line in lst :
x,y,z = line.split()
datas_dic['time'].append(int(x)) # temps en secondes
datas_dic['distance'].append(float(y)) # distance en km
datas_dic['elevation'].append(float(z)) # altitude en m
return datas_dic
# on teste :
lst_str = read_datas("data_cycle.txt")
dic_datas = parse(lst_str)
print(dic_datas)
Q2 Toutes les données du fichiers sont maintenant disponibles à l'aide de la seule variable dic_datas obtenue par retour de la fonction parse(...). Écrire alors une fonction python duree_totale(...) qui reçoit le dictionnaire dic_datas et qui renvoie la durée totale de la sortie en secondes.
(Pour les plus rapides, ajouter une fonction de conversion qui reçoit des secondes et qui renvoie le tuple (heures,minutes,secondes) correspondant.)
def duree_totale(dic : dict) -> int:
""" renvoie la duree totale en seconde des données
stockées dans le dictionnaire 'datas' """
tot = dic['time'][-1]
return tot
def conv(duree : int)->tuple:
""" reçoit une durée en secondes et renvoie un tuple
(heures,minutes,secondes)"""
s = duree % 60
duree = duree // 60
h = duree // 60
m = duree % 60
return (h,m,s)
# on teste :
dic_datas = parse(read_datas("data_cycle.txt"))
duree = duree_totale(dic_datas)
print(f"duree totale : {duree} secondes")
hms = conv(duree)
print(f"duree totale : {hms[0]} h, {hms[1]} m, et {hms[2]} secondes")
duree totale : 26719 secondes duree totale : 7 h, 25 m, et 19 secondes
Q3. Écrire ensuite une fonction python distance_totale(dic) qui reçoit le dictionnaire dic_datas et qui renvoie la distance totale de la sortie en km.
def distance_totale(dic : dict) -> int:
""" renvoie la distance totale en kilomètres des données
stockées dans le dictionnaire 'datas' """
tot = dic['distance'][-1]
return tot
# on teste :
dic_datas = parse(read_datas("data_cycle.txt"))
distance = distance_totale(dic_datas)
print(f"distance totale : {distance} kilomètres")
distance totale : 186.6670492058025 kilomètres
Q4. Écrire une fonction python vitesse_moyenne(dic) qui reçoit le dictionnaire dic_datas et qui renvoie la vitesse moyenne de la sortie (en km/h).
def vitesse_moyenne(dic : dict) -> int:
""" renvoie la vitesse moyenne en km/h"""
d = distance_totale(dic) # distance en km
t = duree_totale(dic)/3600 # duree en h
v = d/t
return v
# on teste :
dic_datas = parse(read_datas("data_cycle.txt"))
vitesse = vitesse_moyenne(dic_datas)
print(f"vitesse moyenne : {vitesse} km/h")
vitesse moyenne : 25.150693406972152 km/h
Q5. Écrire une fonction python alti_max(dic) ui reçoit le dictionnaire dic_datas et qui renvoie l'altitude maximale (en m).
def alti_max(dic : dict)->float:
""" renvoie l'altitude maximale de la sortie"""
return max(dic['elevation'])
# on teste :
dic_datas = parse(read_datas("data_cycle.txt"))
alti = alti_max(dic_datas)
print(f"Altitude maximale {alti} mètres")
Altitude maximale 2363.3 mètres
Q6. Un peu plus élaboré : écrire une fonction python alti_cumul(dic) qui reçoit le dictionnaire dic_datas et qui renvoie le dénivelé cumulé positif total (en m).
def alti_cumul(dic : dict)->float :
""" Renvoie le dénivelé cumulé en mètres de la sortie"""
cum = 0
lst_alti = dic['elevation']
for i in range(0,len(lst_alti)-1):
diff = lst_alti[i+1]-lst_alti[i]
if diff>0 :
cum += diff
return cum
# on teste :
dic_datas = parse(read_datas("data_cycle.txt"))
alti_cumulee = alti_cumul(dic_datas)
print(f"Altitude cumulée {alti_cumulee} mètres")
Altitude cumulée 7522.900000000089 mètres
- durée totale = 26719 s
- distance totale = 187 km
- vitesse moyenne = 25 km/h
- altitude maximale = 2363 m
- dénivelé cumulé = 7523 m