Introduction à la POO
Objets : attributs et création¶
Le libraire du coin de votre rue décide de faire appel à vous pour informatiser son système de gestion de livres : l'objectif de ce tp est de comprendre comment on peut rassember les informations se rapportant à un livre, ainsi que les opérations que l'on peut effectuer sur les livres (en calculer le prix, par exemple) dans une structure cohérente.
En python, le mot-clé class
permet de définir un nouveau type : c'est une nouvelle structure de donnée qui permet de de représenter, structurer et manipuler des objets.
class Livre:bksl-nl passbksl-nlbksl-nllivre1 = Livre()bksl-nlbksl-nl
Attributs d'un objet¶
Le code ci-dessous permet d'ajouter différents attributs au livre : son titre (La peste), son auteur (Albert Camus), et son nombre total de page (59).
livre1.titre = "La peste"bksl-nllivre1.auteur = "Camus Albert"bksl-nllivre1.nbpy-undpages = 59bksl-nlbksl-nllivre2 = Livre()bksl-nl# À compléterbksl-nllivre2.titre = ...bksl-nllivre2.auteur = ...bksl-nllivre2.nbpy-undpages = ...bksl-nlbksl-nl
-
Utiliser Thonny pour inspecter l'objet
livre1
: dans le menu Affichage, faire afficher les panneaux Variables et Inspecteur d'objets en cliquant sur ces entrées. Une fois le panneau Inspecteur d'objets ouvert, cliquer sur le bouton Attributs. Commenter. -
Écrire le code python permettant de représenter le livre Fondation (256 pages), écrit par Isaac Asimov en 1951.
1 2 3 4 5
livre2 = Livre() # À compléter livre2.titre = ... livre2.auteur = ... livre2.nb_pages = ...
Création d'un nouveau livre¶
Écrire une fonction creer_livre
qui prend en argument une chaine de caractère t
, une chaîne de caractères a
et un entier positif n
et qui renvoie l'objet de type Livre
de titre t
, d'auteur a
et constitué de n
pages.
def creerpy-undlivre(t, a, n):bksl-nl """ str, str, int -> Livrebksl-nl Renvoie un nouveau livre """bksl-nl passbksl-nlbksl-nl
À l'aide de la fonction creer_livre
, instancier une variable livre3
de type Livre
qui représente le livre Liens de sang, écrit par Octavia Butler et publié pour la première fois en 1979 (467 pages dans l'édition française par la maison Au diable vauvert).
Fonction __init__
¶
Commenter tout le code précédemment écrit. On remplace la définition précédente de la classe Livre
par la définition suivante.
class Livre:bksl-nl def py-undpy-undinitpy-undpy-und(self, t, a, n):bksl-nl self.titre = tbksl-nl self.auteur = abksl-nl self.nbpy-undpages = nbksl-nlbksl-nl
-
Exécuter ce code, puis exécuter l'instruction suivante dans la console :
1
Livre("Les misérables", "Hugo Victor", 2135)
Observer l'effet sur l'état de la mémoire. Commenter.
-
À quoi peut server la fonction
__init__
placée dans le corps de la classeLivre
? -
-
Peut-on encore instancier une variable de type
Livre
avec l'instructionLivre()
? -
Écrire les instructions permettant d'instancier les variables
livre1
(La peste, Albert Camus, 59 pages),livre2
(Fondation, Isaac Asimov, 256 pages),livre3
(Liens de sang, Octavia Butler, 467 pages) etlivre4
(Les misérables, Victor Hugo, 2135 pages) avec cette nouvelle définition de la classeLivre
.
-
Premières fonctions¶
Afficher un livre¶
Le libraire est un peu perturbé par l'effet de l'instruction print(livre1)
: il préfèrerait un affichage plus lisible. La fonction affiche
prend en argument un objet lvr
de type Livre
et réalise un affichage partiel des informations contenues dans l'objet lvr
.
Modifier la fonction affiche
afin que l'appel affiche(livre1)
indique également le nom de l'auteur du livre dans la description affichée. Tester votre modification sur les variables de type Livre
déjà définies.
def affiche(lvr):bksl-nl """ Livre -> Nonebksl-nl Affiche le livre lvr """bksl-nl titrepy-undlivre = lvr.titrebksl-nl pagespy-undtot = lvr.nbpy-undpagesbksl-nl # À modifierbksl-nl print(f"< Livre '{titrepy-undlivre}', nombre de pages {pagespy-undtot} >")bksl-nlbksl-nl
Prix d'un livre¶
Prix de base¶
Ce libraire peu adepte de la qualité intrinsèque des livres calcule le prix d'un livre de la manière suivante :
- le prix du livre est égal à la somme des prix de ses pages ;
- chaque page avant la 100è (inclue) coûte 10 centimes ;
- chaque page entre la 101è (inclue) et la 1000è (inclue) coûte 2 centimes ;
- chaque page après la 1001è (inclue) coûte 1 centime.
Écrire une fonction prix
qui étant donné un objet lvr
de type Livre
renvoie le prix du livre lvr
.
def prix(lvr):bksl-nl """ Livre -> floatbksl-nl Calcule le prix d'un livre """bksl-nlbksl-nl
Prix réduit¶
Il arrive au libraire de faire occasionnellement des réductions sur le prix des livres. Comme il oublie systématiquement quel calcul il doit effectuer sur sa calculatrice, il aimerait disposer d'une fonction toute prête qui fasse le travail à sa place.
Écrire une fonction prix_reduit
qui étant donné un objet lvr
de type Livre
et un pourcentage de réduction reduc
(un entier compris entre 0 et 100) calcule le prix du livre, après une réduction de reduc
pourcent.
def prixpy-undreduit(lvr, reduc):bksl-nl """ Livre, int -> floatbksl-nl Renvoie le prix du livre après réduction """bksl-nl passbksl-nlbksl-nl
Méthodes d'un objet¶
Sur ce même modèle, on peut imaginer :
- d'autres attributs pour la classe
Livre
. Ils permettent d'ajouter des informations qui permettent de décrire l'objet. - d'autres fonctions (ou méthodes) opérant sur les objets de type
Livre
. Elles permettent de réaliser des opérations sur les objets de typeLivre
.
Afin de structurer efficacement notre code, nous allons encapsuler toutes ces informations dans la classe qui représente notre objet.
Commenter tout le code précédemment écrit, copier-coller le code suivant et exécuter le programme.
class Livre:bksl-nl def py-undpy-undinitpy-undpy-und(self, t, a, n):bksl-nl self.titre = tbksl-nl self.auteur = abksl-nl self.nbpy-undpages = nbksl-nlbksl-nl def affiche(self):bksl-nl """ Livre -> None """bksl-nl titrepy-undlivre = self.titrebksl-nl auteurpy-undlivre = self.auteurbksl-nl pagespy-undtot = self.nbpy-undpagesbksl-nl print(f"< Livre '{titrepy-undlivre}', auteur {auteurpy-undlivre}, nombre de pages {pagespy-undtot} >")bksl-nlbksl-nl def prix(self):bksl-nl """ Livre -> floatbksl-nl Calcule le prix d'un livre """bksl-nl if self.nbpy-undpages <= 100:bksl-nl return self.nbpy-undpages py-str 0.10bksl-nl elif 100 <= self.nbpy-undpages <= 1000:bksl-nl return 100py-str0.10 + (self.nbpy-undpages - 100)py-str0.01 bksl-nl else: bksl-nl return 100py-str0.10 + 900py-str0.02 + (self.nbpy-undpages - 1000)py-str0.01bksl-nlbksl-nl# Initialisation des variablesbksl-nllivre1 = Livre("La peste", "Camus Albert", 59)bksl-nllivre2 = Livre("Fondation", "Asimoov Isaac", 265)bksl-nllivre3 = Livre("Liens de sang", "Octavia Butler", 467)bksl-nllivre4 = Livre("Les misérables", "Victor Hugo", 2135)bksl-nlbksl-nl
Méthodes d'un objet : utilisation¶
Exécuter dans la console les lignes suivantes.
livre1.affiche()bksl-nllivre1.prix()bksl-nlbksl-nl
- Quelle est la différence entre cette syntaxe en notation objet et la syntaxe
affiche(livre1)
etprix(livre1)
? -
Copier-coller le code de la fonction
prix_reduit
dans la classeLivre
, au même degré d'indentation que celui de la fonctionprix
.-
Exécuter dans la console l'instruction
livre1.prix_reduit(50)
.Commenter et corriger l'erreur soulevée par python.
À quoi ce résultat correspond-t-il ?
-
Quelle instruction python permet de calculer le prix du roman Les misérables, si on lui applique une réduction de 42% ?
-
Ajout d'un attribut¶
Modifier la méthode __init__
de la classe Livre
afin d'ajouter un attribut disponible
à la classe Livre
: il s'agit d'un entier positif ou nul qui représente combien de livres de ce type sont disponibles chez le libraire. L'attribut disponible
d'un livre aura pour valeur par défaut 1
.
Reception d'un livre¶
Écrire une méthode recevoir
de la classe Livre
: cette méthode prend comme argument un nombre entier n
correspondant au nombre de copies supplémentaires reçues du livre self
. Celles-ci seront ajoutées aux copies disponibles du livre : on modifiera pour cela l'attribut disponible
.
Attention. On rappelle que le code de cette méthode devra être écrit dans la classe Livre
(c'est à dire au bon niveau d'indentation).
1 2 3 4 |
|
Vente d'un livre¶
Écrire une méthode vendre
de la classe Livre
qui prend en argument un entier reduc
et qui simule la vente du livre self
:
- si aucun livre de ce type n'est disponible, la méthode renvoie
0
. -
sinon : on calcule le prix du livre
self
en appliquant la réduction dereduc
pourcent, et on décrémente de 1 l'attributdisponible
deself
.Enfin la méthode renvoie le prix du livre en euros, arrondi au centime.
1 2 3 |
|
Gestion d'une librairie¶
Introduction et motivation¶
Notre libraire cherche maintenant à gérer une collection de livres. Son stock de livres ne faisant qu'augmenter, il souhaite pouvoir répondre aux clients lui demandant s'il possède ou non un livre dont on lui donne le titre.
Écrire une fonction recherche
qui étant donné une liste de livres collection
et un titre
, renvoie le nombre d'exemplaires disponibles du livre intitulé titre
que possède le libraire. On supposera que chaque titre de la liste collection
est unique.
def recherche(collection, titre):bksl-nl """ [Livre], str -> intbksl-nl Nombre de livres disponible avec le titre indiqué dans la collection. """bksl-nl passbksl-nlbksl-nl
La classe Librairie
¶
Afin de structurer efficacement notre code, on décide de regrouper toutes les fonctions opérant sur une collection de livres dans une classe intitulée Librairie
. Ainsi, à l'aide de cette classe, le libraire pourra efficacement gérer l'ensemble des livres de sa librairie. Dans le code ci-dessous, l'attribut collection
est un objet de type list
constitué d'objets de type Livre
.
class Librairie:bksl-nl def py-undpy-undinitpy-undpy-und(self, c):bksl-nl self.collection = cbksl-nlbksl-nl
-
Avec quelle instruction instancie-t-on une librairie vide (ne contenant aucun livre) ?
-
Instancier une variable
lib
de typeLibrairie
représentant une librairie contenant les livres suivants :- 8 exemplaires du livre La peste, d'Albert Camus (59 pages) ;
- 2 exemplaires du livre Fondation, d'Isaac Asimov (256 pages) ;
- 4 exemplaires du livre Liens de sang, d'Octavia Butler (467 pages)
- 3 exemplairs du livre Les misérables, de Victor Hugo (2135 pages) ;
- 5 exemplaires du livre Harry Potter à l'école des sorciers, de J. K. Rowling (132 pages)
-
-
Transformer la fonction
recherche
écrite précédemment en une méthoderecherche
de la classeLibrairie
. -
En utilisant la syntaxe de la notation objet, écrire l'instruction permettant de déterminer le nombre d'exemplaires du livre Liens de sang présents dans la collection du libraire.
-
Ajouter un livre dans une librairie¶
-
Écrire une méthode
ajoute
de la classeLibrairie
qui prend en argument un objetlvr
de typeLivre
et qui l'ajoute à la librairie représentée parself
: vous modifierez pour cela l'attributcontenu
de la variableself
en lui ajoutant l'objetlvr
.On supposera que l'objet l'objet
lvr
n'est pas déjà présent dans la listeself.contenu
.1 2 3 4
def ajoute(self, lvr): """ Librairie, Livre -> None Ajoute le livre lvr à la librairie self """ pass
-
Écrire le code python permettant d'ajouter à la variable
lib
définie précédemment 11 exemplaires du livre Le roi Babar (15 pages), écrit par Jean de Brunhoff.
(difficile, à passer en première lecture) Modifier la méthode ajoute
afin de prendre en compte le cas où des exemplaires du livre lvr
seraient déjà présent dans la collection du libraire.
Afficher l'ensemble des livres de la librairie¶
Écrire une méthode affiche
de la classe Librairie
qui affiche les informations de tous les livres présents dans la librairie self
.
On utilisera pour cela un parcours de liste de telle sorte que pour chaque élément lvr
de l'attribut collection
de la variable self
, on fasse appel à la méthode affiche
de l'objet de lvr
afin d'afficher le livre en question.
1 2 3 4 |
|
À vous de jouer¶
-
-
Ajouter un nouvel attribut de votre choix à la classe
Livre
. -
Écrire une méthode de la classe
Livre
qui ajoute une fonctionnalité aux objets de typeLivre
(à vous de l'inventer !).
-
-
-
Ajouter un nouvel attribut de votre choix à la classe
Librairie
. -
Écrire une méthode de la classe
Librairie
qui ajoute une fonctionnalité aux objets de typeLibrairie
(à vous de l'inventer !).
-