TP 3¶
Dice¶
Tout comme pour le TP_2, 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_dice.py
avec la bibliothèque py.test
.
- A faire :
- la méthode de classe number_faces n’est pas testée. Créez un tet pour cette méthode (par exemple, créez un dé à 20 faces avec la méthode et testez que son nombre de faces est correct)
- modifiez la méthode test_roll pour que le dé créé soit à une face et simplifiez le test.
dice.py¶
import random
class Dice:
@classmethod
def number_faces(cls, number_faces):
dice = cls()
dice.NUMBER_FACES = number_faces
return dice
def __init__(self, value=1):
self.NUMBER_FACES = 6
self._value = value
def get_value(self):
return self._value
def set_value(self, new_value):
self._value = new_value
def roll(self):
self.set_value(random.randint(1, max(self.NUMBER_FACES, 1)))
test_dice.py¶
from dice import Dice
def test_dice_creation_no_argument():
un_de = Dice()
assert un_de.get_value() == 1
def test_dice_creation_initial_creation():
un_de = Dice(value=3)
assert un_de.get_value() == 3
def test_dice_change_position():
un_de = Dice()
un_de.set_value(6)
assert un_de.get_value() == 6
def test_roll():
un_de = Dice()
un_de.roll()
assert 1 <= un_de.get_value() <= un_de.NUMBER_FACES
UI¶
Le code suivant crée un Dé. Il est lancé et le résultat affiché lorsque l’on clique sur le bouton roll.
Note
Si ce code ne fonctionne pas reportez vous au TP2 où vous avez déjà réglé ce problème.
from appJar import gui
from dice import Dice
dice = Dice()
DICE_LABEL = "dice value"
def on_click(button):
dice.roll()
app.setLabel(DICE_LABEL, dice.get_value())
app = gui()
app.setGeometry(400, 200)
app.addLabel(DICE_LABEL, dice.get_value(), 0, 0)
app.addButton("roll", on_click, 0, 1)
app.go()
Ajoutez une ligne de texte contenant l’heure et la valeur du nouveau dé à chaque fois que l’on clique.
- Pour cela, vous pourrez utiliser :
- les http://appjar.info/pythonWidgets/#listbox pour ajouter les lignes de messages (attention. Les list box ont une hauteur par défaut. En choisissant 200 comme hauteur de la fenêtre, vous devriez pouvoir voir et la 1ère ligne (la valeur du dé et le bouton roll) et la 2nde (la listbox)).
- Pour le temps, on pourra utiliser les objets datetime (voir https://docs.python.org/3.4/library/datetime.html#datetime-objects)
Undo¶
DiceMemento¶
Créez la classe DiceMemento dans le fichier dice_memento.py
et ses tests dans le fichiers test_dice_memento.py
.
- La classe DiceMemento doit avoir :
- un Dice comme paramètre du constructeur.
- une méthode restore() qui remet au dé sauvé la valeur qu’il avait à la création du memento.
Vous pouvez par exemple transformer le code ci-après en test(s) :
dice = Dice()
dice.set_value(2)
memento = DiceMemento(dice)
dice.set_value(6)
memento.restore()
print(dice.get_value()) # doit valoir 2
undo list¶
- Nous allons (enfin, plutôt : vous allez) créer une classe Undo (dans le fichier
undo.py
) qui va nous permettre de sauver des dés (et leurs valeurs) et de les restaurer à la demande. Cette classe doit pouvoir : - sauver un dé avec la méthode : save(dice) (un DiceMemento sera créé dans la méthode save puis sauvegardé)
- restaurer la dernière valeur sauvée avec la méthode restore()
- connaitre le nombre d’item sauvegardé avec la commande len (il faut donc implémenter une méthode __len__)
Bien sur vous créerez un fichier de test test_undo.py
qui testera les 3 fonctionnalités ci-dessus.
UI : Undo¶
Ajoutez à l’UI un bouton undo.
A chaque fois que l’on clique sur le bouton roll, la position du dé doit être sauvée. Cette position doit être restaurée lorsque l’on clique sur le bouton undo. De plus, on doit ajouter un message à la listbox qui prévient que la valeur du dé à été undoué.