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
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.