Aller au contenu

Numérique et sciences informatiques (spécialité) · TerminaleBac

Programmation orientée objet : exercices corrigés de Terminale NSI

Publié le 7 novembre 2026 · Mis à jour le 7 novembre 2026 · Signaler une erreur

L'essentiel

  • Une classe est le modèle ; un objet est un exemplaire créé à partir de ce modèle, avec ses propres valeurs d'attributs.
  • Le constructeur __init__ fixe l'état initial ; les méthodes décrivent le comportement et reçoivent self en premier paramètre.
  • Deux variables peuvent désigner le même objet : une modification faite par l'une se voit aussi par l'autre.
  • Pour modéliser, cherche d'abord ce que l'objet sait (attributs) et ce qu'il fait (méthodes).
  • Pour tracer un programme, suis l'état de chaque objet ligne après ligne dans un tableau.

Comment utiliser ces exercices

Ces exercices te font manipuler la programmation orientée objet en Python, comme au programme de la spécialité NSI en Terminale. Cette façon de programmer consiste à définir des briques logicielles, les objets, et à faire interagir ces objets entre eux 3. Un objet regroupe des informations et des mécanismes qui concernent un même sujet 4. Les exercices avancent par difficulté croissante : lecture de code, écriture de méthodes, puis modélisation.

Les exercices

Exercice 1 Lire une classe : le compte bancaire

★☆☆Environ 8 min

On considère la classe suivante.

class Compte:
    def __init__(self, solde):
        self.solde = solde

    def deposer(self, somme):
        self.solde = self.solde + somme

    def retirer(self, somme):
        if somme <= self.solde:
            self.solde = self.solde - somme

On exécute :

c = Compte(100)
c.deposer(50)
c.retirer(200)
c.retirer(30)
  1. Quel est le rôle de __init__ ici ?
  2. Quelle est la valeur de c.solde à la fin ?
Indice 1

Regarde la condition dans retirer : que se passe-t-il quand la somme dépasse le solde ?

Indice 2

Fais un petit tableau avec le solde après chaque ligne.

Voir la correction pas à pas
  1. __init__ est le constructeur : il est appelé quand on écrit Compte(100) et il donne à l'objet son attribut solde, ici égal à 100.

  2. Après Compte(100), le solde vaut 100.

  3. Après c.deposer(50), le solde vaut 100 + 50 = 150.

  4. Pour c.retirer(200), la condition 200 <= 150 est fausse : rien n'est modifié, le solde reste 150.

  5. Pour c.retirer(30), la condition 30 <= 150 est vraie : le solde devient 150 - 30 = 120.

Le solde final est 120. Une méthode peut refuser de modifier l'objet : c'est un moyen de protéger la cohérence de son état.

Exercice 2 Suivre l'état d'un compteur

★☆☆Environ 8 min

class Compteur:
    def __init__(self, depart, pas):
        self.valeur = depart
        self.pas = pas

    def incrementer(self):
        self.valeur = self.valeur + self.pas

c = Compteur(2, 3)
for i in range(5):
    c.incrementer()

Quelle est la valeur de c.valeur après la boucle ? Que vaut c.pas ?

Indice 1

La boucle appelle la méthode combien de fois ?

Indice 2

À chaque appel, l'attribut valeur augmente de la même quantité.

Voir la correction pas à pas
  1. À la création, c.valeur vaut 2 et c.pas vaut 3.

  2. range(5) répète l'appel c.incrementer() cinq fois.

  3. Chaque appel ajoute 3 : les valeurs successives sont 5, 8, 11, 14, 17.

  4. Aucune ligne ne modifie pas : il reste à 3.

c.valeur vaut 17 et c.pas vaut 3. Un attribut garde sa valeur entre deux appels de méthode : c'est ce qui distingue un objet d'une simple variable locale.

Exercice 3 Écrire une classe Rectangle

★☆☆Environ 10 min

Écris une classe Rectangle dont le constructeur prend une largeur et une hauteur, avec deux méthodes aire() et perimetre() qui renvoient respectivement l'aire et le périmètre.

On crée ensuite r = Rectangle(7, 4). Quelle valeur renvoie r.aire() ?

Indice 1

Les attributs se créent dans __init__ avec self..

Indice 2

Une méthode qui renvoie un résultat utilise return.

Voir la correction pas à pas
  1. Commence par le constructeur : il reçoit deux paramètres et les range dans deux attributs de l'objet, grâce à self..

  2. Ajoute ensuite la méthode d'aire : elle multiplie les deux attributs et renvoie le produit, avec return self.largeur * self.hauteur.

  3. Ajoute la méthode de périmètre : elle renvoie 2 * (self.largeur + self.hauteur).

  4. Assemble le tout, par exemple :

    class Rectangle:
        def __init__(self, a, b):
            self.largeur = a
            self.hauteur = b
    
        def aire(self):
            return self.largeur * self.hauteur
    
        def perimetre(self):
            return 2 * (self.largeur + self.hauteur)
    
  5. Pour Rectangle(7, 4), l'aire vaut 7 × 4 = 28.

r.aire() renvoie 28. Les méthodes n'ont pas besoin qu'on leur repasse les dimensions : elles les lisent dans l'objet via self.

Exercice 4 Deux noms, un seul objet

★★☆Environ 12 min

class Panier:
    def __init__(self):
        self.articles = []

    def ajouter(self, nom):
        self.articles.append(nom)

a = Panier()
a.ajouter("pomme")
b = a
b.ajouter("poire")
c = Panier()
c.ajouter("kiwi")
  1. Combien d'articles contient a.articles ? Et c.articles ?
  2. Quelle est la valeur de len(a.articles) + len(c.articles) ?
  3. Que faudrait-il changer pour que b soit un panier indépendant de a ?
Indice 1

Que fait l'instruction b = a : crée-t-elle un nouvel objet ?

Indice 2

Quelle ligne crée réellement un nouvel objet de la classe ?

Voir la correction pas à pas
  1. Après a = Panier() puis a.ajouter("pomme"), le panier de a contient « pomme ».

  2. b = a ne crée aucun objet : b est un second nom pour le même panier que a.

  3. b.ajouter("poire") modifie donc le panier commun : a.articles contient « pomme » et « poire », soit 2 articles.

  4. c = Panier() crée un autre objet, avec sa propre liste vide ; après l'ajout, c.articles contient 1 article (« kiwi »).

  5. La somme vaut 2 + 1 = 3.

  6. Pour avoir un panier indépendant, il faut écrire b = Panier() : seul un appel à la classe crée un nouvel objet.

La somme vaut 3. Retiens que l'affectation entre deux variables copie une référence, pas l'objet ; seul Classe(...) fabrique un nouvel exemplaire.

Exercice 5 Calculer une moyenne avec une méthode

★★☆Environ 12 min

class Eleve:
    def __init__(self, nom):
        self.nom = nom
        self.notes = []

    def ajouter_note(self, note):
        self.notes.append(note)

    def moyenne(self):
        return sum(self.notes) / len(self.notes)

On exécute :

e = Eleve("Lina")
e.ajouter_note(12)
e.ajouter_note(15)
e.ajouter_note(9)
  1. Que renvoie e.moyenne() ?
  2. Quelle erreur se produit si on appelle moyenne() sur un élève qui n'a aucune note ? Propose une correction.
Indice 1

sum additionne tous les éléments d'une liste.

Indice 2

Que vaut len([]) ?

Voir la correction pas à pas
  1. La liste des notes est [12, 15, 9].

  2. La somme vaut 12 + 15 + 9 = 36 et la liste contient 3 notes.

  3. La moyenne est 36 / 3 = 12.

  4. Sans note, len(self.notes) vaut 0 et la division par 0 provoque une erreur ZeroDivisionError.

  5. Correction possible : tester d'abord if len(self.notes) == 0: et renvoyer None (ou lever une erreur explicite) avant de diviser.

e.moyenne() renvoie 12. Une bonne méthode prévoit les états limites de l'objet, ici une liste vide.

Exercice 6 Total d'une liste d'objets

★★☆Environ 14 min

class Produit:
    def __init__(self, nom, prix, quantite):
        self.nom = nom
        self.prix = prix
        self.quantite = quantite

    def cout(self):
        return self.prix * self.quantite

stock = [Produit("cahier", 2.5, 4),
         Produit("calculatrice", 10, 1),
         Produit("stylo", 1.2, 5)]

total = 0
for p in stock:
    total = total + p.cout()
  1. Calcule le coût de chaque produit.
  2. Quelle est la valeur finale de total ?
  3. Écris une instruction qui construit la liste des noms des produits dont le coût dépasse 8.
Indice 1

Appelle mentalement cout() sur chaque objet de la liste.

Indice 2

Pour la question 3, pense à une liste en compréhension avec une condition.

Voir la correction pas à pas
  1. Cahier : 2,5 × 4 = 10.

  2. Calculatrice : 10 × 1 = 10.

  3. Stylo : 1,2 × 5 = 6.

  4. La boucle additionne les trois coûts : 10 + 10 + 6 = 26.

  5. Pour la liste des noms : [p.nom for p in stock if p.cout() > 8] ; elle contient « cahier » et « calculatrice ».

total vaut 26. Chaque objet de la liste sait calculer son propre coût : la boucle n'a pas besoin de connaître les détails.

Exercice 7 Additionner deux fractions avec un objet

★★★Environ 16 min

class Fraction:
    def __init__(self, num, den):
        self.num = num
        self.den = den

    def additionner(self, autre):
        n = self.num * autre.den + autre.num * self.den
        d = self.den * autre.den
        return Fraction(n, d)

    def valeur(self):
        return self.num / self.den

f = Fraction(1, 4)
g = Fraction(1, 6)
h = f.additionner(g)
  1. Quels sont les attributs de h ?
  2. Les objets f et g ont-ils été modifiés par l'appel ?
  3. Donne la valeur décimale renvoyée par h.valeur(), arrondie à 10 chiffres après la virgule.
Indice 1

Dans additionner, quelle instruction fabrique un nouvel objet ?

Indice 2

Applique la formule de la méthode sans simplifier la fraction.

Voir la correction pas à pas
  1. Dans la méthode, self désigne f (1/4) et autre désigne g (1/6).

  2. Le numérateur calculé est 1 × 6 + 1 × 4 = 10.

  3. Le dénominateur calculé est 4 × 6 = 24.

  4. La méthode renvoie Fraction(10, 24) : h.num vaut 10 et h.den vaut 24 (la fraction n'est pas simplifiée).

  5. f et g ne sont pas modifiés : la méthode ne fait aucune affectation sur self.num ni sur autre.num, elle construit un nouvel objet.

  6. h.valeur() renvoie 10 / 24 = 0,4166666667 (arrondi).

La valeur est environ 0,4166666667. Une méthode peut soit modifier l'objet courant, soit renvoyer un nouvel objet : ici, f et g restent intacts.

Exercice 8 Modéliser une bibliothèque

★★★Environ 20 min

Un lycée veut gérer les prêts de livres de son CDI. La programmation orientée objet demande une étape de modélisation : on décide quels objets représenter et comment ils interagissent 3.

  1. Propose une classe Livre avec au moins trois attributs et une méthode qui indique si le livre est disponible.
  2. Propose une classe Emprunteur et une méthode emprunter(livre).
  3. Que doit faire emprunter si le livre est déjà prêté ?
  4. Écris le code Python de l'ensemble.
Indice 1

Demande-toi pour chaque classe : que sait l'objet (attributs) ? Que sait-il faire (méthodes) ?

Indice 2

Un livre peut avoir un attribut booléen qui change quand il est prêté.

Voir la correction pas à pas
  1. Pour Livre, on retient le titre, l'auteur et un booléen disponible initialisé à True, plus une méthode est_disponible() qui renvoie ce booléen.

  2. Pour Emprunteur, on retient le nom et la liste des livres actuellement empruntés, vide au départ.

  3. La méthode emprunter doit d'abord tester livre.disponible ; si le livre est disponible, elle l'ajoute à la liste de l'emprunteur et passe livre.disponible à False.

  4. Si le livre n'est pas disponible, la méthode ne modifie rien et renvoie False pour signaler l'échec (elle renvoie True en cas de succès).

  5. Code possible :

    class Livre:
        def __init__(self, titre, auteur):
            self.titre = titre
            self.auteur = auteur
            self.disponible = True
    
        def est_disponible(self):
            return self.disponible
    
    class Emprunteur:
        def __init__(self, nom):
            self.nom = nom
            self.livres = []
    
        def emprunter(self, livre):
            if livre.disponible:
                self.livres.append(livre)
                livre.disponible = False
                return True
            return False
    

Il n'y a pas une seule bonne modélisation : l'essentiel est que chaque classe regroupe des données et les actions qui les concernent, et que les objets interagissent par leurs méthodes. Ici, Emprunteur agit sur un Livre qu'on lui passe en paramètre.

Les questions qu'on se pose

Quelle différence entre une classe et un objet ?

La classe est un modèle : elle décrit les caractéristiques et les comportements communs. Un objet est créé à partir de ce modèle et en reprend les caractéristiques et les comportements 4. Par exemple, la classe Compte décrit ce qu'est un compte, tandis que Compte(100) crée un compte précis avec son solde.

À quoi sert la programmation orientée objet ?

Elle permet de représenter des concepts du problème sous forme d'objets qui ont une structure interne et un comportement, et qui interagissent entre eux 3. Le programme devient ainsi plus proche de la situation modélisée. Elle est utilisée dans plusieurs langages, dont Python 3, avec lequel tu travailles en NSI.

Pourquoi `self` apparaît-il partout ?

Dans une méthode, self désigne l'objet sur lequel on appelle la méthode. Quand tu écris c.deposer(50), Python place c dans self automatiquement. C'est pourquoi self est le premier paramètre de chaque méthode mais qu'on ne le fournit pas à l'appel. Écrire self.solde signifie « l'attribut solde de cet objet-ci ».

Sources

  1. Langages et programmation - Structures de données et POO, Éduscol. Consulté le 7 novembre 2026.
  2. Formation NSI Terminale - Concepts POO, Université Grenoble Alpes. Consulté le 7 novembre 2026.
  3. Programmation orientée objet, Wikipédia. Consulté le 7 novembre 2026.
  4. Objet (informatique), Wikipédia. Consulté le 7 novembre 2026.

Les numéros dans le texte renvoient à ces sources. Une source qui ne dit pas ce qu'on lui fait dire ? Signale-le.

Signaler une erreur sur cette page

Je suis en…

Primaire

  • CP Bientôt
  • CE1 Bientôt
  • CE2 Bientôt
  • CM1 Bientôt
  • CM2 Bientôt

Collège

Lycée

Supérieur

  • BTS Bientôt
  • BUT Bientôt
  • Licence Bientôt
  • Prépas Bientôt

Sur cette page