Évaluation

Durée : 2 heures
Tout document autorisé

Fréquence cardiaque

L'objectif de cet exercice est d'évaluer les fréquences cardiaques des zones de récupération, d'aérobie et d'anaérobie à l'aide des formules de Karvonen.

La Fréquence Cardiaque Maximale (FCMax) est calculée, selon l'équation d'Astrand, comme suit :

La Fréquence Cardiaque Minimale (FCMin) correspond à la fréquence cardiaque au repos.

La Fréquence Cardiaque de Réserve (FCR) est égale à : FCR = FCMax - FCMin

Une Zone Cible (ZC) à N% est calculée de la manière suivante : ZC = FCR × N% + FCMin

ZC de récupérationde 60% à 70%
ZC d'aérobiede 70% à 80%
ZC d'anaérobiede 80% à 90%

Exercice

Écrivez un script fc.py qui calcule les fréquences des trois Zones Cibles à partir du sexe, de l'âge et de la fréquence cardiaque au repos d'un individu. Ces trois informations seront saisies au clavier :



#############################
#                           #
#  Calcul des Zones Cibles  #
#                           #
#############################


Êtes-vous une femme (F) ou un homme (H) ? H
Quel âge avez-vous ? 45
Quelle est votre fréquence cardiaque au repos (ppm) ? 59



ZC de récupération : 129 à 140 ppm
ZC d'aérobie       : 140 à 152 ppm
ZC d'anaérobie     : 152 à 163 ppm
Correction
print("\n\n")
print("#############################")
print("#                           #")
print("#  Calcul des Zones Cibles  #")
print("#                           #")
print("#############################")
print("\n")

gender = input("Êtes vous une femme (F) ou un homme (H) ? ")
age    = float(input("Quel âge avez-vous ? "))
fcmin  = float(input("Quelle est votre fréquence cardique au repos (ppm) ? "))

print("\n\n")

if gender == "F":
    fcmax = 226 - age
else:
    fcmax = 220 - age

fcr = fcmax - fcmin

zc60 = round(fcr*0.6 + fcmin)
zc70 = round(fcr*0.7 + fcmin)   
zc80 = round(fcr*0.8 + fcmin)
zc90 = round(fcr*0.9 + fcmin)

print("ZC de récupération : " + str(zc60) + " à " + str(zc70) + " ppm")     
print("ZC d'aérobie       : " + str(zc70) + " à " + str(zc80) + " ppm")     
print("ZC d'anaérobie     : " + str(zc80) + " à " + str(zc90) + " ppm")

Données au format CSV

Le fichier RATJ2012-21km-herve.schely.csv contient une liste de temps, de distances et d'élévations relevés le long du parcours d'un semi-marathon.

Time;Distance;Elevation
0.0;0;82.0
13.0;22.09;82.0
33.0;22.09;82.0
54.0;165.61;82.0
59.0;176.49;83.0
65.0;180.75;83.0
82.0;246.95;82.0
84.0;259.62;82.0

Exercice

Écrivez un script plotcsv.py qui charge le fichier RATJ2012-21km-herve.schely.csv en remplissant trois listes (time, distance et elevation). Vous générerez un graphique des distances par rapport au temps. Vous tracerez aussi la droite passant par les deux points extrêmes (ici en orange) afin d'évaluer visuellement la régularité de la cadence de course.

Correction
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('data/RATJ2012-21km-herve.schely.csv', sep=';')

time = list(df['Time'])
distance = list(df['Distance'])
elevation = list(df['Elevation'])

plt.plot(time, distance)
plt.plot([0, time[-1]],[0, distance[-1]])
plt.xlabel("Temps (s)")
plt.ylabel("Distance (m)")
plt.show()

Exercice

Écrivez un script ele95.py afin d'identifier l'instant (temps en secondes) où le coureur a atteint pour la première fois l'altitude de 95m.


Altitude de 95 mètres atteinte au bout de 2014 secondes.
Correction
import pandas as pd
import matplotlib.pyplot as plt

# Chargement du fichier CSV
df = pd.read_csv('data/RATJ2012-21km-herve.schely.csv', sep=';')

# Filtrage du DataFrame pour ne conserver que les lignes dont
# l'altitude est supérieure à 95 mètres
df95 = df[ df['Elevation']>= 95 ]

# Extraction de la première valeur à l'aide du premier
# indice (df95.index[0])
time = df95['Time'][df95.index[0]]

# Affichage du résultat
print('Altitude de 95 mètres atteinte au bout de ' + str(time) + ' secondes.')

Calcul de distances

Lorsqu'on souhaite calculer la distance sur la surface de la Terre entre deux points (lat1,lon1) et (lat2,lon2) assez proches, on doit pouvoir utiliser le théorème de Pythagore plutôt que les fonctions trigonométriques : ce qui revient à considérer la distance euclidienne (ligne droite) plutôt que la distance géodésique.

Exercice

Écrivez un script pythagore.py qui définit une fonction shortestDistance(lat1, lon1, lat2, lon2)qui calcule :

A = R × | lon2 - lon1 | (coté adjacent)

B = R × | lat2 - lat1 | (coté opposé)

Pour déduire la longueur de l'hypoténuse D = ( A2 + B2 ) 1/2

Info

R = 6371008.8 est le rayon moyen de la Terre exprimé en mètres.

Attention !

Les angles doivent être convertis en radians au préalable
Correction
from math import *

#
# Calcul du rayon moyen de la Terre
# https://en.wikipedia.org/wiki/Great-circle_distance#Radius_for_spherical_Earth
#

# Rayon de la Terre au niveau de l'équateur (en mètres)
a = 6378137

# Rayon de la Terre au niveau des pôles (en mètres)
b = 6356752 

# Rayon moyen de la Terre (en mètres)
R = (2*a+b)/3


def shortestDistance(lat1, lon1, lat2, lon2):
    global R

    lat1 = radians(lat1)
    lon1 = radians(lon1)
    lat2 = radians(lat2)
    lon2 = radians(lon2)

    A = R*fabs(lon2 - lon1)
    B = R*fabs(lat2 - lat1)

    return sqrt(A*A + B*B)

Données au format TCX

Le format Training Center XML (TCX) contient des données d'activités sportives : en plus des relevés GPS, on trouve des informations sur la dépense énergétique, la vitesse maximale durant une session.

<?xml version="1.0" encoding="UTF-8"?>
<TrainingCenterDatabase
  xsi:schemaLocation="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"
  xmlns:ns5="http://www.garmin.com/xmlschemas/ActivityGoals/v1"
  xmlns:ns3="http://www.garmin.com/xmlschemas/ActivityExtension/v2"
  xmlns:ns2="http://www.garmin.com/xmlschemas/UserProfile/v2"
  xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns4="http://www.garmin.com/xmlschemas/ProfileExtension/v1">
  <Activities>
    <Activity Sport="Running">
      <Id>2015-01-20T13:26:30.000Z</Id>
      <Lap StartTime="2015-01-20T13:26:30.000Z">
        <TotalTimeSeconds>419.855</TotalTimeSeconds>
        <DistanceMeters>1000.0</DistanceMeters>
        <MaximumSpeed>2.8459999561309814</MaximumSpeed>
        <Calories>64</Calories>
        <Intensity>Active</Intensity>
        <TriggerMethod>Manual</TriggerMethod>
        <Track>
          <Trackpoint>
            <Time>2015-01-20T13:26:30.000Z</Time>
            <Position>
              <LatitudeDegrees>25.06334876641631</LatitudeDegrees>
              <LongitudeDegrees>121.6330941952765</LongitudeDegrees>
            </Position>
            <AltitudeMeters>19.799999237060547</AltitudeMeters>
            <DistanceMeters>0.0</DistanceMeters>
            <Extensions>
              <TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2">
                <Speed>0.0</Speed>
                <RunCadence>0</RunCadence>
              </TPX>
            </Extensions>

Attention !

L'espace de nommage d'un fichier TCX est différent de celui d'un fichier GPX.
http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2

Exercice

Écrivez un script calories.py qui charge le fichier running.tcx afin d'extraire le nombre total de calories dépensées.


Nombre total de calories : 333.0
Correction
from bs4 import BeautifulSoup

# Chargement du fichier XML
content = open('data/running.tcx')

# Construction de l'arborescence
soup = BeautifulSoup(content, 'lxml')

# Initialisation du total de calories
total = 0

# Parcours des éléments calories
calories = soup.find_all('calories')
for element in calories:
  total = total + float(element.string)
  
# Affichage du résultat
print("Nombre total de calories : " + str(total))

Exercice

Complétez le script printtcx.py afin d'extraire les informations TotalTimeSeconds, DistanceMeters et MaximumSpeed pour chaque tour de piste (élément Lap). Ces informations seront enregistrées dans un fichier running.csv en respectant le format suivant :

TotalTimeSeconds;DistanceMeters;MaximumSpeed
419.855;1000.0;2.8459999561309814
399.273;1000.0;2.809000015258789
398.574;1000.0;2.6500000953674316
420.2;1000.0;2.5380001068115234
407.782;1000.0;3.871999979019165
25.127;65.73;2.6410000324249263
Correction
from bs4 import BeautifulSoup
import pandas as pd

# Chargement du fichier XML
content = open('data/running.tcx')

# Construction de l'arborescence
soup = BeautifulSoup(content, 'lxml')

# Création d'un DataFrame vide
df = pd.DataFrame([], columns=['TotalTimeSeconds', 'DistanceMeters', 'MaximumSpeed'])
row = 0

# Parcours des éléments lap
lap_list = soup.find_all('lap')
for lap in lap_list:
  df.loc[row, 'TotalTimeSeconds'] = lap.find('totaltimeseconds').string
  df.loc[row, 'DistanceMeters'] = lap.find('distancemeters').string
  df.loc[row, 'MaximumSpeed'] = lap.find('maximumspeed').string
  
  row += 1
  
# Enregistrement du DataFrame df au format CSV
df.to_csv('running.csv', index = False)