Épreuve pratique NSI

Sujet n° 3 · Session 2026 · 1 heure

Prédire le cycle menstruel

Une application calcule les phases d'un cycle de 28 jours et exporte les prochaines dates de règles vers un agenda. Années bissextiles, assertions, tests de dates, puis un fichier iCalendar que les logiciels refusent.

  • Conditions imbriquées
  • Assertions
  • Tuples
  • Tests
  • Format de fichier

Mise en situationLe cycle

Le cycle menstruel commence par convention le premier jour des règles, et l'ovulation a lieu 14 jours avant le début des règles suivantes. On suppose un cycle régulier de 28 jours et quatre phases :

PhaseNuméroJours du cycle
Règles11 à 5
Phase folliculaire26 à 13
Ovulation314
Phase lutéale415 à 28

Une date est un tuple d'entiers (jour, mois, annee), toujours valide : le 7 septembre 2025 s'écrit (7, 9, 2025).

Toutes les cellules de cette page partagent le même Python, comme un notebook : une fonction écrite à une question sert aux suivantes. Maj + Entrée exécute la cellule.

Pour l'examinateur

Repère

Le module ics sert au test de la question 4. Dans la page, il est installé automatiquement au premier lancement de Python, ce qui ajoute quelques secondes.

1

Question 1Les années bissextiles

Une année est bissextile si elle est divisible par 4, à l'exception des années divisibles par 100, sauf si ce sont des multiples de 400. Ainsi 2024 est bissextile, 2100 ne l'est pas, 2000 l'est.

Écrire en Python une fonction nommée est_bissextile qui prend en paramètre un entier correspondant à une année et qui renvoie un booléen indiquant si elle est bissextile, en appliquant la règle donnée ci-dessus.

Appel professeur

À demander au candidat

  1. Dans quel ordre testez-vous les divisibilités par 4, 100 et 400 ? Que se passerait-il en commençant par 4 ?
  2. Donnez une année qui distingue une règle « divisible par 4 » d'une règle complète.
Point de vigilance

L'ordre des tests compte : 400 avant 100, et 100 avant 4. On peut aussi écrire une seule expression booléenne.

Résultats attendus
2024, 2100, 2000
True, False, True
2

Question 2La phase d'un jour

Écrire en Python une fonction nommée determiner_phase qui prend en paramètre un entier, compris entre 1 et 28 inclus, qui correspond au jour d'un cycle et qui renvoie un entier correspondant au numéro de la phase associée. À l'aide d'une assertion, on garantira que l'entier donné en argument est compris entre 1 et 28 inclus.

Appel professeur

À demander au candidat

  1. Où placez-vous l'assertion, et que se passe-t-il pour determiner_phase(0) ?
  2. Pourquoi n'est-il pas nécessaire de tester jour >= 6 dans la deuxième condition ?
Point de vigilance

Les bornes : le jour 5 est encore en phase 1, le jour 14 seul en phase 3.

3

Question 3Tester l'ajout de jours

La fonction ajouter_jours, dont le code est déjà fourni, prend en paramètres une date et un entier représentant un nombre de jours. Elle renvoie la nouvelle date obtenue après ajout de ces jours.

Compléter la fonction test_ajouter_jours en ajoutant au moins trois autres tests pertinents. Pour chaque test ajouté, une brève justification doit être donnée afin d'expliquer pourquoi ce cas est important à vérifier.

Appel professeur

À demander au candidat

  1. Justifiez chacun de vos tests : quel cas particulier de ajouter_jours vérifie-t-il ?
  2. Pourquoi tester février en année bissextile et en année ordinaire ?
Point de vigilance

Des tests pertinents couvrent le changement de mois, le changement d'année, février bissextile ou non, l'ajout de 0 jour.

4

Question 4Un calendrier invalide

Dans le but d'ajouter l'ensemble des dates de début de règles sur un agenda en ligne, on souhaite créer un fichier au format iCalendar. Un calendrier commence par BEGIN:VCALENDAR, VERSION:2.0 et PRODID: suivi du nom du calendrier, puis une suite d'événements, et se termine par END:VCALENDAR. Chaque événement d'une journée s'écrit entre BEGIN:VEVENT et END:VEVENT, avec une ligne DTSTART: donnant la date sous la forme AAAAMMJJ et une ligne SUMMARY: donnant la description. Les nombres strictement inférieurs à 10 sont complétés par un 0 : le 3 juillet 2026 s'écrit DTSTART:20260703.

La fonction calendrier_cycles prend en paramètre une date correspondant au premier jour des dernières règles et renvoie, au format iCalendar et sous la forme d'une chaîne de caractères, la liste chronologique des dates de début de règles qui se présentent dans les 100 jours suivant cette date, date incluse.

Observer avec la fonction test_calendrier_cycles que le calendrier renvoyé par la fonction calendrier_cycles n'est pas dans un format valide. Identifier le problème dans la fonction calendrier_cycles, proposer une démarche de résolution et la mettre en œuvre.

Appel professeur

À demander au candidat

  1. Que produit str(annee) + str(mois) + str(jour) pour le 12 mars 2026 ? Pourquoi un logiciel ne peut-il pas relire cette date ?
  2. Quelles solutions pour écrire un nombre sur deux chiffres ?
  3. Combien de dates le calendrier contient-il ? La date du 4 juin 2026, 84 jours après le 12 mars, devrait-elle y figurer ?
Point de vigilance

Le défaut demandé : mois et jour ne sont pas complétés par un 0, d'où DTSTART:2026312 (7 caractères).

Remarque pour un candidat rapide : la condition jours_ecoules + 28 <= 100 oublie la date du jour 84, pourtant dans les 100 jours.

Résultats attendus
Code fourni
DTSTART:2026312, refusé par ics
Corrigé, à partir du 12/03/2026
20260312, 20260409, 20260507

Le fichier du candidat

Le jour de l'épreuve, le candidat travaille dans un seul fichier. Ce bouton rassemble vos cellules dans l'ordre, telles qu'elles sont à l'écran, en un cycle_menstruel.py à ouvrir dans votre éditeur habituel.

Chargement de Python…