Mission 10

Mission 10

L'objectif de cette mission est de créer des robots maintenant un état représentant leur position à l'écran et des opérations permettant de les faire bouger sur l'écran. On peut se baser sur plusieurs bibliothèques graphiques pour implémenter de tels robots. On vous fournira une première implémentation basé sur la bibliothèque graphics.py de Python. A vous de proposer une implémentation similaire en utilisant la bibliothèque turtle. Ces deux types de robots sont polymorphe: ils comprennent exactement les mêmes messages, mais l'un est implémenté avec des positions absolues sur un plan XY, tandis que l'autre utilise des positions relatives. Ensuite on vous demandera d'étendre la fonctionnalité de ces robots, ce qui vous permettra de découvrir la puissance du concept de l'héritage pour la réutilisation du code.

Il sera aussi important de bien tester les classes qui vous sont fournies ou que vous implémenterez, avec des tests unitaires. C'est-à-dire que vous créerez, par classe à tester, une classe test correspondante, avec des méthodes tests pour chacune des méthodes de la classe à tester. Ceci vous permet de tester, à une granularité fine, les différents unités (les classes et les méthodes) de votre code orienté objet.

Les différents concepts traités dans cette mission seront, entre autres : le polymorphisme, la composition, la délégation, l'héritage, la duplication et la réutilisation de code, la substitutabilité, l'utilisation de self et de super, et les tests unitaires. Vous travaillerez par groupes de deux.

Etapes

Etape 1 : Tester la classe XYRobot

L'objectif de cette première étape sera de créer une classe test TestXYRobot avec des tests unitaires pour une classe XYRobot qui vous est fournie.

  • Avant de commencer, vous devez installer le package graphics.py permettant de dessiner des figures simples dans une fenêtre graphique. Cette bibliothèque sera utilisée par la classe XYRobot. Vous pouvez installer ce package facilement depuis Thonny en suivant les étapes suivantes: (1) Sélectionner le menu Tools > Manage Packages... en Thonny; (2) taper graphics.py dans le champs de recherche pour retrouver le bon package et appuyez sur Install .

  • La classe XYRobot utilise aussi des fonctions mathématiques comme math.cos et math.sin ainsi que des constantes mathématiques comme math.pi, fournies par la bibliothèque math.

  • La classe XYRobot (dont l'implémentation se trouve dans le fichier XYRobot.py qui vous est fourni sur le site inginious où vous pouvez remettre votre solution) représente un robot ayant un nom, une position (x, y), et une direction (angle). Quand il bouge, ce robot dessine ses mouvements dans une fenêtre représentant un plan XY.

  • En plus des méthodes __init__ et __str__ et des méthodes accesseurs et mutateurs, cette classe implémente des méthodes comme:

    moveforward(distance) :

    fait avancer le robot de distance pixels et trace une ligne lors de ce mouvement

    movebackward(distance) :

    fait reculer le robot de distance pixels et trace une ligne lors de ce mouvement

    turnleft() :

    fait tourner le robot de 90 degrés vers la gauche (dans le sens contraire des aiguilles d'une montre)

    turnright() :

    fait tourner le robot de 90 degrés vers la droite (dans le sens des aiguilles d'une montre)

    Appeler ces méthodes fait bouger le robot et dessine des figures sur un plan XY. Il suffit d'exécuter le code fourni dans le fichier pour avoir un exemple concret. N'oubliez pas d'installer d'abord la bibliothèque graphics.py avant d'exécuter ce fichier.

L'implémentation de cette classe XYRobot vous est fournie mais il manque une classe avec des tests unitaires afin de vérifier que le robot bouge et met à jour ses attributs correctement. Implémentez cette classe de test TestXYRobot afin de vérifier le comportement correct des différentes méthodes de la classe XYRobot.

Par exemple, quand on crée un nouveau robot r2d2 = XYRobot("R2-D2") il se trouvera à la position (x=100,y=100) avec comme angle 0 (direction Est). Après avoir exécuté r2d2.moveforward(50) le robot devrait se trouver à la position (x=150, y=100), approximativement, à cause des arrondis dans les calculs. Ensuite, après avoir exécuté r2d2.turnleft() l'angle du robot sera 90° (approximativement), etc.

Soyez le plus complet possible dans vos tests. Mettez votre classe test TestXYRobot dans un fichier séparé TestXYRobot.py qui s'occupera de charger le fichier XYRobot.py et d'exécuter les différents tests sur la classe XYRobot.

Etape 2 : implémenter une classe TurtleBot

Dans cette deuxième étape c'est à vous d'implémenter une classe TurtleBot qui est polymorphe avec la clase XYRobot de l'étape précédente. C'est-à-dire que, en plus des méthodes __init__ et __str__ et des méthodes accesseurs (dont getangle() et position()) et mutateurs, elle doit implémenter les mêmes méthodes :

moveforward(distance) :
fait avancer le robot de distance pixels et trace une ligne lors de ce mouvement
movebackward(distance) :
fait reculer le robot de distance pixels et trace une ligne lors de ce mouvement
turnleft() :
fait tourner le robot de 90 degrés vers la gauche (dans le sens contraire des aiguilles d'une montre)
turnright() :
fait tourner le robot de 90 degrés vers la droite (dans le sens des aiguilles d'une montre)

La différence majeure est que la classe TurtleBot fait ces dessins via un objet de type Turtle. Cette classe sera donc assez facile à implémenter en utilisant un objet de type Turtle comme attribut. Le travail d'avancer, tourner et dessiner pourra alors être délégué à ce turtle.

Pour tester son comportement correct, on vous fournit une fichier TestTurtleBot.py (ce fichier se trouve sur le site inginious où vous pouvez remettre votre solution.) Ce fichier test contient des tests unitaires pour votre classe TurtleBot qui doit se trouver dans un fichier TurtleBot.py.

Vous pouvez aussi vérifier que le comportement de votre robot est correct en vérifiant que ce qu'il dessine sur l'écran correspond à ce que vous attendez.

Etape 3 : étendre les classes XYRobot et TurtleBot

Maintenant, on veut étendre la fonctionnalité des robots. A vos deux classes XYRobot et TurtleBot , ajoutez des méthodes pour:

  • garder une trace des actions exécutées auparavant par ce robot
  • rejouer ces action à l'envers (c'est-à-dire de défaire ces actions).

Plus spécifiquement, il faut ajouter les deux méthodes suivantes:

getHistory(self) :

retourne l'historique des actions précédentes, comme une liste du style:

[('forward', 50), ('left', 90), ('forward', 50), ...]

unplay(self) :
rejouer les actions précédentes dans le sens inverse et vider l'historique après avoir rejoué ces actions

Etape 4

Ajouter aux deux classes de test TestXYRobot et TestTurtleBot les tests unitaires nécessaires pour tester si les deux classes XYRobot et TurtleBot, avec la fonctionnalité historique et la fonctionnalité pour défaire les actions, marchent correctement.

Etape 5

Si vous n'avez pas encore utilisé l'héritage lors de l'étape 3, il est fort probable que vous ayez créé des méthodes très similaires dans les deux classes XYRobot et TurtleBot. Ces deux classes représentent tous les deux un robot ayant une mémoire contenant les actions déjà effectuées ainsi qu'une méthode pour défaire ces actions. Une bonne manière d'éviter le code redondant (recopié/dupliqué dans les deux classes) est de le mettre dans un classe mère Robot commune à ces deux classes, et de déclarer XYRobot et TurtleBot comme des classes filles de cette classe. En particulier, la classe mère peut contenir tout le code pour retenir les actions effectuées et de les refaire dans le sens inverse.

Lors de cet étape on vous demande donc de :

  • Créer une nouvelle classe mère Robot qui doit se trouver dans un fichier Robot.py.
  • Réécrivez les classes XYRobot et TurtleBot comme sous-classes de Robot.
  • Bouger le code qui est commun entre les classes filles XYRobot et TurtleBot vers la classe mère Robot.

Etape 6

Rejouez les tests unitaires de l'étape 4 sur les nouvelle classes XYRobot et TurtleBot qui héritent de la nouvelle clases mère. Si tout va bien ces tests doivent toujours fonctionner. Si ce n'est pas le cas, adapter le code ou les tests où nécessaire.

Remise de votre solution

  1. Un fichier Robot.py qui contient la classe mère Robot avec le code de gestion de l'historique.

    (Si vous n'êtes pas arrivé à l'étape 5, remettez simplement un fichier vide ici.)

  2. Un fichier XYRobot.py qui contient la classe XYRobot qui hérite de Robot.

    (Si vous n'êtes pas arrivé à l'étape 5, remettez la version de votre XYRobot sans héritage ici.)

  3. Un fichier TurtleBot.py qui contient la classe TurtleBot qui hérite de Robot.

    (Si vous n'êtes pas arrivé à l'étape 5, remettez la version de votre TurtleBot sans héritage ici.)

  4. Un fichier TestXYRobot.py qui contient les tests unitaires pour votre classe XYRobot.

    Ce fichier TestXYRobot.py doit charger le fichier XYRobot.py et exécuter les différents tests unitaires sur la classe XYRobot.

  5. Un fichier TestTurtleBot.py qui contient les tests unitaires pour votre classe TurtleBot.

    Ce fichier TestTurtleBot.py doit charger le fichier TurtleBot.py et exécuter les différents tests unitaires sur la classe TurtleBot.

Please log in to see this exercise

Page précédente Page suivante
<string>