Aller au contenu

Licence du TP

Ce TP et l'archive afférente sont placés sous licence Creative Commons By-SA 4.0.

Avant de faire ce TP veuillez lire le cours suivant sur les dictionnaires. Vous pouvez aussi, si vous préférez apprendre en vous entraînant faire la série de notebook suivant.

Travailler chez soi

Pour continuer à travailler ce TP chez vous, vous devez vous l'envoyer par mail ou le mettre dans un espace en ligne. De plus il vous faudra installer Flask et python chez vous (voir le TP Client Serveur)

Manipulation de dictionnaires en Python (MVC)⚓︎

Un annuaire avec Flask ⁉⚓︎

Bienvenue pour ce TP sur la manipulation des dictionnaires en utilisant Flask ! Au cours de ce TP, vous allez apprendre à créer une application Web simple qui permettra de gérer un annuaire de contacts. Vous aurez à votre disposition un squelette Flask pour vous aider à démarrer rapidement et les fichiers HTML pour la partie interface utilisateur.

Téléchargez l'archive contenant le squelette ici et extrayez là dans votre dossier personnel (celui partagé par tout les ordinateurs du lycée).

N'hésitez pas à poser des questions si vous avez des doutes ou des incohérences dans les consignes.

Besoin d'aide ?

Si vous avez besoin d'aide, les section Protocole détaillé sont là. Elles contiennent des astuces pour réaliser la fonctionnalité demandée. Attention, ne les utilisez que si vous avez vraiment besoin. Si elles ne suffisent encore pas, cliquez sur les blocs Détails pour avoir une explication du code à écrire.

Pré-requis ✔⚓︎

  • Connaissance de base en programmation :
    • les boucles,
    • les conditions,
    • les fonctions,
    • les variables.
  • Connaissance de Flask :
    • Associer une route à une fonction,
    • renvoyer une page HTML dynamique
  • Connaissance des dictionnaires en Python :
    • Stockage de donnée,
    • accès aux données,
    • modifications de données.

HTML,CSS,JS

La connaissance complète de HTML, CSS et Javascript n'est pas requise. Cependant, une compréhension de base de ces technologies pourra être utile pour comprendre comment fonctionne l'interface utilisateur de l'application et pour la modifier.

Rendu⚓︎

Votre rendu final est une archive ZIP nommée nom_prenom.zip contenant les fichiers suivants:

  • Un fichier README rédigé au format Markdown,
  • le sous répertoire template et tout les fichiers de l'application,
  • tout fichier qui serait nécessaire à l'exécution du programme.

Le fichier README⚓︎

Ce fichier doit contenir vos réponses aux questions du TP. Vous devez aussi y détailler le(s) prolongement(s) choisi(s) et pourquoi.

Interface utilisateur (15 minutes)⚓︎

Observation de l'interface fournie⚓︎

Ouvrez les différents fichiers html dans geany.

Question

  • Lesquelles sont des fichiers statiques (non générés par Flask)?
  • D'après le formulaire d'ajout de contact, comment sera représenté un contact ? Quel structure de donnée est adaptée pour accéder facilement à ces informations ?
  • D'après le formulaire de visualisation, comment identifier un contact ?
  • Donnez en 2-3 lignes un scénario d'utilisation de cette application.
url_for

On utilise la fonction url_for de Flask pour générer les URL pour chaque route. Cela permet de ne pas avoir à hardcoder les URL dans le code HTML et de les maintenir à jour automatiquement si vous modifiez les noms de routes dans le code Flask.

Logique de l'application (1h)⚓︎

Le squelette de base de l'application web est dans le fichier app.py, il ne sera modifié que dans les prolongements si nécessaire.

Vous allez travailler sur le fichier modele.py, qui contient les fonctions pour utiliser les données de votre annuaire.

MVC

Cette méthodologie de développement est nommée MVC. Elle est indiquée pour les applications web et graphiques. Elle demande de diviser l'application en trois parties: * Modèle: Toutes les données et les fonctions pour les manipuler * Vue: La visualisation et la mise en page des données ainsi que des moyens de les modifier. * Contrôleur: Le lien entre le Modèle et la Vue. Dans notre cas, la vue et le contrôleur sont fournis, vous allez écrire le modèle.

Vous devez le compléter petit à petit pour obtenir l'application globale. À chaque étape, vous devez tester votre code et l'application.

Annuaire (5')⚓︎

Question préliminaire:

L'application va gérer un ensemble de contacts, quelle structure est adaptée pour stocker un ensemble de valeurs sans liens particuliers ?

Vous devez compléter les fonctions creer_annuaire et ajoute_contact pour que l'on puisse obtenir un annuaire vide et ajouter un contact à un annuaire.

!!! warning ajoute_contact Cette fonction renvoie un annuaire contenant tout les contacts de l'ancien et le contact en plus.

Protocole détaillé
  • Pour creer_annuaire, vous devez créer une structure de données vide qui permettra de stocker une séquence de contacts.
    On utilisera une liste pour représenter la séquence, vous devez donc renvoyer une liste vide.
  • Pour ajoute_contact, il vous faut ajouter l'argument contact à l'annuaire, au début ou à la fin, puis renvoyer l'annuaire modifié.
    Pour ajouter un élément à la fin d'une liste on peut écrire: liste_modifiee = liste + [e] ou bien liste.append(e) pour modifier la liste originale.

Une fois que tout ceci est fait, la page /contacts doit s'afficher sans erreurs, mais vide.

Création de contact (30')⚓︎

Observez la fonction add_contact_handler dans app.py et le fichier add_contact.html.

Questions préliminaire

  • Par quel requête HTTP sont envoyées les données du formulaire ?
  • Que contient la variable email ?
  • Que contient la variable annuaire quand aucun contact n'a encore été ajouté ?

Si on a envoyé un formulaire à la page, alors on crée le contact correspondant dans l'annuaire existant et on redirige sur la page permettant de le visualiser.

!!! question 'Consigne' Vous devez compléter les quatres fonctions relative à la gestion d'un contact pour que cette page et celle de visualisation fonctionne.

Protocole détaillé
  • Pour ajoute_contact, vous devez juste créer la structure de données en associant les valeurs passées en arguments aux bonnes clés.
    un contact est représenté par un dictionnaire, pour créer un dictionnaire on écrit: nom_dico = { 'cle': valeur, 'cle2': valeur2 ...}. Ensuite, vous devez renvoyer ce dictionnaire.
  • Pour les fonctions prenom,nom,email il vous suffit de renvoyer la valeur appropriée du contact.
    Pour accéder à la valeur associée à la clé prenom dans le dictionnaire contact on écrit: contact['prenom'].

Visualisation de contacts (20')⚓︎

Affichage d'un contact (15')⚓︎

Dans cette partie nous allons créer la route qui permet de visualiser les détails d'un contact d'abord. Pour cela l'utilisateur final devra taper l'email dans la page de recherche ou cliquer sur l'email dans l'annuaire global. Ici, nous allons juste faire la logique de la page /contact/view/<email>, la page de recherche est un prolongement simple.

Consigne

Vous devez compléter la fonction trouve_contact pour trouver dans le contact qui est associé à email dans annuaire.

Aucun contact correspondant

Si aucun contact n'est trouvé, il faudra renvoyer la valeur None.

Protocole détaillé
  1. On commence par itérer (boucler) sur l'annuaire.
    une liste est itérable, on peut donc faire for element in liste pour parcourir tout les éléments
  2. Dès que l'on a trouvé le contact dont le champ email est identique à celui passé en paramètre, on peut le renvoyer.
    Il faut utiliser une condition d'égalité (==) entre le paramètre email et un des champs du contact courant.
  3. Si on a trouvé aucun contact, alors on renverra None.
    On a trouvé aucun contact si l'on est sorti de la boucle, on peut donc écrire le return après la boucle.

Question

Ici on parcourt la liste pour trouver le bon contact, ce qui est peu efficace si on a plusieurs centaines de milliers de contacts. Quelle structure de donnée pourrait-on utiliser pour trouver rapidement un contact étant donné son email ?

Prolongements⚓︎

Plusieurs prolongements vous sont proposés, vous devez en choisir un (ou plusieurs) et l'inclure dans votre rendu final en expliquant pourquoi vous l'avez choisi.

Pour chaque prolongement, il est possible que vous deviez créer des fichiers HTML, des routes dans app.py et des fonctions dans modele.py

  • Recherche d'un contact via n'importe quelle information du dictionnaire (Ajout de routes, de formulaire et de fonctions dans le modèle.)

    • Description: Ajout d'une fonction qui permet de rechercher un contact en utilisant toutes les informations présentes dans ce contact.
    • Inspirez vous de la fonctionnalité d'ajout de contact pour créez les deux routes. et de la fonction trouve_contact.
    • Temps estimé: 1h à 1h30
  • Suppression d'un contact

    • Description: Ajout d'une fonctionnalité qui permet de supprimer un contact en fonction de son identifiant (par exemple, son email).
    • Temps estimé: 45min à 1h
  • Modification d'un contact

    • Description: Ajout d'une fonctionnalité qui permet de modifier les informations d'un contact en fonction de son identifiant (par exemple, son email).
    • Temps estimé: 1h à 1h30
  • Lien avec le format vCard

    • Description: Ajout d'une fonction qui permet d'exporter un contact ou tous les contacts en format vCard.
    • Temps estimé: 1h30 à 2h

Notez que ces temps sont des estimations et peuvent varier.