0 XP
?
Python : de zéro à la maîtrise/Projet final : Calculatrice et gestionnaire de tâches
Intermédiaire120 min80 XP

Objectifs de cette leçon

  • Construire une calculatrice CLI complète
  • Créer un gestionnaire de tâches avec fichiers
  • Combiner toutes les notions apprises

Projet final : Application de gestion de bibliotheque 📚

Objectif du projet 🎯

Cree une application console en Python qui gere une bibliotheque avec :

  • Des livres (titre, auteur, ISBN, disponibilite)
  • Des emprunts et retours
  • Une recherche de livres
  • Des statistiques

Ce projet utilise toutes les competences des lecons precedentes !


Architecture du projet 🏗️

bibliotheque/
├── main.py              # Point d'entree
├── livre.py             # Classe Livre
├── bibliothecaire.py    # Classe Bibliothecaire (gestion des livres)
├── utils.py             # Fonctions utilitaires
└── data.json            # Sauvegarde des donnees

Etape 1 : Creer la classe Livre 📖

# livre.py

class Livre:
    def __init__(self, titre, auteur, isbn):
        self.titre = titre
        self.auteur = auteur
        self.isbn = isbn
        self.disponible = True
        self.emprunte_par = None
        self.date_emprunt = None

    def emprunter(self, nom_emprunteur):
        if not self.disponible:
            return False, f"'{self.titre}' n'est pas disponible"
        self.disponible = False
        self.emprunte_par = nom_emprunteur
        from datetime import datetime
        self.date_emprunt = datetime.now().strftime("%d/%m/%Y")
        return True, f"'{self.titre}' emprunte par {nom_emprunteur}"

    def retourner(self):
        if self.disponible:
            return False, f"'{self.titre}' n'a pas ete emprunte"
        emprunteur = self.emprunte_par
        self.disponible = True
        self.emprunte_par = None
        self.date_emprunt = None
        return True, f"'{self.titre}' retourne par {emprunteur}"

    def to_dict(self):
        return {
            "titre": self.titre,
            "auteur": self.auteur,
            "isbn": self.isbn,
            "disponible": self.disponible,
            "emprunte_par": self.emprunte_par,
            "date_emprunt": self.date_emprunt,
        }

    @classmethod
    def from_dict(cls, data):
        livre = cls(data["titre"], data["auteur"], data["isbn"])
        livre.disponible = data.get("disponible", True)
        livre.emprunte_par = data.get("emprunte_par")
        livre.date_emprunt = data.get("date_emprunt")
        return livre

    def __str__(self):
        statut = "✅ Disponible" if self.disponible else f"❌ Emprunte par {self.emprunte_par}"
        return f"📖 {self.titre} — {self.auteur} [{self.isbn}] {statut}"

    def __repr__(self):
        return f"Livre('{self.titre}', '{self.auteur}', '{self.isbn}')"

Etape 2 : Creer la classe Bibliothecaire 📋

# bibliothecaire.py

import json
from livre import Livre

class Bibliothecaire:
    def __init__(self, nom="Bibliotheque Centrale"):
        self.nom = nom
        self.livres = []
        self.charger()

    def ajouter_livre(self, titre, auteur, isbn):
        for livre in self.livres:
            if livre.isbn == isbn:
                return False, "Ce livre existe deja (ISBN duplique)"
        nouveau = Livre(titre, auteur, isbn)
        self.livres.append(nouveau)
        self.sauvegarder()
        return True, f"'{titre}' ajoute avec succes"

    def supprimer_livre(self, isbn):
        for i, livre in enumerate(self.livres):
            if livre.isbn == isbn:
                titre = livre.titre
                if not livre.disponible:
                    return False, "Impossible de supprimer un livre emprunte"
                del self.livres[i]
                self.sauvegarder()
                return True, f"'{titre}' supprime"
        return False, "Livre introuvable"

    def rechercher(self, terme):
        terme_lower = terme.lower()
        resultats = [
            l for l in self.livres
            if terme_lower in l.titre.lower()
            or terme_lower in l.auteur.lower()
            or terme_lower in l.isbn
        ]
        return resultats

    def emprunter(self, isbn, nom):
        for livre in self.livres:
            if livre.isbn == isbn:
                succes, msg = livre.emprunter(nom)
                if succes:
                    self.sauvegarder()
                return succes, msg
        return False, "Livre introuvable"

    def retourner(self, isbn):
        for livre in self.livres:
            if livre.isbn == isbn:
                succes, msg = livre.retourner()
                if succes:
                    self.sauvegarder()
                return succes, msg
        return False, "Livre introuvable"

    def statistiques(self):
        total = len(self.livres)
        disponibles = sum(1 for l in self.livres if l.disponible)
        empruntes = total - disponibles
        auteurs = set(l.auteur for l in self.livres)
        return {
            "total": total,
            "disponibles": disponibles,
            "empruntes": empruntes,
            "auteurs_uniques": len(auteurs),
            "taux_emprunt": f"{empruntes/total*100:.1f}%" if total > 0 else "0%",
        }

    def sauvegarder(self):
        data = [l.to_dict() for l in self.livres]
        with open("data.json", "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2, ensure_ascii=False)

    def charger(self):
        try:
            with open("data.json", "r", encoding="utf-8") as f:
                data = json.load(f)
                self.livres = [Livre.from_dict(d) for d in data]
        except (FileNotFoundError, json.JSONDecodeError):
            self.livres = []

Etape 3 : Creer le menu principal 🎮

# main.py

from bibliothecaire import Bibliothecaire

def afficher_menu():
    print("\n" + "=" * 40)
    print("📚 BIBLIOTHEQUE")
    print("=" * 40)
    print("1. 📖 Afficher tous les livres")
    print("2. 🔍 Rechercher un livre")
    print("3. ➕ Ajouter un livre")
    print("4. 🗑️  Supprimer un livre")
    print("5. 📥 Emprunter un livre")
    print("6. 📤 Retourner un livre")
    print("7. 📊 Statistiques")
    print("8. 💾 Sauvegarder")
    print("0. 🚪 Quitter")
    print("=" * 40)

def main():
    biblio = Bibliothecaire("Ma Bibliotheque")

    while True:
        afficher_menu()
        choix = input("\nVotre choix : ").strip()

        if choix == "1":
            print("\n📚 Liste des livres :")
            if not biblio.livres:
                print("  Aucun livre enregistre")
            for livre in biblio.livres:
                print(f"  {livre}")

        elif choix == "2":
            terme = input("Terme de recherche : ")
            resultats = biblio.rechercher(terme)
            print(f"\n🔍 {len(resultats)} resultat(s) :")
            for l in resultats:
                print(f"  {l}")

        elif choix == "3":
            titre = input("Titre : ")
            auteur = input("Auteur : ")
            isbn = input("ISBN : ")
            succes, msg = biblio.ajouter_livre(titre, auteur, isbn)
            print(f"{'✅' if succes else '❌'} {msg}")

        elif choix == "4":
            isbn = input("ISBN du livre a supprimer : ")
            succes, msg = biblio.supprimer_livre(isbn)
            print(f"{'✅' if succes else '❌'} {msg}")

        elif choix == "5":
            isbn = input("ISBN du livre a emprunter : ")
            nom = input("Votre nom : ")
            succes, msg = biblio.emprunter(isbn, nom)
            print(f"{'✅' if succes else '❌'} {msg}")

        elif choix == "6":
            isbn = input("ISBN du livre a retourner : ")
            succes, msg = biblio.retourner(isbn)
            print(f"{'✅' if succes else '❌'} {msg}")

        elif choix == "7":
            stats = biblio.statistiques()
            print("\n📊 Statistiques :")
            for cle, val in stats.items():
                print(f"  {cle.replace('_', ' ').title()} : {val}")

        elif choix == "8":
            biblio.sauvegarder()
            print("✅ Donnees sauvegardees !")

        elif choix == "0":
            biblio.sauvegarder()
            print("👋 Au revoir !")
            break

        else:
            print("❌ Choix invalide")

if __name__ == "__main__":
    main()

Etape 4 : Ameliorations possibles 🚀

Ajouter la validation des entrees

def demander_entier(message):
    while True:
        try:
            return int(input(message))
        except ValueError:
            print("Veuillez entrer un nombre")

def demander_non_vide(message):
    while True:
        valeur = input(message).strip()
        if valeur:
            return valeur
        print("Ce champ ne peut pas etre vide")

Ajouter des couleurs au terminal

class Couleurs:
    VERT = "\033[92m"
    ROUGE = "\033[91m"
    BLEU = "\033[94m"
    JAUNE = "\033[93m"
    FIN = "\033[0m"

def afficher_succes(msg):
    print(f"{Couleurs.VERT}✅ {msg}{Couleurs.FIN}")

def afficher_erreur(msg):
    print(f"{Couleurs.ROUGE}❌ {msg}{Couleurs.FIN}")

Conseils pour reussir 💡

  1. Code par etapes : commence par la classe Livre, teste-la, puis passe a Bibliothecaire
  2. Teste chaque fonction avant de passer a la suivante
  3. Gere les erreurs avec try/except pour chaque action utilisateur
  4. Sauvegarde souvent les donnees dans data.json
  5. Commente ton code pour qu'il soit lisible

🎯 Ce projet te fait pratiquer :

  • ✅ Classes et objets (POO)
  • ✅ Gestion d'erreurs (exceptions)
  • ✅ Manipulation de fichiers (JSON)
  • ✅ Boucles et conditions
  • ✅ Fonctions et arguments
  • ✅ Listes et dictionnaires

🚀 Felicitations ! Tu as termine le parcours Python ! Tu maitrises maintenant les bases solides pour creer n'importe quel programme. Continue a pratiquer et a creer des projets ! 🎉

⚡ Simulateur — Projet : Calculatrice

Étape 1/10
📝 Pseudo-code
1def calculer(a, b, op):
2 if op == "+":
3 return a + b
4 elif op == "-":
5 return a - b
6 elif op == "*":
7 return a * b
8 elif op == "/":
9 return a / b
10
11print(calculer(10, 5, "+"))
12print(calculer(10, 5, "-"))
⚙️ Exécution
📦 Mémoire
Aucune variable
🔀 Flux d'exécution
def calculer()
3
Définition de la fonction

La fonction calculer prend deux nombres et un opérateur. Elle retourne le résultat de l'opération correspondante.