Browse Source

refonte complète pour cours

master
Lapin-Blanc 3 years ago
parent
commit
ed02442e97
4 changed files with 354 additions and 3096 deletions
  1. +59
    -61
      encodage_eleves.py
  2. +140
    -167
      formulaire.py
  3. +0
    -2826
      liste-des-codes-postaux-belges-fr.csv
  4. +155
    -42
      utils.py

+ 59
- 61
encodage_eleves.py View File

@@ -1,78 +1,76 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sqlite3
from utils import dessine_tableau
from utils import print_table

def main():
db = sqlite3.connect('ecole.sqlite3')
cursor = db.cursor()
db = sqlite3.connect('ecole.sqlite3')
cursor = db.cursor()

cursor.execute("""CREATE TABLE IF NOT EXISTS eleves(
ID_Eleve INTEGER PRIMARY KEY AUTOINCREMENT,
Prenom TEXT,
Nom TEXT);
""")
cursor.execute("""CREATE TABLE IF NOT EXISTS eleves(
ID_Eleve INTEGER PRIMARY KEY AUTOINCREMENT,
Prenom TEXT,
Nom TEXT,
UNIQUE (Prenom, Nom));
""")
while True:
choix = input("\nVeuillez choisir une action à réaliser [A]jouter, [L]ister, " \
"[M]odifier, [S]upprimer, [Q]uitter : ")
if choix == "":
continue
if choix[0] in 'lL':
cursor.execute("""SELECT * FROM eleves ORDER BY ID_eleve;""")
liste_eleves = cursor.fetchall()
titres = ['Id', 'Prénom', 'Nom']
liste_eleves.insert(0, titres)
print_table(liste_eleves)

while True:
choix = input("\nVeuillez choisir une action à réaliser [A]jouter, [L]ister, " \
"[M]odifier, [S]upprimer, [Q]uitter : ")
if choix == "":
if choix[0] in 'aA':
prenom = input("\nVeuillez entrer un prenom : ").capitalize()
nom = input("Veuillez entrer un nom : ").upper()
if prenom=="" or nom=="":
print('Vous devez renseigner le nom et le prénom')
continue
if choix[0] in 'lL':
cursor.execute("""SELECT * FROM eleves ORDER BY ID_eleve;""")
liste_eleves = cursor.fetchall()
titres = ['Id', 'Prénom', 'Nom']
dessine_tableau(liste_eleves, titres)
if choix[0] in 'aA':
prenom = input("\nVeuillez entrer un prenom : ").capitalize()
nom = input("Veuillez entrer un nom : ").upper()
cursor.execute("""SELECT prenom, nom FROM eleves;""")
liste_eleves = cursor.fetchall()
if (prenom, nom) in liste_eleves:
print('Cet élève existe déjà !')
elif prenom=="" or nom=="":
print('Vous devez renseigner le nom et le prénom')
else:
else:
try:
cursor.execute("""INSERT INTO eleves(prenom, nom)
VALUES(?,?);""",
(prenom, nom))
db.commit()
if choix[0] in 'mM':
id_eleve = input("Veuillez entrez l'identifiant de l'élève à modifier : ")
cursor.execute("""SELECT prenom, nom FROM eleves WHERE ID_Eleve=?""", (id_eleve,))
prenom, nom = cursor.fetchone()
n_prenom = input(f"\nVeuillez entrer un prenom (actuellement {prenom}): ")
n_nom = input(f"Veuillez entrer un nom (actuellement {nom}): ")
if n_prenom:
prenom = n_prenom
if n_nom:
nom = n_nom
except sqlite3.IntegrityError:
print(f"{prenom} {nom} existe déjà dans la base de données")

if choix[0] in 'mM':
id_eleve = input("Veuillez entrez l'identifiant de l'élève à modifier : ")
cursor.execute("""SELECT prenom, nom FROM eleves WHERE ID_Eleve=?""", (id_eleve,))
prenom, nom = cursor.fetchone()
n_prenom = input(f"\nVeuillez entrer un prenom (actuellement {prenom}): ")
n_nom = input(f"Veuillez entrer un nom (actuellement {nom}): ")
if n_prenom:
prenom = n_prenom
if n_nom:
nom = n_nom
try:
cursor.execute("""UPDATE eleves
SET prenom=?,
nom=?
WHERE ID_Eleve=?;""",
(prenom.capitalize(), nom.upper(), id_eleve))
db.commit()
except sqlite3.IntegrityError:
print(f"{prenom} {nom} existe déjà dans la base de données")

if choix[0] in 'sS':
id_eleve = input("Veuillez entrez l'identifiant de l'élève à supprimer : ")
cursor.execute("""SELECT prenom, nom FROM eleves WHERE ID_Eleve=?""", (id_eleve,))
prenom, nom = cursor.fetchone()
confirmation = input(f"Confirmez-vous la suppression de {prenom} {nom} ? [O/n] : ")
if not confirmation=='n':
cursor.execute("""DELETE FROM eleves WHERE ID_Eleve=?""",(id_eleve,))
db.commit()
if choix[0] in 'qQ':
break

print('Bye !')
db.close()
if choix[0] in 'sS':
id_eleve = input("Veuillez entrez l'identifiant de l'élève à supprimer : ")
cursor.execute("""SELECT prenom, nom FROM eleves WHERE ID_Eleve=?""", (id_eleve,))
prenom, nom = cursor.fetchone()
confirmation = input(f"Confirmez-vous la suppression de {prenom} {nom} ? [O/n] : ")
if not confirmation=='n':
cursor.execute("""DELETE FROM eleves WHERE ID_Eleve=?""",(id_eleve,))
db.commit()
if choix[0] in 'qQ':
break

if __name__ == '__main__':
main()
print('Bye !')
db.close()

+ 140
- 167
formulaire.py View File

@@ -1,65 +1,52 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import PySimpleGUI as sg
import sqlite3

db = sqlite3.connect('ecole.sqlite3')
cursor = db.cursor()

cursor.execute("""PRAGMA foreign_keys=ON;""")
cursor.execute("""CREATE TABLE IF NOT EXISTS localites(
ID_Localite INTEGER PRIMARY KEY,
"zipcode" TEXT,
"localite" TEXT,
"sous-commune" TEXT,
"commune-principale" TEXT,
"province" TEXT);
""")
cursor.execute("""CREATE TABLE IF NOT EXISTS eleves(
ID_Eleve INTEGER PRIMARY KEY AUTOINCREMENT,
Prenom TEXT,
Nom TEXT,
RefLocalite INTEGER,
FOREIGN KEY(RefLocalite) REFERENCES localites(Id_Localite));
""")

def select_all_eleves():
cursor.execute("""SELECT id_eleve, nom, prenom, ifnull(refLocalite, ''), ifnull(zipcode, '-'), ifnull(localite, '-')
FROM eleves
LEFT JOIN localites
ON eleves.reflocalite=localites.id_localite
ORDER BY nom, prenom;
""")
liste_eleves = cursor.fetchall()
return liste_eleves
# Instructions SQL
CREATE_TABLE = """CREATE TABLE IF NOT EXISTS eleves(
ID_Eleve INTEGER PRIMARY KEY,
Prenom TEXT,
Nom TEXT,
UNIQUE (Prenom, Nom));
"""

SELECT_ALL = """SELECT id_eleve, nom, prenom
FROM eleves
ORDER BY nom, prenom;
"""

DELETE_BY_ID = """DELETE FROM eleves
WHERE ID_Eleve=?;
"""

INSERT_STUDENT = """INSERT INTO eleves(prenom, nom)
VALUES(?,?);"""

def select_all_localites():
cursor.execute("""SELECT id_Localite, zipcode, localite
FROM localites
ORDER BY zipcode, localite;
""")
liste_localite = cursor.fetchall()
return liste_localite
UPDATE_STUDENT_BY_ID = """UPDATE eleves
SET prenom=?, nom=?
WHERE id_eleve=?;
"""

cursor.execute(CREATE_TABLE)

liste_eleves = select_all_eleves()
liste_localites = select_all_localites()
liste_localites_combo = [f"{cp} {loc}" for _, cp, loc in liste_localites]

def make_main_window():
cursor.execute(SELECT_ALL)
liste_eleves = cursor.fetchall()
col = [
[sg.Button('Ajouter', size=(10, 1), bind_return_key=True)],
[sg.Button('Modifier', size=(10, 1))],
[sg.Button('Supprimer', size=(10, 1))],
[sg.Button('Quitter', size=(10, 1))],
[sg.Button('Ajouter', size=(12, 1))],
[sg.Button('Modifier', size=(12, 1))],
[sg.Button('Supprimer', size=(12, 1))],
[sg.Button('Quitter', size=(12, 1))],
]
layout = [
[sg.Text('Liste des élèves')],
[sg.Table(values=liste_eleves,
headings=['', 'Prénom', 'Nom', '', 'Code postal', 'Localité'],
headings=['Id', 'Prénom', 'Nom'],
max_col_width=25,
col_widths=[0, 15, 15, 0, 10, 15],
col_widths=[0, 20, 20],
hide_vertical_scroll=True,
background_color='light blue',
text_color='black',
@@ -72,142 +59,128 @@ def make_main_window():
]
window = sg.Window('Formulaire',
layout=layout,
size=(650, 500),
size=(500, 500),
finalize=True)
window.liste_eleves = liste_eleves
return window


def make_add_window(caption,
role='create',
initial_values=None,
eleve_id=None):
prenom, nom, id_localite, combo_value = ('','', '', '') if not initial_values else initial_values
def make_add_window(caption, role='create', initial_values=None):
if initial_values:
eleve_id, prenom, nom = initial_values
else:
eleve_id = prenom = nom = ''
layout = [
[sg.Text(text='Prénom', size=(10,2)),
sg.InputText(default_text=prenom,
size=(20,2),
k='prenom')],
[sg.Text(text='Nom', size=(10,2)),
sg.InputText(default_text=nom,
size=(20,2),
k='nom')],
[sg.Text(text='Localité', size=(10,2)),
sg.Combo(liste_localites_combo,
size=(18,10),
k='localite',
enable_events=True,
default_value=combo_value)],
[sg.Button('Valider', bind_return_key=True),
sg.Button('Annuler', bind_return_key=True)],
[sg.InputText(default_text=id_localite, k="id_localite", visible=False)]
[sg.InputText(eleve_id, k='eleve_id', visible=False)],
[sg.Text(text='Prénom', size=(10,2)), sg.InputText(default_text=prenom, size=(20,2), k='prenom')],
[sg.Text(text='Nom', size=(10,2)), sg.InputText(default_text=nom, size=(20,2), k='nom')],
[sg.Button('Valider', bind_return_key=True), sg.Button('Annuler', bind_return_key=True)]
]
window = sg.Window(caption,
layout=layout,
finalize=True)
window.role = role
window.eleve_id = eleve_id
return window


def main():
liste_eleves = select_all_eleves()
liste_localites = select_all_localites()
liste_localites_combo = [f"{cp} {loc}" for _, cp, loc in liste_localites]

window1, window2 = make_main_window(), None

while True:
window, event, values = sg.read_all_windows()
print(f'window : {window}, event : {event}, values : {values}')
if window == window1:
if event in (sg.WIN_CLOSED, 'Quitter'):
break
window1, window2 = make_main_window(), None

while True:
window, event, values = sg.read_all_windows()
# print(f'window : {window}, event : {event}, values : {values}')
if window == window1:
if event in (sg.WIN_CLOSED, 'Quitter'):
break
if event == 'Ajouter':
window2 = make_add_window('Ajouter', role='create')
window2.make_modal()
if event == 'Supprimer':
try:
# dans le cas d'un tableau, la valeur est un tableau de(s)
# index sélectionnés. On garde le premier quoi qu'il arrive
selected_line = values['table_eleves'][0]
# la colonne id est cachée au niveau de l'affichage
id_eleve = window1.liste_eleves[selected_line][0]
except IndexError:
sg.popup_ok('Veuillez sélectionner un enregistrement à supprimer')
continue
confirmation = sg.popup("Confirmez-vous la suppression ?",
button_type=sg.POPUP_BUTTONS_OK_CANCEL,
custom_text=("Oui", "Non"))
if confirmation=="Non":
continue
cursor.execute(DELETE_BY_ID, (id_eleve,))
db.commit()
if event == 'Ajouter':
window2 = make_add_window('Ajouter', role='create')
window2.make_modal()
if event == 'Supprimer':
try:
id_eleve = liste_eleves[values['table_eleves'][0]][0]
except IndexError:
sg.popup_ok('Veuillez sélectionner un enregistrement à supprimer')
continue
confirmation = sg.popup("Confirmez-vous la suppression ?",
button_type=sg.POPUP_BUTTONS_OK_CANCEL,
custom_text=("Oui", "Non"))
if confirmation=="Non":
continue
cursor.execute("""DELETE FROM eleves WHERE ID_Eleve=?""",(id_eleve,))
db.commit()
liste_eleves = select_all_eleves()
window1['table_eleves'].update(values=liste_eleves,
num_rows=len(liste_eleves))

if event == 'Modifier':
try:
id_eleve, nom, prenom, refLocalite, zipcode, localite = liste_eleves[values['table_eleves'][0]]
except IndexError:
sg.popup_ok('Veuillez sélectionner un enregistrement à modifier')
continue
window2 = make_add_window('Modifier',
initial_values=[prenom, nom, refLocalite, zipcode+" "+localite],
role='modify',
eleve_id=id_eleve)
window2.make_modal()

if window == window2:
if event in (sg.WIN_CLOSED, 'Annuler'):
window2.close()
window2 = None
if event == 'localite':
index = liste_localites_combo.index(values['localite'])
ID_Localite = liste_localites[index][0]
window['id_localite'].update(ID_Localite)
if window.role == 'create' and event == 'Valider':
prenom = values['prenom'].capitalize()
nom = values['nom'].upper()
id_localite = values['id_localite']
# print(f"prenom : {prenom}, nom : {nom}")
cursor.execute("""INSERT INTO eleves(prenom, nom, refLocalite)
VALUES(?,?,?);""", (prenom, nom, id_localite))
liste_eleves = cursor.execute(SELECT_ALL).fetchall()
window1['table_eleves'].update(values=liste_eleves,
num_rows=len(liste_eleves))
# On ne peut pas retrouver la liste des élèves à partir du tableau;
# alors on l'attache à la window1
window1.liste_eleves = liste_eleves

if event == 'Modifier':
try:
# voir 'Supprimer' pour une explication
selected_line = values['table_eleves'][0]
id_eleve, nom, prenom = window1.liste_eleves[selected_line]
except IndexError:
sg.popup_ok('Veuillez sélectionner un enregistrement à modifier')
continue
window2 = make_add_window('Modifier',
initial_values=[id_eleve, prenom, nom],
role='modify')
window2.make_modal()

if window == window2:
if event in (sg.WIN_CLOSED, 'Annuler'):
window2.close()
window2 = None
if event == 'Valider' and window.role == 'create' :
prenom = values['prenom'].capitalize()
nom = values['nom'].upper()
try:
cursor.execute(INSERT_STUDENT, (prenom, nom))
db.commit()
liste_eleves = select_all_eleves()
window1['table_eleves'].update(values=liste_eleves, num_rows=len(liste_eleves))
window2.close()
window2 = None
if window.role == 'modify' and event == 'Valider':
confirmation = sg.popup("Confirmez-vous la modification ?",
button_type=sg.POPUP_BUTTONS_OK_CANCEL,
custom_text=("Oui", "Non"))
if confirmation=="Non":
continue
prenom = values['prenom'].capitalize()
nom = values['nom'].upper()
id_localite = values['id_localite']
# print(f"prenom : {prenom}, nom : {nom}")
cursor.execute("""UPDATE eleves
SET prenom=?,
nom=?,
refLocalite=?
WHERE id_eleve=?;
""", (prenom, nom, id_localite, window.eleve_id))
except sqlite3.IntegrityError:
sg.popup_error('Cet élève existe déjà dans la base de données')

liste_eleves = cursor.execute(SELECT_ALL).fetchall()
window1['table_eleves'].update(values=liste_eleves,
num_rows=len(liste_eleves))
window1.liste_eleves = liste_eleves
window2.close()
window2 = None

if event == 'Valider' and window.role == 'modify':
confirmation = sg.popup("Confirmez-vous la modification ?",
button_type=sg.POPUP_BUTTONS_OK_CANCEL,
custom_text=("Oui", "Non"))
if confirmation=="Non":
continue
prenom = values['prenom'].capitalize()
nom = values['nom'].upper()
eleve_id = values['eleve_id']
try:
cursor.execute(UPDATE_STUDENT_BY_ID, (prenom, nom, eleve_id))
db.commit()
liste_eleves = select_all_eleves()
window1['table_eleves'].update(values=liste_eleves,
num_rows=len(liste_eleves))
window2.close()
window2 = None

window1.close()
if window2 is not None:
window2.close()

db.close()
print('Bye !')

if __name__ == "__main__":
main()
except sqlite3.IntegrityError:
sg.popup_error('Cet élève existe déjà dans la base de données')

liste_eleves = cursor.execute(SELECT_ALL).fetchall()
window1['table_eleves'].update(values=liste_eleves,
num_rows=len(liste_eleves))
window1.liste_eleves = liste_eleves
window2.close()
window2 = None

window1.close()
if window2 is not None:
window2.close()

db.close()
print('Bye !')

+ 0
- 2826
liste-des-codes-postaux-belges-fr.csv
File diff suppressed because it is too large
View File


+ 155
- 42
utils.py View File

@@ -1,45 +1,158 @@
def dessine_tableau(tableau, titres=None):
lengths = []
if titres:
tableau.insert(0, titres)
nb_columns = len(tableau[0])
nb_rows = len(tableau)
for i in range(nb_columns):
lengths.append(max([len(str(x[i])) for x in tableau]))
class FormatError(Exception):
pass

sample = [
['Id', 'Nom', 'Prénom'],
['1', 'Tiny', 'Toon'],
['2', 'Wile E.', 'Coyote'],
['33', 'Bugs', 'Bunny'],
]

def max_lengths(table):
"""
retourne les largeurs maximales des colonnes d'un tableau

Paramètres
----------
table: list
Le tableau constitué d'une liste (lignes) de listes
(cellules). Les nombres de cellules pour chaque ligne
être égaux
Retourne
--------
une liste d'entiers correspondant aux largeurs maximales
pour de chacune des colonnes du tableau
Exemple
-------
>>> sample = [
['Id', 'Nom', 'Prénom'],
['1', 'Tiny', 'Toon'],
['2', 'Wile E.', 'Coyote'],
['33', 'Bugs', 'Bunny'],
]
>>> max_lengths(sample)
[2, 7, 6]
"""
nb_lines = len(table)
nb_columns = len(table[0])
max_lengths = []
print('╭', end='')
for col in range(nb_columns):
print('─'*lengths[col], end='')
if not col+1==nb_columns:
print('┬', end='')
print('╮')

if titres:
print('│', end='')
for col, cell in enumerate(tableau[0]):
width = lengths[col]
print(f"{cell: <{width}}", end='│')
print()
print('┝', end='')
for col in range(nb_columns):
print('━'*lengths[col], end='')
if not col+1==nb_columns:
print('┿', end='')
else:
print('┥')
for num_column in range(nb_columns):
column_lengths = []
for line in table:
cell_content = str(line[num_column])
column_lengths.append(len(cell_content))
max_column_length = max(column_lengths)
max_lengths.append(max_column_length)
return max_lengths


def print_cell(text, width, alignment='left', padding=' '):
"""affiche un texte dans une cellule d'une largeur définie

Paramètres
----------
text : str
Le texte à afficher. Si l'argument est d'un type différent, il est
converti en texte à l'aide de str(texte)
width : int
La largeur de la cellule, doit être supérieure ou égale à len(text)
alignement : str, optionel
L'alignement par défaut du texte dans la cellule. Les valeurs valides
sont 'left', 'center' ou 'right'. 'left' par défaut.
padding : str, optionel
Le caractère à utiliser pour remplir les espaces vides de la cellule.
L'espace est utilisé par défaut
Returns
-------
None
La fonction ne retourne rien
Exemple
-------
>>> print_cell('Bob', 20, alignment='center', padding='*')
********Bob*********
"""

# Gestion des arguments invalides
text = str(text)
if (not type(width) == int) or (len(text) > width) :
raise FormatError("'width' doit être un nombre entier valant au moins " \
"la longeur de 'text'")
if not alignment in ['left', 'right', 'center']:
raise FormatError("'alignment' doit être une chaîne choisie parmi " \
"'left', 'center' ou 'right'")
if not type(padding) == str or len(padding) != 1:
raise FormatError("'padding' doit être une chaîne ne contenant qu'un " \
"seul caractère")
empty_spaces = width - len(text)
if alignment == 'left':
print(text + padding * empty_spaces, end="")
elif alignment == 'center':
left_spaces = empty_spaces // 2
right_spaces = empty_spaces - left_spaces
print(left_spaces*padding + text + right_spaces*padding, end="")
else:
print(padding*empty_spaces + text, end="")


def print_row(cells, lengths, left_c='|', middle_c='|', right_c='|'):
"""affiche une ligne de contenu d'un tableau

arguments
---------
cells : list
La liste des contenus à afficher (les cellules)
lenghts : list
Une liste d'entiers, les tailles respectives de chaque cellule
à afficher
left_c, middle_c, right_c : string (optionel)
Chaînes d'un caractère à utiliser comme délimiteurs du tableau
"""
nb_cells = len(cells)
print(left_c, end="")
for num_row in range(nb_cells):
print_cell(cells[num_row], lengths[num_row])
if num_row < nb_cells-1:
print(middle_c, end='')
print(right_c)


def print_table(table):
"""affiche un tableau complet avec titres
arguments
---------
table : list
le tableau à imprimer, sous forme d'une liste de listes,
les lignes du tableau. La liste doit au moins comporter
deux lignes, la liste des titres et une ligne de contenu.
"""
lengths = max_lengths(table)
# Bordure supérieure
border = []
for width in lengths:
border.append('─' * width)
print_row(border, lengths, left_c='╭', middle_c='┬', right_c='╮')
starting_row = 1 if titres else 0
for row in tableau[starting_row:]:
if row:
print('│', end='')
for col, cell in enumerate(row):
width = lengths[col]
print(f"{cell: <{width}}", end='│')
print()
# 1ère ligne du tableau
for line in table[:1]:
print_row(line, lengths)

# Bordure entre titres et lignes
border = []
for width in lengths:
border.append('━' * width)
print_row(border, lengths, left_c='┝', middle_c='┿', right_c='┥')
print('╰', end='')
for col in range(nb_columns):
print('─'*lengths[col], end='')
if not col+1==nb_columns:
print('┴', end='')
print('╯')
# lignes suivantes du tableau
for line in table[1:]:
print_row(line, lengths)

# Bordure inférieure
border = []
for width in lengths:
border.append('─' * width)
print_row(border, lengths, left_c='╰', middle_c='┴', right_c='╯')

# print_table(sample)


Loading…
Cancel
Save