--- redirect_from: - "/projets/erwancornic-nicolashainak-labypython/rapport" interact_link: content/projets/ErwanCornic_NicolasHainak_LabyPython/rapport.ipynb kernel_name: python3 kernel_path: content/projets/ErwanCornic_NicolasHainak_LabyPython has_widgets: false title: |- Laby en Python, Erwan Cornic et Nicolas Hainak pagenum: 5 prev_page: url: /projets/JiaxuanLiu_BellmanFordLeaflet/rapport.html next_page: url: suffix: .ipynb search: de la et des pour un le les en qui notre nous que une dans ce du est name ou instructions fourmi plus avec widget par avons sur code visualisation laby faire il pas permet niveau nos avoir fonctionnement widgets jeu peut mais valueplayerwidget boutons lon python lhistorique encore permettant dun c jupyter fait enfin fonction player projet retour algorithme simple comprendre dplacer bien exemple tant sera cest notamment trs beaucoup celui ci crer sont utilis suite porte cela diffrentes se comme pouvoir entre bibliothques slider fin autre labyrinthe tre ne caillou votre donc condition rapport mise objectifs etapes programmation comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---
Laby en Python, Erwan Cornic et Nicolas Hainak

Rapport Laby_Python

laby

Cornic Erwan et Hainak Nicolas

Sommaire :

Mise en contexte

Le but de ce TER (travaux d'études et de recherches), est de faire des implémentations d'algorithmes qui soient interactifs, ce qui a pour objectif de voir l'évolution d'un algorithme pas à pas. Pour ce faire on utilise des widgets, il en existe de toutes sortes qui permettent de faire un grand nombre d'intéractions.

Pour ce projet, nous avons choisi de partir sur l'idée de transformer Laby (un outil que l'on a utilisé en première année de licence, qui permet d'apprendre à utiliser la base de la programmation) qui est de base un programme en C++ en Python, et par la suite ajouter de l'interaction à ce programme, chose que l'on expliquera par la suite. Ce jeu est assez simple à comprendre, le joueur contrôle une fourmi qui doit arriver à la porte, cela représente la sortie du niveau. Pour ce faire, le joueur peut appeler différentes méthodes qui permettent à la fourmi de se déplacer, bien sûr plus l’utilisateur avance dans les niveaux, plus il y aura de choses à gérer. Déplacer des obstacles pour en détruire par exemple.

from global_fr import *
Laby("0")
debut()
avance()
avance()
avance()
droite()
avance()
avance()
ouvre()

Ce jeu a été porté sur Jupyther mais uniquement en langage C++, le but étant de répliquer cette implémentation en python. De plus, comme pour l'implémentation en C++ un value_player_widget est nécessaire pour gérer l'historique de notre niveau et pour pouvoir le réutiliser. Suite à des discussions avec nos camarades sur leurs projets et sur ce dont chacun avait besoin il est paru assez évident que le value_player_widget que nous implémentons leur sera utile pour gérer l'historique de leur algorithme. C'est pourquoi nous avons choisi de réaliser un value_player_widget séparer de notre Laby afin de pouvoir permettre à nos camarades de l'utiliser.

Pour s’y prendre nous avons utilisé Jupyter, c’est une application utilisée pour programmer dans un certain nombre de langages, notamment Julia, Python et R (d'où JUlia, PYThon, et R). C'est un outil très intéressant car il permet de séparer son code d'une manière fluide et de pouvoir faire des affichages simplifiés et de mettre du texte entre les cellules. Il y a aussi un certain nombre de bibliothèques qui permettent de réaliser beaucoup de tâches entre de la visualisation de graphe, la gestion de thread grâce à la bibliothèque Timer ou bien encore le fait de générer des nombres aléatoires.

Dévelopement de notre projet

Objectifs et motivations

Notre objectif est la transformation du jeu Laby de C++ en Python. Mais il faut d'abord prendre en main différents widgets pour trouver comment le rendre interactif, et par la suite implémenter notre propre widget d’affichage.

Notre Widget d'affichage sera un value_player_widget dont le but sera de relier notre algorithme à un historique afin de pouvoir naviguer dans celui-ci et avoir une trace de ce que l'on a codé. Ce widget sera composé uniquement de boutons permettant la naviguation dans l'historique (steps by steps , play , pause ect.) mais aussi d'un slider permettant d'accélerer la visualisation de l'algorithme et un slider permettant de montrer a quelle itération nous sommes et de naviguer directememnt dans l'historique.

Pour nos motivations nous voulons avoir quelque chose d'interactif et pratique d'utilisation, de concret comme le jeu de base pour apprendre des choses à des personnes qui vont utiliser ce programme, et enfin de réutilisable notamment avec le widget que l'on a implémenté et qui sera expliqué un peu plus tard.

Etapes de réalisation

1) Nous avons commencé par comprendre comment le code était construit en C++.
2) Nous avons dans un premier temps réalisé  l'affichage des différents niveaux.
3) Par la suite, le déplacement de la fourmi, et les différentes fonctions qui vont avec. (porter, regarder etc.)
4) La création de value_player_widget
5) Le lien entre notre widget et la résolution du niveau.


Nous obtenons à la fin un niveau que l’on a chargé, une cellule du Notebook permettant de faire appels aux différentes fonctions pour contrôler la fourmi et deux sliders, un permettant de contrôler la vitesse d’exécution du code que l’on a écrit, et un autre permettant de choisir à quel moment de l’historique on veut aller.

Pour les widgets que nous utilisons, il y a :

HBox c’est un widget qui permet de créer une boîte horizontale, dans notre code elle contient les différents boutons que nous avons pour contrôler l’historique des actions que nous avons attribué à notre fourmi.

VBox qui est une boîte verticale, ici elle contient notre labyrinthe (ou visualisation) puis nos boutons et enfin le message (dans le cas du labyrinthe). GridBox est utilisé dans la classe View, elle permet de contenir notre labyrinthe sous forme d’images en png.

Et enfin les sliders, notamment FloatSlider qui gère à quelle vitesse les actions s'enchaînent dans le labyrinthe et un IntSlider qui contient pour chaque valeur une itération de la fourmi et qui représente notre historique. Il nous permet de naviguer dans celui-ci.

Fonctionnement de Laby et de value_player_widget

Le fonctionnement de Laby est simple : Laby("0") permet de charger le niveau 0 et peut-être remplacé par nimporte quel autre niveau déjà créé. Pour jouer et faire se déplacer la fourmi des instructions simples sont a utilisées (indiquées dans notre démo) telle que : avance(). Le but étant de réussir à ouvrir la porte et sortir du niveau. Les cailloux et toiles d'araignées sont des obstacles que l'on ne peut pas traverser tous comme les murs. Cependant notre fourmi peut soulever les cailloux et les déplacer. Elle peut en posant un caillou sur une toile d'araignée la détruire et libérer le passage.

Notre Value_player_widget est un outil permettant de créer et d'intéragir avec l'historique de nos éxecutions lorsque l'on exécute un algorithme ou lorsqu'on joue a Laby par exemple (vous pouvez voir nos exemples d'utilisation ici ou dans le rapport de notre camarade dans son utilisation pour le jeu des cruches ici ). Pour utiliser ce widget, vous devez créer une visualisation de votre côté, la donner en argument à notre value_player_widget et celui-ci va vous renvoyer votre affichage de visualisation avec notre widget. La dernière étape et d'ajouter dans votre algorithme la fonction : player.set_value(x) où x est votre value qui sera modifiée et qui impactera votre visualisation. Ce widgets est très adapté pour de la visualisation très simple via des sliders ou des box ipywidgets simples. Cependant nous nous sommes rendu compte que celui-ci était un peu plus adapté pour notre Laby par exemple qui était fait pour marcher avec. Mais très compliqué à adapter pour un jeu tel que le jeu des cruches ou dans l'implémentation actuelle de notre camarade. Les boutons font partis de l'affichage mais aussi de l'algorithme, ce qui créer des problèmes et une adaptabilité compliquée. La création de notre widget se réalise via une simple fonction telle que présentait dans la cellule suivante. La visualisation nous permet de créer un player. Celui-ci va gérer l'historique, via ce player, nous créons un PlayerView qui n'est autre que notre widget et ses fonctions qui agissent sur le player. Enfin nous retournons notre app créée.

def ValuePlayerWidget(visualisation):
    player=Player(visualisation)
    app=PlayerView(player) 

    return app

Autocritique

Du coté Laby, nos idées d’amélioration : On pourrait implémenter des boutons qui iraient écrire directement dans une cellule en-dessous. Pour les boutons on aurait ceux de base :

  • Avance
  • Droite
  • Gauche
  • Prend
  • Regarde
  • Pose
  • Ouvre

Mais aussi quatre autres boutons qui serviront pour l’appel des boucles for, des boucles whiles, du if et enfin de la création d’une fonction. Une fois un des boutons appuyé on changerait son nom par Fin de For ou Fin de While (en fonction du bouton) pour fermer l'indentation du code, le bouton if serait remplacé par else/else if puis pour arrêter l’indentation.
Cela serait peut-être plus simple pour des personnes qui ne savent pas encore appuyer sur les touches d’un clavier avec une certaine rigueur.

Afficher correctement les cases de notre niveau car actuellement l'écart entre les lignes est correct mais concernant celui entre deux cases de la même ligne l'écart est beaucoup trop important. Il est donc difficile de savoir combien de cases nous séparent de la fin d'un couloir par exemple.

Mr Thiéry, qui est à l’origine de ce programme, avait commencé l’implémentation de la fonction sow(), qui laisse une trace du passage de la fourmi sur le labyrinthe. Cela pourrait être un ajout pour des labyrinthes avec plus de salles que des “couloirs”. Ajout de la superposition des images pour savoir quand notre fourmi porte un caillou ou non. Pour que ce soit plus simple à comprendre d’un seul coup d’oeil.

Côté Widget :
Via ces crossovers (utilisation du widget dans une des phases de travail du projet d'un autre groupe de camarade) et pour les cruches. Nous nous sommes rendu compte que notre widget pouvait avoir plusieurs choses à améliorer. Tout d'abord si une personne ne maîtrise pas les widgets de visualisation, il est difficile de comprendre et d'utiliser facilement notre widget. De plus une idée d'amélioration rapide serait de donner directement un historique rempli et non les valeurs au fur et à mesure. Cela pourrait sans doute aider certain à comprendre plus facilement leurs erreurs. Enfin comme expliqué précédemment dans certains projets la visualisation et l'algorithme peuvent se rencontrer notamment dans des programmes intéractifs. Cela pose donc des problèmes d'adaptabilité de notre widget qui demande actuellement une stricte séparation de la visualisation et de l'algorithme. Pour améliorer notre widget nous devrions déplacer le slider time et la gestion du temps qui sont actuellement opérés dans le player afin que celle-ci soit réalisé dans le player view car c'est plus naturel étant donné que notre slider fait partie de l'affichage et que notre player view gère l'affichage.

Expériences acquises

Technologies

Tout d’abord, la prise en main de python, nous en avons tous les deux fait un peu durant notre licence mais sans jamais approfondir plus ce langage. Nous avons donc pu apprendre comment étaient gérées les classes, les méthodes statiques ou bien encore les nombreuses bibliothèque qu’il y a.

Concernant les bibliothèques, nous avons beaucoup utilisé celle de ipywidgets, notamment pour les HBox, VBox ou encore GridBox. Nous avons eu l’avantage que cette bibliothèque soit assez complète en ligne avec des personnes qui avaient déjà eu les problèmes que nous avions rencontrés.

Et enfin Rise, qui est une extension de Jupyter Notebook qui permet de faire des diaporamas à partir de nos fichiers .ipynb, et, en plus de pouvoir exécuter du code pendant le diaporama.

Programmation

Nous avons appris à transformer un code de C++ en python, avec les inconvénients de chacun des langages. Par exemple le fait d’énumérer toutes les tuiles du jeu, le timer ou encore l’héritage.

Le non-typage des variables en Python donne une facilité dans le code mais peut avoir dez problèmes en portée de variable par exemple.

Des structures simples de C++ telle que les class Enum (servant au énumération peuvent être diffèrentes en quelques points et donc ne plus convenir à l'utilisation dont nous avions besoin.

Méthodologie

Avec notre value_player_widget, nos camarades peuvent avoir une visualisation pas à pas de leur(s) algorithme(s).

Étant donné que nous avions été deux pour ce projet, on a utilisé GitHub (un logiciel de contrôle de version permettant de partager des fichiers avec d’autres collaborateurs, sans modifier leur code) ce qui a été très pratique.

 Retour d’expérience

Avec ce projet, nous avons appris l’existence des widgets, qui permettent de faire des interactions avec nos algorithmes. Les widgets sont de différentes natures, on peut avoir des boutons ou encore des sliders. Nous pouvons donc dire que Jupyter est bien adapté dans le principe de programmation d’algorithme intéractif avec une bonne implémentation des algorithmes.

Note à un étudiant

Jupyter permet de déboguer très facilement, en séparant notre code si on a une erreur, on peut localiser rapidement une erreur. Les jupyter notebooks peuvent être utiles pour créer un code, ajouter des commentaires ou des notes de façon claire tout en ayant des tests lisibles et des affichages progressifs. Pour la prise en main des widgets, il est préférable notamment pour le slider de commencer avec des exemples sur internet pour bien comprendre comment l’appeler et voir rapidement la plupart des possibilités d’utilisation. L'extension Rise de Jupyter permet de faire des Diaporama dynamiques en incluant du code et en ayant un facilité d'exécution et de simplicité . Pour ce qui est l’échelle du réalisable, nous n’avons pas vu de limite, en tout cas pour la partie des bibliothèques. Bien sûr certains algorithmes auront besoin de widgets en plus que les nôtres,et , qui ne sont pas encore implémentés. Concernant la partie difficile, c’est de passer d’un langage à un autre ou encore passer du temps pour implémenter des algorithmes alors qu’ils sont déjà faits dans des bibliothèques.

Préconisations :

Avoir une version Linux sous Windows ou un Linux natif, avoir (beaucoup) de places sur le disque si on souhaite avoir beaucoup de bibliothèques sous la main. Et avoir un bon niveau en anglais car comme souvent dans les codes en ligne on a beaucoup plus d’informations en ligne en anglais.

Annexe

Instructions

Voici les instructions utiles pour faire déplacer la fourmi:

avance();       // Fait un pas vers l'avant
droite();       // Fait pivoter la fourmi vers la droite
gauche();       // ou la gauche
prend();        // Prend le caillou situé sur la case devant la fourmi
pose();         // Pose le caillou devant la fourmi
regarde();      // Renvoie Vide, Caillou, Mur, Toile, Sortie, ou Inconnu
                // selon ce qui se trouve sur la case devant la fourmi

ouvre();        // Ouvre la porte située devant la fourmi (fin du niveau)

Retour au fonctionnement.

Constructions

Construction de condition, boucle et fonction pour notre jeu:

Tant que la condition est respectée, répète les instructions:

while condition:
    instructions

Pour tant d'itérations, répète les instructions:

for i in range (0,nombre d'itérations):
    instructions

Si condition est vrai, exécute les instructions 1 sinon les instructions 2:

if  condition:
    instructions1
else: 
    instructions2


Définit une fonction f:

def f(): 
    instructions

Retour au fonctionnement.