EC321 : évaluation en contrôle continu
Durée : 2h
Tout document autorisé
1. NYC Athletic Facilities API
Cette API répertorie les 6879 installations sportives réparties dans les 5 arrondissements (borough) de la ville de New York.
https://data.cityofnewyork.us/resource/qnem-b8re.json
Exercice 1
Écrivez un script nyc-boroughs.py
qui calcule le nombre d'installations sportives par
arrondissement sachant que :
- B correspond à Brooklyn
- M correspond à Manhattan
- Q correspond au Queens
- R correspond à Staten Island (comté de Richmond)
- X correspond au Bronx
#############################
# #
# NYC Athletic Facilities #
# #
#############################
Brooklyn : 2212
Manhattan : 1099
Queens : 2120
Staten Island: 293
The Bronx : 1146
import requests as rq
import pandas as pd
def get_facilities_by_borough(code):
parameters = {
'$limit': 10000,
'borough': code
}
response = rq.get('https://data.cityofnewyork.us/resource/qnem-b8re.json', params=parameters)
if response.status_code == 200:
return len(response.json())
else:
print('Error', response.status_code, response.reason)
return -1
print('Brooklyn :', get_facilities_by_borough('B'))
print('Manhattan :', get_facilities_by_borough('M'))
print('Queens :', get_facilities_by_borough('Q'))
print('Staten Island:', get_facilities_by_borough('R'))
print('The Bronx :', get_facilities_by_borough('X'))
Exercice 2
Écrivez un script queens-courts.py
qui, sur une carte centrée sur
[40.742054, -73.769417]
place un marqueur sur chaque terrain de basketball du Queens dont la couleur dépend du type de revêtement :
- Gris pour
Asphalt
- Rouge pour
Synthetic
- Bleu pour
Rubber
import requests as rq
import pandas as pd
import folium as fl
m = fl.Map(location=[40.742054, -73.769417], tiles='OpenStreetMap', zoom_start=12)
parameters = {
'$limit': 10000,
'borough': 'Q',
'basketball': True
}
response = rq.get('https://data.cityofnewyork.us/resource/qnem-b8re.json', params=parameters)
if response.status_code == 200:
for court in response.json():
if court['surface_type'] == 'Asphalt':
c = 'gray'
elif court['surface_type'] == 'Synthetic':
c = 'red'
else:
c = 'blue'
coords = court['multipolygon']['coordinates'][0][0][0]
fl.Marker([coords[1], coords[0]],
popup=court['surface_type'],
icon=fl.Icon(color=c)).add_to(m)
m.save('queens-courts.html')
else:
print('Error', response.status_code, response.reason)
2. One Punch Man
Le fichier joints.xlsx
contient les positions 3D des segments articulaires estimés par
MediaPipe pour chaque frame de la vidéo.
La feuille IMAGE
contient les coordonnées, exprimées en pixels, de chaque articulation au fil du
temps.
- L'axe X est horizontal, dirigé vers la droite
- L'axe Y est vertical, dirigé vers le haut
- L'axe Z est perpendiculaire au plan image
- L'origine du repère est située dans le coin gauche inférieur de la vidéo
Exercice 3
Écrivez un script punch-time.py
qui affiche l'instant où le poing frappe le sac, c'est à dire le
moment
où le poignet est le plus avancé dans la vidéo.
Punch time at frame 199
import pandas as pd
joints = pd.read_excel('joints.xlsx', sheet_name='IMAGE')
i = joints['LEFT_WRIST_X'].idxmin()
print('Punch time at frame', joints['frame'][i])
Afin d'évaluer la qualité du suivi effectué par MediaPipe, on souhaite calculer la longueur du bras, distance entre l'épaule et le coude, exprimée en pixels pour chaque frame de la vidéo
Exercice 4
Écrivez un script upper-arm-length.py
qui ajoute une nouvelle colonne UAL
au fichier
joints.xlsx
contenant la longueur du bras, exprimée en pixels, au fil du temps. Le script affichera
la moyenne et l'écart de cette nouvelle colonne ainsi que le graphique des valeurs au fil du temps.
Upper arm length: 202 ± 22 px
import pandas as pd
from math import sqrt
import matplotlib.pyplot as plt
def vector_length(x, y, z):
return sqrt(x**2 + y**2 + z**2)
def distance(x1, y1, z1, x2, y2, z2):
return vector_length(x2-x1, y2-y1, z2-z1)
joints = pd.read_excel('joints.xlsx', sheet_name='IMAGE')
for i in joints.index:
joints.loc[i, 'UAL'] = distance(joints['LEFT_SHOULDER_X'][i], joints['LEFT_SHOULDER_Y'][i], joints['LEFT_SHOULDER_Z'][i], joints['LEFT_ELBOW_X'][i], joints['LEFT_ELBOW_Y'][i], joints['LEFT_ELBOW_Z'][i])
print('Upper arm length:', round(joints['UAL'].mean()), '±', round(joints['UAL'].std()), 'px')
plt.plot(joints['UAL'])
plt.title('Upper arm length')
plt.xlabel('frame')
plt.ylabel('length (pixels)')
plt.legend()
plt.show()
3. Test de Sargent
Le test de Sargent est un test physique qui permet d'évaluer la détente verticale d'une personne. Ce même test permet aussi d'évaluer la puissance des membres inférieurs.
Le test se déroule en deux étapes:
- La personne se tient droite, dos au mur à une distance de 15cm. Elle lève un bras le plus haut possible et on mesure la hauteur H0 (en cm) de l'extrémité des doigts.
- Sans changer de position, le personne doit chercher à sauter le plus haut possible. À l'apogée du saut, on mesure la hauteur H1 (en cm) de l'extrémité des doigts.
La détente sèche D correspond à l'écart entre les hauteurs H0 et H1 :
D = H1 - H0
Intervalle | Interprétation |
---|---|
D > 71 | excellente |
66 < D ≤ 71 | très bonne |
53 < D ≤ 66 | bonne |
49 < D ≤ 53 | moyenne |
40 < D ≤ 49 | faible |
37 < D ≤ 40 | insuffisante |
D ≤ 37 | très insuffisante |
Mais à partir de la valeur D de la détente, on peut déduire la puissance des membres inférieurs grâce à la formule d'Harman :
P = 21.2 × D + 23 × M - 1393
Où M est la masse de l'individu en kg.
Exercice 5
Écrivez un script sargent.py
qui calcule la détente sèche et la puissance des membres
inférieurs à partir de
la saisie au clavier des hauteurs H0, H1 et de la masse M.
#####################
# #
# Test de Sargent #
# #
#####################
H0 (cm) ? 245
H1 (cm) ? 298
M (kg) ? 84
D = 53.0 cm
Détente sèche moyenne
P = 1663 W
print('\n\n')
print('#####################')
print('# #')
print('# Test de Sargent #')
print('# #')
print('#####################')
print('\n')
h0 = float(input('H0 (cm) ? '))
h1 = float(input('H1 (cm) ? '))
m = float(input('M (kg) ? '))
d = h1 - h0
if d > 71:
interpretation = 'excellente'
elif d > 66:
interpretation = 'très bonne'
elif d > 53:
interpretation = 'bonne'
elif d > 49:
interpretation = 'moyenne'
elif d > 40:
interpretation = 'faible'
elif d > 37:
interpretation = 'insuffisante'
else:
interpretation = 'très insuffisante'
print('\nD =', d, 'cm')
print('Détente sèche', interpretation)
print('\nP =', round(21.2 * d + 23.0 * m - 1393), 'W')