Exercice 3Amérique du Nord
– Bac NSI 2026 – Jour 2
🔥🔥🔥🔥🔥
Un club d’athlétisme organise une compétition de course à pied sur route. Deux épreuves sont proposées : une course de 5 km et une course de 10 km.
Le club souhaite gérer les inscriptions et les résultats de cette compétition à l’aide d’une base de données informatique constituée de deux tables : coureur et epreuve.
mots clés:
BDD, SQL, programmation Python, dictionnaires
Amérique du Nord – Bac NSI 2026 – Jour 2 Énoncé de l'exercice 3
Cet exercice porte sur les bases de données relationnelles, le langage SQL et la programmation Python, en particulier les dictionnaires.
Un club d’athlétisme organise une compétition de course à pied sur route. Deux épreuves sont proposées : une course de 5 km et une course de 10 km.
Partie A : Bases de données
Dans cet exercice, on pourra utiliser les clauses du langage SQL pour :
construire des requêtes d’interrogation à l’aide de SELECT, FROM, WHERE
(avec les opérateurs logiques AND et OR), JOIN ... ON ;
construire des requêtes d’insertion et de mise à jour à l’aide de UPDATE, INSERT et DELETE ;
affiner les recherches à l’aide de DISTINCT et ORDER BY ; réaliser des agrégations à l’aide de COUNT.
Le club souhaite gérer les inscriptions et les résultats de cette compétition à l’aide d’une base de données informatique constituée de deux tables : coureur et epreuve. Le schéma relationnel de cette base de données est représenté cidessous. Sur ce schéma, les clés primaires de chacune des tables sont soulignées et les clés étrangères sont précédées du symbole #.
Figure 1. Schéma de la base de données
Chaque coureur ne peut participer qu’à une seule épreuve.
Relation coureur
L’identifiant du coureur est son numéro de dossard. Ce numéro est automatiquement incrémenté d’une unité à chaque nouvel enregistrement. Les autres champs doivent être saisis par l’organisateur lorsqu’il reçoit les bulletins d’inscription des coureurs. La codification du sexe est « H » pour les hommes et « F » pour les femmes. Les temps sont exprimés en secondes et sont initialisés avec la valeur 0.
Extrait de table coureur
num_dossard
nom
prenom
annee
sexe
id_epreuve
temps
1
DA SILVA
José
1980
H
1
0
2
HANG LI
Léo
2005
H
2
0
3
BODIANE
Lola
2000
F
2
0
4
BRELET
Sandra
1972
F
1
0
Relation epreuve
Cette relation contient actuellement deux enregistrements, l’organisateur prévoyant d’ajouter de nouvelles distances dans le futur. La distance est exprimée en km et le prix de l’inscription en euros. Le champ horaire donne l’heure de départ de la course.
epreuve
id_epreuve
distance
horaire
prix
juge_arbitre
1
5
10
10
GAVEAU Philippe
2
10
11
20
BOULA Awa
Expliquer le choix de num_dossard comme clé primaire pour la relation coureur.
Décrire ce que donne la requête SQL suivante :
SELECT nom, prenom
FROM coureur
ORDER BY nom ;
Écrire une requête SQL permettant d’établir le nom et prénom de toutes les femmes inscrites à la compétition.
Écrire une requête SQL permettant de connaître le nombre total d’inscrits à la compétition.
L’organisateur reçoit le bulletin d’inscription contenant les informations suivantes :
Nom : REMY ; Prénom : Patrice
Civilité : homme
Course : 5 km
Année de naissance : 1973
Écrire une requête SQL permettant d’insérer ce participant dans la base.
Le coureur dont le numéro de dossard est le 137 s’est blessé quelques jours avant l’épreuve, il ne pourra pas participer à la course.
Écrire une requête SQL qui permettra à l’organisateur de supprimer son inscription de la base de données.
Le coureur dont le numéro de dossard est le 256 a oublié sur quelle épreuve (5 km ou 10 km) il s’est inscrit. Il contacte l’organisateur pour qu’il lui rappelle la distance qu’il devra parcourir ainsi que l’horaire de son départ.
Écrire une requête SQL permettant de lui fournir ces informations.
Lorsque les coureurs franchissent la ligne d’arrivée, le juge arbitre note leur numéro de dossard et leur temps de course (en secondes) sur une feuille de pointage. Voici un extrait d’une telle feuille :
dossard
temps
57
1242
72
1845
183
1284
2
1285
Les temps de tous les coureurs ayant été enregistrés, on souhaite afficher le classement général de la catégorie Master Femme pour la course de 10 km. Cette catégorie regroupe les coureuses nées avant 1986.
Écrire une requête SQL renvoyant le numéro de dossard, le nom, le prénom et le temps de course de ces participantes classées par temps de course croissant.
Partie B : Programmation Python
Émilie, fille de l’organisateur et élève en classe de terminale spécialité NSI propose de réaliser une étude pluriannuelle des performances accomplies.
Pour enregistrer les informations elle crée pour chaque type de course un dictionnaire de performances. Les clés d’un tel dictionnaire sont les années où ce type de course a eu lieu. La valeur associée à une année est la liste des meilleurs temps réalisés dans chacune des six catégories suivantes (dans cet ordre).
Junior homme (JH) et Junior femme (JF) : moins de 18 ans ;
Sénior homme (SH) et Sénior femme (SF) : de 18 à 40 ans ;
Master homme (MH) et Master femme (MF) : plus de 40 ans ;
Par exemple, le dictionnaire ci-dessous enregistre les performances pour les courses de 5 km. Il indique par exemple qu’en 2024 le meilleur temps réalisé dans la catégorie junior femme (JF) est de 1010 s, et celui dans la catégorie master homme (MH) de 1022 s.
Donner la valeur de l’expression dict_perf_5km[2025][2]
En 2026, pour la course de 5km, les meilleurs temps réalisés dans chaque catégorie sont les suivants :
Résultats par catégories - 2026
JH
JF
SH
SF
MH
MF
1004
1016
1000
1140
1023
1024
Écrire l’instruction permettant d’ajouter ces informations dans le dictionnaire dict_perf_5km.
Écrire le code de la fonction scratch qui prend en paramètres un dictionnaire de performances dico et une année annee, et qui renvoie le meilleur temps (toutes catégories confondues) de cette année. On suppose que annee est une clé présente dans dico.
On n’utilisera pas les fonctions natives min et max de Python.
Par exemple, l’appel scratch(dict_perf_5km, 2024) renvoie 1000.
Émilie propose maintenant la fonction suivante :
def mystere(dico, cat):
categories = ['JH','JF','SH','SF','MH','MF'] # ligne 2
s = 0 # ligne 3
nb = 0
for i in range(len(categories)):
if cat == categories[i]:
i_cat = i
for annee in dico.keys():
s = s + dico[annee][i_cat]
nb = nb + 1
return s/nb
Indiquer la valeur affectée à la variable i_cat au cours de l’appel mystere(dict_perf_5km, 'SH').
Un appel du type mystere(dict_perf_5km,'SG') pose problème car 'SG' n’est pas une catégorie répertoriée.
Indiquer quel sera le message d’erreur renvoyé à la console parmi les choix suivants :
“expected an indented block” ;
“takes 2 positionnals arguments but 3 were given” ;
“local variable 'i_cat' referenced before assignement” ;
“list index out of range”.
Proposer une assertion à ajouter entre la ligne 2 et la ligne 3 pour indiquer une éventuelle faute de saisie par un message à l’utilisateur du script.
Indiquer le résultat de l’appel mystere(dict_perf_5km,'SH').
Émilie souhaiterait disposer d’une fonction records prenant en paramètre un dictionnaire de performances et renvoyant la liste des meilleurs temps enregistrés pour chaque catégorie et toutes années confondues. Par exemple, l’appel records(dict_perf_5km) devrait renvoyer [998, 1010, 900, 959, 1002,
980]. On suppose que les temps enregistrés pour les différentes catégories et les différentes années n’excèdent jamais 24 h.
Amérique du Nord – Bac NSI 2026 – Jour 2 Correction de l'exercice 3
PARTIE A – Bases de données
1. Expliquer le choix de num_dossard comme clé primaire pour la relation coureur.
Le champ num_dossard est une bonne clé primaire car il identifie de manière unique chaque coureur. Deux coureurs ne peuvent pas avoir le même numéro de dossard.
2. Décrire ce que donne la requête SQL suivante.
SELECT nom, prenom
FROM coureur
ORDER BY nom;
Cette requête affiche les noms et prénoms de tous les coureurs, triés par ordre alphabétique des noms.
3. Écrire une requête SQL permettant d’établir le nom et prénom de toutes les femmes inscrites à la compétition.
SELECT nom, prenom
FROM coureur
WHERE sexe = 'F';
4. Écrire une requête SQL permettant de connaître le nombre total d’inscrits à la compétition.
SELECT COUNT(*)
FROM coureur;
5. Écrire une requête SQL permettant d’insérer ce participant dans la base.
6. Écrire une requête SQL qui permettra à l’organisateur de supprimer son inscription de la base de données.
DELETE FROM coureur
WHERE num_dossard = 137;
7. Écrire une requête SQL permettant de fournir la distance et l’horaire du départ du coureur 256.
SELECT distance, horaire
FROM coureur
JOIN epreuve ON coureur.id_epreuve = epreuve.id_epreuve
WHERE num_dossard = 256;
8. Écrire une requête SQL renvoyant le numéro de dossard, le nom, le prénom et le temps de course des participantes Master Femme du 10 km classées par temps croissant.
SELECT num_dossard, nom, prenom, temps
FROM coureur
JOIN epreuve ON coureur.id_epreuve = epreuve.id_epreuve
WHERE sexe = 'F'
AND annee < 1986
AND distance = 10
ORDER BY temps;
def scratch(dico, annee):
meilleur = dico[annee][0] # premier temps de la liste
for temps in dico[annee]:
if temps < meilleur:
meilleur = temps
return meilleur
12. Indiquer la valeur affectée à la variable i_cat au cours de l’appel mystere(dict_perf_5km, 'SH').
i_cat = 2
13. Indiquer le message d’erreur renvoyé pour mystere(dict_perf_5km,'SG').
"local variable 'i_cat' referenced before assignment"
14. Proposer une assertion à ajouter entre la ligne 2 et la ligne 3.
assert cat in categories, "Catégorie invalide"
15. Indiquer le résultat de l’appel mystere(dict_perf_5km,'SH').
1000.0
16. Écrire le code de la fonction records.
def records(dico):
resultat = [86400, 86400, 86400, 86400, 86400, 86400]
for annee in dico:
for i in range(6): # les 6 catégories
if dico[annee][i] < resultat[i]:
resultat[i] = dico[annee][i]
return resultat