Gestion d'une médiathèque

Épreuve pratique NSI — Session 2026 Terminale — voie générale Durée : 1 heure Sujet n° — (variante)
Le sujet comporte cette page ainsi que les fichiers livres.py, emprunts.py et catalogue.py présents sur l'ordinateur. Le candidat doit agir en autonomie et faire preuve d'initiative tout au long de l'épreuve. En cas de difficulté, il peut solliciter l'examinateur aux moments indiqués par un appel professeur. L'examinateur peut intervenir à tout moment s'il le juge utile.

Contexte

Une médiathèque municipale souhaite informatiser la gestion de son catalogue et de ses emprunts. Un développeur a commencé à structurer les données en Python à l'aide de deux fichiers distincts. L'objectif de ce sujet est d'écrire les fonctions nécessaires à l'analyse de ces données, puis d'identifier et de corriger un défaut dans une fonction déjà rédigée.

Rappel de cours — Programmation orientée objet En Python, une classe permet de définir un nouveau type d'objet. Chaque objet créé à partir de cette classe est appelé une instance. La méthode spéciale __init__ est le constructeur : elle est appelée automatiquement à la création de chaque instance et initialise ses attributs via le paramètre self. On accède à un attribut avec la notation pointée : objet.attribut.

Description des fichiers fournis

Fichier livres.py

Ce fichier définit la classe Livre ainsi qu'une liste nommée livres, qui contient dix instances de cette classe. Chaque instance possède les attributs suivants :

Attribut Type Description Exemple
titre chaîne Titre complet de l'ouvrage "Les Misérables"
auteur chaîne Nom de l'auteur "Victor Hugo"
annee entier Année de première publication 1862
nb_pages entier Nombre de pages de l'édition de référence 1488
genre chaîne Genre littéraire parmi : "aventure", "roman", "roman historique", "roman social", "philosophique", "conte", "poésie" "roman historique"

Fichier emprunts.py

Ce fichier contient la liste emprunts : une liste de dictionnaires, chacun représentant un emprunt enregistré par la médiathèque. Chaque dictionnaire comporte les clés suivantes :

Clé Type Description Exemple
'titre' chaîne Titre du livre emprunté (correspond à un titre de livres.py) "L'Étranger"
'adherent' chaîne Nom et prénom de l'adhérent "Alice Moreau"
'duree' entier Durée effective de l'emprunt, en jours 14
'note' entier Note attribuée par l'adhérent, de 1 à 5 5

Fichier catalogue.py

Ce fichier importe les deux jeux de données et contient :

L'ensemble du travail doit être rédigé dans le fichier catalogue.py, en conservant les imports existants.


Question 1 Ancienneté moyenne du catalogue

Énoncé

Écrire une fonction anciennete_moyenne(livres) qui prend en paramètre une liste d'instances de la classe Livre et renvoie l'ancienneté moyenne des ouvrages du catalogue, exprimée en années.

L'ancienneté d'un livre est définie comme la différence entre l'année en cours (2026) et son année de publication. Si la liste fournie est vide, la fonction doit renvoyer None.

Écrire au moins deux tests pour valider le bon fonctionnement de cette fonction, dont un traitant le cas d'une liste vide.

Conseil Commencer par traiter les cas particuliers (liste vide) avant de calculer la moyenne. Penser à utiliser la fonction len() pour obtenir le nombre d'éléments dans la liste.
Indice

Pour calculer une moyenne, il faut d'abord accumuler la somme de toutes les valeurs souhaitées, puis diviser par leur nombre. L'attribut de chaque instance qui contient l'année de publication s'appelle annee ; on y accède par livre.annee.

Éditeur interactif — Question 1

Les éditeurs ci-dessous fonctionnent dans le navigateur grâce à PyScript. Les données réelles de livres.py sont disponibles directement. Écrire votre code dans Thonny pour le rendu final.

Appel professeur Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.

Question 2 Dictionnaire des emprunts par livre

Énoncé

Écrire une fonction dictionnaire_emprunts(livres, emprunts) qui prend en paramètre la liste des livres et la liste des emprunts. Elle doit renvoyer un dictionnaire dans lequel :

  • chaque clé est le titre d'un livre présent dans la liste livres ;
  • la valeur associée est la liste de tous les dictionnaires d'emprunt concernant ce titre.

Si un livre de la liste ne possède aucun emprunt enregistré, la liste correspondante dans le dictionnaire doit être vide.

Concevoir une série de tests pertinente pour vérifier le bon comportement de cette fonction.

Exemple de retour attendu (extrait)
{
  "Les Misérables": [
    {"titre": "Les Misérables", "adherent": "Bruno Leroy",    "duree": 28, "note": 4},
    {"titre": "Les Misérables", "adherent": "Alice Moreau",   "duree": 35, "note": 5},
    {"titre": "Les Misérables", "adherent": "Camille Dupuis", "duree": 40, "note": 4}
  ],
  "Germinal": [
    {"titre": "Germinal", "adherent": "Camille Dupuis", "duree": 14, "note": 3},
    ...
  ],
  ...
}
Indice

Initialiser d'abord le dictionnaire résultat en associant une liste vide à chacun des titres présents dans livres. Parcourir ensuite chaque emprunt et ajouter le dictionnaire correspondant à la liste du bon titre.

Éditeur interactif — Question 2

Question 3 Analyse d'une fonction défaillante

Afin de ne conserver que les emprunts ayant duré suffisamment longtemps pour être significatifs sur le plan statistique, un développeur a rédigé la fonction supprimer_emprunts_courts. Cette fonction, fournie dans le fichier catalogue.py, est censée retirer de la liste tous les emprunts dont la durée est strictement inférieure à 10 jours.

Cependant, lorsqu'on exécute la fonction de test sur les données, on constate qu'un certain nombre d'emprunts courts subsistent dans la liste finale.

Code fourni dans catalogue.py
def supprimer_emprunts_courts(liste_emprunts):
    """
    Supprime de la liste tous les emprunts dont la durée
    est strictement inférieure à 10 jours.
    """
    for emprunt in liste_emprunts:
        if emprunt['duree'] < 10:
            liste_emprunts.remove(emprunt)
    return liste_emprunts

def test_supprimer():
    emprunts_test = [
        {'titre': 'Livre A', 'adherent': 'Alice', 'duree':  4, 'note': 5},
        {'titre': 'Livre B', 'adherent': 'Alice', 'duree':  5, 'note': 4},
        {'titre': 'Livre C', 'adherent': 'Alice', 'duree': 15, 'note': 3},
        {'titre': 'Livre D', 'adherent': 'Alice', 'duree':  7, 'note': 4},
        {'titre': 'Livre E', 'adherent': 'Alice', 'duree':  8, 'note': 5},
    ]

    supprimer_emprunts_courts(emprunts_test)

    print("Résultat après suppression des emprunts courts :")
    for e in emprunts_test:
        print(f"{e['titre']} — durée : {e['duree']} jour(s)")
Énoncé

Exécuter la fonction test_supprimer dans Thonny et analyser son code pour identifier la source de cette erreur logique. Décrire précisément, par écrit, la cause du dysfonctionnement.

Indice

Observer attentivement ce qui se passe lorsque deux éléments à supprimer se suivent dans la liste. Réfléchir à la façon dont Python gère les indices internes lors du parcours d'une liste que l'on modifie simultanément.

Éditeur interactif — Reproduire le dysfonctionnement

Exécuter le code ci-dessous pour observer le comportement défaillant et comparer avec le résultat attendu.

Appel professeur Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.

Question 4 Correction de la fonction

Énoncé

Proposer une version corrigée de la fonction supprimer_emprunts_courts qui réponde parfaitement à l'objectif défini : supprimer de la liste tous les emprunts dont la durée est strictement inférieure à 10 jours, sans en oublier aucun.

Valider la correction à l'aide de la fonction test_supprimer.

Conseil Il existe plusieurs approches correctes. En choisir une qui soit lisible et conforme aux bonnes pratiques Python. Ne pas modifier la signature de la fonction (nom et paramètre).
Indice

Il est risqué de supprimer des éléments d'une liste pendant qu'on la parcourt. Une solution classique consiste à construire une nouvelle liste ne contenant que les éléments à conserver, puis à remplacer le contenu de la liste originale par cette nouvelle liste.

Éditeur interactif — Question 4
Appel professeur Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.

Description du dossier fourni

Le dossier remis au candidat comporte les éléments suivants :