Aller au contenu

Corrigé du TP Programmation Orientée Objet


2. Classe Auteur

class Auteur:
    def __init__(self, nom, naissance, deces=False):
        """
        Méthode constructeur de Auteur.

        :param nom: (str) Nom de l'auteur
        :param naissance: (int) Année de naissance de l'auteur
        :param deces: (int/bool) Année de décès / False si toujours en vie
        """
        self.nom = nom
        self.annee_naissance = naissance
        self.deces = deces

    def __repr__(self):
        """Représentation de l'auteur."""
        if self.deces:
            return f"{self.nom} ({self.annee_naissance}-{self.deces})"
        else:
            return f"{self.nom} (né en {self.annee_naissance})"

Explications : - L'attribut deces a une valeur par défaut (False) pour gérer les auteurs vivants - La méthode __repr__ est ajoutée pour un affichage lisible


3. Classe Livre

class Livre:
    def __init__(self, titre, genre, auteur):
        """
        Méthode constructeur de Livre.

        :param titre: (str) Titre du livre
        :param genre: (str) Genre du livre
        :param auteur: (Auteur) Auteur du livre (objet de type Auteur)
        """
        self.titre = titre
        self.genre = genre
        self.auteur = auteur

    def __repr__(self):
        """Représentation du livre."""
        return f"{self.titre} - {self.auteur.nom}"

Point important : - L'attribut auteur doit être un objet de type Auteur, pas une chaîne de caractères - Cela permet d'accéder aux informations de l'auteur via livre.auteur.nom, livre.auteur.annee_naissance, etc.


4. Classe Bibliothèque

class Bibliotheque:
    def __init__(self, rayon):
        """
        Méthode constructeur de Bibliothèque.
        L'ensemble des livres est vide lors de l'initialisation.

        :param rayon: (str) Type de livre que la bibliothèque peut recevoir
        """
        self.rayon = rayon
        self.ens_livre = []

    def add_livre(self, livre):
        """
        Méthode permettant d'ajouter un livre.

        :param livre: (Livre) Livre à ajouter
        :return: (str) Précise si le livre est ajouté ou non
        """
        if livre.genre == self.rayon:
            self.ens_livre.append(livre)
            return "Livre ajouté"
        else:
            return "Impossible d'ajouter le livre (genre incompatible)"

    def est_dispo(self, nom_livre):
        """
        Méthode parcourant l'ensemble des livres de la bibliothèque
        pour savoir si un livre est disponible.

        :param nom_livre: (str) Nom du livre à rechercher
        :return: (int) Indice du livre si dispo, -1 sinon
        """
        i = 0
        while i < len(self.ens_livre):
            if self.ens_livre[i].titre == nom_livre:
                return i
            i += 1
        return -1

    def prete_livre(self, nom_livre):
        """
        Méthode permettant de prêter un livre s'il est disponible.

        :param nom_livre: (str) Nom du livre à emprunter
        :return: (Livre/bool) Livre si emprunt possible, False sinon
        """
        indice = self.est_dispo(nom_livre)
        if indice != -1:
            livre = self.ens_livre[indice]
            # Suppression du livre de la liste
            self.ens_livre = self.ens_livre[:indice] + self.ens_livre[indice+1:]
            return livre
        else:
            return False

    def __repr__(self):
        """Représentation de la bibliothèque."""
        return f"Bibliothèque [{self.rayon}] - {len(self.ens_livre)} livre(s)"

Explications : - add_livre vérifie que le genre du livre correspond au rayon - est_dispo parcourt la liste et renvoie l'indice ou -1 - prete_livre utilise est_dispo et supprime le livre de la liste via les slices


5. Création des objets

# Création des auteurs
a1 = Auteur('Victor Hugo', 1802, 1885)
a2 = Auteur('J.K. Rowling', 1965)
a3 = Auteur('Agatha Christie', 1890, 1976)
a4 = Auteur('Stephen King', 1947)

# Création des livres
l1 = Livre('Les Misérables', 'Classique', a1)
l2 = Livre('Notre-Dame de Paris', 'Classique', a1)
l3 = Livre("Harry Potter à l'école des sorciers", 'Fantastique', a2)
l4 = Livre('Le Crime de l\'Orient-Express', 'Policier', a3)
l5 = Livre('Shining', 'Horreur', a4)
l6 = Livre('Ça', 'Horreur', a4)

# Création des bibliothèques
biblio_classique = Bibliotheque('Classique')
biblio_horreur = Bibliotheque('Horreur')

# Ajout des livres
print(biblio_classique.add_livre(l1))  # "Livre ajouté"
print(biblio_classique.add_livre(l2))  # "Livre ajouté"
print(biblio_classique.add_livre(l3))  # "Impossible..." (genre incompatible)

print(biblio_horreur.add_livre(l5))    # "Livre ajouté"
print(biblio_horreur.add_livre(l6))    # "Livre ajouté"

# Affichage
print(biblio_classique)  # Bibliothèque [Classique] - 2 livre(s)
print(biblio_horreur)    # Bibliothèque [Horreur] - 2 livre(s)

6. Tests complets

# Test de disponibilité
print(biblio_classique.est_dispo('Les Misérables'))  # 0
print(biblio_classique.est_dispo('Livre inexistant'))  # -1

# Test de prêt
livre_emprunte = biblio_classique.prete_livre('Les Misérables')
print(livre_emprunte)  # Les Misérables - Victor Hugo
print(biblio_classique)  # Bibliothèque [Classique] - 1 livre(s)

# Le livre n'est plus disponible
print(biblio_classique.est_dispo('Les Misérables'))  # -1

# Tentative de prêt d'un livre non disponible
print(biblio_classique.prete_livre('Les Misérables'))  # False

Diagramme de classes (UML simplifié)

+----------------+       +----------------+       +------------------+
|    Auteur      |       |     Livre      |       |  Bibliotheque    |
+----------------+       +----------------+       +------------------+
| - nom          |       | - titre        |       | - rayon          |
| - annee_naiss. |<------| - genre        |       | - ens_livre      |
| - deces        |       | - auteur       |------>|                  |
+----------------+       +----------------+       +------------------+
| + __init__()   |       | + __init__()   |       | + __init__()     |
| + __repr__()   |       | + __repr__()   |       | + add_livre()    |
+----------------+       +----------------+       | + est_dispo()    |
                                                  | + prete_livre()  |
                                                  | + __repr__()     |
                                                  +------------------+

Pour aller plus loin

Ajout d'une méthode de retour de livre

def retour_livre(self, livre):
    """
    Méthode permettant de retourner un livre emprunté.

    :param livre: (Livre) Livre à retourner
    :return: (str) Message de confirmation
    """
    if livre.genre == self.rayon:
        self.ens_livre.append(livre)
        return f"'{livre.titre}' a été retourné"
    else:
        return "Ce livre n'appartient pas à ce rayon"

Ajout d'une recherche par auteur

def livres_par_auteur(self, nom_auteur):
    """
    Renvoie tous les livres d'un auteur donné.

    :param nom_auteur: (str) Nom de l'auteur
    :return: (list) Liste des livres de cet auteur
    """
    resultat = []
    for livre in self.ens_livre:
        if livre.auteur.nom == nom_auteur:
            resultat.append(livre)
    return resultat

Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster

Licence CC BY NC

Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.