Le but de cet UE est d'apprendre à maîtriser les concepts et les outils informatiques liés
de grandes quantités de données.
Vous apprendrez à organiser les étapes du développement autour
Section 1
Une donnée informatique est un élément d'information ayant subi un encodage numérique :
Les données persistantes sont une des composantes essentielles des programmes informatiques.
Il s'agit par définition des informations qui doivent être conservées entre deux exécutions.
Avec l’augmentation des capacités de stockage et leur mise en réseau, les quantités de données conservées ont considérablement augmenté au cours des dernières décennies.
Les données liées à l'utilisateur (données personnelles, sauvegardes,…)
Les données de l'entreprise:
données comptables
ventes
achats
employés
stocks
production
etc..
Bases d'information:
Documents en ligne
Services (trajets SNCF, articles commerciaux à vendre, données météo, articles de presse…)
Échanges et communication
index web (moteurs de recherche)
graphes de liens et messages (réseaux sociaux)
Une base de données est une infrastructure matérielle et logicielle permettant :
des algorithmes de stockage et de classement efficace (afin d’accélérer les temps de recherche)
SELECT *
FROM Eleves
WHERE NOM = 'Dugenou'
Section 2
f = open("/chemin/vers/mon_fichier", "r")Ouverture d'un fichier :
initialisation d'un descripteur de fichier f:
f est un objet qui implémente un flux de données.
les données sont lues dans l'ordre dans lequel elles ont été écrites par le serveur
On parle d'accès séquentiel aux données
f = open("/chemin/vers/mon_fichier", "r")L'opération de lecture :
dépile l'élément situé en tête de flux (dans la mémoire cache)
et le retourne à l'utilisateur
les donnée sont lues en fonction des demandes du programme
typiquement le système charge plusieurs pages en avance dans la mémoire cache
s = f.readline()Le système d'exploitation modifie le cache sans modifier immédiatement le fichier
f.write(s)f.close()L'écriture dans la mémoire secondaire est garantie lors de la fermeture
f.flush()Pour forcer l'écriture sans fermer le fichier, on on effectue un "vidage" du cache dans la mémoire secondaire
import sqlite3
db = sqlite3.connect("/chemin/vers/mabase.db"))Le programme n'est donc plus en communication directe avec le système d'exploitation mais avec une application tierce
C'est maintenant sqlite3 qui gère le flux de données.
import sqlite3
db = sqlite3.connect("/chemin/vers/mabase.db"))Le curseur est l'objet qui gère l'accès séquentiel aux données
c = db.cursor()c.execute("SELECT * FROM MaTable")Le programme sqlite3 exécute la requête et génère un flux de données
t = c.fetchone()Lecture de la première réponse (du premier tuple) du flux:
Le curseur est l'objet qui gère l'accès séquentiel aux données
c.execute("INSERT INTO MaTable VALUES (v1, v2, v3)")db.commit()Les modifications sont conservées dans la mémoire cache de sqlite. Néanmoins, pour s'assurer d'un enregistrement effectif en mémoire secondaire, il faut effectuer un commit (pour forcer l'écriture)
Un appariement (Mapping) est une couche d'abstraction logicielle qui permet :
de manipuler les données de la base données de manière plus conviviale et intuitive,
essentiellement en faisant correspondre les tuples (enregistrements) de la base de données avec des variables du programme
correspondance objets/données
On parle aussi d'interface objets/données
"Vues" d'une base de données :
tables virtuelles correspondant à des requêtes pré-définies
–> en RAM
Mapping objet/Relationnel (ORM – Object-Relational Mapping) :
mise en correspondance table/classe
+ ajout de getters/setters
patron de conception DAO (Data Access Object)
Approche “CRUD”: les requêtes se réduisent à quatre grandes familles d'opérations:
Création (Create) : ajout de nouveaux objets
Lecture/recherche (Read) : consulation du contenu d'un objet
Mise à jour (Update) : changement du contenu existant
Suppression (Delete) : suppression des objets périmés
Analyse de données :
Mise en forme hiérarchique des données :
Dimensions (indexation multiple hiérarchique)
Agrégation multi-critères (tableaux croisés dynamiques, cubes de données etc.)
Visualisation
Les système d'exploitation (pour la gestion des fichiers)
Le gestionnaire de BD (requêtes vers une BD)
en maintenant en mémoire l'état des objets modifiés par l'utilisateur
en chargeant de manière parcimonieuse le contenu de la base (seuls les données réellement utilisées doivent être chargées en mémoire)
Section 3
Les variables et objets manipulé sont régulièrement sauvegardés
Pour plus d'efficacité, le fichier de sauvegarde est une base de données
Au niveau de la conception du programme, on doit distinguer les données persistances des données non-persistantes
Mise en correspondance et synchronisation entre les donnée du programme et la base de données
Maintien de la cohésion assuré par la mémoire cache (interface entre application et SGBD)
Retrouver le programme dans l'état dans lequel on l'a laissé lorsqu'on l'a précédemment quitté:
Les données persistantes sont conservées dans une base de données relationnelle dont le schéma est établi au cours de l'étape de modélisation.
Conception initiale sous forme d'un modèle Entité/Association (cours de première année)
Passage au modèle relationnel (cours de première année)
Modélisation UML
Enseignant(e-mail-ens, nom, prénom, tel)
UE(code_UE, intitulé, semestre, nb_crédits, e-mail-ens)
Séance(id_séance, code_UE, e-mail-ens, type, salle, date, heure)
Présence(e-mail-eleve, id_seance)
Elève(e-mail-eleve, nom, prénom, tel)
Examen(code_UE, e-mail-eleve, date, heure, note)
CREATE TABLE Enseignant (
e_mail_ens VARCHAR(30) NOT NULL,
nom VARCHAR(30) NOT NULL,
prénom VARCHAR(30) NOT NULL,
tel VARCHAR(12),
PRIMARY KEY (e_mail_ens));Enseignant(e-mail-ens, nom, prénom, tel)
UE(code_UE, intitulé, semestre, nb_crédits, e-mail-ens)
CREATE TABLE UE (
code_UE VARCHAR(30) NOT NULL,
intitulé VARCHAR(30) NOT NULL,
semestre INTEGER NOT NULL,
nb_crédits INTEGER NOT NULL,
e_mail_ens VARCHAR(30) NOT NULL,
PRIMARY KEY (code_UE),
FOREIGN KEY (e_mail_ens) REFERENCES Enseignant);Pour chaque Entité une classe distincte.
class Enseignant:
def __init__(self, e_mail_ens , nom, prénom, tel):
self.e_mail_ens = e_mail_ens
self.nom = nom
self.prénom = prénom
self.tel = tel
self.responsabilités = set()
self.séances = set()
def ajoute_seance(self, séance):
self.séances.add(séance)
def ajoute_responsabilité(self, UE):
self.responsabilités.add(UE)Pour chaque Entité une classe distincte.
class Séance:
def __init__(self, id_séance , date, heure, salle, type, enseignant):
self.id_séance = id_séance
self.date = date
self.heure = heure
self.salle = salle
self.type = type
self.enseignant = enseignant
self.présence = set()
def ajoute_présence(self, élève):
self.présence.add(élève)
Un DAO (Data Access Object) est une classe qui réalise l'interface entre une classe d'objets persistants et la base de données.
Une classe DAO permet de mettre en œuvre les quatre opérations de base (CRUD) :
Create
Read
Update
Delete
Il existe autant de classes DAO que de classes persistantes
Dans l'exemple considéré, on doit donc avoir les six classes suivantes:
Enseignant_DAO
UE_DAO
Séance_DAO
Elève_DAO
Examen_DAO
En python :
class Enseignant_DAO:
def __init__(self, db_name):
self.db = sqlite3.connect(db_name)
def create_enseignant(self, enseignant):
...
def get_enseignant_by_id(self, id_enseignant): # Read
...
def update_enseignant(self, enseignant):
...
def delete_enseignant(self, enseignant):
...En python :
class Enseignant_DAO:
def __init__(self, db_name):
self.db = sqlite3.connect(db_name)
def create_enseignant(self, enseignant):
...
def get_enseignant_by_id(self, id_enseignant): # Read
...
def update_enseignant(self, enseignant):
...
def delete_enseignant(self, enseignant):
...En python :
from enseignant import Enseignant
class Enseignant_DAO:
def __init__(self, db_name):
self.db = sqlite3.connect(db_name)
def create_enseignant(self, enseignant):
...
def get_enseignant_by_id(self, id_enseignant, fill=True): # Read
c = db.cursor()
t_enseignant = c.execute("SELECT * FROM Enseignant WHERE e_mail_ens = ?", (id_enseignant,)).fetchone()
enseignant = Enseignant(t_enseignant[0], t_enseignant[1], t_enseignant[2], t_enseignant[3])
if fill:
seance_DAO = Seance_DAO(self.db_name)
liste_id_seances = c.execute("SELECT id_séance FROM Seance WHERE e_mail_ens = ?", (id_enseignant,)).fetchall()
for t_id_seance in liste_id_seances:
enseignant.séances.add(seance_DAO.get_seance_by_id(t_id_seance), fill=False)
ue_DAO = UE_DAO(self.db_name)
liste_code_UE = c.execute("SELECT code_UE FROM UE WHERE e_mail_ens = ?")
for t_code_UE in liste_code_UE:
enseignant.responsabilité.add(ue_DAO.get_UE_by_id(t_code_UE), fill=False)
return enseignant
def update_enseignant(self, enseignant):
...
def delete_enseignant(self, enseignant):
...En python :
class DAO:
def __init__(self, db_name):
self.db = sqlite3.connect(db_name)
class Enseignant_DAO(DAO):
def create_enseignant(self, enseignant):
...
def get_enseignant_by_id(self, id_enseignant): # Read
...
def update_enseignant(self, enseignant):
...
def delete_enseignant(self, enseignant):
...Exemple : relation many-to-many entre Elève et Séance :
La méthode get_séance_by_id fait appel à get_eleve_by_id pour établir la liste de présence
La méthode get_eleve_by_id fait appel à get_séance_by_id pour établir la liste des séances auxquelles l'élève a assisté
etc….
Il faut donc prévoir de ne charger qu'une partie des informations, celle qui est réellement utile au programme (inutile de charger l'emploi du temps de chaque élève lorsqu'on s'intéresse à la liste de présence d'une séance particulière).
Avec le patron DAO, il faut gérer au cas par cas
Les Gestionnaires de persistance ORM (django, Pony ORM) permettent de gérer le chargement des données "à la demande", à la manière de la mémoire cache.
Section 4
Section 5
Une Interface graphique (ou GUI -- Graphical User Interface) est constituée essentiellement de deux modules :
Le "front-end" (la "devanture"), qui est la partie du programme visible pour l'utilisateur et avec laquelle l'utilisateur peut interagir à l'aide de menus, de boutons et de formulaires…
Le "back-end" (l'"arrière-boutique"), qui correspond aux rouages invisible à l'utilisateur, permettant au programme de réaliser la tâche pour laquelle il a été conçu.
Pour développer un tel programme, on le divise généralement en trois modules appelés respectivement:
le Modèle
la Vue
le Contrôleur
Le modèle est la partie du programme :
Modèle
La Vue est la partie du programme qui gère la mise en page, la disposition des informations, des boutons et des formulaires, l'organisation et la visibilité des différentes fenêtres du programme s'il y en a.
La Vue fait appel au Contrôleur à chaque fois que l'utilisateur effectue une action (saisie d'information, pointage de souris, sélection de menu, activation d'un bouton etc…)
La Vue fait appel au Modèle pour afficher en permanence un contenu actualisé par les actions de l'utilisateur.
Modèle
Contrôleur
Vue
READ
ACT
Le contrôleur est la partie du programme qui gère les actions de l'utilisateur. Chacune des actions proposées dans la vue est implémentée dans le contrôleur sous la forme d'une fonction.
Le contrôleur fait appel au Modèle lorsque l'action modifie les variables et objets manipulés par le programme.
Modèle
Contrôleur
Vue
CREATE
UPDATE
DELETE
ACT
L'écriture d'une interface graphique permet de mettre en œuvre les principes de la programmation événementielle:
Une interface est constituée de plusieurs éléments graphiques (appelés widgets) positionnés dans une fenêtre.
les widgets sont éditables/positionnables via les méthodes définies dans la librairie
il est possible de modifier leur contenu en cours d'exécution (via des événements)
Les actions de l'utilisateur (mouvements et clics de souris, entrées clavier ,…) produisent des événements:
Les événements sont déclenchés par des widgets actifs (boutons, menus,…) capables de lancer l'exécution d'une ou plusieurs opérations:
mise à jour d'une variable ou d'un attribut
lancement d'un calcul
envoi d'un message
modification du rendu visuel
arrêt du programme
etc.
Dans le cadre du patron MVC, les informations affichées dans l'interface (le contenu des widgets) sont paramétrées par les objets du modèle. On a typiquement le cycle suivant :
L'utilisateur déclenche une action via l'interface
Le contrôleur exécute l'action
Les changements produits par l'action sont répercutés dans le modèle
l'interface consulte le modèle pour mettre à jour son contenu.
Section 1
comptes rendus,
série de notes, de valeurs sans format précis :
Le format txt désigne des données non structurées de type “texte” regroupant différents modes d’encodage :
ASCII (caractères sans accent),
utf8 (caractères accentués et spéciaux),
…
Organisation des données correspondant à une structure d’arbre.
Dans le cas d’un recueil de données, correspond à la définition de rubriques et sous-rubriques.
Formats xml, xhtml, json, …
Pour les données organisées de manière hiérarchique. Des balises servent à séparer les différents attributs.
<nom> Dubois </nom>
<prénom> Martine </prénom>
<adresse>
<num> 28 </num>
<voie> rue des Lilas </voie>
<code postal> 45000 </code postal>
<ville> Orléans </ville>
</adresse>
<âge> 45 </âge>XML
Formats xml, xhtml, json, …
Pour les données organisées de manière hiérarchique. Des balises servent à séparer les différents attributs.
{
"nom" : "Dubois",
"prénom" : "Martine",
"adresse" :
{
"numero" : 28,
"voie" : "rue des Lilas",
"code_postal" : 45000,
"ville" : "Orléans"
},
"âge" : 45
}json (JavaScript Object Notation)
Formats xml, xhtml, json, …
Pour les données organisées de manière hiérarchique. Des balises servent à séparer les différents attributs.