Projet : Amélioration des objets cartes
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 :
- d'accéder aux attribut
- une tentative de modification produira une erreur
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 :
print(ace_pique)
print(str(ace_pique))
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 commandeeval
(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é
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.