Fiche d'exercices : Rappels de Première
Navigation par thèmes
Exercice 1 : Calculatrice personnelle
Créez un programme qui :
- Demande le nom de l'utilisateur
- Demande deux nombres
- Effectue les quatre opérations de base
- Affiche les résultats avec un message personnalisé
Exemple : "Bonjour Alice ! 5 + 3 = 8"
Exercice 2 : Convertisseur d'unités
Écrivez un programme qui convertit :
- Des mètres en pieds et pouces
- Des kilogrammes en livres
- Des degrés Celsius en Fahrenheit
Le programme doit demander le type de conversion et la valeur à convertir.
Exercice 3 : Validateur de données
Créez un programme qui valide :
- Un âge (entre 0 et 120)
- Un email (contient @ et .)
- Un mot de passe (au moins 8 caractères)
- Un numéro de téléphone (10 chiffres)
Utilisez des variables booléennes pour stocker les résultats de validation.
Exercice 4 : Système de notes
Créez un programme qui :
- Demande une note sur 20
- Affiche la mention correspondante
- Indique si l'élève est admis (≥ 10)
- Propose de saisir une nouvelle note
Mentions : Très bien (≥16), Bien (≥14), Assez bien (≥12), Passable (≥10)
Exercice 5 : Tables de multiplication
Écrivez un programme qui :
- Demande un nombre à l'utilisateur
- Affiche sa table de multiplication (1 à 10)
- Utilise une boucle for
- Formate joliment l'affichage
Bonus : Permettre de choisir la limite (au lieu de 10)
Exercice 6 : Jeu de devinette amélioré
Créez un jeu qui :
- Génère un nombre aléatoire entre 1 et 100
- Donne des indices (trop grand/petit)
- Compte le nombre d'essais
- Propose différents niveaux de difficulté
- Permet de rejouer
Exercice 7 : Motifs géométriques
Créez des programmes qui dessinent :
- Un triangle d'étoiles de taille variable
- Un carré creux avec des bordures
- Un losange centré
- Une pyramide inversée
La taille doit être paramétrable par l'utilisateur.
Exercice 8 : Bibliothèque mathématique
Créez des fonctions pour :
aire_cercle(rayon)
: calcule l'aire d'un cercleperimetre_rectangle(longueur, largeur)
moyenne(a, b, c)
: moyenne de trois nombresest_pair(nombre)
: retourne True si pair
Testez chaque fonction avec plusieurs exemples.
Exercice 9 : Générateur de mots de passe
Créez une fonction qui génère un mot de passe :
- Longueur paramétrable
- Inclut lettres, chiffres et symboles
- Option pour exclure les caractères ambigus
- Fonction de validation de la force
Exercice 10 : Calculatrice scientifique
Développez un programme avec des fonctions pour :
- Opérations de base (+, -, *, /)
- Puissance et racine carrée
- Fonctions trigonométriques
- Menu interactif
- Historique des calculs
Exercice 11 : Gestionnaire de notes
Créez un programme qui :
- Stocke les notes d'un élève dans une liste
- Calcule la moyenne
- Trouve la meilleure et la pire note
- Compte les notes au-dessus de la moyenne
- Permet d'ajouter/supprimer des notes
Exercice 12 : Tri et recherche
Implémentez :
- Tri par sélection (sans utiliser sort())
- Recherche linéaire
- Suppression des doublons
- Fusion de deux listes triées
Testez avec des listes de nombres et de chaînes.
Exercice 13 : Jeu du pendu
Développez un jeu du pendu avec :
- Liste de mots prédéfinis
- Affichage du mot avec des tirets
- Gestion des lettres déjà proposées
- Compteur d'erreurs avec limite
- Interface utilisateur claire
Exercice 14 : Matrices et opérations
Travaillez avec des matrices (listes de listes) :
- Addition et soustraction de matrices
- Multiplication par un scalaire
- Transposition
- Vérification de symétrie
- Calcul du déterminant (2x2)
Projet 1 : Carnet d'adresses
Développez un carnet d'adresses complet :
- Ajouter/modifier/supprimer des contacts
- Recherche par nom ou téléphone
- Tri alphabétique
- Sauvegarde dans un fichier texte
- Interface menu avec options
Compétences : Listes, fonctions, fichiers, validation
Projet 2 : Jeu de bataille navale
Créez une bataille navale simplifiée :
- Grille 10x10 avec coordonnées
- Placement aléatoire des navires
- Système de tir avec feedback
- Compteur de coups et de navires coulés
- Affichage de la grille mise à jour
Compétences : Matrices, boucles, conditions, fonctions
Projet 3 : Gestionnaire de bibliothèque
Système de gestion pour une petite bibliothèque :
- Base de données de livres (titre, auteur, ISBN)
- Système d'emprunt et de retour
- Recherche multicritères
- Statistiques (livres les plus empruntés)
- Gestion des retards
Compétences : Structures de données, algorithmes, validation
Solution : Calculatrice personnelle
nom = input("Quel est votre nom ? ")
nombre1 = float(input("Premier nombre : "))
nombre2 = float(input("Deuxième nombre : "))
addition = nombre1 + nombre2
soustraction = nombre1 - nombre2
multiplication = nombre1 * nombre2
division = nombre1 / nombre2 if nombre2 != 0 else "Division par zéro!"
print(f"Bonjour {nom} !")
print(f"{nombre1} + {nombre2} = {addition}")
print(f"{nombre1} - {nombre2} = {soustraction}")
print(f"{nombre1} × {nombre2} = {multiplication}")
print(f"{nombre1} ÷ {nombre2} = {division}")
Solution : Système de notes
while True:
note = float(input("Entrez une note sur 20 : "))
if note >= 16:
mention = "Très bien"
elif note >= 14:
mention = "Bien"
elif note >= 12:
mention = "Assez bien"
elif note >= 10:
mention = "Passable"
else:
mention = "Insuffisant"
if note >= 10:
resultat = "Admis"
else:
resultat = "Refusé"
print(f"Note : {note}/20")
print(f"Mention : {mention}")
print(f"Résultat : {resultat}")
continuer = input("Nouvelle note ? (o/n) : ")
if continuer.lower() != 'o':
break
Solution : Bibliothèque mathématique
import math
def aire_cercle(rayon):
return math.pi * rayon ** 2
def perimetre_rectangle(longueur, largeur):
return 2 * (longueur + largeur)
def moyenne(a, b, c):
return (a + b + c) / 3
def est_pair(nombre):
return nombre % 2 == 0
# Tests
print(f"Aire cercle (r=5) : {aire_cercle(5):.2f}")
print(f"Périmètre rectangle (3x4) : {perimetre_rectangle(3, 4)}")
print(f"Moyenne (10,15,20) : {moyenne(10, 15, 20)}")
print(f"8 est pair : {est_pair(8)}")
print(f"7 est pair : {est_pair(7)}")
Solution : Gestionnaire de notes
notes = []
def ajouter_note():
note = float(input("Nouvelle note : "))
notes.append(note)
print(f"Note {note} ajoutée.")
def supprimer_note():
if notes:
print(f"Notes actuelles : {notes}")
index = int(input("Index à supprimer : "))
if 0 <= index < len(notes):
note_supprimee = notes.pop(index)
print(f"Note {note_supprimee} supprimée.")
else:
print("Index invalide.")
else:
print("Aucune note à supprimer.")
def calculer_statistiques():
if not notes:
print("Aucune note enregistrée.")
return
moyenne = sum(notes) / len(notes)
meilleure = max(notes)
pire = min(notes)
au_dessus_moyenne = len([n for n in notes if n > moyenne])
print(f"Moyenne : {moyenne:.2f}")
print(f"Meilleure note : {meilleure}")
print(f"Pire note : {pire}")
print(f"Notes au-dessus de la moyenne : {au_dessus_moyenne}")
# Menu principal
while True:
print("\n1. Ajouter note")
print("2. Supprimer note")
print("3. Statistiques")
print("4. Quitter")
choix = input("Votre choix : ")
if choix == '1':
ajouter_note()
elif choix == '2':
supprimer_note()
elif choix == '3':
calculer_statistiques()
elif choix == '4':
break
else:
print("Choix invalide.")
Solution : Tri et recherche
def tri_selection(liste):
"""Tri par sélection"""
n = len(liste)
for i in range(n):
min_index = i
for j in range(i + 1, n):
if liste[j] < liste[min_index]:
min_index = j
liste[i], liste[min_index] = liste[min_index], liste[i]
return liste
def recherche_lineaire(liste, element):
"""Recherche linéaire"""
for i, valeur in enumerate(liste):
if valeur == element:
return i
return -1
def supprimer_doublons(liste):
"""Supprime les doublons en gardant l'ordre"""
resultat = []
for element in liste:
if element not in resultat:
resultat.append(element)
return resultat
def fusionner_listes_triees(liste1, liste2):
"""Fusionne deux listes triées"""
resultat = []
i, j = 0, 0
while i < len(liste1) and j < len(liste2):
if liste1[i] <= liste2[j]:
resultat.append(liste1[i])
i += 1
else:
resultat.append(liste2[j])
j += 1
# Ajouter les éléments restants
resultat.extend(liste1[i:])
resultat.extend(liste2[j:])
return resultat
# Tests
nombres = [64, 34, 25, 12, 22, 11, 90]
print(f"Liste originale : {nombres}")
print(f"Liste triée : {tri_selection(nombres.copy())}")
print(f"Position de 25 : {recherche_lineaire(nombres, 25)}")
liste_doublons = [1, 2, 2, 3, 4, 4, 5]
print(f"Sans doublons : {supprimer_doublons(liste_doublons)}")
liste1 = [1, 3, 5, 7]
liste2 = [2, 4, 6, 8]
print(f"Fusion : {fusionner_listes_triees(liste1, liste2)}")
Solution : Jeu du pendu
import random
def jeu_pendu():
mots = ["python", "programmation", "ordinateur", "algorithme",
"fonction", "variable", "boucle", "condition"]
mot_secret = random.choice(mots).upper()
lettres_trouvees = set()
lettres_essayees = set()
erreurs = 0
max_erreurs = 6
print("=== JEU DU PENDU ===")
print(f"Le mot contient {len(mot_secret)} lettres.")
while erreurs < max_erreurs:
# Affichage du mot avec les lettres trouvées
mot_affiche = ""
for lettre in mot_secret:
if lettre in lettres_trouvees:
mot_affiche += lettre + " "
else:
mot_affiche += "_ "
print(f"\nMot : {mot_affiche}")
print(f"Lettres essayées : {', '.join(sorted(lettres_essayees))}")
print(f"Erreurs : {erreurs}/{max_erreurs}")
# Vérifier si le mot est trouvé
if set(mot_secret) <= lettres_trouvees:
print(f"\n🎉 Félicitations ! Vous avez trouvé le mot : {mot_secret}")
break
# Demander une lettre
lettre = input("Proposez une lettre : ").upper()
if len(lettre) != 1 or not lettre.isalpha():
print("Veuillez entrer une seule lettre.")
continue
if lettre in lettres_essayees:
print("Vous avez déjà essayé cette lettre.")
continue
lettres_essayees.add(lettre)
if lettre in mot_secret:
lettres_trouvees.add(lettre)
print(f"✓ Bonne lettre !")
else:
erreurs += 1
print(f"✗ Lettre incorrecte.")
if erreurs >= max_erreurs:
print(f"\n💀 Perdu ! Le mot était : {mot_secret}")
rejouer = input("\nVoulez-vous rejouer ? (o/n) : ")
if rejouer.lower() == 'o':
jeu_pendu()
# Lancer le jeu
jeu_pendu()
Solution : Matrices et opérations
def creer_matrice(lignes, colonnes, valeur=0):
"""Crée une matrice remplie d'une valeur"""
return [[valeur for _ in range(colonnes)] for _ in range(lignes)]
def afficher_matrice(matrice):
"""Affiche une matrice de façon lisible"""
for ligne in matrice:
print(" ".join(f"{x:4}" for x in ligne))
print()
def additionner_matrices(mat1, mat2):
"""Addition de deux matrices"""
if len(mat1) != len(mat2) or len(mat1[0]) != len(mat2[0]):
return None
resultat = []
for i in range(len(mat1)):
ligne = []
for j in range(len(mat1[0])):
ligne.append(mat1[i][j] + mat2[i][j])
resultat.append(ligne)
return resultat
def multiplier_par_scalaire(matrice, scalaire):
"""Multiplication par un scalaire"""
resultat = []
for ligne in matrice:
nouvelle_ligne = [element * scalaire for element in ligne]
resultat.append(nouvelle_ligne)
return resultat
def transposer(matrice):
"""Transposition d'une matrice"""
lignes = len(matrice)
colonnes = len(matrice[0])
resultat = creer_matrice(colonnes, lignes)
for i in range(lignes):
for j in range(colonnes):
resultat[j][i] = matrice[i][j]
return resultat
def est_symetrique(matrice):
"""Vérifie si une matrice est symétrique"""
if len(matrice) != len(matrice[0]):
return False
for i in range(len(matrice)):
for j in range(len(matrice)):
if matrice[i][j] != matrice[j][i]:
return False
return True
def determinant_2x2(matrice):
"""Calcule le déterminant d'une matrice 2x2"""
if len(matrice) != 2 or len(matrice[0]) != 2:
return None
return matrice[0][0] * matrice[1][1] - matrice[0][1] * matrice[1][0]
# Tests
mat1 = [[1, 2], [3, 4]]
mat2 = [[5, 6], [7, 8]]
print("Matrice 1 :")
afficher_matrice(mat1)
print("Matrice 2 :")
afficher_matrice(mat2)
print("Addition :")
afficher_matrice(additionner_matrices(mat1, mat2))
print("Multiplication par 3 :")
afficher_matrice(multiplier_par_scalaire(mat1, 3))
print("Transposée de mat1 :")
afficher_matrice(transposer(mat1))
print(f"mat1 est symétrique : {est_symetrique(mat1)}")
print(f"Déterminant de mat1 : {determinant_2x2(mat1)}")
Solution : Carnet d'adresses
import json
import os
class CarnetAdresses:
def __init__(self, fichier="contacts.json"):
self.fichier = fichier
self.contacts = self.charger_contacts()
def charger_contacts(self):
"""Charge les contacts depuis le fichier"""
if os.path.exists(self.fichier):
try:
with open(self.fichier, 'r', encoding='utf-8') as f:
return json.load(f)
except:
return []
return []
def sauvegarder_contacts(self):
"""Sauvegarde les contacts dans le fichier"""
with open(self.fichier, 'w', encoding='utf-8') as f:
json.dump(self.contacts, f, indent=2, ensure_ascii=False)
def ajouter_contact(self):
"""Ajoute un nouveau contact"""
nom = input("Nom : ").strip()
if not nom:
print("Le nom est obligatoire.")
return
telephone = input("Téléphone : ").strip()
email = input("Email : ").strip()
adresse = input("Adresse : ").strip()
contact = {
"nom": nom,
"telephone": telephone,
"email": email,
"adresse": adresse
}
self.contacts.append(contact)
self.sauvegarder_contacts()
print(f"Contact {nom} ajouté avec succès.")
def afficher_contacts(self):
"""Affiche tous les contacts"""
if not self.contacts:
print("Aucun contact enregistré.")
return
contacts_tries = sorted(self.contacts, key=lambda x: x['nom'].lower())
print("\n=== CARNET D'ADRESSES ===")
for i, contact in enumerate(contacts_tries, 1):
print(f"{i}. {contact['nom']}")
if contact['telephone']:
print(f" 📞 {contact['telephone']}")
if contact['email']:
print(f" 📧 {contact['email']}")
if contact['adresse']:
print(f" 🏠 {contact['adresse']}")
print()
def rechercher_contact(self):
"""Recherche un contact"""
terme = input("Rechercher (nom ou téléphone) : ").strip().lower()
if not terme:
return
resultats = []
for contact in self.contacts:
if (terme in contact['nom'].lower() or
terme in contact['telephone']):
resultats.append(contact)
if resultats:
print(f"\n{len(resultats)} résultat(s) trouvé(s) :")
for contact in resultats:
print(f"- {contact['nom']} ({contact['telephone']})")
else:
print("Aucun contact trouvé.")
def supprimer_contact(self):
"""Supprime un contact"""
if not self.contacts:
print("Aucun contact à supprimer.")
return
self.afficher_contacts()
try:
index = int(input("Numéro du contact à supprimer : ")) - 1
if 0 <= index < len(self.contacts):
contact_supprime = self.contacts.pop(index)
self.sauvegarder_contacts()
print(f"Contact {contact_supprime['nom']} supprimé.")
else:
print("Numéro invalide.")
except ValueError:
print("Veuillez entrer un numéro valide.")
def menu_principal(self):
"""Menu principal de l'application"""
while True:
print("\n=== CARNET D'ADRESSES ===")
print("1. Ajouter un contact")
print("2. Afficher tous les contacts")
print("3. Rechercher un contact")
print("4. Supprimer un contact")
print("5. Quitter")
choix = input("Votre choix : ").strip()
if choix == '1':
self.ajouter_contact()
elif choix == '2':
self.afficher_contacts()
elif choix == '3':
self.rechercher_contact()
elif choix == '4':
self.supprimer_contact()
elif choix == '5':
print("Au revoir !")
break
else:
print("Choix invalide.")
# Lancement de l'application
if __name__ == "__main__":
carnet = CarnetAdresses()
carnet.menu_principal()
Solution : Jeu de bataille navale
import random
class BatailleNavale:
def __init__(self):
self.taille = 10
self.grille = [['~' for _ in range(self.taille)] for _ in range(self.taille)]
self.navires = []
self.coups_tires = 0
self.navires_coules = 0
self.total_navires = 5
def placer_navires(self):
"""Place les navires aléatoirement sur la grille"""
tailles_navires = [5, 4, 3, 3, 2] # Porte-avions, croiseur, 2 destroyers, sous-marin
for taille in tailles_navires:
place = False
tentatives = 0
while not place and tentatives < 100:
# Direction aléatoire (0=horizontal, 1=vertical)
direction = random.randint(0, 1)
if direction == 0: # Horizontal
x = random.randint(0, self.taille - taille)
y = random.randint(0, self.taille - 1)
positions = [(x + i, y) for i in range(taille)]
else: # Vertical
x = random.randint(0, self.taille - 1)
y = random.randint(0, self.taille - taille)
positions = [(x, y + i) for i in range(taille)]
# Vérifier si les positions sont libres
if all(self.grille[pos[1]][pos[0]] == '~' for pos in positions):
# Placer le navire
for pos in positions:
self.grille[pos[1]][pos[0]] = 'N'
self.navires.append({
'positions': positions,
'touches': set(),
'coule': False
})
place = True
tentatives += 1
def afficher_grille(self, montrer_navires=False):
"""Affiche la grille de jeu"""
print("\n ", end="")
for i in range(self.taille):
print(f"{i:2}", end=" ")
print()
for i in range(self.taille):
print(f"{i:2} ", end="")
for j in range(self.taille):
cellule = self.grille[i][j]
if cellule == 'N' and not montrer_navires:
print(" ~", end=" ")
elif cellule == 'X':
print(" X", end=" ") # Touché
elif cellule == 'O':
print(" O", end=" ") # Raté
elif cellule == 'N' and montrer_navires:
print(" N", end=" ") # Navire (mode debug)
else:
print(" ~", end=" ") # Eau
print()
def tirer(self, x, y):
"""Effectue un tir aux coordonnées données"""
if not (0 <= x < self.taille and 0 <= y < self.taille):
return "Coordonnées invalides"
if self.grille[y][x] in ['X', 'O']:
return "Déjà tiré ici"
self.coups_tires += 1
if self.grille[y][x] == 'N':
self.grille[y][x] = 'X'
# Vérifier quel navire a été touché
for navire in self.navires:
if (x, y) in navire['positions'] and not navire['coule']:
navire['touches'].add((x, y))
# Vérifier si le navire est coulé
if len(navire['touches']) == len(navire['positions']):
navire['coule'] = True
self.navires_coules += 1
return "Coulé !"
else:
return "Touché !"
else:
self.grille[y][x] = 'O'
return "Raté"
def jeu_termine(self):
"""Vérifie si tous les navires sont coulés"""
return self.navires_coules == self.total_navires
def jouer(self):
"""Boucle principale du jeu"""
print("=== BATAILLE NAVALE ===")
print(f"Trouvez et coulez les {self.total_navires} navires !")
print("Entrez les coordonnées sous la forme 'x y' (ex: 3 5)")
self.placer_navires()
while not self.jeu_termine():
self.afficher_grille()
print(f"\nCoups tirés : {self.coups_tires}")
print(f"Navires coulés : {self.navires_coules}/{self.total_navires}")
try:
coordonnees = input("\nCoordonnées (x y) : ").split()
if len(coordonnees) != 2:
print("Format invalide. Utilisez 'x y'")
continue
x, y = int(coordonnees[0]), int(coordonnees[1])
resultat = self.tirer(x, y)
print(f"Résultat : {resultat}")
except ValueError:
print("Veuillez entrer des nombres valides.")
except KeyboardInterrupt:
print("\nPartie interrompue.")
break
if self.jeu_termine():
self.afficher_grille(montrer_navires=True)
print(f"\n🎉 Félicitations ! Vous avez coulé tous les navires en {self.coups_tires} coups !")
# Lancement du jeu
if __name__ == "__main__":
jeu = BatailleNavale()
jeu.jouer()
Solution : Gestionnaire de bibliothèque
from datetime import datetime, timedelta
import json
import os
class GestionnaireBibliotheque:
def __init__(self, fichier_livres="livres.json", fichier_emprunts="emprunts.json"):
self.fichier_livres = fichier_livres
self.fichier_emprunts = fichier_emprunts
self.livres = self.charger_donnees(fichier_livres)
self.emprunts = self.charger_donnees(fichier_emprunts)
self.duree_emprunt = 14 # jours
def charger_donnees(self, fichier):
"""Charge les données depuis un fichier JSON"""
if os.path.exists(fichier):
try:
with open(fichier, 'r', encoding='utf-8') as f:
return json.load(f)
except:
return []
return []
def sauvegarder_donnees(self, donnees, fichier):
"""Sauvegarde les données dans un fichier JSON"""
with open(fichier, 'w', encoding='utf-8') as f:
json.dump(donnees, f, indent=2, ensure_ascii=False)
def ajouter_livre(self):
"""Ajoute un nouveau livre"""
titre = input("Titre : ").strip()
auteur = input("Auteur : ").strip()
isbn = input("ISBN : ").strip()
if not all([titre, auteur, isbn]):
print("Tous les champs sont obligatoires.")
return
# Vérifier si l'ISBN existe déjà
if any(livre['isbn'] == isbn for livre in self.livres):
print("Un livre avec cet ISBN existe déjà.")
return
livre = {
'id': len(self.livres) + 1,
'titre': titre,
'auteur': auteur,
'isbn': isbn,
'disponible': True,
'nb_emprunts': 0
}
self.livres.append(livre)
self.sauvegarder_donnees(self.livres, self.fichier_livres)
print(f"Livre '{titre}' ajouté avec succès.")
def afficher_livres(self):
"""Affiche tous les livres"""
if not self.livres:
print("Aucun livre dans la bibliothèque.")
return
print("\n=== CATALOGUE DES LIVRES ===")
for livre in self.livres:
statut = "📗 Disponible" if livre['disponible'] else "📕 Emprunté"
print(f"{livre['id']}. {livre['titre']}")
print(f" Auteur: {livre['auteur']}")
print(f" ISBN: {livre['isbn']}")
print(f" Statut: {statut}")
print(f" Emprunts: {livre['nb_emprunts']}")
print()
def rechercher_livres(self):
"""Recherche des livres par titre, auteur ou ISBN"""
terme = input("Rechercher (titre, auteur ou ISBN) : ").strip().lower()
if not terme:
return
resultats = []
for livre in self.livres:
if (terme in livre['titre'].lower() or
terme in livre['auteur'].lower() or
terme in livre['isbn'].lower()):
resultats.append(livre)
if resultats:
print(f"\n{len(resultats)} résultat(s) trouvé(s) :")
for livre in resultats:
statut = "Disponible" if livre['disponible'] else "Emprunté"
print(f"- {livre['titre']} par {livre['auteur']} ({statut})")
else:
print("Aucun livre trouvé.")
def emprunter_livre(self):
"""Emprunte un livre"""
self.afficher_livres()
try:
livre_id = int(input("ID du livre à emprunter : "))
livre = next((l for l in self.livres if l['id'] == livre_id), None)
if not livre:
print("Livre introuvable.")
return
if not livre['disponible']:
print("Ce livre est déjà emprunté.")
return
emprunteur = input("Nom de l'emprunteur : ").strip()
if not emprunteur:
print("Le nom de l'emprunteur est obligatoire.")
return
# Créer l'emprunt
emprunt = {
'id': len(self.emprunts) + 1,
'livre_id': livre_id,
'emprunteur': emprunteur,
'date_emprunt': datetime.now().isoformat(),
'date_retour_prevue': (datetime.now() + timedelta(days=self.duree_emprunt)).isoformat(),
'date_retour_effective': None
}
# Mettre à jour le livre
livre['disponible'] = False
livre['nb_emprunts'] += 1
# Sauvegarder
self.emprunts.append(emprunt)
self.sauvegarder_donnees(self.livres, self.fichier_livres)
self.sauvegarder_donnees(self.emprunts, self.fichier_emprunts)
print(f"Livre emprunté par {emprunteur}.")
print(f"Date de retour prévue : {datetime.fromisoformat(emprunt['date_retour_prevue']).strftime('%d/%m/%Y')}")
except ValueError:
print("Veuillez entrer un ID valide.")
def retourner_livre(self):
"""Retourne un livre emprunté"""
# Afficher les emprunts en cours
emprunts_actifs = [e for e in self.emprunts if e['date_retour_effective'] is None]
if not emprunts_actifs:
print("Aucun emprunt en cours.")
return
print("\n=== EMPRUNTS EN COURS ===")
for emprunt in emprunts_actifs:
livre = next((l for l in self.livres if l['id'] == emprunt['livre_id']), None)
if livre:
date_retour = datetime.fromisoformat(emprunt['date_retour_prevue'])
retard = (datetime.now() - date_retour).days
statut_retard = f" (RETARD: {retard} jours)" if retard > 0 else ""
print(f"{emprunt['id']}. {livre['titre']}")
print(f" Emprunteur: {emprunt['emprunteur']}")
print(f" Retour prévu: {date_retour.strftime('%d/%m/%Y')}{statut_retard}")
print()
try:
emprunt_id = int(input("ID de l'emprunt à retourner : "))
emprunt = next((e for e in self.emprunts if e['id'] == emprunt_id), None)
if not emprunt or emprunt['date_retour_effective']:
print("Emprunt introuvable ou déjà retourné.")
return
# Mettre à jour l'emprunt
emprunt['date_retour_effective'] = datetime.now().isoformat()
# Mettre à jour le livre
livre = next((l for l in self.livres if l['id'] == emprunt['livre_id']), None)
if livre:
livre['disponible'] = True
# Sauvegarder
self.sauvegarder_donnees(self.livres, self.fichier_livres)
self.sauvegarder_donnees(self.emprunts, self.fichier_emprunts)
print("Livre retourné avec succès.")
except ValueError:
print("Veuillez entrer un ID valide.")
def afficher_statistiques(self):
"""Affiche les statistiques de la bibliothèque"""
total_livres = len(self.livres)
livres_disponibles = len([l for l in self.livres if l['disponible']])
livres_empruntes = total_livres - livres_disponibles
emprunts_actifs = len([e for e in self.emprunts if e['date_retour_effective'] is None])
total_emprunts = len(self.emprunts)
# Livres les plus empruntés
livres_populaires = sorted(self.livres, key=lambda x: x['nb_emprunts'], reverse=True)[:5]
# Retards
retards = 0
for emprunt in self.emprunts:
if emprunt['date_retour_effective'] is None:
date_retour = datetime.fromisoformat(emprunt['date_retour_prevue'])
if datetime.now() > date_retour:
retards += 1
print("\n=== STATISTIQUES ===")
print(f"Total de livres : {total_livres}")
print(f"Livres disponibles : {livres_disponibles}")
print(f"Livres empruntés : {livres_empruntes}")
print(f"Emprunts actifs : {emprunts_actifs}")
print(f"Total emprunts historique : {total_emprunts}")
print(f"Retards : {retards}")
if livres_populaires:
print("\nLivres les plus empruntés :")
for i, livre in enumerate(livres_populaires, 1):
if livre['nb_emprunts'] > 0:
print(f"{i}. {livre['titre']} ({livre['nb_emprunts']} emprunts)")
def menu_principal(self):
"""Menu principal de l'application"""
while True:
print("\n=== GESTIONNAIRE DE BIBLIOTHÈQUE ===")
print("1. Ajouter un livre")
print("2. Afficher tous les livres")
print("3. Rechercher des livres")
print("4. Emprunter un livre")
print("5. Retourner un livre")
print("6. Statistiques")
print("7. Quitter")
choix = input("Votre choix : ").strip()
if choix == '1':
self.ajouter_livre()
elif choix == '2':
self.afficher_livres()
elif choix == '3':
self.rechercher_livres()
elif choix == '4':
self.emprunter_livre()
elif choix == '5':
self.retourner_livre()
elif choix == '6':
self.afficher_statistiques()
elif choix == '7':
print("Au revoir !")
break
else:
print("Choix invalide.")
# Lancement de l'application
if __name__ == "__main__":
bibliotheque = GestionnaireBibliotheque()
bibliotheque.menu_principal()