3 Python Et SQLite Poly

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 30

Informatique : Systèmes d'Information

Troisième Partie

Python et SQLite
Formulaires avec Agro_GUI

www.agroparistech.fr/Systeme-d-Information.html
https://tice.agroparistech.fr

UFR d'Informatique
Département MMIP

AgroParisTech
Année 2019-2020
2
Table des matières

TD 9 ................................................................................................................................................... 4
1 Interaction avec des bases de données en Python ................................................................. 4
1.1 Se connecter à une base de données SQLite en Python ..................................................... 4
1.2 Interroger une base de données SQLite en Python ............................................................ 5
1.3 Interrogation contextuelle................................................................................................. 6
1.4 Se déconnecter d'une base de données SQLite en Python ................................................. 7
1.5 Insertions et suppressions ................................................................................................. 7
1.6 Résumé ............................................................................................................................. 8
1.7 Exercices du TD 9 .............................................................................................................. 9
TD 10 & 11 ....................................................................................................................................... 12
2 Le package Agro_GUI ....................................................................................................... 12
2.1 Introduction .................................................................................................................... 12
2.2 Installation et utilisation .................................................................................................. 13
2.3 Créer une fenêtre graphique ........................................................................................... 14
2.4 Fonctionnalités de composition de textes ........................................................................ 14
2.5 Interactions avec l'utilisateur : Les widgets ...................................................................... 17
2.6 Récupérer les données saisies ......................................................................................... 22
2.7 Exercices du TD 10 et TD 11 ............................................................................................. 27

3
TD 9
1 Interaction avec des bases de données en Python

Python fournit des modules (ou bibliothèques) permettant d'utiliser les informations stockées dans de
nombreux systèmes de gestion des bases de données (MySQL, PostgreSQL, SQLite, etc.). Ce cours
illustre comment un programme Python peut interagir avec une base de données SQLite.

Pour accéder aux fonctionnalités nécessaires à mettre en œuvre l’interaction entre Python et SQLite,
il suffit d'importer le module sqlite3 intégré à Python :

import sqlite3

Le chiffre à la fin du nom représente le numéro de la version actuelle du module d'interface. Il est
possible qu’il évolue avec le temps.

1.1 Se connecter à une base de données SQLite en Python

Une base de données SQLite est matérialisée par un fichier dans lequel sont stockés le schéma et
contenu de la BD, dans un format SQLite.

Pour pouvoir se connecter dans Python à une base de données, il faut utiliser la méthode connect() et
connaître le nom du fichier sous lequel la BD a été sauvegardée :

ma_connexion = sqlite3.connect("client_commande.sqlite")

Noter que dans cet exemple on suppose que le programme Python et le fichier avec la BD se trouve
dans le même dossier.

Dans l’exemple ci-dessous le nom du fichier est donné un utilisant le chemin absolu qui permet de le
retrouver sur le disque. Cette façon de faire est moins portable si on change de machine.

ma_connexion = sqlite3.connect("N:/SI/client_commande.sqlite")

Le nom du fichier pourrait être stocké dans une variable intermédiaire, comme ci-dessous :

fichierDonnees = "E:/1A/bd_test.sqlite"
ma_connexion = sqlite3.connect(fichierDonnees)

Le résultat de l’exécution de la méthode connect() est la création d’un objet de type connexion qui est
stockée dans une variable, nommée ma_connexion dans l’exemple ci-dessus, et qui sera utilisé par la
suite pour l’interaction du programme Python avec la BD.

Une fois l'objet connexion créé, il faut créer un objet dit curseur destiné à mémoriser temporairement
les données en cours de traitement et les opérations que vous effectuez sur elles, avant leur transfert
définitif dans la base de données. Cette technique permet donc d'annuler, si nécessaire, une ou
plusieurs opérations qui se seraient révélées inadéquates, et de revenir en arrière dans le traitement,
sans que la base de données n'en soit affectée.

4
mon_curseur = ma_connexion.cursor()

Grâce aux objets connexion et curseur créés, il est désormais possible de « dialoguer » avec la base de
données en effectuant des requêtes SQLite.

1.2 Interroger une base de données SQLite en Python

Pour rappel, une base de données se compose d'une ou plusieurs tables, qui contiendront
les enregistrements (ou lignes), ceux-ci comportant un certain nombre de champs (ou colonnes) de
différents types (entier, chaine de caractères, etc.).

L'interrogation de la base s'effectue à l'aide de requêtes SQLite, exprimées sous la forme de chaînes
de caractères, par l’intermédiaire de la méthode execute() appliqué au curseur.

Si nous souhaitons par exemple récupérer toutes les informations provenant d'une table qui
s'appellerait membres nous avons à écrire l'instruction suivante :

mon_curseur.execute("SELECT * FROM membres")

La requête ci-dessous demande la sélection d'un ensemble particulier d'enregistrements, qui devront
être transférés de la base de données au curseur.

mon_curseur.execute("SELECT age, nom, taille FROM membres")

Les enregistrements sélectionnés par la requête SQLite sont transférés dans le curseur, dans un format
spécifique. Pour les extraire et les utiliser dans Python il existe deux façons qui tirent parti du fait que
l'objet curseur produit par Python est un itérateur, c'est-à-dire un dispositif générateur de séquences.

Vous pouvez parcourir directement la séquence qu'il produit, à l'aide d'une boucle for classique. Vous
obtenez une série de tuples (séquences analogues aux listes mais non modifiables et bordés par des
parenthèses).

Par exemple :
for un_tuple in mon_curseur:
print(un_tuple)
pourrait avoir comme résultat ce qui suit si la base de données contient bien les quatre membres cités
ci-dessous :
(21, 'Dupont', 1.83)
(15, 'Blumâr', 1.57)
(18, 'Özémir', 1.69)
(17, 'JeanJean', 1.74)

5
Vous pouvez stocker le contenu du curseur dans une liste, en vue d'un traitement ultérieur, en faisant
appel à la méthode fetchall() du curseur :

mon_curseur.execute("SELECT * FROM membres")


liste_resultats = mon_curseur.fetchall()
#[(21, 'Dupont', 1.83), (15, 'Blumâr', 1.57), (18, 'Özémir', 1.69), (17,
‘Jeanjean’, 1.74)]
Cette deuxième méthode présente l'avantage de pouvoir clore la connexion avec la base de données
au plus tôt et est donc à privilégier.

Il faut remarquer que la longueur de cette liste est donnée par le nombre de lignes du résultat de la
requête en SQLite, et que chaque élément de cette liste est un tuple avec autant de membres qu’il a
eu de colonnes sélectionnées dans la requête SQLite. En plus l’ordre des membres du tuples est le
même que l’ordre des colonnes dans la requête SELECT, i.e. (age,nom,taille).

1.3 Interrogation contextuelle

Dans la pratique, les données que l'on souhaite extraire de notre base de données dépendent le plus
souvent du contexte dans lequel on se trouve. Par exemple, nous souhaitons avoir les informations
sur un client en particulier qui vient de se connecter à notre application de commande en ligne. Du
point du vue du programme Python cela signifie que les requêtes SQLite vont donc dépendre de la
valeur de variables en Python.

Vous devrez donc construire la chaîne de caractères contenant la requête SQL, en y incluant les valeurs
tirées de ces variables. Il est cependant fortement déconseillé de faire appel dans ce but aux
techniques ordinaires de formatage des chaînes, car cela peut ouvrir une faille de sécurité dans vos
programmes, en y autorisant les intrusions par la méthode de piratage connue sous le nom de SQL
injection. Il faut donc plutôt confier le formatage de vos requêtes au module d'interface lui-même.

La bonne technique est d’utiliser la méthode execute() avec deux paramètres :

• Le premier paramètre est une chaîne « squelette » qui utilise le point d'interrogation comme
balise de conversion (ou un « trou » qui sera rempli par une valeur au moment de l’exécution).
• Le deuxième paramètre représente la liste des valeurs à considérer, un pour chaque élément
représenté par un "?", dans l'ordre où il se présente dans la chaîne « squelette ».

Dans l’exemple
nom_client = input(‘donnez un nom :’) #exemple de saisie : Durand
mon_curseur.execute("SELECT * from clients WHERE nom LIKE ?", [nom_client])
la requête SQLite qui sera exécutée est
SELECT * from clients WHERE nom LIKE "Durand"

Dans l’exemple
age_saisi = int(input(‘donnez un age :’)) #exemple : 18
taille_saisie = float(input(‘donnez une taille :’)) #exemple : 1.60
mon_curseur.execute("SELECT nom from membres WHERE age = ? and taille > ?",
[age_saisi, taille_saisie])
la requête SQLite qui sera exécutée est
SELECT nom from membres WHERE age = 18 and taille > 1.60

6
1.4 Se déconnecter d'une base de données SQLite en Python

Une fois les échanges souhaités avec la base de données réalisés, le curseur et la connexion doivent
être refermés, dans cet ordre :

mon_curseur.close()
ma_connexion.close()

1.5 Insertions et suppressions

Lorsque l'on souhaite rajouter ou modifier de l'information dans une base de données depuis un
programme Python, on utilise la méthode execute() appliqué au curseur, avec des requêtes SQLite de
mise à jour des BD (e.g. INSERT, UPDATE, DELETE), en utilisant la même technique que dans le §1.3
pour avoir des requêtes contextuelles.

Attention : Pour que les requêtes de mise à jour de la BD modifie vraiment son contenu, il est
obligatoire d’utiliser la méthode commit() !

Exemple de code pour ajouter un enregistrement dans la table membres :

mon_curseur.execute("INSERT INTO membres(age,nom,taille) VALUES(24,"Mozart",1.63)")


ma_connexion.commit()

Exemples de codes pour des mises à jour :

mon_curseur.execute("UPDATE membres SET nom ='Gerart' WHERE nom='Ricard'")


ma_connexion.commit()

requete = "DELETE FROM membres WHERE nom='Gerart'"


mon_curseur.execute(requete)
ma_connexion.commit()

Voici un exemple de code pour ajouter quatre enregistrements :

data =[(17,"Durand",1.74),(22,"Berger",1.71),(20,"Weber",1.65),(21,"Willy",1.62)]
for tu in data:
mon_curseur.execute("INSERT INTO membres(age,nom,taille) VALUES(?,?,?)", tu)
ma_connexion.commit()

Dans cet exemple, la chaîne de « squelette » comporte 3 points d'interrogation, qui sont des balises.
Elles seront remplacées par les 3 éléments du tuple tu à chaque itération de la boucle for, le module
d'interface avec SQLite se chargeant de traiter chaque variable correctement en fonction de son type.

Attention :
Toutes les modifications apportées au curseur se passent en mémoire vive, et de ce fait rien n'est
enregistré définitivement tant que vous n'exécutez pas l'instruction ma_connexion.commit().
Si vous fermez prématurément la connexion avec l'instruction ma_connexion.close()les
modifications seront perdues.
Si l'on souhaite annuler toutes les modifications apportées depuis le commit() précédent, il faudra
avoir recours à l'instruction : ma_connexion.rollback().

7
1.6 Résumé
Les étapes de l’interaction de Python avec une BD sont les suivantes :

Pour consulter la BD Pour modifier la BD


Importation du module nécessaire pour l’interaction avec SQLite
import sqlite3
1. Connexion à la base de données
connexion = sqlite3.connect("client_commande.sqlite")
2. Création d’un curseur d’échange
curseur = connexion.cursor()
3. Interrogation de la BD (SELECT) 3’. Mises à jour (INSERT, UPDATE, DELETE)
curseur.execute(requeteSQL) curseur.execute(requeteSQL)
4. Traitement du résultat 4’. Validation de la modification
resultat = curseur.fetchall() connexion.commit()

5. Fermeture de la connexion
curseur.close()
connexion.close()

8
. Recherches sélectives dans une base de données▲

1.7 Exercices du TD 9
Le but des premiers exercices est de montrer des exemples d’interactions de Python avec la base de
données client_commande.sqlite, base que vous avez utilisée dans la deuxième partie du module
SI. Le schéma de cette BD est le suivant :

Depuis la page du cours sur TICE sauvegardez dans votre dossier personnel les scripts qui se trouvent
dans 3_Pyton et SQLite/Exemples pour TD 9, ainsi que le fichier client_commande.sqlite.

Exercice 1

• Ouvrez le fichier BricoStore_select.py et exécutez-le en mode console dédiée. La requête de


sélection en ligne 34 du script est exécutée.
• Pour exécuter une deuxième requête, mettez en commentaire la ligne 34 et décommettez la ligne
38. Exécutez cette deuxième requête.
• Exécutez une à une toutes les requêtes du fichier BricoStore_select.py.

Exercice 2

• Ouvrez le fichier BricoStore_select_param.py et exécutez-le en mode console dédiée. La requête


de sélection construite lignes 31 à 34 dans le script est exécutée, ayant comme paramètre le nom
de la ville que l’utilisateur saisi dans la console. Testez cette requête avec plusieurs noms de villes.
• Mettez en commentaire cette première requête, ensuite décommettez et exécutez la deuxième
requête paramétrée du fichier BricoStore_select_param.py.

Exercice 3

• Ouvrez le fichier BricoStore_maj.py et exécutez-le en mode console dédiée. La requête de mise à


jour de la ligne 49 du script est exécutée. Remarquez la modification du stock du produit concerné.
Exécutez à nouveau le script. Que se passe-t-il ?
• Mettez en commentaire la ligne 53 et exécutez le script. Que se passe-t-il ?

9
Exercice 4

• Ouvrez le fichier BricoStore_insert.py et exécutez-le en mode console dédiée. La requête de la


ligne 50, une requête d’insertion dans la table produit, est exécutée. Remarquez la modification
du contenu de la table produit. Exécutez à nouveau le script. Que se passe-t-il ?
• Ouvrez le fichier BricoStore_insert_param.py et exécutez-le en mode console dédiée. Que se
passe-t-il ?
• Ouvrez le fichier BricoStore_count.py et exécutez-le en mode console dédiée. Expliquez comment
est réalisé l’affichage du résultat.

Exercice 5 : Les Simpsons

On donne la base de données simpsons.sqlite qui contient pour le moment une table nommée
personnages ayant trois colonnes nommée ID, Prenom, et Nom.

1. Écrivez un script nommé simpsons.py permettant de se connecter à cette base de


données.
2. Ajoutez à votre script une fonction affiche_noms permettant d'afficher tous les noms
présents dans la base. Complétez votre programme principal pour tester votre fonction.
3. Ajoutez à votre script une fonction affiche_prenoms qui, étant donné un nom, permet
d'afficher les prénoms qui lui sont associés dans la base de données. Complétez votre
programme pour tester votre fonction avec un nom choisi par l'utilisateur. Pensez à vérifier
que l'utilisateur a bien fourni un nom contenu dans la base de données.
4. Ajoutez à votre script une fonction decompte_familles qui pour chaque nom de famille
présent dans la base de données indique de combien de membres elle est constituée et
retourne les résultats sous forme d’une liste de tuples.
5. Ajoutez à votre script une fonction draw_familles qui produit un diagramme un bâtons
associant à chaque nom de famille le nombre de membres qui la compose. Vous utiliserez pour
cela la fonction précédente et la bibliothèque Matplotlib.

10
Exercice 6 : StarBoat (again)

Lors du TD 8 vous avez construit la BD pour le système d’information de la société Starboat, système
qui doit fournir ces fonctionnalités:

– la liste de tous les bateaux en cours de location ;


– la liste des bateaux accompagnés des informations correspondant à leur modèle et classés
par modèle ;
– la liste de tous les bateaux de type Flying Bridge ;
– le nom du dernier bateau révisé ;
– la liste des bateaux qui ont subi un dommage en cours de location ;
– la liste des bateaux disponibles à la location.

La base de données vous est fournie et est contenue dans le fichier starboat.sqlite. Son schéma est
le suivant

Figure 1 : Schéma de la base de données Starboat

Écrivez un script Python nommé StarBoat.py qui se connecte à la BD starboat.sqlite et qui implémente
chaque fonctionnalité donnée ci-dessus par une fonction. Implémentez et testez ces fonctionnalités
une à une.

11
TD 10 & 11
2 Le package Agro_GUI

2.1 Introduction

Pour compléter les notions abordées jusqu'à présent, améliorer nos capacités à interagir avec les
utilisateurs et avec les bases de données, et donc être en mesure de produire des systèmes
d'information complets, la réalisation d'interfaces graphiques est nécessaire.

Il existe pour cela en Python différentes bibliothèques (Tkinter, PyGtk, PyQt, ...). Celles-ci sont assez
volumineuses, pas toujours très simples d'abord et pas focalisées sur nos besoins pour cet
enseignement. Aussi, nous avons développé un Package spécifique qui s'appuie sur la bibliothèque
Tkinter et qui renferme les fonctionnalités nécessaires à la création d'interfaces graphiques
permettant de proposer des formulaires de saisie à un utilisateur et de lui fournir des retours en
fonctions de ses actions.

Jusqu'à présent, les programmes que nous avons écrits avaient un déroulement bien déterminé. Ils
réalisaient une succession d'actions dans un ordre totalement spécifié dans lequel on pouvait mettre
en évidence les étapes de la Figure 2.

Figure 2 : Déroulement d'une application console

À partir du moment où l'on met en place une interface graphique, le déroulement de l'application n'est
plus connu par avance mais dépend des actions de l'utilisateur. Les différentes actions de l'utilisateur

12
correspondent à différents évènements (usage du clavier, de la souris, ...) pour lesquels il faudra
préciser les retours à apporter.

Le déroulement d'une application graphique peut être résumé par le schéma de la Figure 3.

Figure 3 : Déroulement d'une application avec interface graphique

En effet, après une étape d'initialisation qui comportera les instructions nécessaires à la création de la
fenêtre graphique notamment, une boucle est mise en place pour détecter les différents évènements
et déclencher, suivant leur nature, les fonctions adéquates. Dans la plupart des bibliothèques
d'interface graphique de haut niveau, la mise en place de cette boucle est facilitée. Reste à développer
bien entendu les différentes fonctions que l'on veut associer à chaque évènement que l'on souhaite
gérer et à faire le lien entre eux.

Nous verrons dans les sections suivantes quelles sont les possibilités offertes par le package
Agro_GUI et comment les mettre en œuvre.

2.2 Installation et utilisation

Le package Agro_GUI peut être récupéré sur la page du cours sous forme d'une archive qu'il faudra
décompresser dans le même dossier que les programmes qui y feront référence.

Il s'agit d'un dossier nommé Agro_GUI qui contient plusieurs scripts python.

Sur vos ordinateurs personnels vous pouvez également sauvegarder le dossier Agro_GUI dans le
dossier Anaconda3/Lib/site-packages ce qui vous permettra d'y avoir accès depuis n'importe
quel dossier de votre ordinateur.

Comme toute bibliothèque ou package Python son utilisation se fait par le mécanisme d'import.

Dans tous vos scripts qui feront référence aux fonctionnalités de ce package vous devrez faire figurer
l'instruction suivante :

from agro_GUI.agro_widgets import *

13
2.3 Créer une fenêtre graphique

Le package Agro_GUI permet de créer simplement une fenêtre dont on pourra préciser le titre.

L'exemple ci-dessous indique les instructions nécessaires pour cela.

from agro_GUI.agro_widgets import * #import des fonctionnalités de Agro_GUI

app = Agro_App("Première fenêtre") #création d'une fenêtre dont le titre


#est donné comme paramètre
app.show() #affichage de la fenêtre

Son exécution permet l'affichage de la fenêtre suivante qui pour le moment est vide. En effet, aucun
contenu n'a encore été ajouté à celle-ci.

La méthode show que l'on applique à la fenêtre app permet à la fois son affichage et le lancement de
la boucle d'évènements.

Nous allons voir dans les deux sections qui suivent comment l'on peut ajouter du contenu dans nos
fenêtres et quel contenu peut y être ajouté.

De manière analogue aux nombres, listes, chaînes de caractères ou tout autre type de variables déjà
utilisées auparavant en Python, le package Agro_GUI définit un nouveau type de données nommé
Agro_App qui représente ces fenêtres particulières que nous allons exploiter.

Les fonctionnalités que nous verrons par la suite sont propres à ce type d'éléments particuliers et
s'appliquent donc uniquement sur un élément de ce type (Agro_GUI) au même titre que la fonction
upper de mise en majuscule d'une chaîne de caractères s'applique exclusivement sur une chaîne de
caractères (cf. première partie du module).

2.4 Fonctionnalités de composition de textes

Le package Agro_GUI contient un certain nombre de fonctionnalités spécifiquement liées à


l'affichage de la fenêtre ou de son contenu. Celles-ci sont présentées ci-dessous. Notez bien que toutes
ces méthodes s'appliquent sur un élément de type Agro_GUI.

• manage_view()
Méthode de mise à jour de la dimension et du focus de la fenêtre
À appeler chaque fois que l'on modifie le contenu de la fenêtre

14
• show()
Méthode d'affichage de la fenêtre
À appeler une unique fois après avoir mis en place le premier contenu de la fenêtre
Cette méthode lance la boucle d'évènement de la fenêtre

• clear()
Méthode de suppression du contenu de la fenêtre
Elle supprime la totalité de son contenu

• inserer_text(text, pos='LEFT')
Méthode d'insertion d'un texte dans la fenêtre avec une police par défaut
- text : string -- paramètre obligatoire qui représente le texte que l'on veut ajouter
- pos : string -- paramètre optionnel permettant de préciser le positionnement du texte
Par défaut, le texte est positionné à gauche : 'LEFT'
'CENTER' permet de le placer au centre
'RIGHT' permet de le placer à droite

• inserer_titre(text, niveau)
Méthode d'insertion d'un titre de niveau 1, 2 ou 3 dans la fenêtre sur laquelle on l'applique avec
des styles prédéfinis pour chaque niveau
- text : string -- paramètre obligatoire qui représente le texte à insérer
- niveau : int -- paramètre obligatoire qui représente le niveau du titre
Seules les valeurs 1, 2 et 3 sont admises.

• inserer_listebullets(list_text)
Méthode d'insertion d'une liste de textes précédés par des points
- list_text : list -- paramètre obligatoire qui représente la liste des textes que l'on veut
insérer

• inserer_tableau(table_valeurs, liste_entetes=[] )
Méthode d'insertion d'un tableau de valeurs avec une mise en page en lignes et en colonnes
- table_valeurs : list -- paramètre obligatoire, liste de listes des valeurs que l'on veut
afficher. Un élément de la liste contient la liste des valeurs d'une ligne du tableau que l'on
veut insérer
- liste_entetes : list -- paramètre optionnel qui représente les intitulés des colonnes
s'il y a lieu
La longueur de liste_entetes doit être la même que la longueur de chaque élément
de table_valeurs.

• inserer_separateur(longueur, couleur='#778899')
Méthode d'insertion d'un séparateur dans la fenêtre (barre horizontale)
- longueur : int -- paramètre obligatoire indiquant la taille à l'horizontale de la barre que
l'on veut insérer
- couleur : str -- paramètre optionnel indiquant la couleur de la barre au format html

• sauter_ligne()
Méthode d'insertion d'une ligne vide dans la fenêtre

• inserer_image(url)
Méthode d'insertion d'une image dans la fenêtre

15
- url : str -- paramètre obligatoire représentant le chemin d'accès à l'image que l'on
souhaite ajouter

Voici un exemple d'usage des fonctionnalités présentées ci-dessus :

from agro_GUI.agro_widgets import *


import matplotlib.pyplot as plt

def mise_en_page () :
"""
Fonction de composition de la fenêtre app créée dans le programme principal
"""
global app

app.inserer_titre("Voici un titre de niveau 1", 1)


texte = "Du texte qui peut être plus ou moins long"
texte += " et contenir des sauts de ligne"
app.inserer_text(texte)

app.inserer_text("Un tableau avec des colonnes nommées")


valeurs = [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h']]
entetes = ['nom', 'prenom', 'adresse', 'compte']
app.inserer_tableau(valeurs, entetes)

app.inserer_text("Une liste")
app.inserer_listebullets(['bonjour', 'tout le monde'])

app.inserer_text("Une image")
app.inserer_image('img/perso.png')

app.inserer_text("Une image obtenu avec la bibliothèque matplotlib !")


draw_graph('img/scatter.png')
app.inserer_image('img/scatter.png')

app.manage_view() #afin de garantir un affichage correct de la fenêtre

def draw_graph(name):
"""
Fonction de création et sauvegarde d'un graphique simple
"""
plt.scatter([1,2,3], [1,2,3], marker='s', s=200) #On créé le nuage de points
plt.savefig(name, dpi=30) #On sauvegarde la figure produite

###############################################################################
# Programme Principal #
###############################################################################

app = Agro_App("Première fenêtre")


mise_en_page()
app.show()

16
L'exécution de ce script permet de déclencher l'affichage de la fenêtre ci-dessous.

2.5 Interactions avec l'utilisateur : Les widgets

On appelle widget tout élément avec lequel l'utilisateur peut interagir par saisie, sélection ou autre.

Sont présentées ci-dessous les différentes fonctions permettant d'insérer les widgets fournis dans ce
package.

Les boutons

Un bouton est un élément qui réagit au clic de souris et permet de déclencher une fonction sans
paramètre.

• inserer_bouton(label, action)
Méthode d'insertion d'un bouton cliquable dans la fenêtre
- label : str -- paramètre obligatoire représentant le texte à afficher sur le bouton
- action : function -- paramètre obligatoire représentant la fonction sans paramètre
qui sera déclenchée lorsque le bouton sera actionné

17
• inserer_list_boutons(list_labels, list_actions)
Méthode d'insertion d'un ensemble de boutons cliquables sur une ligne dans la fenêtre
- list_labels : list[str] -- paramètre obligatoire représentant une liste de textes à
afficher sur les différents boutons
- list_actions : list[function] -- paramètre obligatoire représentant une liste de
fonctions sans paramètre qui seront déclenchées lorsque les boutons seront actionnés
Les paramètres list_labels et list_actions doivent être de même longueur.

Les champs de saisie

Un champ de saisie est une zone qui réagit aux actions sur le clavier et qui retient les différents
caractères pressés.
Suivant leur taille ou l'affichage associés, trois variantes sont disponibles.

• inserer_champ_text(label, text, width=30)


Méthode d'insertion d'un champ de saisie texte dans la fenêtre
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
- width : int -- paramètre optionnel représentant la longueur du champ en nombre de
caractères
Les données récupérables sont des chaînes de caractères (une chaîne à chaque action de
récupération des données)

• inserer_list_champs_text(list_labels, list_texts, list_widths=[])


Méthode d'insertion d'un ensemble de champs texte sur une ligne dans la fenêtre
- list_labels : list[str] -- paramètre obligatoire représentant la liste des identifiants
des champs
- list_texts : list[str] -- paramètre obligatoire représentant une liste de textes à
afficher pour expliciter le rôle de chaque champ
- list_width : list[int] -- paramètre optionnel permettant d'indiquer une taille pour
chaque champ
Les paramètres list_labels et list_actions doivent être de même longueur.
Lorsqu'il est fourni, le paramètre list_widths doit également être de même longueur.
Les données récupérables sont des chaînes de caractères (une chaîne par champ à chaque action
de récupération des données)

• inserer_champ_passwd(label, text, width=30)


Méthode d'insertion d'un champ de saisie texte dans la fenêtre
Les caractères saisis sont remplacés par des '*'
Ce type de champ convient par exemple pour la saisie de mots de passe
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
- width : int -- paramètre optionnel représentant la longueur du champ en nombre de
caractères
Les données récupérables sont des chaînes de caractères (une chaîne à chaque action de
récupération des données)

18
• inserer_champ_paragraphe(label, text, nb_lignes = 3)
Méthode d'insertion d'un champ de saisie texte de grande taille dans la fenêtre
Ce type de champ est intéressant pour la saisie de textes de longueur libre
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
- nb_lignes : int -- paramètre optionnel représentant le nombre de lignes du champ
Les données récupérables sont des chaînes de caractères (une chaîne à chaque action de
récupération des données)

Sélectionner une date

Agro_GUI dispose d'un widget calendrier qui permet à l'utilisateur de sélectionner à l'aide de la
souris une date particulière.

• inserer_calendrier(label, text)
Méthode d'insertion d'un calendrier dans la fenêtre afin que l'utilisateur puisse sélectionner
une date
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
Les données récupérables sont des chaînes de caractères formatées ainsi : aaaa-mm-dd (une
chaîne à chaque action de récupération des données)

Les Widgets de sélection

Il est fréquent dans des formulaires que l'on ait à choisir des variables parmi un certain nombre de
valeurs proposées ou dans des intervalles particuliers s'il s'agit de nombres.
Il existe pour cela différents widgets que l'on utilisera suivant que l'on veut pouvoir choisir une unique
valeur ou au contraire plusieurs, suivant qu'il s'agit de textes ou de nombres, suivant le nombre de
propositions, ....

• inserer_group_radios(label, text, list_labels, list_values=[])


Méthode d'insertion de listes à choix unique
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
- list_labels : list -- paramètre obligatoire représentant la liste des textes à afficher
en face des boutons de sélection
- list_values : list -- paramètre optionnel représentant la liste des valeurs à retourner
pour chacun des boutons de sélection. Ce paramètre est à renseigner lorsque l'on
souhaite que la légende des boutons diffère de la valeur associée.

Si le paramètre list_values est fourni, les listes list_labels et list_values


doivent être de même longueur .
Les données récupérables sont des éléments de list_labels si list_values n'est pas
fournie, ou de list_values dans le cas contraire.
Un seul élément est fourni à chaque récupération des données.

19
• inserer_checkbutton(label, text)
Méthode d'insertion d'une case à cocher
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
Si la case n'est pas cochée la valeur récupérable est 0, 1 dans le cas contraire.

• inserer_listebox(label, text, list_labels, list_values=[], select_mode =


SINGLE)
Méthode d'insertion de listes de choix dans laquelle la sélection peut être unique ou multiple.
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
- list_labels : list -- paramètre obligatoire représentant la liste des textes à afficher
dans la liste de choix
- list_values : list -- paramètre optionnel représentant la liste des valeurs à retourner
pour chacun des labels de la liste. Ce paramètre est à renseigner lorsque l'on souhaite que
la légende dans la liste diffère de la valeur associée.
- select_mode : str -- paramètre optionnel représentant le mode de sélection
SINGLE (valeur par défaut) pour des listes à sélection unique.
EXTENDED pour des listes à sélection multiple.

Si le paramètre list_values est fourni, les listes list_labels et list_values doivent


être de même longueur.
Les données récupérables sont des éléments de list_labels si list_values n'est pas
fournie, ou de list_values dans le cas contraire.
Quel que soit le mode de sélection, une liste d'éléments éventuellement vide est fournie à
chaque récupération des données.

• inserer_scale(label, text, mini, maxi, pas = 1)


Méthode d'insertion d'un curseur de sélection d'une valeur dans un intervalle donné.
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
- mini : float -- paramètre obligatoire représentant la valeur minimale sélectionnable
- maxi : float -- paramètre obligatoire représentant la valeur maximale sélectionnable
- pas : float -- paramètre optionnel représentant le pas entre deux valeurs possibles
Les données récupérables sont des valeurs numériques (une à la fois).

• inserer_spinbox_float(label, text, mini, maxi, pas)


Méthode d'insertion d'une liste déroulante de valeurs dans un intervalle donné
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
- mini : float -- paramètre obligatoire représentant la valeur minimale sélectionnable
- maxi : float -- paramètre obligatoire représentant la valeur maximale sélectionnable
- pas : float -- paramètre optionnel représentant le pas entre deux valeurs possibles
Les données récupérables sont des valeurs numériques (une à la fois).

20
• inserer_spinbox_values(label, text, list_labels, list_values = [])
Méthode d'insertion d'une liste déroulante de valeurs dans une liste de labels donnés
- label : str -- paramètre obligatoire représentant l'identifiant du champ
- text : str -- paramètre obligatoire représentant le texte explicatif associé au champ
- list_labels : list -- paramètre obligatoire représentant la liste des textes à afficher
dans la liste de choix
- list_values : list -- paramètre optionnel représentant la liste des valeurs à retourner
pour chacun des labels de la liste. Ce paramètre est à renseigner lorsque l'on souhaite que
la légende dans la liste diffère de la valeur associée.
Si le paramètre list_values est fourni, les listes list_labels et list_values doivent
être de même longueur.
Les données récupérables (une valeur à la fois) sont des éléments de list_labels si
list_values n'est pas fournie, ou de list_values dans le cas contraire.

Voici un exemple d'usage de certaines fonctionnalités présentées dans cette section :

# script : formulaire_sans_traitement.py

from agro_GUI.agro_widgets import *

def formulaire_saisie () :
"""
Fonction de composition de la fenêtre pour le formulaire
"""
app.inserer_titre("Premier formulaire", 1)
app.inserer_champ_text('nom', 'Saisissez votre nom :')
app.inserer_champ_text('prenom', 'Saisissez votre prénom :', width=15)
app.inserer_scale('age','Quel est votre âge :', 18, 30, 1.0)
mess = 'Combien de frères et soeurs avez-vous :'
app.inserer_spinbox_float('spin_float',mess, 0, 10, 1.0)
app.inserer_checkbutton('bilingue', 'Etes-vous bilingue : ')
liste_langages = ['C', 'Python', 'Matlab', 'PHP']
mess = 'Quels langages connaissez-vous : '
app.inserer_listebox('langages',mess,liste_langages,select_mode = EXTENDED)
app.inserer_calendrier( 'vac', 'Quand commencent vos prochaines vacances :')
mess = 'Saisissez un commentaire si vous le souhaitez :'
app.inserer_champ_paragraphe('para',mess)
app.inserer_bouton('Valider', bilan_saisie)
app.manage_view()

def bilan_saisie () :
"""
Fonction de traitement et de restitution des données récoltées
"""
pass

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Programme Principal #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#création de la fenêtre
app = Agro_App("Gestion de la base de données client-commande")
#appel de la fonction de première composition de la fenêtre
formulaire_saisie()
#affichage de la fenêtre
app.show()

L'exécution de ce script permet de déclencher l'affichage de la fenêtre présentée en Figure 4.

21
Figure 4 : Fenêtre générée par le script formulaire_sans_traitement.py.

Tous les widgets disponibles ne sont pas exploités dans cet exemple mais il est représentatif de la
plupart des usages et, de ce fait, les instructions à écrire seront analogues pour les éléments restants.

Par ailleurs, pour le moment, l'action sur le bouton Valider n'a aucun effet car la fonction
bilan_saisie ne contient pas d'instructions. Nous verrons dans la section suivante comment la
compléter et récupérer les données saisies dans un formulaire.

2.6 Récupérer les données saisies

Pour stocker les données provenant des différents widgets contenus dans une fenêtre Agro_App à
un moment donné, un type particulier de variable, nommé dictionnaire, est utilisé.

2.6.1 Les dictionnaires (rappel)

Un dictionnaire en Python est une collection de couple clé : valeur, entourée d'accolades.
Contrairement aux listes, les éléments qu'il contient ne sont pas ordonnés mais sont accessibles par la
valeur de leur clé.

Voici ci-dessous un petit exemple d'usage des dictionnaires.

22
# création, ajout et suppression d'éléments dans un dictionnaire

dico = {} # dictionnaire vide


dico['I'] = 'je' # ajout de la clé 'I' et de la valeur associée 'je'
dico['she'] = 'elle'
dico['you'] = 'vous'

print (dico) # affiche {'I':'je', 'she':'elle', 'you':'vous'}


print (dico['I']) # affiche 'je'

del dico['I'] # suppression de la clé 'I' et de la valeur associée


print (dico) # affiche {'she':'elle', 'you':'vous'}

dico['we'] = 'nous'
print (dico) # affiche {'we': 'nous', 'you': 'vous', 'she': 'elle'}

Parcourir un dictionnaire

Compte tenu de la structure des dictionnaires, il existe plusieurs méthodes pour les parcourir suivant
ce qui est recherché. En effet, étant donné un dictionnaire, on peut souhaiter connaître l'ensemble de
ses clés, l'ensemble de ses valeurs ou l'ensemble des couples qu'il contient.

En fonction de cela nous utiliserons l'une des trois méthodes présentées dans l'exemple ci-dessous.

for key in dico.keys() : # on parcourt l'ensemble des clés


print (key)

for value in dico.values() : # on parcourt l'ensemble des valeurs


print (value)

for key, value in dico.items() : # on parcourt l'ensemble des couples


print (key + ':' + value)

she
you
we
elle
vous
nous
she:elle
you:vous
we:nous

23
2.6.2 Gestion des données dans Agro_GUI

Est associé à toute fenêtre Agro_App un dictionnaire nommé datas qui sera mis à jour lors de
l'appel à la fonction get_datas présentée ci-dessous.

• get_datas()
Méthode de récupération des données saisies dans les différents champs présents dans la
fenêtre au moment où la méthode est déclenchée. Elle met à jour le dictionnaire datas.

Si elle n'existe pas encore, pour chaque widget présent dans la fenêtre, une clé égale au label du
widget concerné sera créée et la valeur du widget à ce moment donné lui sera associée.

Dans le cas contraire, l'ancienne valeur associée au label considéré sera remplacée par la valeur
actuelle.

Il est donc nécessaire de veiller à fournir des valeurs de labels cohérentes pour tous les widgets utilisés
dans l'application développée.

La nature des données récupérées dépend de la nature de chaque widget (cf. documentations des
fonctions d'insertion des différents widgets section 2.5).

Nous disposons désormais des éléments pour compléter notre exemple précédent.

Voici, dans ce qui suit, un exemple de script fournissant et traitant un formulaire.

Le formulaire est identique à celui de l'exemple précédent, la fonction bilan_saisie a en revanche


été complétée pour indiquer dans la fenêtre pour chaque widget du formulaire la valeur récoltée.

24
from agro_GUI.agro_widgets import *

def formulaire_saisie () :
"""
Etape 1 : Fonction de composition de la fenêtre pour le formulaire
"""
app.inserer_titre("Premier formulaire", 1)
app.inserer_champ_text('nom', 'Saisissez votre nom :')
app.inserer_champ_text('prenom', 'Saisissez votre prénom :', width=15)
app.inserer_scale('age','Quel est votre âge :', 18, 30, 1.0)
mess = 'Combien de frères et soeurs avez-vous :'
app.inserer_spinbox_float('spin_float',mess, 0, 10, 1.0)
app.inserer_checkbutton('bilingue', 'Etes-vous bilingue : ')
liste_langages = ['C', 'Python', 'Matlab', 'PHP']
mess = 'Quels langages connaissez-vous : '
app.inserer_listebox('langages',mess,liste_langages,select_mode = EXTENDED)
app.inserer_calendrier( 'vac', 'Quand commencent vos prochaines vacances :')
mess = 'Saisissez un commentaire si vous le souhaitez :'
app.inserer_champ_paragraphe('para',mess)
app.inserer_bouton('Valider', bilan_saisie)
app.manage_view()

def bilan_saisie () :
"""
Etape 2 : Fonction de traitement et de restitution des données récoltées
A un sens que si elle est exécutée APRES l’étape 1 (formulaire_saisie)
"""
app.get_datas() # récupération des données
app.clear() # suppression du contenu actuel de la fenêtre pour le remplacer
# Composition de la fenêtre compte tenu des données récoltées
app.inserer_titre ('Bilan du formulaire précédent', 1)

# Affichage de tous le dictionnaire app.datas


textes = []
for cle, valeur in app.datas.items() :
texte = 'Pour le widget nommé ' + str(cle)
texte += ' la valeur récupérée est : ' + str(valeur)
textes.append(texte)
# Insertion du texte dans la fenêtre avec un bullet pour chaque élément
app.inserer_listebullets(textes)

# Récupération de certaines valeurs saisies dans le formulaire


prenom_saisi = app.datas['prenom'] # c’est une chaine de caractères
age_saisi = app.datas['age'] # c’est une valeur numérique
liste_langages_saisie = app.datas['langages'] # c’est une liste de string

# Insertion d'un bouton de fermeture de l'application


app.inserer_bouton('Quitter', app.quit)
app.manage_view() # Gestion de l'affichage

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Programme Principal #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#création de la fenêtre
app = Agro_App("Premier formulaire")
#appel de la fonction de première composition de la fenêtre
formulaire_saisie()
#affichage de la fenêtre
app.show()

25
L'exécution de ce script permet de déclencher l'affichage de la fenêtre ci-dessous.

Désormais, cliquer sur le bouton valider permettra d'afficher une fenêtre analogue à celle de l'image
suivante en fonction des données saisies.

Dans cet exemple, le traitement proposé est simple afin de vous familiariser avec les fonctionnalités
d'Agro_GUI. Néanmoins, une fois les données récupérées convenablement, elles sont exploitables
par tous les biais déjà connus. Elles pourraient notamment servir lors de l'interrogation d'une base de
données comme nous le verrons dans les exercices proposés en section 2.7.

26
2.7 Exercices du TD 10 et TD 11

Exercice 7 : Petit questionnaire

Le but de cet exercice est de réaliser un premier petit formulaire et le traitement des données saisies
dans celui-ci.

Pour chaque widget que vous utiliserez, vous mettrez en place un affichage spécifique des données
récoltées.

1. Dans un script premier_formulaire.py, créez la fenêtre avec comme titre Premier


formulaire et faites la afficher.
2. Complétez votre script en définissant une fonction formulaire qui pour le moment ajoute
le titre Formulaire dans la fenêtre et complétez votre programme principal en conséquence.
3. Complétez la fonction formulaire afin d'ajouter dans la fenêtre un bouton de validation.
Définissez également une fonction que vous nommerez traitement qui sera déclenchée
par le bouton précédent et qui pour le moment efface le contenu de la fenêtre et insère le
nouveau titre Bilan.
4. On souhaite faire figurer dans le formulaire un champ de saisie pour récupérer le prénom de
l'utilisateur et afficher dans le bilan en texte correspondant à ce qui aura été saisi. Complétez
vos fonctions formulaire et traitement en conséquence.
5. Complétez vos fonctions pour connaître le sexe de l'utilisateur par l'intermédiaire d'un groupe
radio.
6. Ajouter une liste de choix à sélection unique demandant le style musical préféré parmi des
valeurs que vous proposerez. Complétez vos fonctions formulaire et traitement en
conséquence.
7. Ajouter une case à cocher pour demander à l'utilisateur s'il est musicien. Votre bilan devra
faire apparaître le texte 'Vous êtes musicien' si la case a été cochée et 'Vous n'êtes pas
musicien' dans le cas contraire. Complétez vos fonctions formulaire et traitement en
conséquence.
8. Ajouter une liste de choix à sélection multiple demandant à l'utilisateur de quels instruments
il a déjà joué parmi des valeurs que vous proposerez. Votre bilan devra faire apparaître pour
chaque instrument sélectionné un texte analogue à "Vous avez joué de cet instrument : Piano"
. Complétez vos fonctions formulaire et traitement en conséquence.
9. Complétez votre programme pour que le formulaire soit reproposé à l'utilisateur s'il n'a pas
complété son nom, son sexe ou son style de musique préféré avec un message indiquant les
éléments qui doivent encore être renseignés.

27
Exercice 8 : Blackjack

Le but de cet exercice est de faire un petit jeu de blackjack simplifié.

Les règles sont les suivantes :

• Le joueur a un score initial de 0,


• Tant que la partie n'est pas terminée, à chaque tour, plusieurs actions lui sont proposées.
• Il peut choisir de tirer une carte (un nombre entre 1 et 10), auquel cas la valeur de la carte
s'ajoute à son score actuel,
o Si son score dépasse 21, le joueur a perdu.
o Si son score est exactement 21, il a gagné.
• Il peut choisir de "rester", c'est-à-dire arrêter de tirer des cartes, auquel cas la banque tire
ses propres cartes (un seul nombre entre 17 et 21 inclus),
et si le joueur a un score supérieur à celui de la banque, il gagne, sinon il perd.
• Il peut choisir de recommencer et débuter une nouvelle partie.

1. Dans un script blackjack.py, créez la fenêtre avec comme titre Blackjack et faites la
afficher.

2. Complétez votre script pour ajoutez à cette fenêtre un titre de niveau 1 indiquant le but de
l'application et un texte pour afficher le score du joueur initialement nul.
Définissez à cette occasion une variable pour stocker cette information.
Pensez par ailleurs que toute modification du contenu de la fenêtre nécessite l'appel de la
méthode manage_view (cf. section 2.4).

3. Complétez votre script pour ajoutez les trois boutons correspondant aux 3 actions possibles :
tirer une carte, recommencer la partie, rester et comparer avec la banque.
Définissez également les méthodes tirer, recommencer et rester qui y seront
associées. Pour le moment, elles afficheront uniquement un message indiquant leur nom dans
la console.

4. Implémentez une à une les méthodes tirer, recommencer et rester pour compléter
votre jeu compte tenu des règles énoncées initialement.
Des messages relatifs à l'issue de la partie devront figurer dans la fenêtre.
Par ailleurs, seul le bouton recommencer devra encore figurer dans la fenêtre lorsqu'une partie
est terminée.

28
Exercice 9 : Les simpsons (suite ...)

Le but de cet exercice est de développer une application de saisie de commentaires concernant les
personnages des Simpsons.

L'application que l'on va développer aura le comportement suivant :


• À l'ouverture de l'application la fenêtre propose de choisir un nom parmi la liste de noms
présents dans une base de données SQLite nommée simpsons_comm.sqlite par
exemple grâce à un widget Listbox à sélection unique. Par ailleurs, les doublons de noms seront
à bannir ! Le schéma de cette base de données est fourni en Figure 5.
• La validation de ce premier petit formulaire permet l'affichage d'un deuxième demandant de
sélectionner dans une liste un prénom. Cette liste devra contenir uniquement les prénoms en
lien avec le nom sélectionné précédemment. Un texte dans la fenêtre rappelant le nom
sélectionné est souhaité.
• La validation du deuxième formulaire permet l'affichage d'un dernier formulaire proposant à
l'utilisateur de saisir un commentaire concernant le personnage qu'il a sélectionné.
• La validation du troisième formulaire doit permettre d'enregistrer dans la base de données
simpsons_comm.sqlite le commentaire saisi par l'utilisateur et d'afficher dans la
fenêtre l'ensemble des commentaires enregistrés jusqu'à présent pour le personnage
concerné ainsi qu'un bouton recommencer qui permettra de reprendre depuis le début
éventuellement pour un autre personnage.

Figure 5 : Schéma de la base de données simpsons_comm.sqlite

Nous allons pour cela procéder par étape.

1. Dans un script simpsons_GUI.py, créez et affichez une fenêtre dont le titre sera "Autour
des Simpsons".

2. Toujours dans le script simpsons_GUI.py, créez les fonctions select_nom,


select_prenom, add_commentaire et bilan qui respectivement vont permettre de
gérer les étapes de l'application décrites ci-dessous. Pour le moment, chaque fonction ne fera
qu'afficher dans la fenêtre un titre cohérent et un bouton pour passer à l'étape d'après. Par
exemple, la fonction select_nom pourra afficher "Etape 1 : Sélection d'un nom" et son
bouton déclenchera la fonction select_prenom et ainsi de suite. Vérifiez que le
déroulement de votre application est conforme.

3. Complétez maintenant les différentes fonctions une à une pour répondre aux objectifs initiaux.

29
Exercice 10 : Autour des complexes protéine-protéine

On considère la base de données dont le schéma est fourni ci-dessous :

Celle-ci permet de stocker tous les éléments connus se rapportant à des complexes protéiques
(associations viables et actives de plusieurs protéines). Elle est stockée dans le fichier nommé
db_pdb.sqlite.

Dans cet exercice, nous allons développer une application dont le but est d'afficher pour une chaine
donnée et deux axes sélectionnés, la projection dans le plan correspondant du nuage de points des
atomes qui la compose.

Inspirez-vous de l'Exercice 9 pour que votre application propose une succession de formulaires afin de
récolter les informations nécessaires ainsi qu'un bilan affichant les informations saisies, l'image d'un
graphique généré grâce à la bibliothèque MatplotLib et un bouton pour réitérer le processus.

30

Vous aimerez peut-être aussi