
PROJETS PERSONNELS : Scripting Python
Hello !
Ici je publie des scripts développés avec Python au fur et à mesure de mon apprentissage.
Le script le plus récent sera toujours en tête de page.
Le gestionnaire de listes avec base de données et interface graphique
Refonte du gestionnaire de listes vu précédemment mais cette fois-ci avec une interface graphique. Je voulais faire une sorte de mini chat bot où l’utilisateur choisit ce qu’il veut faire et l’application lui répond.
La prochaine amélioration sera de laisser l’utilisateur créer le type de liste qu’il veut.
Exemple d’exécution :








from lib import *
from PySide6 import QtWidgets, QtCore
from PySide6.QtCore import QTimer
class App(QtWidgets.QWidget):
"""
Application de gestion de listes avec interface graphique.
Attributs:
current_state (str): État actuel de l'application.
current_list (Liste): Liste en cours de gestion.
bdcourses (bool): Indicateur de la base de données des courses.
bdtaches (bool): Indicateur de la base de données des tâches.
liste_de_courses (Liste): Liste des courses.
liste_de_taches (Liste): Liste des tâches.
"""
def __init__(self):
super().__init__()
self.current_state = "initial" # État initial
self.current_list = None # Liste en cours de gestion
self.setWindowTitle("Gestionnaire de listes")
self.setup_ui()
self.setup_css()
self.setup_connections()
self.lancement()
# Déclarez ces variables comme attributs de la classe
self.bdcourses = False
self.bdtaches = False
self.liste_de_courses = None
self.liste_de_taches = None
def setup_ui(self):
"""Configure l'interface utilisateur."""
self.layout = QtWidgets.QVBoxLayout(self)
self.la_cmd = QtWidgets.QLabel()
self.le_user = QtWidgets.QLineEdit()
self.la_cmd.setText("Bienvenue !\n Taper 'ok' pour commencer.")
self.layout.addWidget(self.la_cmd)
self.layout.addWidget(self.le_user)
self.la_cmd.setMinimumWidth(300)
self.la_cmd.setMinimumHeight(400)
def setup_connections(self):
"""Connecte les signaux aux méthodes appropriées."""
self.le_user.returnPressed.connect(self.reponse)
self.le_user.textChanged.connect(self.mettre_a_jour_texte)
def mettre_a_jour_texte(self, texte):
""" Met à jour l'attribut texte_utilisateur à chaque modification """
self.texte_utilisateur = texte.strip().lower()
def setup_css(self):
"""Configure les styles CSS de l'interface."""
self.setStyleSheet("""
background-color: rgb(30, 30, 30);
color: rgb(240, 240, 240);
border: 0;
""")
self.la_cmd.setStyleSheet("color: rgb(255, 255, 255);")
self.le_user.setStyleSheet("background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);")
def mettre_a_jour_interface(self, message, focus=True):
"""Met à jour l'interface utilisateur.
Args:
message (str): Message à afficher.
focus (bool): Indique si le focus doit être remis sur le champ de texte.
"""
self.la_cmd.setText(message)
self.la_cmd.adjustSize()
self.le_user.clear()
if focus:
self.le_user.setFocus()
def gerer_liste(self, liste):
"""Gère la liste sélectionnée par l'utilisateur.
Args:
liste (Liste): Liste à gérer.
"""
tmp = self.affiche_menu()
self.mettre_a_jour_interface(tmp)
self.current_state = "gestion_liste"
def affiche_menu(self):
"""Renvoie le texte du menu d'options."""
actions = [
"Ajouter un élément",
"Retirer un élément",
"Afficher les éléments",
"Vider la liste",
"Revenir au menu principal"
]
return "\n".join([f"{i+1} : {action}" for i, action in enumerate(actions)])
def process_reponse(self, liste):
""" Affiche le 2ème menu et gère la réponse de l'utilisateur.
Args:
liste (Liste): Liste à gérer.
"""
choix_process_reponse = self.texte_utilisateur
print(f"Choix de gestion : {choix_process_reponse}")
if choix_process_reponse == "1":
self.mettre_a_jour_interface("Ajoutez un élément à la liste :")
self.current_state = "ajout_element"
elif choix_process_reponse == "2":
self.mettre_a_jour_interface("Retirez un élément de la liste :")
self.current_state = "retrait_element"
elif choix_process_reponse == "3":
self.afficher_liste(liste)
message = liste.afficher()
self.mettre_a_jour_interface(f"{message}\nAppuyez sur 'Entrée' pour revenir au menu.")
self.current_state = "afficher_liste"
elif choix_process_reponse == "4":
self.vider_liste(liste)
self.mettre_a_jour_interface("La liste a été vidée.\nAppuyez sur 'Entrée' pour revenir au menu.")
self.current_state = "gestion_liste"
elif choix_process_reponse == "5":
self.mettre_a_jour_interface("Retour au menu principal.\n\n Taper 'ok' pour commencer.")
self.current_state = "initial"
else:
# Construire le message d'options à afficher
tmp = self.affiche_menu()
self.mettre_a_jour_interface(f"Option invalide. Réessayez.\n\n{tmp}")
def vider_liste(self, liste):
""" Vide la liste. """
liste.effacer()
def process_ajout(self, liste):
""" Demande à l'utilisateur un élément à ajouter à la liste. """
element_ajout = self.le_user.text().strip() # Récupérer et nettoyer l'entrée utilisateur
if not element_ajout:
self.mettre_a_jour_interface("L'élément à ajouter est vide. Veuillez entrer un élément.")
return # Ne pas continuer tant que l'utilisateur n'a pas saisi quelque chose
# Ajouter l'élément à la liste
liste.ajouter(element_ajout)
message = f"L'élément '{element_ajout}' a bien été ajouté à la liste."
self.mettre_a_jour_interface(message)
self.current_state = "gestion_liste"
# Supprimer tous les anciens signaux pour éviter les doublons
try:
self.le_user.returnPressed.disconnect()
except TypeError:
pass
# Reconnecter pour retourner au menu en appuyant sur Entrée
self.le_user.returnPressed.connect(lambda: self.gerer_element(liste))
def process_retrait(self, liste):
""" Demande à l'utilisateur un élément à retirer de la liste. """
element_a_retirer = self.le_user.text().strip() # Récupérer et nettoyer l'entrée utilisateur
if not element_a_retirer:
self.mettre_a_jour_interface("Veuillez entrer un élément.")
return # Ne pas continuer tant que l'utilisateur n'a pas saisi quelque chose
# Ajouter l'élément à la liste
liste.enlever(element_a_retirer)
message = f"L'élément '{element_a_retirer}' a bien été retirer de la liste."
self.mettre_a_jour_interface(message)
self.current_state = "gestion_liste"
# Supprimer tous les anciens signaux pour éviter les doublons
try:
self.le_user.returnPressed.disconnect()
except TypeError:
pass
# Reconnecter pour retourner au menu en appuyant sur Entrée
self.le_user.returnPressed.connect(lambda: self.gerer_element(liste))
def afficher_liste(self, liste):
"""Affiche la liste dans l'interface
Args:
liste (Liste): Une liste instance de la classe Liste
"""
self.mettre_a_jour_interface(liste.afficher())
def gerer_element(self, liste):
"""Teste si la liste est vide ou non et appelle la méthode gerer_liste
Args:
liste (Liste): Une liste instance de la classe Liste
"""
if liste.taille() == 0:
print("Votre liste est vide.")
else:
print(liste.afficher())
return self.gerer_liste(liste)
def lancement(self):
""" Lance le programme et attend la réponse de l'utilisateur pour naviguer dans les options. """
self.mettre_a_jour_interface("Bienvenue !\n Taper 'ok' pour commencer.")
def reponse(self):
"""Traite la réponse de l'utilisateur et se connecte aux bases de données selon l'état actuel."""
choix_reponse = self.texte_utilisateur
if self.current_state == "initial":
if choix_reponse == "ok" or choix_reponse == "5":
self.mettre_a_jour_interface(
"Que voulez-vous faire ?\n (1) - Gérer ma liste de courses\n (2) - Gérer ma liste de tâches\n (3) - Quitter"
)
self.current_state = "choix_liste"
else:
self.mettre_a_jour_interface("Commande inconnue. Tapez 'ok' pour commencer.")
elif self.current_state == "choix_liste":
if choix_reponse == "1":
try:
conn = sqlite3.connect(DATABASE)
c = conn.cursor()
c.execute("SELECT * FROM courses")
donnees_courses = c.fetchall()
conn.commit()
conn.close()
if donnees_courses:
self.liste_de_courses = Liste("courses")
for row in donnees_courses:
self.liste_de_courses.ajouter(row[0])
self.bdcourses=True
except sqlite3.Error as e:
self.bdcourses = False
# Créer la liste de courses si elle n'existe pas encore
if not self.bdcourses:
self.liste_de_courses = Liste("courses") # Crée une nouvelle liste de courses
self.bdcourses = True # Marquer la liste comme créée
#self.afficher_liste(self.liste_de_courses)
message = self.liste_de_courses.afficher()
self.current_list = self.liste_de_courses
message += f"\nVous avez choisi de gérer votre liste de courses.\nTapez 'Entrer' pour continuer."
self.mettre_a_jour_interface(message)
self.gerer_element(self.liste_de_courses)
elif choix_reponse == "2":
try:
conn = sqlite3.connect(DATABASE)
c = conn.cursor()
c.execute("SELECT * FROM taches")
donnees_taches = c.fetchall()
conn.commit()
conn.close()
if donnees_taches:
self.liste_de_taches = Liste("taches")
for row in donnees_taches:
self.liste_de_taches.ajouter(row[0])
self.bdtaches=True
except:
self.bdtaches = False
# Créer la liste de taches si elle n'existe pas encore
if not self.bdtaches:
self.liste_de_taches = Liste("taches") # Crée une nouvelle liste de taches
self.bdtaches = True # Marquer la liste comme créée
#self.afficher_liste(self.liste_de_courses)
message = self.liste_de_taches.afficher()
message += f"\nVous avez choisi de gérer votre liste de taches.\nTapez 'Entrer' pour continuer."
self.mettre_a_jour_interface(message)
self.current_list = self.liste_de_taches
self.gerer_element(self.liste_de_taches)
elif choix_reponse == "3":
self.mettre_a_jour_interface("Quitter le programme.")
QtCore.QTimer.singleShot(1000, self.close)
else:
self.mettre_a_jour_interface("Choix invalide. Essayez encore.\n\nQue voulez-vous faire ?\n (1) - Gérer ma liste de courses\n (2) - Gérer ma liste de tâches\n (3) - Quitter")
elif self.current_state == "gestion_liste":
self.process_reponse(self.current_list)
elif self.current_state == "ajout_element":
element = self.le_user.text().strip()
if element:
self.current_list.ajouter(element)
self.mettre_a_jour_interface(f"L'élément '{element}' a bien été ajouté.")
self.current_state = "gestion_liste"
self.gerer_liste(self.current_list)
elif self.current_state == "retrait_element":
element = self.le_user.text().strip()
if element:
self.current_list.enlever(element)
self.mettre_a_jour_interface(f"L'élément '{element}' a bien été retiré.")
self.current_state = "gestion_liste"
self.gerer_liste(self.current_list)
elif self.current_state == "afficher_liste":
self.gerer_liste(self.current_list)
app = QtWidgets.QApplication([])
win = App()
win.show()
app.exec()
Le Ciné Club
Un petit gestionnaire de films avec interface graphique. On peut ajouter des films dans une liste stockée dans un fichier json ou supprimer des films de la liste.
Exemple d’exécution :
Fichier movie.py
import os
import json
import logging
CUR_DIR = os.path.dirname(__file__)
DATA_FILE = os.path.join(CUR_DIR, "data", "movies.json")
def get_movies():
with open(DATA_FILE, "r") as f:
movie_list = json.load(f)
return [Movie(movie_title) for movie_title in movie_list]
class Movie(str):
def __init__(self, movie_title):
self.movie_title = movie_title.title()
def __str__(self) -> str:
return self.movie_title
def _getMovies(self):
with open(DATA_FILE, "r") as f:
movie_list = json.load(f)
return movie_list
def _write_movies(self, movies):
with open(DATA_FILE, "w") as f:
json.dump(movies, f, indent = 4)
def add_to_movies(self):
# Récupérer la liste des films
movies = self._getMovies()
# Vérifier que le film n'est pas déjà dans la liste
if self.movie_title not in movies:
# Il n'y est pas, on l'ajoute
movies.append(self.movie_title)
self._write_movies(movies)
return True
else:
# Il y est. On affiche un message
logging.warning(f"{self.movie_title} est déjà dans la liste de films.")
return False
def remove_from_movies(self):
# Récupérer la liste des films
movies = self._getMovies()
# Vérifier si le film est dans la liste
if self.movie_title in movies:
# Si c'est le cas, enlever le film
movies.remove(self.movie_title)
self._write_movies(movies)
from PySide6 import QtWidgets, QtCore
from movie import *
class App(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Ciné Club")
self.setup_ui()
self.setup_css()
self.setup_connections()
self.populate_movies()
def setup_ui(self):
self.layout = QtWidgets.QVBoxLayout(self)
self.lne = QtWidgets.QLineEdit()
self.btn_add = QtWidgets.QPushButton("Ajouter un film")
self.lst = QtWidgets.QListWidget()
self.btn_del = QtWidgets.QPushButton("Supprimer le(s) film(s)")
self.lst.setSelectionMode(QtWidgets.QListWidget.ExtendedSelection)
self.layout.addWidget(self.lne)
self.layout.addWidget(self.btn_add)
self.layout.addWidget(self.lst)
self.layout.addWidget(self.btn_del)
def setup_connections(self):
self.btn_add.clicked.connect(self.add_movie)
self.btn_del.clicked.connect(self.del_movie)
self.lne.returnPressed.connect(self.add_movie)
def setup_css(self):
self.setStyleSheet("""
background-color: rgb(30, 30, 30);
color: rbg(240, 240, 240);
border: 0;
""")
self.lne.setStyleSheet("background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);")
self.btn_add.setStyleSheet("color: rgb(255, 255, 255);")
self.lst.setStyleSheet("background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);")
self.btn_del.setStyleSheet("color: rgb(255, 255, 255);")
def populate_movies(self):
movies = get_movies()
self.lst.addItems([m.movie_title for m in movies])
def add_movie(self):
if self.lne.displayText() != "":
movie = Movie(self.lne.displayText())
if movie.add_to_movies():
self.lst.addItem(movie.movie_title)
self.lst.sortItems()
print(f"Film ajouté : {self.lne.displayText()}")
self.lne.setText("")
return True
else:
self.lne.setText("")
return False
print("Le champ est vide.")
return False
def del_movie(self):
if self.lst.selectedItems():
selected_movies = [i.text() for i in self.lst.selectedItems()]
for m in selected_movies:
movie = Movie(m)
movie.remove_from_movies()
# Recherche l'élément correspondant dans la QListWidget et le supprime
items = self.lst.findItems(m, QtCore.Qt.MatchExactly)
for item in items:
self.lst.takeItem(self.lst.row(item)) # Supprime l'élément de la liste
print(f"Film {movie.movie_title} supprimé")
return True
print("Aucun film n'est seléctionné.")
return False
app = QtWidgets.QApplication([])
win = App()
win.show()
app.exec()
Le convertisseur de devises
Le classique convertisseur de devises qui convertit toutes devises.
Exemple d’exécution
from PySide6 import QtWidgets
import currency_converter
class App(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.c = currency_converter.CurrencyConverter()
self.setWindowTitle("Convertisseur de devises")
self.setup_ui()
self.set_default_values()
self.setup_css()
self.setup_connections()
def setup_ui(self):
self.layout = QtWidgets.QHBoxLayout(self)
self.cbb_devisesFrom = QtWidgets.QComboBox()
self.spn_montant = QtWidgets.QSpinBox()
self.cbb_devisesTo = QtWidgets.QComboBox()
self.spn_montantConverti = QtWidgets.QSpinBox()
self.btn_inverser = QtWidgets.QPushButton("Inverser devises")
self.layout.addWidget(self.cbb_devisesFrom)
self.layout.addWidget(self.spn_montant)
self.layout.addWidget(self.cbb_devisesTo)
self.layout.addWidget(self.spn_montantConverti)
self.layout.addWidget(self.btn_inverser)
self.cbb_devisesFrom.setMinimumHeight(10)
self.cbb_devisesFrom.setMinimumWidth(50)
self.cbb_devisesTo.setMinimumWidth(50)
def set_default_values(self):
self.cbb_devisesFrom.addItems(sorted(list(self.c.currencies)))
self.cbb_devisesTo.addItems(sorted(list(self.c.currencies)))
self.cbb_devisesFrom.setCurrentText("EUR")
self.cbb_devisesTo.setCurrentText("EUR")
self.spn_montant.setRange(1, 1000000000)
self.spn_montantConverti.setRange(1, 1000000000)
self.spn_montant.setValue(100)
self.spn_montantConverti.setValue(100)
def setup_connections(self):
self.cbb_devisesFrom.activated.connect(self.compute)
self.cbb_devisesTo.activated.connect(self.compute)
self.spn_montant.valueChanged.connect(self.compute)
self.btn_inverser.clicked.connect(self.inverser_devises)
def setup_css(self):
self.setStyleSheet("""
background-color: rgb(30, 30, 30);
color: rbg(240, 240, 240);
border: 0;
""")
self.cbb_devisesFrom.setStyleSheet("color: rgb(255, 255, 255);")
self.cbb_devisesTo.setStyleSheet("color: rgb(255, 255, 255);")
self.spn_montant.setStyleSheet("color: rgb(255, 255, 255);")
self.spn_montantConverti.setStyleSheet("color: rgb(255, 255, 255);")
self.btn_inverser.setStyleSheet("color: rgb(255, 255, 255);")
def compute(self):
montant = self.spn_montant.value()
devise_from = self.cbb_devisesFrom.currentText()
devise_to = self.cbb_devisesTo.currentText()
try:
resultat = self.c.convert(montant, devise_from, devise_to)
except currency_converter.currency_converter.RateNotFoundError:
print("La convertion n'a pas fonctionné.")
else:
self.spn_montantConverti.setValue(resultat)
def inverser_devises(self):
devise_from = self.cbb_devisesFrom.currentText()
devise_to = self.cbb_devisesTo.currentText()
self.cbb_devisesFrom.setCurrentText(devise_to)
self.cbb_devisesTo.setCurrentText(devise_from)
self.compute()
app = QtWidgets.QApplication([])
win = App()
win.show()
app.exec()
Un CRM en POO et avec une base de données tinyDB
Un gestionnaire d’utilisateurs aléatoires générés avec le module Faker et sauvegardés dans une base de données tinydb, enregistrée dans un fichier .json.
Exemple d’exécution du programme:
import re
import string
from tinydb import TinyDB, where
from pathlib import Path
class User():
DB = TinyDB(Path(__file__).resolve().parent / 'db.json', indent=4)
def __init__(self, first_name: str, last_name: str, phone_number: str="", adress: str="" ):
self.first_name = first_name
self.last_name = last_name
self.phone_number = phone_number
self.adress = adress
def __repr__(self) -> str:
return f"User({self.first_name}, {self.last_name})"
def __str__(self):
return(f"{self.full_name}\n{self.phone_number}\n{self.adress}")
@property
def full_name(self):
return f"{self.first_name} {self.last_name}"
@property
def db_instance(self):
return User.DB.get((where('first_name') == self.first_name) & (where('last_name') == self.last_name))
def _checks(self):
self._check_names()
self._check_phone_number()
def _check_phone_number(self):
phone_number = re.sub(r"[+()\s]*", "", self.phone_number)
if len(phone_number) < 10 or not phone_number.isdigit():
raise ValueError(f"Numéro de téléphone {self.phone_number} invalide.")
def _check_names(self):
if not self.first_name and self.last_name:
raise ValueError("Le prénom et le nom de famille ne peuvent pas être vide.")
special_characters = string.punctuation + string.digits
for character in self.first_name + self.last_name:
if character in special_characters:
raise ValueError(f"Nom invalide {self.full_name}.")
def exists(self):
return bool(self.db_instance)
def delete(self) -> list[int]:
if self.exists():
return User.DB.remove(doc_ids=[self.db_instance.doc_id])
return []
def save(self, validate_data: bool=False) -> int:
if validate_data:
self._checks()
if self.exists():
return -1
else:
return User.DB.insert(self.__dict__)
def get_all_users():
return [User(**user) for user in User.DB.all()]
if __name__ == "__main__":
from faker import Faker
fake = Faker(locale="fr_FR")
for _ in range(10):
user = User(first_name=fake.first_name(),
last_name=fake.last_name(),
phone_number=fake.phone_number(),
adress=fake.address())
print(user.save())
print(user.__str__())
print("-"*20)
Le gestionnaire de listes en POO
Un gestionnaire de listes qui reprend la base du script de la liste de courses, présentée précédemment.
Pour cet exemple, j’utiliserai la Programmation Orientée Objet en créant mes propres objets de classe Liste() qui hériteront de la classe list(). J’utilise aussi les bases de données SQL avec le module sqlite3 pour enregistrer les listes.
Dans ce programme, on ne gère que 2 systèmes de listes : la liste de courses et la liste de taches. La prochaine étape sera de demander à l’utilisateur le type de listes qu’il souhaite enregistrer.
On commence avec le script de constantes : constants.py
import os
CUR_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(CUR_DIR, "data")
DATABASE = os.path.join(DATA_DIR, "database.db")
import json
import logging
import os
import sqlite3
from constants import *
LOGGER = logging.getLogger()
class Liste(list):
def __init__(self, nom):
self.nom = nom
def sauvegarder(self):
if not os.path.exists(DATA_DIR):
os.makedirs(DATA_DIR)
conn = sqlite3.connect(DATABASE)
table_name = self.nom
c = conn.cursor()
c.execute(f"""
CREATE TABLE IF NOT EXISTS {table_name}
(
element text
)
""")
c.execute(f"DELETE FROM {table_name}")
for el in self:
c.execute(f"INSERT INTO {table_name} (element) VALUES (?)", (el,))
conn.commit()
conn.close()
return True
def ajouter(self, element):
if not isinstance(element, str):
raise ValueError("Vous ne pouvez ajouter que des chaines de caractères!")
if element in self:
LOGGER.error(f"{element} est déjà dans la liste.")
return False
else:
self.append(element)
self.sauvegarder()
return True
def enlever(self, element_a_supprimer):
if element_a_supprimer in self:
self.remove(element_a_supprimer)
table_name = self.nom
conn = sqlite3.connect(DATABASE)
c = conn.cursor()
c.execute(f"DELETE FROM {table_name} WHERE element=?", (element_a_supprimer,))
conn.commit()
conn.close()
return True
return False
def afficher(self):
print(f"\nMa liste de {self.nom} : ")
print("_"*50+"\n")
for element in self:
print(f" - {element}")
print("_"*50+"\n")
return True
def effacer(self):
self.clear()
conn = sqlite3.connect(DATABASE)
table_name = self.nom
c = conn.cursor()
c.execute(f"DELETE FROM {table_name}")
conn.commit()
conn.close()
return True
def taille(self):
return len(self)
from lib import *
actions = [
"Ajouter un élément à la liste",
"Retirer un élément de la liste",
"Afficher les éléments de la liste",
"Vider la liste",
"Revenir au menu principal"
]
valide = False
bdcourses = False
bdtaches = False
def gerer_liste(liste):
choix = 0
element=""
while choix !=5 :
print("\nChoisissez parmi les 5 options suivantes :\n")
for i, element in enumerate(actions):
print(f"{i+1} : {element}")
reponse = input("Votre choix : ")
if reponse.isdigit() :
choix = int(reponse)
else :
print("Vous devez taper un chiffre !\n")
continue
if choix == 1 :
article = input("Que souhaitez-vous ajouter à la liste ? ")
if liste.ajouter(article):
print(f"L'élément '{article}' a bien été ajouté à la liste.\n")
elif choix == 2 :
article = input("Quel élément souhaitez-vous retirer ? ")
if article in liste :
liste.enlever(article)
print(f"L'élément '{article}' a bien été retiré de la liste.\n")
else :
print(f"L'élément '{article}' n'est pas dans la liste.\n")
elif choix == 3 :
liste.afficher()
elif choix == 4 :
liste.effacer()
print("La liste a été vidée.\n")
elif choix == 5:
break
else:
print("Je n'ai pas compris. Veuillez recommencez.\n")
continue
return True
def gerer_element(liste):
if liste.taille() == 0:
print("Votre liste est vide.")
else:
liste.afficher()
return gerer_liste(liste)
while not valide:
reponse = input("Que voulez-vous faire ? \n\t (1) - Gérer ma liste de courses \n\t (2) - Gérer ma liste de taches \n\t (3) - Quitter le programme \n Votre choix : ")
if not reponse.isdigit():
print("\nVous devez saisir un chiffre.\n")
continue
else:
if int(reponse) > 3:
print("\nVous devez saisir un chiffre valide.\n")
else:
try:
conn = sqlite3.connect(DATABASE)
c = conn.cursor()
c.execute("SELECT * FROM courses")
donnees_courses = c.fetchall()
conn.commit()
conn.close()
if donnees_courses:
liste_de_courses = Liste("courses")
for row in donnees_courses:
liste_de_courses.ajouter(row[0])
bdcourses=True
except:
bdcourses = False
try:
conn = sqlite3.connect(DATABASE)
c = conn.cursor()
c.execute("SELECT * FROM taches")
donnees_taches = c.fetchall()
conn.commit()
conn.close()
if donnees_taches:
liste_de_taches = Liste("taches")
for row in donnees_taches:
liste_de_taches.ajouter(row[0])
bdtaches=True
except:
bdtaches = False
if int(reponse) == 1:
if not bdcourses:
liste_de_courses = Liste("courses")
print(f"La liste de {liste_de_courses.nom} est créée.")
gerer_element(liste_de_courses)
elif int(reponse) == 2:
if not bdtaches:
liste_de_taches = Liste("taches")
print(f"La liste de {liste_de_taches.nom} est créée.")
gerer_element(liste_de_taches)
else:
print("Bye ! ")
break
La liste de courses en POO
Refonte du script de la liste de courses (ou autres listes) en programmation orientée objet (POO).
Le fichier principal : lib.py
import json
import logging
import os
from constants import DATA_DIR
LOGGER = logging.getLogger()
class Liste(list):
def __init__(self, nom):
self.nom = nom
def ajouter(self, element):
if not isinstance(element, str):
raise ValueError("Vous ne pouvez ajouter que des chaines de caractères!")
if element in self:
LOGGER.error(f"{element} est déjà dans la liste.")
return False
self.append(element)
return True
def enlever(self, element):
if element in self:
self.remove(element)
return True
return False
def afficher(self):
print(f"Ma liste de {self.nom} : ")
for element in self:
print(f" - {element}")
def sauvegarder(self):
chemin = os.path.join(DATA_DIR, f"{self.nom}.json")
if not os.path.exists(DATA_DIR):
os.makedirs(DATA_DIR)
with open(chemin, "w") as f:
json.dump(self, f, indent=4)
return True
if __name__ == "__main__":
liste = Liste("courses")
liste.ajouter("Pommes")
liste.ajouter("Poires")
liste.afficher()
liste.sauvegarder()
import os
CUR_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(CUR_DIR, "data")
print(DATA_DIR)
La liste de prénoms
Script qui récupère une liste de prénoms à l’intérieur d’un fichier .txt, la nettoie (enlève les points, virgules et espaces superflus), la trie par ordre alphabétique, et la sauvegarde à nouveau dans le fichier.
from pathlib import Path
import os
SOURCE_DIR = Path(__file__).resolve().parent / "prenoms.txt"
liste_prenoms=[]
liste_clean=[]
if os.path.exists(SOURCE_DIR):
with open(SOURCE_DIR, "r") as f:
lines = f.read().splitlines()
for i in lines:
liste_prenoms.extend(i.split())
liste_clean = sorted([prenom.strip(",. ") for prenom in liste_prenoms])
with open(SOURCE_DIR, "w") as f:
f.write("\n".join(liste_clean))
Le trieur de fichiers et dossiers
Un petit script, utilisant le module ‘pathlib’, qui permet de faire du tri dans le dossier ‘Téléchargements’ de Windows, en créant des sous-dossiers en fonctions du type de fichiers présents (Images, Documents, Vidéos, etc), dans un unique dossier nommé ‘DATA’.
from pathlib import Path
SOURCE_FILE =Path(r"C:\Users\***\Downloads") #remplacer *** par le nom utilisateur sur windows
DATA_DIR = SOURCE_FILE / "DATA"
DATA_DIR.mkdir(exist_ok=True)
dirs = {".png": "Images",
".jpg": "Images",
".jpeg": "Images",
".gif": "Images",
".wav": "Music",
".m4a": "Music",
".mp4": "Videos",
".mov": "Videos",
".zip": "Archives",
".rar": "Archives",
".pdf": "Documents",
".txt": "Documents",
".json": "Documents",
".pptx": "Documents",
".nk": "Compositing",
".gizmo": "Compositing",
".exe": "Programs",
".msi": "Programs"}
folders_list = [f for f in SOURCE_FILE.iterdir() if f.is_dir() and f != DATA_DIR]
files_list = [f for f in SOURCE_FILE.iterdir() if f.is_file()]
for f in files_list:
output_dir = DATA_DIR / dirs.get(f.suffix, "Autres")
output_dir.mkdir(exist_ok=True)
f.rename(output_dir / f.name)
for d in folders_list:
output_dir = DATA_DIR / "FOLDERS"
output_dir.mkdir(exist_ok=True)
d.rename(output_dir / d.name)
La liste de courses avec sauvegarde dans un fichier
Le même programme que ‘La liste de courses’ précédemment mais augmenté avec la gestion de fichier JSON
import sys
import json
import os
cur_dir = os.path.dirname(__file__)
chemin = cur_dir+r"\liste_de_courses.json"
if os.path.exists(chemin):
with open(chemin,"r") as f:
liste_de_course = json.load(f)
pass
else:
liste_de_course=[]
actions = [
"Ajouter un élément à la liste de courses",
"Retirer un élément de la liste de courses",
"Afficher les éléments de la liste de courses",
"Vider la liste de courses",
"Quitter le programme"
]
choix = 0
article=""
while choix !=5 :
print("Choisissez parmi les 5 options suivantes :")
for i, element in enumerate(actions):
print(f"{i+1} : {element}")
reponse = input("Votre choix : ")
if reponse.isdigit() :
choix = int(reponse)
else :
print("Vous devez taper un chiffre !\n")
continue
if choix == 1 :
article = input("Que souhaitez-vous ajouter à la liste ? ")
liste_de_course.append(article)
print(f"L'article '{article}' a bien été ajouté à la liste.\n")
elif choix == 2 :
article = input("Quel article souhaitez-vous retirer ? ")
if article in liste_de_course :
liste_de_course.remove(article)
print(f"L'article '{article}' a bien été retiré de la liste.\n")
else :
print(f"L'article '{article}' n'est pas dans la liste.\n")
elif choix == 3 :
print("Voici le contenu de la liste :\n")
for i, element in enumerate(liste_de_course):
print(f"{i+1}. {element}")
print("__________________________________________\n")
elif choix == 4 :
liste_de_course.clear()
print("La liste de courses a été vidée.\n")
else :
if choix != 5:
print("Je n'ai pas compris. Veuillez recommencez.\n")
with open(chemin, "w") as f:
json.dump(liste_de_course, f, ensure_ascii = False, indent = 4)
pass
print("La liste de courses a été sauvegardée ! ")
print("A bientôt !")
sys.exit
Le jeu de rôle
Une simulation de jeu de rôle style années 80. L’utilisateur se bat contre l’ordi, avec 50 points de vie chacun. A chaque tour, l’utilisateur choisit soit d’attaquer, soit de boire une potion pour récupérer des points de vie. Le premier qui arrive à zéro a perdu.
import random
#Déclaration des constantes
user_lives = 50
ennemy_lives = 50
user_potions = 3
#Message de bienvenue
print("-"*50+"\n")
print("*** Bienvenue dans le jeu de role ! ***")
print("-"*50+"\n")
#Boucle
while user_lives > 0 and ennemy_lives > 0:
action = input("Souhaitez-vous attaquer (1) ou utiliser une potion (2) ? ")
if not action.isdigit():
print("Vous devez saisir un nombre.")
continue
elif int(action) > 2:
print("Vous devez saisir un nombre entre 1 et 2.")
continue
else:
if int(action) == 1:
#Choix de l'attaque
ennemy_lost = random.randint(5,11)
ennemy_lives-=ennemy_lost
print(f"L'ennemi a perdu {ennemy_lost} points de vie et est maintenant à {ennemy_lives} points de vie.")
else:
#Choix de la potion
potion = random.randint(15,51)
user_lives+=potion
user_potions-=1
print(f"Vous prenez un potion. Vous récupérez {potion} points de vie.")
print(f"Il vous reste {user_potions} potions et {user_lives} points de vie.")
print("Vous passez votre tour...")
#Dans tous les cas, l'ennemi attaque
user_lost=random.randint(5,16)
user_lives-=user_lost
print(f"L'ennemi vous attaque. Vous perdez {user_lost} points de vie.\nVous avez maintenant {user_lives} points de vie.")
#L'un des deux joueurs a perdu
#On teste qui a perdu
if user_lives <= 0:
print("\nVous avez perdu !")
elif ennemy_lives <= 0:
print("\nVous avez gagné !")
Le nombre mystère
Un programme simple, à exécuter dans un terminal, qui implémente le jeu du nombre mystère. Un nombre est choisi aléatoirement, entre 0 et 100, et l’utilisateur à 5 essais pour trouver le nombre choisi.
import random
import sys
essais = 5
nombre_mystere = random.randint(0,101)
nombre_propose = 0
print("-"*50)
print("*** Le jeu du nombre mystère ***")
print("Tu dois trouver un nombre entre 0 et 100.")
print("-"*50)
while essais > 0:
print(f"Il te reste {essais} essais")
nombre_propose = input("Devine le nombre : ")
if not nombre_propose.isdigit():
print("Il faut entrer un nombre valide.")
continue
else:
nombre_propose=int(nombre_propose)
if nombre_propose == nombre_mystere:
print(f"Bravo ! Tu as gagné en {5-essais} essais ! Le nombre mystère est bien {nombre_mystere}.")
print("Le jeu est terminé.")
sys.exit()
else:
if nombre_propose < nombre_mystere:
print(f"Le nombre mystère est plus grand que {nombre_propose}")
else:
print(f"Le nombre mystère est plus petit que {nombre_propose}")
essais -= 1
continue
print("-"*50)
print(f"Tu as perdu ! Le nombre mystère était {nombre_mystere}.")
La liste de courses
Un petit programme, à exécuter dans un terminal, qui permet de simuler la gestion d’une liste de courses.
On peut ajouter un article, le retirer, afficher la liste ou vider la liste.
import sys
actions = [
"Ajouter un élément à la liste de courses",
"Retirer un élément de la liste de courses",
"Afficher les éléments de la liste de courses",
"Vider la liste de courses",
"Quitter le programme"
]
choix = 0
liste_de_course=[]
article=""
while choix !=5 :
print("Choisissez parmi les 5 options suivantes :")
for i, element in enumerate(actions):
print(f"{i+1} : {element}")
reponse = input("Votre choix : ")
if reponse.isdigit() :
choix = int(reponse)
else :
print("Vous devez taper un chiffre !\n")
continue
if choix == 1 :
article = input("Que souhaitez-vous ajouter à la liste ? ")
liste_de_course.append(article)
print(f"L'article '{article}' a bien été ajouté à la liste.\n")
elif choix == 2 :
article = input("Quel article souhaitez-vous retirer ? ")
if article in liste_de_course :
liste_de_course.remove(article)
print(f"L'article '{article}' a bien été retiré de la liste.\n")
else :
print(f"L'article '{article}' n'est pas dans la liste.\n")
elif choix == 3 :
print("Voici le contenu de la liste :\n")
for i, element in enumerate(liste_de_course):
print(f"{i+1}. {element}")
print("-"*50+"\n")
elif choix == 4 :
liste_de_course.clear
print("La liste de courses a été vidée.\n")
else :
if choix != 5:
print("Je n'ai pas compris. Veuillez recommencez.\n")
print("A bientôt !")
sys.exit
Nicolas MARIE © 2025
A bientôt ! 😉