TP 2

Les images des cartes sont placées dans le fichier zip ./resources.zip dézipez le pour pouvoir les utiliser.

Card

Toute classe doit posséder ses tests pour être sur que tout fonctionne bien avant d’être utilisé. Créez les deux fichiers dont le code est donné ci après et vérifiez que tous les tests passent en exécutant le fichier test_card.py avec la bibliothèque py.test.

Puis ajoutez un test pour être sûr que l’as est bien plus grand que les autres cartes.

cards.py

class Card:
    SPADES = "spade"
    HEARTS = "heart"
    CLUBS = "club"
    DIAMONDS = "diamond"

    def __init__(self, value, color):
        self.value = value
        self.color = color

    def __str__(self):
        return "Card(" + str(self.value) + ", " + str(self.color) + ")"

    def __eq__(self, other):
        return self.value == other.value and self.color == other.color

    def __hash__(self):
        return hash((self.value, self.color))

    def __lt__(self, other):
        return (other.value == 1 and self.value != 1) or 1 < self.value < other.value

    def __gt__(self, other):
        return (self.value == 1 and other.value != 1) or self.value > other.value > 1

    def image(self):
        return "resources/Playing_card_" + self.color + "_" + str(self.value) + ".gif"

test_card.py

from cards import Card


def test_str():
    assert str(Card(1, Card.SPADES)) == 'Card(1, spade)'


def test_card_equality():
    assert Card(1, Card.SPADES) == Card(1, Card.SPADES)
    assert Card(1, Card.SPADES) != Card(1, Card.DIAMONDS)

    assert Card(1, Card.SPADES) != Card(13, Card.DIAMONDS)


def test_card_lesser_than():
    assert not Card(3, Card.SPADES) < Card(3, Card.SPADES)
    assert Card(2, Card.SPADES) < Card(3, Card.SPADES)


def test_card_larger_than():
    assert not Card(3, Card.SPADES) > Card(3, Card.SPADES)
    assert Card(3, Card.SPADES) > Card(2, Card.SPADES)


def test_image():
    assert Card(11, Card.DIAMONDS).image() == "resources/Playing_card_diamond_11.gif"

UI

Le code suivant crée une carte selon ce qui est sélectionné dans les option boxs. Exécutez le code et comprenez comment tout ceci fonctionne. Assurez vous que vous avez bien dézipé le fichier resources.zip pour que python trouve bien les différentes images.

Note

Si ce code ne fonctionne pas c’es que vous êtes encore en python2 et pas en python3... Reportez vous à https://wiki.centrale-marseille.fr/informatique/public:python:utiliser_pycharm#installer_un_interpreteur_python3 pour changer votre interpréteur par défaut. Au pire créez un nouveau projet et faites bien attention à ce que ce soit l’interpréteur python3 qui soit utilisé.

from appJar import gui

from cards import Card


app = gui()


app.addLabelOptionBox("color", [Card.DIAMONDS, Card.SPADES, Card.CLUBS, Card.HEARTS], 0, 0)
app.addLabelOptionBox("value", [str(i) for i in range(1, 14)], 0, 1)


def on_click(button):
    color = app.getOptionBox("color")
    value = app.getOptionBox("value")
    app.setImage("card_image", Card(int(value), color).image())

app.addButton("show card", on_click, 1, 0, 2)


app.addImage("card_image", "resources/empty.gif", 2, 0, 2)


app.go()

Deck

A deck est un tas de cartes. Nous allons créer petit à petit cette classe en lui ajoutant des fonctionnalités. On commence ainsi par ajouter une classe vide dans le fichier cards.py :

class Deck:
    pass

Et un test vide dans test_card.py :

from cards importDeck

def test_deck_creation():
    deck = Deck()
    assert deck != None

Vérifiez que les tests passent.

On va maintenant ajouter petit à petit les tests qui vont nous permettre d’ajouter des fonctionnalités à la classe. On va toujours suivre le même pattern :

  1. ajouter un test et le voir planter en exécutant tous les tests
  2. ajouter la fonctionnalité voulue à la classe
  3. exécutez les tests et voir le tout fonctionner.

Ajout de cartes

Un deck est un conteneur. Il doit être vide à la création et on doit pouvoir lui ajouter des cartes.

On commence par un test vérifiant que l’on a implémenté une une méthdoe __len__ permettant d’utiliser la commande len() de python :

def test_deck_empty_at_creation():
    deck = Deck()
    assert len(deck) == 0

Une fois que le test passe, on ajoute un test qui vérifie que l’on peut ajouter une carte au deck :

def test_add_card():
    deck = Deck()
    deck.add(Card(1, Card.SPADES))
    assert len(deck) == 1

Attention, un deck doit être une FIFO : on ajoute une carte au début du deck et on prend une carte à la fin.

Voir des cartes

On veut créer deux méthodes, show_first et show_last qui montrent respectivement la première et la dernière carte du deck. Vous allez tester et implémenter ces deux méthodes.

On commence par show_first :

def test_show_first():
    deck = Deck()
    deck.add(Card(1, Card.SPADES))
    deck.add(Card(2, Card.SPADES))
    assert deck.show_first() == Card(2, Card.SPADES)

Puis show_last :

def test_show_first():
    deck = Deck()
    deck.add(Card(1, Card.SPADES))
    deck.add(Card(2, Card.SPADES))
    assert deck.show_last() == Card(1, Card.SPADES)

Donner des cartes

La dernière méthode à implémenter est get qui donne et enlève une carte du deck.

On commence par tester le fait que l’on rend None si le deck est vide:

def test_get_empty_deck():
    deck = Deck()

    assert deck.get() == None

Puis que l’on récupère bien les carte dans l’ordre :

def test_show_first():
    deck = Deck()
    deck.add(Card(1, Card.SPADES))
    deck.add(Card(2, Card.SPADES))
    card = deck.get()

    assert card == Card(1, Card.SPADES)
    assert len(deck) == 1

UI : Deck

Ajout d’un deck

Modifiez le code de l’UI précédente pour que :
  • ce que l’on voit soit la première carte d’un deck (la dernière ajoutée)
  • que toutes les cartes soient ajoutées à ce deck lorsque l’on clique sur le bouton.
  • ajoutez un label qui donne le nombre de carte du deck.

Dépot des cartes

Ajoutez un bouton et un emplacement pour un autre deck.

Lorsque l’on cliquera sur le deuxième bouton, on prendra la dernière carte du premier deck et on l’ajoutera au second.