Projet : Amélioration des objets dés
Nous allons améliorer la classé que nous avions crée lors du projet précédent (en prérequis).
Valeur par défaut
Faites en sorte que l'on puisse créer des dés avec une valeur initiale, On doit pouvoir :
- créer un dé sans paramètre,
Dé(), et sa valeur doit être sur la valeur 1 - créer un dé avec un paramètre qi sera sa valeur par défaut
Dé(4)par exemple.
corrigé
corrigé
Fichier dé.py :
class Dé:
def __init__(self, valeur=1):
self.valeur = valeur
Ajoutez des tests pour prendre en compte de cette nouvelle fonctionnalité.
corrigé
corrigé
Fichier test_dé.py :
def test_valeur():
assert Dé().valeur == 1
assert Dé(valeur=4).valeur == 4
On utilise toujours la technique qui consiste à utiliser directement un objet créé via le constructeur.
Afficher des dés
Remplacez la méthode Dé.texte() par la méthode Dé.__str__().
corrigé
corrigé
Fichier dé.py :
class dé:
# ..
def __str__(self):
if self.valeur == 1:
return "⚀"
elif self.valeur == 2:
return "⚁"
elif self.valeur == 3:
return "⚂"
elif self.valeur == 4:
return "⚃"
elif self.valeur == 5:
return "⚄"
else:
return "⚅"
On utilise toujours la technique qui consiste à utiliser directement un objet créé via le constructeur.
Modifiez les tests pour prendre en compte de cette nouvelle méthode.
corrigé
corrigé
Fichier test_dé.py :
def test_str():
dé = Dé()
assert str(dé) == "⚀"
dé.valeur = 4
assert str(dé) == "⚃"
Implémentez la méthode spéciale __repr__ et restez là en utilisant la fonction repr.
corrigé
corrigé
Fichier dé.py :
class dé:
# ..
def __repr__(self):
return f"Dé(valeur={self.valeur})"
Fichier test_dé.py :
def test_repr():
assert repr(Dé()) == "Dé(valeur=1)"
Accesseur pour la valeur
On ne devrait pas pouvoir modifier la valeur d'un dé sans le lancer :
Implémentez un accesseur pour l'attribut valeur
corrigé
corrigé
Il y a plusieurs façon de faire. Nous allons montrer une version concise :
Fichier dé.py :
class Dé:
def __init__(self, valeur=1):
self._valeur = valeur
valeur = property(lambda self: self._valeur)
def lancer(self):
self._valeur = random.randrange(1, 6 + 1)
# ...
On utilise le fait que si l'on ne donne qu'un seul argument à la fonction property on ne donne qu'un accesseur et le mutateur est interdit, et l'accesseur est décrit sous la forme d'une fonction lambda de python très utiles pour ce genre de choses.
Il faut aussi changer le test de str. On s'autorise à utiliser directement l'attribut _valeur car les tests font partie du code :
Fichier test_dé.py :
# ...
def test_str():
dé = Dé()
assert str(dé) == "⚀"
dé._valeur = 4
assert str(dé) == "⚃"
# ...
min et max dans classe
Notre classe Dé contient 2 magic numbers qui sont les bornes du lancé. Supprimons-les :
Créez deux attributs de classes MIN_VALEUR et MAX_VALEUR qui vont permettre de supprimer les magics numbers de la méthode Dé.lancer()
corrigé
corrigé
Fichier dé.py :
class dé:
MIN_VALEUR = 1
MAX_VALEUR = 6
# ...
def lancer(self):
self._valeur = random.randrange(self.MIN_VALEUR, self.MAX_VALEUR + 1)
Comparaisons
Créez et testez la comparaison < entree deux dés (méthode spéciale __lt__).
corrigé
corrigé
Fichier dé.py :
class dé:
# ...
def __lt__(self, other):
return self._valeur < other.valeur
Fichier test_dé.py :
def test_lt():
d1 = Dé()
d2 = Dé()
assert not d1 < d2
d2._valeur = 5
assert d1 < d2
assert not d2 < d1
Cette comparaison permet de trier des listes de dés !
Créez le fichier main.py et placez y le code suivant que vous pourrez tester :
from dé import Dé
liste_d = [Dé() for _ in range(5)]
print(liste_d)
for d in liste_d:
d.lancer()
print(liste_d)
liste_d.sort()
print(liste_d)