Un corrigé pédagogique pour comprendre et justifier vos réponses. Les conseils de rédaction ne constituent pas un barème officiel détaillé.
Application
Cartes de révision et répétition espacée de Leitner
Une carte de révision possède une question, une réponse, un niveau de 0 à 4 et une prochaine date de révision. Une réussite augmente le niveau sans dépasser 4 ; une erreur remet immédiatement au niveau 0. La prochaine date se calcule depuis aujourd’hui avec le délai du nouveau niveau. Le paquet est une liste d’instances Carte. On veut ensuite extraire les cartes dues, puis toutes celles au niveau minimal.
| Niveau | Délai après traitement |
|---|---|
| 0 | 1 jour |
| 1 | 3 jours |
| 2 | 7 jours |
| 3 | 15 jours |
| 4 | 30 jours |
Le fichier fournit trois cartes : capitale de l’Italie/Rome au niveau 2 et due dans 4 jours ;7×8/56 au niveau 0 et due demain ; symbole du fer/Fe au niveau 0 et due dans 7 jours. Le test de renforcement crée séparément des niveaux 2,1,2 pour révéler un défaut.
Le dossier comporte le sujet et les fichiers listés dans les téléchargements. Les codes de départ sont reproduits ci-dessous. Travaillez sur une copie. Les appels professeur signalés dans les questions servent à présenter votre démarche ; vous pouvez aussi demander de l’aide en cas de difficulté.
Code fourni : cartes.py
import datetime
def date_future(nb_jours):
"""Renvoie la date située nb_jours après aujourd'hui"""
return datetime.date.today() + datetime.timedelta(days=nb_jours)
# Variable contenant les délais en jours pour chaque niveau (index 0 à 4)
DELAIS = [1, 3, 7, 15, 30]
class Carte:
def __init__(self, question, reponse):
self.question = question
self.reponse = reponse
self.niveau = 0
# À la création, la carte est à réviser le jour même
self.date_prochaine = datetime.date.today()
def __repr__(self):
return f"<Carte: {self.question} (Niveau {self.niveau})>"
#############################################################################
# Écrire la méthode traiter_reponse(self, succes) de la question 1 #
#############################################################################
# Des cartes et un paquet de cartes pour réaliser des tests
c1 = Carte("Capitale de l'Italie ?", "Rome")
c1.niveau = 2
c1.date_prochaine = date_future(4)
c2 = Carte("7 x 8 ?", "56")
c2.date_prochaine = date_future(1)
c3 = Carte("Symbole du Fer ?", "Fe")
c3.date_prochaine = date_future(7)
paquet = [c1, c2, c3]
#############################################################################
# Écrire la fonction extraire_cartes_du_jour de la question 2 #
#############################################################################
#############################################################################
# Fonction défaillante à analyser et corriger pour la question 3 #
#############################################################################
def extraire_cartes_a_renforcer(paquet):
"""
Parcourt le paquet et renvoie la liste des cartes ayant le
niveau d'avancement le plus faible.
"""
if len(paquet) == 0:
return []
niveau_min = paquet[0].niveau
a_renforcer = []
for carte in paquet:
if carte.niveau < niveau_min:
niveau_min = carte.niveau
a_renforcer.append(carte)
elif carte.niveau == niveau_min:
a_renforcer.append(carte)
return a_renforcer
def test_renforcement():
# Création d'un paquet de test
c1 = Carte("Capitale de l'Italie ?", "Rome")
c1.niveau = 2
c2 = Carte("7 x 8 ?", "56")
c2.niveau = 1
c3 = Carte("Symbole du Fer ?", "Fe")
c3.niveau = 2
mon_paquet = [c1, c2, c3]
# Appel de la fonction défaillante
resultat = extraire_cartes_a_renforcer(mon_paquet)
print("Cartes à renforcer (celles ayant le niveau le plus bas) :")
print(resultat)
Question 1
#Écrire traiter_reponse(self, succes), qui modifie le niveau selon les règles, puis date_prochaine en utilisant DELAIS et date_future(nb_jours).
PythonPlanifier la prochaine révision au bon niveauÉcrivez votre solution et mettez-la à l’épreuve
Complétez traiter_reponse(self, succes). Une réussite augmente le niveau de 1, plafonné à 4 ; une erreur ramène au niveau 0. Puis date_prochaine devient date_future(DELAIS[nouveau_niveau]). DELAIS et date_future sont fournis. Modifiez cette carte, sans créer une instance de remplacement.
class Carte:
def __init__(self, question, reponse):
self.question = question
self.reponse = reponse
self.niveau = 0
# À la création, la carte est à réviser le jour même
self.date_prochaine = datetime.date.today()
def traiter_reponse(self, succes):
# Complétez cette méthode
pass
Les cas de test proposés :
- Premier succès : La date utilise le niveau 1 obtenu après la réponse, pas le niveau 0 initial.
- Niveau maximal : Le plafond évite un niveau 5 absent du tableau DELAIS.
- Erreur après progression : Une erreur réinitialise le niveau et la date.
- Deux réussites successives : Chaque réponse agit sur l’état issu de la précédente.
- Même carte et contenu conservé : La méthode modifie le calendrier de l’objet sans toucher au contenu de révision.
Indice
Mettre à jour le niveau avant de lire le délai.
Comprendre la correction
def traiter_reponse(self, succes):
if succes:
self.niveau = min(4, self.niveau + 1)
else:
self.niveau = 0
self.date_prochaine = date_future(DELAIS[self.niveau])La date doit utiliser le niveau après la réponse. Une carte de niveau 0 réussie passe au niveau 1 et attend donc 3 jours, pas 1. Une erreur au niveau 4 impose le niveau 0 et un délai d’un jour. Le plafond empêche de lire DELAIS[5], indice inexistant. La méthode modifie l’objet et ne doit pas créer une autre carte.
carte = Carte('7 x 8 ?', '56')
carte.traiter_reponse(True)
assert carte.niveau == 1 and carte.date_prochaine == date_future(3)
carte.niveau = 4
carte.traiter_reponse(True)
assert carte.niveau == 4 and carte.date_prochaine == date_future(30)
carte.traiter_reponse(False)
assert carte.niveau == 0 and carte.date_prochaine == date_future(1)Question 2
#Écrire extraire_cartes_du_jour(paquet,date_jour), qui renvoie une nouvelle liste des cartes dont date_prochaine≤date_jour. Les dates sont comparables avec les opérateurs habituels.
Comprendre la correction
def extraire_cartes_du_jour(paquet, date_jour):
return [carte for carte in paquet if carte.date_prochaine <= date_jour]La borne inclut les cartes prévues aujourd’hui et celles en retard. Utiliser== oublierait les révisions déjà dépassées. On crée une nouvelle liste, tout en conservant les mêmes objets Carte : les révisions pourront ensuite modifier leur niveau dans le paquet d’origine. Pour le paquet fourni, à aujourd’hui+1 jour on obtient seulement la carte 7×8 ; à aujourd’hui+4 jours, cette carte et celle surRome.
assert extraire_cartes_du_jour([],date_future(0)) == []
assert extraire_cartes_du_jour(paquet,date_future(1)) == [c2]
assert extraire_cartes_du_jour(paquet,date_future(4)) == [c1,c2]Question 3
#Exécuter test_renforcement, expliquer l’incohérence puis corriger extraire_cartes_a_renforcer pour ne conserver que les cartes au niveau minimum.
PythonNe garder que les cartes vraiment prioritairesÉcrivez votre solution et mettez-la à l’épreuve
Corrigez extraire_cartes_a_renforcer(paquet). Renvoyez une nouvelle liste de toutes les cartes au niveau minimum, dans leur ordre du paquet. Conservez les mêmes objets Carte et ne modifiez pas le paquet. La liste vide donne []. L’auxiliaire de test faire_cartes(niveaux) crée une carte par niveau pour faciliter la lecture des cas.
def extraire_cartes_a_renforcer(paquet):
# À vous de jouer
pass
Les cas de test proposés :
- Le minimum baisse : La première carte ajoutée devient inadmissible dès que le niveau 1 apparaît.
- Deux cartes prioritaires : Une égalité au minimum ajoute une solution.
- Plusieurs baisses du minimum : Chaque nouveau minimum doit invalider toute l’ancienne sélection.
- Toutes au même niveau : Nouvelle liste, mais mêmes objets dans le même ordre.
- Paquet intact : La sélection ne demande ni de trier ni de changer les niveaux.
- Aucune carte : Aucun minimum n’est recherché dans une liste vide.
Indice
Quand le minimum baisse, les cartes déjà retenues restent-elles admissibles ?
Comprendre la correction
Le parcours ajoute la première carte de niveau 2. Lorsqu’il rencontre la carte de niveau 1, il change le minimum mais ajoute cette carte sans supprimer l’ancienne. La liste finale contient donc un niveau 2 devenu inadmissible. Un nouveau minimum doit réinitialiser la liste ; une égalité doit seulement la compléter.
def extraire_cartes_a_renforcer(paquet):
if not paquet:
return []
niveau_min = paquet[0].niveau
a_renforcer = []
for carte in paquet:
if carte.niveau < niveau_min:
niveau_min = carte.niveau
a_renforcer = [carte]
elif carte.niveau == niveau_min:
a_renforcer.append(carte)
return a_renforcerSur les niveaux 2,1,2, les états successifs sont : minimum 2 avec la première carte ; minimum 1 avec uniquement la deuxième ; aucun changement à la troisième. Sur 2,1,1, les deux cartes de niveau 1 sont conservées. Le paquet d’origine reste inchangé. Une autre méthode valide consiste à calculer d’abord le minimum puis à filtrer, mais la version ci-dessus réalise les deux opérations en un parcours.
test_renforcement()
a,b,d = Carte('a',''),Carte('b',''),Carte('d','')
a.niveau,b.niveau,d.niveau = 2,1,1
assert extraire_cartes_a_renforcer([a,b,d]) == [b,d]
assert extraire_cartes_a_renforcer([]) == []
assert extraire_cartes_a_renforcer([a]) == [a]La liste des candidats dépend toujours du minimum actuel. Quand ce minimum diminue, tous les anciens candidats deviennent trop avancés et doivent disparaître de la sélection. Quand il reste identique, une nouvelle carte au même niveau est une solution supplémentaire. Cette distinction entre remplacement et ajout apparaît dans beaucoup de problèmes : toutes les altitudes les plus froides, tous les meilleurs scores ou toutes les occurrences d’un minimum. Savoir l’expliquer à partir de ce petit paquet permet de réutiliser le raisonnement dans d’autres exercices du bac.
Conserver uniquement les minima actuelsUn atelier pour expérimenter
Choisissez une réponse puis confrontez votre intuition à l’explication. Vous pouvez modifier vos choix.
Lire les réponses et leurs explications
- Après niveaux 3 puis 1, quelle liste de niveaux garder ?
[1]. Le nouveau minimum remplace tous les candidats précédents.
- Après niveaux 1 puis 1, que faire ?
Garder les deux cartes.. Une égalité ajoute une autre solution.
Appuyez votre explication sur les valeurs et les conditions exactes du programme.
Faire évoluer une carte au fil des révisionsUn atelier pour expérimenter
Écrivez une suite de V (réussite) et F (erreur), séparés par des virgules. Chaque révision suivante a lieu au jour prévu par la précédente. Les jours sont relatifs au début de l’expérience.
Lire le résultat de l’expérience initiale
Niveau final2, prochaine révision au jour 21.
Le délai est choisi après la mise à jour du niveau. Une erreur remet au niveau0, donc à un délai d’un jour.
| Révision | Jour | Réponse | Niveau après | Prochain jour |
|---|---|---|---|---|
| 1 | 0 | Réussite | 1 | 3 |
| 2 | 3 | Réussite | 2 | 10 |
| 3 | 10 | Erreur | 0 | 11 |
| 4 | 11 | Réussite | 1 | 14 |
| 5 | 14 | Réussite | 2 | 21 |
L’ordre des mises à jour définit le comportement : d’abord le niveau, ensuite sa prochaine échéance.
Du sujet à la méthode
Votre prochaine séance de révision
- Vérifier les changements d’état de l’objet après l’appel.
- Quand une meilleure solution apparaît, décider explicitement du sort des anciens candidats.
Retrouver ces notions dans d’autres sujets
Toutes les annales de NSI · Le guide pour préparer le bac NSI 2027
Énoncé : sujet 26_BCG_NSI_21 (PDF). Corrigé et explications pédagogiques proposés par Sofien.
