Projet : Amélioration des objets cartes
Nous allons améliorer la classé que nous avions crée lors du projet précédent (en prérequis).
Un code possible d'une carte
Un code possible d'une carte
Fichier carte.py :
SEPT = 7
HUIT = 8
NEUF = 9
DIX = 10
VALET = 11
DAME = 12
ROI = 13
AS = 14
PIQUE = 4
COEUR = 3
CARREAU = 2
TREFLE = 1
VALEURS = (SEPT, HUIT, NEUF, DIX, VALET, DAME, ROI, AS)
COULEURS = (TREFLE, CARREAU, COEUR, PIQUE)
class Carte:
def __init__(self, valeur, couleur):
self.couleur = couleur
self.valeur = valeur
def texte(self):
valeur = ["7", "8", "9", "10", "V", "D", "R", "1"]
couleur = ["♣︎", "♦", "♥", "♠"]
return valeur[self.valeur - 7] + couleur[self.couleur - 1]
def plus_grande_ou_égale_que(self, other):
return (self.valeur > other.valeur) or (
(self.valeur == other.valeur) and (self.couleur >= other.couleur)
)
Fichier test_carte.py :
import carte
from carte import Carte
def test_constructeur():
assert isinstance(Carte(carte.SEPT, carte.TREFLE), Carte)
def test_texte():
assert Carte(carte.SEPT, carte.TREFLE).texte() == "7♣︎"
def test_plus_grande_ou_égale_que():
assert Carte(carte.AS, carte.TREFLE).plus_grande_ou_égale_que(Carte(carte.VALET, carte.PIQUE))
assert Carte(carte.AS, carte.TREFLE).plus_grande_ou_égale_que(Carte(carte.AS, carte.TREFLE))
assert Carte(carte.AS, carte.PIQUE).plus_grande_ou_égale_que(Carte(carte.AS, carte.TREFLE))
assert not Carte(carte.VALET, carte.PIQUE).plus_grande_ou_égale_que(Carte(carte.AS, carte.TREFLE))
Affichage d'une carte
Remplacez la méthode Carte.texte() par la méthode Carte.__str__().
Modifiez les tests pour prendre en compte de cette nouvelle méthode.
Attribut de classes
Pour créer les cartes on utilise des constantes définies dans le fichier carte.py. Commençons par mettre ces constantes directement dans la classe pour ne pas avoir à tout importer :
Placez les différentes constantes relatives aux valeurs et aux couleur des cartes en attributs de classe et modifiez les tests en conséquence.
Cependant, pour spécifier à l'utilisateur les valeurs et couleurs possibles, utilisez des constantes et des tuples n'est cependant pas optimal. Pour gérer les énumérations, python met à disposition les Enum.
On pourrait ainsi gérer les couleurs ainsi :
>>> from enum import Enum
>>> couleur = Enum("Couleur", [("Pique", 4), ("Cœur", 3), ("Carreau", 2), ("Trèfle", 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.cœur
Couleur.carreau
Couleur.trèfle
Utilisez des Enum pour gérer les constantes VALEURS et COULEURS,puis supprimez les constantes relatives aux différentes valeurs et couleurs individuelles (on n'utilisera que les enum).
Modifiez les tests en conséquence.
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.
Comparaisons
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, rendons nos attributs privés :
Rendez les attributs valeurs et couleurs de chaque carte privé.
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).
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.