Aller au contenu

La classe Train⚓︎

On souhaite dans cet exercice créer une classe Train permettant de relier des objets de type Wagon.

Un objet de type Wagon possède deux attributs :

  • un contenu contenu de type str,
  • un lien vers le wagon suivant suivant de type Wagon.

On inclut aussi deux méthodes permettant d'afficher le wagon dans la console ou sous forme d'une chaine de caractère.

La classe Wagon (pour information)
🐍 Script Python
class Wagon:
    def __init__(self, contenu):
        "Constructeur"
        self.contenu = contenu
        self.suivant = None

    def __repr__(self):
        "Affichage dans la console"
        return f'Wagon de {self.contenu}'

    def __str__(self):
        "Conversion en string"
        return self.__repr__()

Cette classe est déjà "importée" dans la zone de saisie ci-dessous. Il est inutile de la recopier.

Un objet de la classe Train possède deux attributs :

  • premier contient son premier wagon (de type Wagon) ou None si le train est vide (il n'y a que la locomotive),
  • nb_wagons (de type int) contient le nombre de wagons attachés à la locomotive.

Lors de sa création, un objet de type Train sera toujours vide.

Les méthodes de la classe Train sont présentées ci-dessous (train est un objet de type Train) :

  • train.est_vide() renvoie True si train est vide (ne comporte aucun wagon), False sinon ;
  • train.donne_nb_wagons() renvoie le nombre de wagons de train ;
  • train.transporte_du(contenu) détermine si train transporte du contenu (une chaine de caractères). Renvoie True si c'est le cas, False sinon ;
  • train.ajoute_wagon(wagon) ajoute un wagon à la fin du train. On passe en argument le wagon à ajouter ;
  • train.supprime_wagon_de(contenu) prend en argument une chaine de caractères contenu et supprime le premier wagon de contenu du train. Si le train est vide ou ne comporte aucun wagon de contenu, la méthode renvoie False. S'il en contient un et que celui-ci est effectivement supprimé, la méthode renvoie True.

On inclut là-aussi aussi deux méthodes permettant d'afficher le train dans la console ou sous forme d'une chaine de caractères.

Exemples
  • Création d'un train vide :
🐍 Console Python
>>> train = Train()
  • Ajout de wagons :
🐍 Console Python
>>> w1 = Wagon('blé')
>>> train.ajoute_wagon(w1)
>>> w2 = Wagon('riz')
>>> train.ajoute_wagon(w2)
>>> train.ajoute_wagon(Wagon('sable'))
>>> train
'Locomotive - Wagon de blé - Wagon de riz - Wagon de sable'
  • Description du train :
🐍 Console Python
>>> train.est_vide()
False
>>> train.donne_nb_wagons()
3
>>> train.transporte_du('blé')
True
>>> train.transporte_du('matériel')
False
  • Suppression de wagon
🐍 Console Python
>>> train.supprime_wagon_de('riz')
True
>>> train
'Locomotive - Wagon de blé - Wagon de sable'
>>> train.supprime_wagon_de('riz')
False

On pourra parcourir tous les wagons du train en utilisant les instructions ci-dessous :

🐍 Script Python
wagon = self.premier
while wagon is not None:
    # actions à effectuer
    wagon = wagon.suivant

En plusieurs occasions il faudra prendre soin de traiter séparément le cas du premier wagon et celui des suivants.

Enfin, lors de la suppression d'un wagon, on se contentera de l'omettre en liant son wagon précédent à son suivant. La figure ci-dessous illustre ainsi l'instruction train.supprime_wagon_de('riz') avant et après la suppression.

Suppression

###
# Testsbksl-nltrain = Train()bksl-nlw1 = Wagon("blé")bksl-nltrain.ajoutepy-undwagon(w1)bksl-nlw2 = Wagon("riz")bksl-nltrain.ajoutepy-undwagon(w2)bksl-nltrain.ajoutepy-undwagon(Wagon("sable"))bksl-nlassert str(train) == "Locomotive - Wagon de blé - Wagon de riz - Wagon de sable"bksl-nlassert not train.estpy-undvide()bksl-nlassert train.donnepy-undnbpy-undwagons() == 3bksl-nlassert train.transportepy-unddu("blé")bksl-nlassert not train.transportepy-unddu("matériel")bksl-nlassert train.supprimepy-undwagonpy-undde("riz")bksl-nlassert str(train) == "Locomotive - Wagon de blé - Wagon de sable"bksl-nlassert not train.supprimepy-undwagonpy-undde("riz")bksl-nlbksl-nlbksl-nl# Tests secretsbksl-nltrain = Train()bksl-nlfor k in range(10):bksl-nl train.ajoutepy-undwagon(Wagon("A"))bksl-nl train.ajoutepy-undwagon(Wagon("B"))bksl-nl assert train.donnepy-undnbpy-undwagons() == 2 py-str (k + 1)bksl-nl assert train.nbpy-undwagons == train.donnepy-undnbpy-undwagons()bksl-nlassert str(train) == "Locomotive - " + " - ".join(["Wagon de A", "Wagon de B"] py-str 10)bksl-nlassert train.transportepy-unddu("A")bksl-nlassert train.transportepy-unddu("B")bksl-nlassert not train.transportepy-unddu("C")bksl-nlfor k in range(10):bksl-nl assert train.supprimepy-undwagonpy-undde("A")bksl-nl assert train.donnepy-undnbpy-undwagons() == 20 - (k + 1)bksl-nlassert str(train) == "Locomotive - " + " - ".join(["Wagon de B"] py-str 10)bksl-nlassert not train.supprimepy-undwagonpy-undde("A")bksl-nlassert not train.supprimepy-undwagonpy-undde("C")bksl-nlbksl-nl 5/5

#--- HDR ---#bksl-nlclass Wagon:bksl-nl def py-undpy-undinitpy-undpy-und(self, contenu):bksl-nl "Constructeur"bksl-nl self.contenu = contenubksl-nl self.suivant = Nonebksl-nlbksl-nl def py-undpy-undreprpy-undpy-und(self):bksl-nl "Affichage dans la console"bksl-nl return f"Wagon de {self.contenu}"bksl-nlbksl-nl def py-undpy-undstrpy-undpy-und(self):bksl-nl "Conversion en string"bksl-nl return self.py-undpy-undreprpy-undpy-und()bksl-nl#--- HDR ---#bksl-nlclass Train:bksl-nl def py-undpy-undinitpy-undpy-und(self):bksl-nl "Constructeur"bksl-nl self.premier = Nonebksl-nl self.nbpy-undwagons = ...bksl-nlbksl-nl def estpy-undvide(self):bksl-nl """renvoie True si ce train est vide (ne comporte aucun wagon),bksl-nl False sinonbksl-nl """bksl-nl return ...bksl-nlbksl-nl def donnepy-undnbpy-undwagons(self):bksl-nl "Renvoie le nombre de wagons de ce train"bksl-nl return ...bksl-nlbksl-nl def transportepy-unddu(self, contenu):bksl-nl """Détermine si ce train transporte du {contenu} (une chaine de caractères).bksl-nl Renvoie True si c'est le cas, False sinonbksl-nl """bksl-nl wagon = self.premierbksl-nl while wagon is not None:bksl-nl if wagon.contenu == ...:bksl-nl return ...bksl-nl ... = wagon....bksl-nl return ...bksl-nlbksl-nl def ajoutepy-undwagon(self, nouveau):bksl-nl """Ajoute un wagon à la fin de ce train.bksl-nl L'argument est le wagon à ajouterbksl-nl """bksl-nl if self.estpy-undvide():bksl-nl self.premier = ...bksl-nl else:bksl-nl wagon = self.premierbksl-nl while ....suivant is not None:bksl-nl wagon = ....suivantbksl-nl wagon.suivant = ...bksl-nl self.nbpy-undwagons = ...bksl-nlbksl-nl def supprimepy-undwagonpy-undde(self, contenu):bksl-nl """Supprime le premier wagon de {contenu}bksl-nl Renvoie False si ce train ne contient pas de {contenu},bksl-nl True si la suppression est effectuéebksl-nl """bksl-nl # On parcourt le train afin de trouver le contenubksl-nl precedent = Nonebksl-nl wagon = self.premierbksl-nl while wagon is not ... and wagon.contenu != ...:bksl-nl precedent = wagonbksl-nl wagon = wagon....bksl-nlbksl-nl if wagon is ...: # on a parcouru tout le train sans trouver le contenubksl-nl return ...bksl-nl if precedent is ...: # le wagon supprimé est le premier du trainbksl-nl self.premier = wagon....bksl-nl else: # le wagon supprimé n'est pas le premierbksl-nl precedent.... = wagon....bksl-nl self.nbpy-undwagons -= ...bksl-nl return ...bksl-nlbksl-nl def py-undpy-undreprpy-undpy-und(self):bksl-nl "Affichage dans la console"bksl-nl contenuspy-undwagons = ['']bksl-nl wagon = self.premierbksl-nl while wagon is not None:bksl-nl contenuspy-undwagons.append(str(wagon))bksl-nl wagon = wagon.suivantbksl-nl return "Locomotive" + " - ".join(contenuspy-undwagons)bksl-nlbksl-nl def py-undpy-undstrpy-undpy-und(self):bksl-nl "Conversion en string"bksl-nl return self.py-undpy-undreprpy-undpy-und()bksl-nlbksl-nlbksl-nl# Testsbksl-nltrain = Train()bksl-nlw1 = Wagon("blé")bksl-nltrain.ajoutepy-undwagon(w1)bksl-nlw2 = Wagon("riz")bksl-nltrain.ajoutepy-undwagon(w2)bksl-nltrain.ajoutepy-undwagon(Wagon("sable"))bksl-nlassert str(train) == 'Locomotive - Wagon de blé - Wagon de riz - Wagon de sable'bksl-nlassert not train.estpy-undvide()bksl-nlassert train.donnepy-undnbpy-undwagons() == 3bksl-nlassert train.transportepy-unddu('blé')bksl-nlassert not train.transportepy-unddu('matériel')bksl-nlassert train.supprimepy-undwagonpy-undde('riz')bksl-nlassert str(train) == 'Locomotive - Wagon de blé - Wagon de sable'bksl-nlassert not train.supprimepy-undwagonpy-undde('riz')bksl-nlbksl-nlclass Wagon:bksl-nl def py-undpy-undinitpy-undpy-und(self, contenu):bksl-nl "Constructeur"bksl-nl self.contenu = contenubksl-nl self.suivant = Nonebksl-nlbksl-nl def py-undpy-undreprpy-undpy-und(self):bksl-nl "Affichage dans la console"bksl-nl return f"Wagon de {self.contenu}"bksl-nlbksl-nl def py-undpy-undstrpy-undpy-und(self):bksl-nl "Conversion en string"bksl-nl return self.py-undpy-undreprpy-undpy-und()bksl-nlbksl-nlbksl-nlclass Train:bksl-nl def py-undpy-undinitpy-undpy-und(self):bksl-nl "Constructeur"bksl-nl self.premier = Nonebksl-nl self.nbpy-undwagons = 0bksl-nlbksl-nl def estpy-undvide(self):bksl-nl """renvoie True si ce train est vide (ne comporte aucun wagon),bksl-nl False sinonbksl-nl """bksl-nl return self.nbpy-undwagons == 0bksl-nlbksl-nl def donnepy-undnbpy-undwagons(self):bksl-nl "Renvoie le nombre de wagons de ce train"bksl-nl return self.nbpy-undwagonsbksl-nlbksl-nl def transportepy-unddu(self, contenu):bksl-nl """Détermine si ce train transporte du contenu (une chaine de caractères).bksl-nl Renvoie True si c'est le cas, False sinonbksl-nl """bksl-nl wagon = self.premierbksl-nl while wagon is not None:bksl-nl if wagon.contenu == contenu:bksl-nl return Truebksl-nl wagon = wagon.suivantbksl-nl return Falsebksl-nlbksl-nl def ajoutepy-undwagon(self, nouveau):bksl-nl """Ajoute un wagon à la fin de ce train.bksl-nl L'argument est le wagon à ajouterbksl-nl """bksl-nl if self.estpy-undvide():bksl-nl self.premier = nouveaubksl-nl else:bksl-nl wagon = self.premierbksl-nl while wagon.suivant is not None:bksl-nl wagon = wagon.suivantbksl-nl wagon.suivant = nouveaubksl-nl self.nbpy-undwagons += 1bksl-nlbksl-nl def supprimepy-undwagonpy-undde(self, contenu):bksl-nl """Supprime le premier wagon de {contenu}bksl-nl Renvoie False si ce train ne contient pas de {contenu},bksl-nl True si la suppression est effectuéebksl-nl """bksl-nl # On parcourt le train afin de trouver le contenubksl-nl precedent = Nonebksl-nl wagon = self.premierbksl-nl while wagon is not None and wagon.contenu != contenu:bksl-nl precedent = wagonbksl-nl wagon = wagon.suivantbksl-nlbksl-nl if wagon is None: # on a parcouru tout le train sans trouver le contenubksl-nl return Falsebksl-nl if precedent is None: # le wagon supprimé est le premier du trainbksl-nl self.premier = wagon.suivantbksl-nl else: # le wagon supprimé n'est pas le premierbksl-nl precedent.suivant = wagon.suivantbksl-nl self.nbpy-undwagons -= 1bksl-nl return Truebksl-nlbksl-nl def py-undpy-undreprpy-undpy-und(self):bksl-nl "Affichage dans la console"bksl-nl contenuspy-undwagons = [""]bksl-nl wagon = self.premierbksl-nl while wagon is not None:bksl-nl contenuspy-undwagons.append(str(wagon))bksl-nl wagon = wagon.suivantbksl-nl return "Locomotive" + " - ".join(contenuspy-undwagons)bksl-nlbksl-nl def py-undpy-undstrpy-undpy-und(self):bksl-nl "Conversion en string"bksl-nl return self.py-undpy-undreprpy-undpy-und()bksl-nlbksl-nl

A

Sous ses allures pseudo-concrètes, le sujet permet d'implémenter une liste chainée (classe Train) dont les maillons sont les objets de la classe Wagon.

Z