Projet : Amélioration des objets cartes

Prérequis :

Protéger les attributs

Une fois la carte créée, il ne faudrait plus pouvoir la modifier. Or pour l'instant on a directement accès aux attributs, donc rien n'interdit de le faire.

Accesseurs

Pour pallier ça, il suffit de définir un accesseur sans mutateur pour les 2 attributs valeur et couleur. Cela permet :

On a alors créé un value object c'est à dire un objet non mutable, comme un entier ou une chaîne de caractères en python.

En utilisant @property, créez et testez des accesseurs pour les attributs valeur et couleur.

Si on a le choix :

Méthode de conception

Lorsque l'on crée un objet, si on a pas de raison particulière de le rendre modifiable on crée un value object. Cela évite les effets de bords (et rend la programmation concurrente et parallèle bien plus simple).

Enum

Pour spécifier à l'utilisateur les valeurs et couleurs possibles, on utilise pour l'instant des constantes et des tuples. Ceci n'est cependant pas optimal.

Pour gérer les énumérations, python met à disposition les Enum. On peut gérer les couleurs ainsi :

>>> from enum import Enum
>>> couleur = Enum("Couleur", [("pique", 4), ("coeur", 3), ("carreau", 2), ("trefle", 1)])
>>> print(couleur.pique.name)
pique
>>> print(couleur.pique.value)
4
>>> c = couleur.pique
>>> c
<Couleur.pique: 4>
>>> for c in couleur:
...     print(c)
...
Couleur.pique
Couleur.coeur
Couleur.carreau
Couleur.trefle

Utilisez des Enum pour gérer les couleurs et les valeurs des cartes

Cette technique est redoutable : elle est à la fois lisible, sans magic number et portable ! Utilisez-la dès que vous voulez gérer des énumérations.

Affichage à l'écran

La méthode spéciale __str__ permet de remplacer notre méthode texte()

Codez la méthode __str__ d'une carte. Le code suivant doit pouvoir fonctionner :

>>> from carte import Carte, AS, PIQUE
>>> ace_pique = Carte(AS, PIQUE)
>>> print(ace_pique)
as de pique

Faites un test de cette méthode en testant la représentation sous la forme d'une chaîne de caractères d'une Carte.

La représentation sous la forme d'une chaîne de caractères un objet x est le résultat de str(x).

Lorsque l'on écrit print(ace_pique), python transforme l'objet en chaîne de caractères avec la commande str qui elle-même cherche la méthode __str__. Les trois instructions suivantes sont donc équivalentes :

  1. print(ace_pique)
  2. print(str(ace_pique))
  3. print(ace_pique.__str__())

Vous verrez parfois une autre méthode de représentation d'un objet utilisant la commande repr(). Cette fonction doit permettre de reconstruire l'objet si nécessaire.

Par exemple :

>>> from carte import Carte
>>> ace_pique = Carte("as", "pique")
>>> print(repr(ace_pique))
Carte('as', 'pique')

On utilise souvent repr() pour du débogage (donc de l'affichage développeur), alors que str() est utilisé pour de l'affichage utilisateur.

  • on utilise str(objet) (créée avec la méthode __str__) pour un affichage à l'écran. On transforme l'objet en un texte.
  • on utilise repr(objet) (créée avec la méthode __repr__) pour représenter l'objet sous la forme d'une chaîne de caractères. On doit pouvoir reconstruire un objet identique avec la commande eval (eval(repr(objet)) doit rendre un objet similaire à objet.

Un petit tuto français pour expliciter les différences entre les deux représentations : https://www.youtube.com/watch?v=ejGYAnf_X24

Créez et testez la méthode __repr__

corrigé

class Carte:
    # ...

    def __repr__(self):
        return "Carte(" + repr(self.valeur) + ", " + repr(self.couleur) + ")"
    
    # ...

Comparaisons de cartes

Ajoutez à votre classe carte les opérateurs de comparaisons :

Codez et testez les opérateurs de comparaisons :

  • == qui correspond a à la méthode __eq__
  • != qui correspond a à la méthode __ne__
  • < qui correspond a à la méthode __lt__
  • > qui correspond a à la méthode __gt__
  • <= qui correspond a à la méthode __le__
  • >= qui correspond a à la méthode __ge__

N'hésitez pas à utiliser des opérateurs déjà codé. Vous pouvez par exemple utiliser les fonctions == et < pour coder les autres les comparaisons.

Refactoring

Modifiez le code de la user story "Ordonnancement" et du jeu en utilisant directement les comparateurs.