Projet : Amélioration des objets dés

Prérequis :

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é

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é

Fichier test_dé.py :

def test_valeur():
    assert().valeur == 1
    assert(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é

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é

Fichier test_dé.py :

def test_str():=()
    assert str() == "⚀".valeur = 4
    assert str() == "⚃"

Implémentez la méthode spéciale __repr__ et restez là en utilisant la fonction repr.

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é(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é

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():=()
    assert str() == "⚀"._valeur = 4
    assert str() == "⚃"


# ...

min et max dans classe

Notre classe 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é

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é

Fichier dé.py :

class dé:

    # ...

    def __lt__(self, other):
        return self._valeur < other.valeur

Fichier test_dé.py :

def test_lt():
    d1 =()
    d2 =()
    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 :

fromimport Dé

liste_d = [() for _ in range(5)]

print(liste_d)

for d in liste_d:
    d.lancer()

print(liste_d)
liste_d.sort()
print(liste_d)

Code final