Exo Objets 2

Identification

Infoforall

15 - Exos Objets Méthodes


Attention, le soin est noté et les codes markdown identiques seront sanctionnés à moins de noter clairement que vous avez travaillé avec un autre élève de la classe.

1 - Classe Livre

Dans le but de gérer une bibliothèque (et avant de faire les Bases de Données, bien plus efficaces pour faire cela que l'ensemble d'objets que nous allons créer aujourd'hui), nous voudrions créer une Classe nous permettant d'enregistrer les informations sur chaque livre et interagir avec lui.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
# Importation import datetime # Déclaration des classes class Livre : def __init__(self, titre, date=datetime.datetime.now().date()) : self.titre = titre # titre de l'ouvrage self.etat = 'Très bon' # état du livre self.enregistrement = date # date d'enregistrement dans la biliothèque self.emprunteur = None # objet-client self.date_emprunt = None # date de l'emprunt self.date_retour = None # date de retour self.avant_dernier_emprunteur = None # objet-client de l'avant-dernier client def empruntable(self) : pass def calcul_retour(self) : pass def retour(self, client, date=datetime.datetime.now().date()) : pass def emprunt(self, client, date=datetime.datetime.now().date()) : pass def modifier_etat(self, nouvel_etat) : pass def informations(self) : if self.emprunteur : return f"{self.titre} - emprunté jusqu'au {self.date_retour} par {self.emprunteur.informations()}" else : return f"{self.titre} - disponible" # Programme de test if __name__ == '__main__' : livre1 = Livre("NSI forever !") livre2 = Livre("Comment réussir ses études supérieures ?") livre3 = Livre("En travaillant !")

01° Comment doit-on nommer Livre ?

  1. un constructeur
  2. une méthode
  3. un attribut
  4. une classe

02° Comment doit-on nommer Livre(), avec les parenthèses cette fois, ?

  1. un constructeur
  2. une méthode
  3. un attribut
  4. une classe

03° Comment doit-on nommer etat sur la ligne 10 ?

  1. un constructeur
  2. une méthode
  3. un attribut
  4. une classe

04° Comment doit-on nommer empruntable sur la ligne 17 ?

  1. un constructeur
  2. une méthode
  3. un attribut
  4. une classe

05° Piègeux. Comment doit-on nommer titre sur la ligne 7 ?

  1. un attribut
  2. un argument
  3. un paramètre
  4. un truc...

06° Piègeux. Comment doit-on nommer le titre de self.titre sur la ligne 9 ?

  1. un attribut
  2. un argument
  3. un paramètre
  4. un truc...

07° Comment doit-on nommer les variables livre1, livre2 et livre3 ?

  1. une Classe
  2. un objet ou une instance
  3. un bouquin
  4. un stance

08° Lancer le programme. Que faut-il taper dans le Shell pour observer le titre du livre 2 ?

09° Compléter maintenant le code de la méthode empruntable. Votre méthode devra renvoyer un booléen : True si le livre n'a pas encore d'emprunteur, False sinon.

Voici le prototype :

1
def empruntable(self:Livre) -> bool :

Il s'agit bien entendu de comparer le contenu de l'attribut emprunteur à None  s'il n'y a pas d'emprunteur, c'est bien que le livre est empruntable.

10° Compléter le code de la méthode modifier_etat. Votre méthode devra remplacer le contenu de l'attribut par le paramètre-string .

Vous imposerez par une assertion que ce paramètre soit bien un string.

Voici le prototype.

1
def modifier_etat(self:Livre, nouvel_etat:str) -> None :

Voici le code à compléter :

1 2
def modifier_etat(self, nouvel_etat) : assert type(nouvel_etat) == str

11° Tapez ceci dans le Shell pour découvrir comment sont stockées les dates d'enregistrement du livre :

>>> livre1.enregistrement datetime.date(2020, 10, 20)
Module datetime

Ce module permet de gérer beaucoup de choses au niveau des dates et des horaires.

On utilise ici notamment la classe datetime (je sais, la Classe porte le même nom que le module et elle ne commence pas par une Majuscule).

On y trouve la méthode now() qui permet d'obtenir avec précision l'année, le mois, le jour et la date exacte de ... maintenant.

>>> import datetime >>> datetime.datetime.now() datetime.datetime(2020, 10, 20, 16, 34, 59, 294905)

Si vous ne voulez que la date, pas l'horaire, il faut appliquer la méthode date sur l'objet-date obtenu avec l'utilisation de now :

>>> datetime.datetime.now().date() datetime.date(2020, 10, 20)

De plus, on peut très bien ne récupérer que l'année, le mois ou le jour :

>>> d = datetime.datetime.now().date() >>> d.year 2020 >>> d.month 10 >>> d.day 20

De la même façon, si vous ne voulez que l'horaire, pas la date :

>>> import datetime >>> datetime.datetime.now().time() datetime.time(16, 38, 25, 578947) >>> t = datetime.datetime.now().time() >>> t.hour 16 >>> t.minute 38 >>> t.second 58 >>> t.microsecond # 1 000 000 µs pour 1s 245178 # soit 0,245178 s

Et comment faire si on veut calculer une date à partir d'aujourd'hui ? Il existe une classe nommée timedelta qui permet de créer des durées. On pourra additionner une date ou un horaire avec cette durée. Le module permet une gestion automatique du passage d'un mois à l'autre. Très pratique.

>>> maintenant = datetime.datetime.now().date() >>> maintenant datetime.date(2020, 10, 20) >>> dans15jours = maintenant + datetime.timedelta(days=15) >>> dans15jours datetime.date(2020, 11, 4)

12° Compléter le code de la méthode calcul_retour : elle doit renvoyer la date à laquelle le livre devra revenir à la bibliothèque, sachant qu'on autorise des emprunts de 21 jours.

Regarder dans la méthode __init__ pour savoir dans quel attribut se trouve la date initiale de l'emprunt.

1 2 3 4
def calcul_retour(self) : date_emprunt = ??? date_retour = date_emprunt + datetime.timedelta(days=???) return ???

Avant de pouvoir continuer à gérer nos livres (à savoir les emprunts et les retours), il va falloir des gens pour les louer. Passons à la classe Client.

2 - classe Client

Passons donc à la classe Client.

Voici le code à utiliser mais pensez bien à placer vos propres versions des méthodes empruntable et calcul_retour dans la classe Livre.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
# Importation import datetime # Déclaration des classes class Livre : def __init__(self, titre, date=datetime.datetime.now().date()) : self.titre = titre # titre de l'ouvrage self.etat = 'Très bon' # état du livre self.enregistrement = date # date d'enregistrement dans la biliothèque self.emprunteur = None # objet-client self.date_emprunt = None # date de l'emprunt self.date_retour = None # date de retour self.avant_dernier_emprunteur = None # objet-client de l'avant-dernier client def empruntable(self) : return True # Placez bien votre propre version ! def calcul_retour(self) : date_emprunt = self.date_emprunt date_retour = date_emprunt + datetime.timedelta(days=15) # Placez bien votre version return date_retour def retour(self, client, date=datetime.datetime.now().date()) : pass def emprunt(self, client, date=datetime.datetime.now().date()) : if self.empruntable() : self.emprunteur = client self.date_emprunt = date self.date_retour = self.calcul_retour() def modifier_etat(self, nouvel_etat) : pass # Placez bien votre version def informations(self) : if self.emprunteur : return f"{self.titre} - emprunté jusqu'au {self.date_retour} par {self.emprunteur.informations()}" else : return f"{self.titre} - disponible" class Client : def __init__(self, nom, prenom, adresse) : self.nom = nom self.prenom = prenom self.adresse = adresse def louer(self, livre, maintenant=datetime.datetime.now().date()) : livre.emprunt(self, maintenant) def rendre(self, livre, maintenant=datetime.datetime.now().date()) : pass def informations(self) : return f"{self.nom} {self.prenom}" # Programme de test if __name__ == '__main__' : livre1 = Livre("NSI forever !") livre2 = Livre("Comment réussir ses études supérieures ?") livre3 = Livre("En travaillant !") c1 = Client("Liddell", "Alice", "Wonderland") c2 = Client("Léponge", "Bob", "Rue de la Mer") c3 = Client("Kent", "Clark", "Metropolis")

13° Donner les contenus des 3 attributs de l'instance de Client nommée c2 après exécution de la ligne 69.

14° Que doit-il s'afficher sur la console si on tape ceci ? Deuxième question : comment doit-on nommer informations ?

>>> c2.informations()

15° Expliquer ce que fait cette méthode ligne par ligne lorsqu'on l'active de cette façon :

>>> c2.louer(livre1) >>> livre1.informations() "NSI forever ! - emprunté jusqu'au 2020-11-05 par Léponge Bob"

16° Comment se nomme le principe de programmation qui nous empêche (par principe, on pourrait le faire en réalité) de coder la modification du livre directement dans le code du Client. Après tout, c'est assez compliqué : on active une méthode d'un client qui va activer une méthode de la classe Livre...

  1. Encapsulation
  2. Encapsulite
  3. Encapsulose
  4. Enfermement

17° Dernière question, plutôt difficile du coup : à vous de coder les méthodes retour de la classe Livre et rendre de la classe Client.

Il faudra remettre les dates ainsi que l'emprunteur à None dans le livre mais stocker l'identifiant de l'ancien emprunteur.

3 - Classe Bibliothèque

Pour finir, juste un peu de blabla.

Si on veut réellement créer notre bibliothèque, nous pourrions créer nos variables livres et clients et gérer ainsi les interactions.

Mais si on veut vraiment respecter la programmation objet, il faudrait en réalité créer un objet de classe Bibliotheque qui pourra stocker les instances des livres et des clients.

Voici cette classe. Elle n'est pas finalisée : on peut juste enregistrer les livres et les clients. Il faudrait encore créer des méthodes d'interface pour sélectionner un client et un livre particulier ainsi que l'action emprunter ou rendre par exemple.

18° Mettre la version 3 classes en mémoire. Lancer le code et lire le programme pour comprendre l'affichage obtenu.

Voici les clients enregistrés : Liddell Alice Léponge Bob Kent Clark Voici les livres disponibles : NSI forever ! - emprunté jusqu'au 2020-11-05 par Léponge Bob Comment réussir ses études supérieures ? - disponible En travaillant ! - disponible

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
# Importation import datetime # Déclaration des classes class Livre : def __init__(self, titre, date=datetime.datetime.now().date()) : self.titre = titre # titre de l'ouvrage self.etat = 'Très bon' # état du livre self.enregistrement = date # date d'enregistrement dans la biliothèque self.emprunteur = None # objet-client self.date_emprunt = None # date de l'emprunt self.date_retour = None # date de retour self.avant_dernier_emprunteur = None # objet-client de l'avant-dernier client def empruntable(self) : return True # Placez bien votre propre version ! def calcul_retour(self) : date_emprunt = self.date_emprunt date_retour = date_emprunt + datetime.timedelta(days=15) # Placez bien votre version return date_retour def retour(self, client, date=datetime.datetime.now().date()) : pass def emprunt(self, client, date=datetime.datetime.now().date()) : if self.empruntable() : self.emprunteur = client self.date_emprunt = date self.date_retour = self.calcul_retour() def modifier_etat(self, nouvel_etat) : pass # Placez bien votre version def informations(self) : if self.emprunteur : return f"{self.titre} - emprunté jusqu'au {self.date_retour} par {self.emprunteur.informations()}" else : return f"{self.titre} - disponible" class Client : def __init__(self, nom, prenom, adresse) : self.nom = nom self.prenom = prenom self.adresse = adresse def louer(self, livre, maintenant=datetime.datetime.now().date()) : livre.emprunt(self, maintenant) def rendre(self, livre, maintenant=datetime.datetime.now().date()) : pass def informations(self) : return f"{self.nom} {self.prenom}" class Bibliotheque : def __init__(self, identifiant) : self.id = identifiant self.livres = [] self.clients = [] def rajouter_client(self, client) : assert isinstance(client, Client) self.clients.append(client) def rajouter_livre(self, livre) : assert isinstance(livre, Livre) self.livres.append(livre) def voir_les_livres(self) : print("Voici les livres disponibles :") for livre in self.livres : print(livre.informations()) def voir_les_clients(self) : print("Voici les clients enregistrés :") for client in self.clients : print(client.informations()) def location(self, num_client, num_livre, maintenant=datetime.datetime.now().date()) : if num_client >= 0 and num_client < len(self.clients) and num_livre >= 0 and num_livre < len(self.livres) : client = self.clients[num_client] livre = self.livres[num_livre] client.louer(livre, maintenant) return True return False def retour(self, num_client, num_livre, maintenant=datetime.datetime.now().date()) : if num_client >= 0 and num_client < len(self.clients) and num_livre >= 0 and num_livre < len(self.livres) : client = self.clients[num_client] livre = self.livres[num_livre] client.rendre(livre, maintenant) return True return False # Programme de test if __name__ == '__main__' : b = Bibliotheque("Ma bibliothèque à moi que j'ai") b.rajouter_client( Client("Liddell", "Alice", "Wonderland") ) b.rajouter_client( Client("Léponge", "Bob", "Rue de la Mer") ) b.rajouter_client( Client("Kent", "Clark", "Metropolis") ) b.rajouter_livre( Livre("NSI forever !") ) b.rajouter_livre( Livre("Comment réussir ses études supérieures ?") ) b.rajouter_livre( Livre("En travaillant !") ) b.location(1, 0) b.voir_les_clients() b.voir_les_livres()

Activité publiée le 21 10 2020
Dernière modification : 21 10 2020
Auteur : ows. h.