Author: Alexandre B.

Projets

Système de gestion de base de données relationnelle sur…

Venez découvrir tout au long de ce compte rendu comment nous avons créé un programme en python permettant à l’utilisateur d’interagir avec la base de donnée que nous avons créé.

Dans un premier, on a importé toutes les bibliothèques nécessaires à la création du programme.

from tkinter import *
from tkinter import ttk
import tkinter as tk
import sqlite3
import pandas
import os

La bibliothèque « tkinter » va servir à créer l’interface graphique ( vous pouvez en apprendre plus grâce à ce tutoriel, créé par Aël, élève en Spé NSI en classe de 1ère ).

La bibliothèque sqlite3 permet d’interagir avec une base de donnée.

La bibliothèque pandas permet de récupérer des données dans un ficher csv.

Et enfin la bibliothèque os permet de supprimer des fichiers dans le cadre de ce programme.

I. Création de la page d’accueil

Nous avons d’abord réfléchi à l’interface graphique que nous souhaitions réaliser.

Il nous fallait d’abord une page d’accueil, avec quatre boutons permettant d’effectuer les quatre fonctions nécessaires à l’utilisation d’une base de données : créer la base, lire la base, modifier la base, et enfin supprimer la base.

Le code ci-dessous permet de créer la page d’accueil, contenant un titre et 4 boutons.

window = Tk() # page d'accueil avec les 4 boutons

window.title("Gérer une base de donnée sur les jeux vidéos")
window.geometry("1280x1024")
window.maxsize(1280,1024)
window.config(bg="#7EBDC2")
window.iconbitmap("manette.ico")

titre = Label(window, text="4 boutons pour intéragir avec la base de données", font=("Consolas",20), bg="#d1fdff", fg="black")
titre.pack(pady=45)

boite = Frame(window, bg="#7EBDC2")
boite.pack(pady=200)

boutonC = Button(boite, text="CREATE", font=("Consolas",15), bg="white", fg="black", command=create, width=10, height=3)
boutonC.grid(row = 1, column = 0, padx = 15, pady=15)

boutonR = Button(boite, text="READ", font=("Consolas",15), bg="white", fg="black", command=read, width=10, height=3)
boutonR.grid(row = 1, column = 1, padx = 15, pady=15)

boutonU = Button(boite, text="UPDATE", font=("Consolas",15), bg="white", fg="black", command=update, width=10, height=3)
boutonU.grid(row = 3, column = 0, padx = 15, pady=15)

boutonD = Button(boite, text="DROP\n DATABASE", font=("Consolas",15), bg="white", fg="black", command=delete, width=10, height=3)
boutonD.grid(row = 3, column = 1, padx = 15, pady=15)

window.mainloop()

Visuel graphique :

II. Comment utiliser nos fonctions

Lier une interface graphique à des fonctions nécessite l’emploi de boutons.

Il nous fallait donc créer 4 fonctions permettant d’interagir avec la base de données.

A. La fonction create()

Nos fichiers à exploiter sont au format .csv. Avec la bibliothèque pandas, nous avons stockés les fichiers csv dans des variables pour pouvoir les exploiter.

ed = pandas.read_csv("relation_editeur.csv")
jv = pandas.read_csv("base_principale.csv")

Puis nous avons dû créer un fichier au format .db (Data Base).

connection = sqlite3.connect('base.db')
curseur = connection.cursor()

Nous avons créé les deux relations en indiquant les attributs et leur type.

curseur.execute("CREATE TABLE IF NOT EXISTS ED(Id_Editeur INTEGER, Editeur TEXT, PRIMARY KEY(Id_Editeur AUTOINCREMENT))")
curseur.execute("CREATE TABLE IF NOT EXISTS JV(Id_Jeu INTEGER, Jeu TEXT, Annee INTEGER, Prix FLOAT, Plateforme TEXT, Id_Editeur INTEGER, PRIMARY KEY(Id_Jeu AUTOINCREMENT), FOREIGN KEY(Id_Editeur) REFERENCES ED(Id_Editeur))")

Et enfin, nous avons créé deux boucles « for » pour ajouter les enregistrements des fichiers .csv dans la base de données automatiquement.

for i in range(len(ed)):
    data = [ed.loc[i, "Editeur"]]
    curseur.execute("INSERT INTO ED(Editeur) VALUES (?)", data)
    
for i in range(len(jv)):
    data = []
    data2 = list(jv.loc[i, ["Jeu", "Annee", "Prix", "Plateforme", "Id_Editeur" ]])
    data2[1] = int(data2[1])
    data2[4] = int(data2[4])
    data.append(tuple(data2))
    curseur.executemany("INSERT INTO JV(Jeu, Annee, Prix, Plateforme, Id_Editeur) VALUES (?, ?, ?, ?, ?)", data)

Pour finir, nous avons mis chacun de ces éléments dans une seule fonction : create(), appelée par le premier bouton de l’accueil. Nous avons décidé d’afficher une phrase pour indiquer à l’utilisateur que la base de données a bien été créé. Un simple Label nous a suffit (allez voir le tutoriel d’Aël pour plus de détails).

B. La fonction drop_database()

En SQL, la commande « DROP DATABASE » permet de supprimer la base de données. En python, il est impossible d’utiliser cette commande. On a donc importé le module os qui permet dans ce cas de supprimer un fichier.

Ainsi, la structure de la fonction drop_database() serait :

os.remove("base.db")

Cependant, si le fichier n’existe pas, tenter de le supprimer affichera, dans l’IDE python, un message d’erreur. Pour éviter ce problème, nous avons créé une variable globale « test » qui prend la valeur 0 si la base n’existe pas, et 1 si la base existe. Nous avons donc testé avec un « if » la valeur de « test », et le fichier ne sera supprimé que si « test » est égal à 1 et un message de confirmation s’affichera, sinon un message apparaît sur la fenêtre tkinter pour indiquer que la base n’existe pas, ce qui nous donne la fonction suivante.

def drop_database(): # supprime le fichier de la base de donnée s'il existe
    global test
    global message
    global texte
    
    if test == 1:
        os.remove("base.db")
        test -= 1
        supmes()
        message = "La base de donnée a bien été suprimée"
        texte = Label(window, text=message, font=("Helvetica",15), bg="#d1fdff", fg="black")
        texte.pack()
    elif test == 0:
        supmes()
        message = "La base de donnée n'existe actuellement pas"
        texte = Label(window, text=message, font=("Helvetica",15), bg="#d1fdff", fg="black")
        texte.pack()

C. La fonction read()

Pour la santé mentale de tout lecteur, nous ne montrerons pas ici l’intégralité de notre fonction (sinon, le fichier entier est téléchargeable en bas de page).

En SQL, pour sélectionner des éléments d’une base de données, on utilise la commande « SELECT Attribut_1, Attribut_2, … FROM DB ». En python, avec la bibliothèque sqlite3, la structure est exactement la même. Or il faut récupérer ce que contient le curseur et le stocker dans une variable, pour ensuite l’afficher. Par exemple, pour afficher tous les attributs d’une relation dans la console de l’IDE Python, on utilise :

curseur.execute("SELECT * FROM RELATION")
lecture = curseur.fetchall()#récupère les données obtenues par la ligne 1 en 'str'
print(lecture)

Lorsque l’on clique sur le bouton « read » de la page d’accueil, une nouvelle fenêtre tkinter apparaît. Sur cette fenêtre, on peut choisir de lire la relation principale (relation Jeux Vidéo), la relation secondaire (relation Editeurs) ou de retourner au menu, soit à l’accueil.

Le bouton « Retour Menu » supprime simplement la fenêtre, avec la commande tkinter :

window_r.destroy()

La lecture de la relation Editeurs est assez simple. En effet, la relation Editeurs ne contient que deux attributs : la clé primaire « Id_Editeur » et le nom de l’éditeur, « Editeur ». On a donc choisi de montrer par défaut toute la relation dans la même fenêtre que celle contenant les boutons de lecture, et donc supprimer les boutons. Nous avons donc dû globaliser nos boutons, afin de les supprimer ainsi :

global bouton
bouton.pack_forget()

Enfin, il a fallu sélectionner tous les éléments et les afficher dans un Label.

curseur.execute("SELECT * FROM ED")#fonction simplifiée
affichage = curseur.fetchall()
affiche = Label(text=affichage)#plus de détails sur le tutoriel
affiche.pack()

Pour finir, il nous a fallu afficher le contenu de la relation principale selon les demandes de l’utilisateur.

Pour cela, nous avons créé, grâce à des recherches supplémentaires sur internet, des checkbutton (des cases à cocher), qui peuvent être sélectionnés ou non pour choisir si l’on affiche l’attribut.

De plus, nous avons permis à l’utilisateur de choisir de spécifier sa demande avec la commande SQL « WHERE Attribut = Valeur ». Cela nous permet donc de faire une sélection très précise d’éléments à afficher.

D. La fonction update()

La dernière fonction à créer !

Modifier la base de données implique 3 actions : ajouter un enregistrement, supprimer un enregistrement, et modifier une valeur d’un des attributs de l’enregistrement.

Nous avons décidé qu’il était impossible, grâce à l’interface, d’ajouter directement un éditeur dans la relation « Editeur ». Ainsi lors de l’ajout ou de la modification d’un enregistrement de la relation Jeux Vidéo, si l’éditeur renseigné n’existe pas dans la relation correspondante, il y est créé. Cet ajout se fait simplement :

#Selon les spécificités de la bibliothèque sqlite3, avec "Editeur" renseigné par l'utilisateur
curseur.execute("SELECT Id_Editeur FROM ED WHERE Editeur = ?",(Editeur,))
temp = curseur.fetchall()
if temp == [] : #si l'éditeur n'existe pas
  curseur.execute("INSERT INTO JV (Editeur) VALUES (?)",(Editeur,))
  curseur.execute("SELECT Id_Editeur FROM ED WHERE Editeur = ?",(Editeur,))
  id_editeur = curseur.fetchall()#après ajout dans ED, on récupère l'Identifiant pour l'ajout dans JV

Pour la fonction ajouter(), nous avons créé 5 entrées correspondant aux valeurs du jeu à ajouter à la relation, et un bouton pour confirmer l’ajout.

Tant que le bouton de confirmation n’est pas cliqué, l’enregistrement n’existe pas dans la base de données.

Lorsque l’utilisateur confirme son ajout, une fonction ajouter_bis() est lancée, exécutant simplement :

valeur_1 = entree_1.get()
valeur_2 = entree_2.get()
valeur_3 = entree_3.get()
valeur_4 = entree_4.get()
#Id_Editeur récupéré par comme précédemment
data = (valeur_1, valeur_2, valeur_3, valeur_4, Id_Editeur)
curseur.execute("INSERT INTO JV (Jeu, Annee, Prix, Plateforme, Id_Editeur) VALUES (?,?,?,?,?)",data)

Ensuite, nous avons créé la fonction modifier(). Nous avons créé deux boutons permettant de modifier soit la relation Jeux Vidéo, soit la relation Editeurs.

Pour modifier la relation Editeur, on peut choisir l’éditeur à modifier soit par son Id_Editeur, soit par son nom actuel grâce à un bouton déroulant. Nous avons donc créé ce bouton déroulant et deux entrées correspondant d’abord au nouveau nom de l’éditeur, et ensuite à l’editeur à modifier. La commande SQL qui s’exécute est la suivante :

if bouton_attribut.get() == "Editeur"	
  curseur.execute("UPDATE ED SET Editeur = ? WHERE Editeur = ?",(entree_1.get(),entree_2.get()))
else :
  curseur.execute("UPDATE ED SET Editeur = ? WHERE Id_Editeur = ?",(entree_1.get(),entree_2.get())  

Si l’éditeur indiqué par son Id_Editeur ou son nom existe, alors l’enregistrement est modifié et un message de confirmation est affiché. Sinon il est indiqué que l’éditeur n’existe pas.

La fonction pour modifier un enregistrement de la relation principale est, dans les grandes lignes la même, mais l’utilisateur doit choisir l’attribut à modifier, avec un bouton déroulant. Ainsi :

curseur.execute("UPDATE ED SET Attribut_1 = ? WHERE Attribut_2 = ?",(entree_1.get(),entree_2.get())

« Attribut_1 » et « Attribut_2 » sont des valeurs fixes, testés par les boutons déroulants (demandant de nombreux tests « if » et « elif »)

Pour finir, il fallait pouvoir supprimer des éléments de la relation principale (la relation secondaire Editeurs ne peut que être lue ou modifiée). Deux attributs permettent d’identifier un jeu : son identifiant unique, et son nom (qui peut ne pas être unique). Pourtant nous avons choisi qu’il serait possible de supprimer un jeu grâce à son nom pour un utilisateur qui ne connaîtrait pas l’identifiant du jeu. Si le jeu indiqué par son Id_Jeu ou son nom existe, alors l’enregistrement est modifié et un message de confirmation est affiché. Sinon il est indiqué que le jeu n’existe pas.

Par la suite, quelque soit le choix de l’utilisateur, le fonction est le même : une entrée apparaît, dans laquelle il est possible de renseigner soit le jeu, soit l’id du jeu. Si le jeu indiqué par son Id_Jeu ou son nom existe, alors l’enregistrement est supprimé et un message de confirmation est affiché. Sinon il est indiqué que le jeu n’existe pas.

Nous avons donc créé les quatre fonctions pour interagir avec une base de données, soit la création, la lecture, la modification et la suppression de la base.

III. Conclusion

Ce compte-rendu touche maintenant à sa fin. N’hésitez pas à aller voir le tutoriel de Aël pour en apprendre plus sur la bibliothèque tkinter. Le fichier zip contenant tous les éléments nécessaires au bon fonctionnement du programme est disponible ci-dessous.

Tutoriels

Installer et utiliser Teleparty

Aujourd’hui dans ce tutoriel, vous allez découvrir comment installer, programmer et utiliser Teleparty avec vos amis !

1. Présentation générale et prérequis

Tout d’abord, Teleparty est une extension disponible sur le chrome web store ainsi que sur Microsoft Edge qui permet de regarder une série ou un film sur différents écrans en même temps. Pour ce faire, il est nécessaire d’avoir un ordinateur mais surtout il vous faut un compte sur la plate-forme de vidéo à la demande par abonnement de la série ou du film. Les 5 plates-formes compatibles avec Teleparty sont : Netflix, Amazon Prime Video, Disney+, Hulu et HBO Max.

2. Installation de l’extension

Pour débuter, il faut bien sûr installer l’extension en allant sur le site teleparty.com et cliquer sur un des 2 deux boutons sur l’image ci-dessous.

Puis cliquer sur « Ajouter à Chrome ».

Une fois fait vous pouvez épingler l’extension en cliquant sur le morceau de puzzle en haut à droite puis sur l’icône de l’épingle associée à Teleparty.

Cliquez ensuite sur « Next ».

Puis sur « Accept & Proceed » et « Autoriser ».

Et enfin cliquez sur les plates-formes dont vous avez un compte puis sur « Continue ».

3. Création d’une « Party »

Pour créer une party avec vos amis, il suffit de cliquer sur un épisode d’une série ou d’un film, puis de cliquer sur l’extension Teleparty en haut à droite et enfin d’appuyer sur « Start the party ». Vous pouvez également choisir de pouvoir exclusivement mettre en pause la vidéo et la reprendre ou vous pouvez partager ce pouvoir à tous les autres utilisateurs en décochant la case « Only I have control ».

Une fois fait, vous pouvez inviter vos amis en copiant le lien créé et en leur envoyant, vous pouvez également afficher et masquer la discussion de la party.

4. Rejoindre une party déjà créée

Pour rejoindre une party déjà créée, il vous suffit de copier le lien que votre ami vous a envoyé, de le coller dans un nouvel onglet puis de cliquer sur « Join the Party ».

5. Conclusion et Bonus

Vous savez désormais comment installer Teleparty, créer une party et rejoindre une party pour regarder une série ou un film avec vos amis. Cette extension propose en bonus un fil de discussion où l’on peut changer de pseudo en cliquant sur l’avatar actuel en haut à droite et en rentrant le nouveau pseudo. On peut également changer d’avatar en cliquant également sur l’avatar actuel en haut à droite puis sur l’avatar plus grand.

Pour finir vous pouvez donc aussi discuter en direct avec vos amis grâce au « chat » à droite.