Travail sur machine séance 4 corrigé

publicité
Master 1 Humanités numériques – Bases de données
Séance 4 : Publication de données sur le Web
Objectif
Extraire de la base Access conçue à la séance 1 des données relatives aux matières enseignées et les publier
dans une page web :
 moyenne et nombre de notes par matières, sous forme de tableau ;
 nombre de notes par matière, sous forme de diagramme circulaire (camembert) ;
 moyennes par matière, sous forme de diagramme en bâtons ;
 moyennes par matière, sous forme de courbe (ce type de diagramme n’étant pas adapté pour ces
données, c’est juste pour s’entraîner à l’utiliser car il est courant par ailleurs).
Page web exemple : http://eric.univ-lyon2.fr/~jdarmont/docs/web/bd-web.html
Prérequis
Connexion Access


Installer un pilote ODBC de même architecture que Python (32 ou 64 bits)
http://eric.univ-lyon2.fr/~jdarmont/?page_id=3139#rs
Installer le module Python PyPyODBC (il faut être administrateur de sa machine)
https://pypi.python.org/pypi/pypyodbc
Graphiques Python

Installer le module Python MatPlotLib
http://matplotlib.org/users/installing.html
Extraction des données
1. Créer un fichier Python. Dans le code, importer le module PyPyODBC.
2. Écrire les instructions de connexion à la base de données Access (utiliser celle créée lors de la séance 1) et
de fermeture de la connexion. Tester. Si Python ne renvoie pas d’erreur, ça fonctionne !
3. Entre la connexion et sa fermeture, créer un curseur et exécuter la requête « intitulé de matière, moyenne
des notes et nombre de notes, regroupés par intitulés et triés par intitulés ». Les sources de données
nécessaires à cette requête sont les tables MATIERE, EPREUVE et PASSER (des jointures sont nécessaires).
M1 HN – BASES DE DONNEES
1/3
Afin de pouvoir accéder aux agrégats (moyenne et compte), il faut les nommer à l’aide d’un alias, par exemple
AVG(Note) AS Moyenne. Fermer le curseur. Tester. Si Python ne renvoie pas d’erreur, ça fonctionne… peutêtre !
4. À des fins de vérification, à la suite de l’exécution de la requête, parcourir le curseur et afficher pour
chacune de ses lignes l’intitulé de matière, la moyenne et le nombre de notes par matière. Tester.
5. Afin de faciliter la génération des graphiques, on va stocker les données du curseur dans trois listes :
listeIntitules, listeMoyennes et listeNb.

Juste avant le curseur, initialiser les trois listes à vide.

Dans la boucle de parcours du curseur, ajouter à listeIntitules, listeMoyennes et listeNb l’intitulé de
matière, la moyenne et le nombre de notes par matière, respectivement. L’affichage de ces données
mis en place à la question 4 peut être mis en commentaire.

Juste après la boucle, insérer l’instruction suivante, qui crée une plage de données indéterminées
dont le nombre de valeurs est égal aux nombres de lignes du curseur. Cette liste servira à la création
des graphiques.
colonnes = range(len(listeIntitules))
6. Vérifier que le code fonctionne.
Génération de la page web
1. Après le code déjà écrit dans votre fichier Python, affectez à une variable de nom codeHTML et de type
chaîne de caractères multiligne le début du code HTML d’une page web (<html><head>…</head><body>),
puis définissez un tableau (<table>…</table>) de légende (<caption>…</caption>) « Moyenne et nombre de
notes par matière » dont la ligne (<tr>…</tr>) d’entête contient trois colonnes (<th>…</th>) : Matière,
Moyenne et Nb.
2. Dans une boucle « pour » sur la plage colonnes définie à la question 6 ci-dessus, concaténer à codeHTML
une ligne (<tr>…</tr>) dont les colonnes de données (<td>…</td>) sont listeIntitules[i], listeMoyennes[i] et
listeNb[i], en supposant que i soit l’indice de boucle. listeMoyennes[i] et listeNb[i] étant des nombres, il faut
les convertir en chaîne de caractères lors de la concaténation (fonction str()).
3. Concaténer à codeHTML la fermeture des balises HTML encore ouvertes (</table></body></html>).
4. Ouvrir le fichier nommé bd-web.html en écriture, y écrire le contenu de codeHTML, fermer le fichier.
5. Tester la création du fichier HTML et vérifier son apparence en l’ouvrant dans un navigateur web. Le cas
échéant, reprenez les étapes précédentes jusqu’à ce que le tableau s’affiche normalement dans le
navigateur.
M1 HN – BASES DE DONNEES
2/3
Inclusion de graphiques
1. Toujours dans le code déjà écrit dans votre fichier Python, importer le module MatPlotLib juste après
PyPyODBC.
2. Après la fermeture de la connexion à la base de données et avant la génération du code HTML, créer un
graphique de type camembert intitulé « Nombre de notes par matière » basé sur listeNb et listeIntitules.
Afficher la figure en mode interactif (plt.show()). Tester.
3. Remplacer l’affichage interactif par la sauvegarde d’un fichier image (plt.savefig("camembert.png"), par
exemple).
4. Dans la dernière partie de la génération de code HTML, ajouter une image (<img />) pointant sur
camembert.png.
5. Tester et vérifier l’affichage du graphique inclus dans bd-web.html à l’aide d’un navigateur web.
6. Répéter les questions 2 à 5 pour :

un diagramme en bâtons intitulé « Moyennes par matière » basé sur colonnes, listeMoyennes et
listeIntitules ;

une courbe également intitulée « Moyennes par matière » basée sur colonnes (les étiquettes de l’axe
des abscisses sont textuelles), listeMoyennes et listeIntitules.
M1 HN – BASES DE DONNEES
3/3
Correction
# Access => graphiques => web
import pypyodbc
pypyodbc.lowercase = False
import matplotlib.pyplot as plt
# Connexion BD
connexion = pypyodbc.connect(
r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" +
r"Dbq=d:\etu.accdb;")
# Curseur
curseur = connexion.cursor()
curseur.execute(
"SELECT Intitulé, AVG(Note) AS Moyenne, COUNT(Note) AS NbNotes
FROM MATIERE M, EPREUVE E, PASSER P
WHERE M.CodeMat = E.CodeMat AND E.CodeEpr = P.CodeEpr
GROUP BY Intitulé
ORDER BY Intitulé"
);
# Préparation de listes de valeurs pour les graphiques
listeIntitules = []
listeMoyennes = []
listeNb = []
for nuplet in curseur.fetchall():
# print(nuplet.get("Intitulé"), nuplet.get("Moyenne"), nuplet.get("NbNotes"))
listeIntitules.append(nuplet.get("Intitulé"))
listeMoyennes.append(nuplet.get("Moyenne"))
listeNb.append(nuplet.get("NbNotes"))
colonnes = range(len(listeIntitules))
# Fermeture curseur
curseur.close()
# Fermeture connexion
connexion.close()
# Création d'un camembert
plt.title("Nombre de notes par matière")
plt.pie(listeNb, labels = listeIntitules, startangle = 90, autopct = "%1.1f%%")
plt.axis("equal") # Produit un cercle plutôt qu'une ellipse
plt.savefig("camembert.png")
#plt.show() # Affiche la figure en mode interactif
plt.clf() # Fermeture figure
M1 HN – BASES DE DONNEES
4/3
# Création d'un diagramme en bâtons
plt.title("Moyennes par matière")
plt.xlabel("Matière")
plt.ylabel("Moyenne")
plt.bar(colonnes, listeMoyennes, align = "center")
plt.xticks(colonnes, listeIntitules)
plt.savefig("batons.png")
#plt.show()
plt.clf()
# Création d'une courbe
plt.title("Moyennes par matière (pas adapté)")
plt.xlabel("Matière")
plt.ylabel("Moyenne")
plt.plot(colonnes, listeMoyennes)
plt.xticks(colonnes, listeIntitules)
plt.savefig("courbe.png")
#plt.show()
plt.clf()
# Génération du code HTML
codeHTML = '''<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8" />
<title>Transfert Access -> Web + Graphiques</title>
</head>
<body>
<h1>Tableau</h1>
<table border="1">
<caption>Moyenne et nombre de notes par matière</caption>
<tr> <th>Matière</th> <th>Moyenne</th> <th>Nb</th> </tr>
'''
for i in colonnes: # Lignes du tableau
codeHTML += "<tr> <td>" + listeIntitules[i] + "</td> <td>" + str(listeMoyennes[i]) + "</td> <td>" +
str(listeNb[i]) + "</td> </tr>\n"
codeHTML += '''</table>
<h1>Camembert</h1>
<p><img src="camembert.png" alt="Notes par matière" /></p>
<h1>Diagramme en bâtons</h1>
<p><img src="batons.png" alt="Moyennes par matière" /></p>
<h1>Courbe</h1>
<p><img src="courbe.png" alt="Moyennes par matière" /></p>
</body>
</html>'''
M1 HN – BASES DE DONNEES
5/3
# Ecriture du fichier HTML
f = open("bd-web.html", "w")
f.writelines(codeHTML)
f.close()
M1 HN – BASES DE DONNEES
6/3
Téléchargement