Fondations Python
Variables · Types · Arithmétique · Input/Output · Strings
Un profil développeur formaté avec des séparateurs visuels.
"=" * 50 répète le caractère 50 fois.print("=" * 50) print(" MON PROFIL DÉVELOPPEUR DIAM") print("=" * 50) print(" Nom : Jean Dupont") print(" Ville : Libreville") print(" Objectif : Python & Data Science") print(" Club : D.I.A.M") print("=" * 50)
Six variables de types différents affichées avec des f-strings.
prenom = "Jean" nom = "Dupont" age = 22 ville = "Libreville" taille = 1.78 est_etudiant = True print(f"Prénom : {prenom}") print(f"Nom : {nom}") print(f"Âge : {age} ans") print(f"Ville : {ville}") print(f"Taille : {taille} m") print(f"Étudiant : {est_etudiant}")
La fonction type() retourne le type Python de chaque valeur.
10 est un int, on peut calculer avec. "123" est une str, impossible d'additionner avec un entier.valeurs = [10, 3.14, "Python", True, "123"] for v in valeurs: print(f" {str(v):<10} -> type : {type(v).__name__}") # DIFFÉRENCE : 10 (int) et "123" (str) # 10 + 5 = 15 -> calcul arithmétique possible # "123" + 5 -> TypeError : impossible ! # "123" + "5" = "1235" (concaténation)
Les 7 opérateurs arithmétiques Python sur deux valeurs.
a, b = 17, 5 print(f"{a} + {b} = {a + b}") # 22 print(f"{a} - {b} = {a - b}") # 12 print(f"{a} * {b} = {a * b}") # 85 print(f"{a} / {b} = {a / b}") # 3.4 print(f"{a} // {b} = {a // b}") # 3 (div entière) print(f"{a} % {b} = {a % b}") # 2 (reste) print(f"{a} ** {b} = {a ** b}") # 1 419 857 (puissance)
Trois calculs mathématiques classiques en Python.
# Aire d'un rectangle longueur, largeur = 12, 5 aire_rect = longueur * largeur print(f"Aire rectangle : {aire_rect} m²") # Aire d'un cercle r = 7 PI = 3.14159 r = 7 aire_cercle = PI * r ** 2 print(f"Aire cercle : {aire_cercle:.4f} m²") # Conversion Celsius -> Fahrenheit celsius = 25 fahrenheit = celsius * 9 / 5 + 32 print(f"{celsius}°C = {fahrenheit}°F")
input() retourne une chaîne → conversion en float() obligatoire.
a = float(input("Premier nombre : ")) b = float(input("Deuxième nombre : ")) print(f"Somme : {a} + {b} = {a + b}") print(f"Différence : {a} - {b} = {a - b}") print(f"class>="cls">Produit : {a} * {b} = {a * b}") if b != 0: print(f"Quotient : {a} / {b} = {a / b:.4f}") else: print("Quotient : Division par zéro impossible !")
Soustraction simple à partir de l'année actuelle.
age = int(input("Votre âge : ")) annee_naissance = 2025 - age print(f"Vous êtes né(e) vers {annee_naissance}.")
Multiplication par le facteur de conversion, affichage à 2 décimales.
km = float(input("Distance en kilomètres : ")) miles = km * 0.621371 print(f"{km} km = {miles:.2f} miles")
Enchaînement des méthodes string sur la chaîne de départ.
texte = " PYTHON EST PUISSANT " print(f"Original : '{texte}'") print(f"strip() : '{texte.strip()}'") print(f"lower() : '{texte.strip().lower()}'") print(f"capitalize() : '{texte.strip().lower().capitalize()}'") print(f"Nb de 'P' : {texte.count('P')}") print(f"replace() : '{texte.strip().replace('PUISSANT', 'GÉNIAL')}'")
Combinaison de title(), upper(), lower() et indexation de chaîne.
prenom = input("Votre prénom : ").strip().title() nom = input("Votre nom : ").strip().upper() initiales = f"{prenom[0]}.{nom[0]}." email = f"{prenom.lower()}.{nom.lower()}class>="fn">@diam.ga" print(f"Prénom : {prenom}") print(f"Nom : {nom}") print(f"Initiales : {initiales}") print(f"Email : {email}")
Le slicing [::-1] inverse une chaîne — on compare avec l'original.
[::-1] = slicing avec pas -1 → parcours de droite à gauche.mot = input("Entrez un mot : ").lower().strip() mot_inverse = mot[::-1] print(f"Mot : {mot}") print(f"Inversé : {mot_inverse}") if mot == mot_inverse: print(f"✅ '{mot}' EST un palindrome !") else: print(f"❌ '{mot}' n'est PAS un palindrome.")
Trois conversions en une seule session interactive.
km = float(input("Distance en km : ")) celsius = float(input("Température en °C : ")) kg = float(input("Poids en kg : ")) miles = km * 0.621371 fahrenheit = celsius * 9 / 5 + 32 livres = kg * 2.205 print(f"\n{km} km -> {miles:.3f} miles") print(f"{celsius}°C -> {fahrenheit:.1f}°F") print(f"{kg} kg -> {livres:.3f} livres")
Calcul HT → TVA 18% → TTC avec affichage formaté.
prix_ht = float(input("Prix unitaire HT (FCFA) : ")) quantite = int(input("Quantité : ")) TVA = 0.18 sous_total_ht = prix_ht * quantite montant_tva = sous_total_ht * TVA total_ttc = sous_total_ht + montant_tva print("\n" + "=" * 44) print(" FACTURE D.I.A.M") print("=" * 44) print(f" {'Prix unitaire HT':<22} : {prix_ht:>9,.0f} F") print(f" {'Quantité':<22} : {quantite:>9}") print(f" {'Sous-total HT':<22} : {sous_total_ht:>9,.0f} F") print(f" {'TVA (18%)':<22} : {montant_tva:>9,.0f} F") print("-" * 44) print(f" {'TOTAL TTC':<22} : {total_ttc:>9,.0f} F") print("=" * 44)
Calcul dynamique de la largeur pour encadrer le texte le plus long.
nom = input("Nom complet : ").strip() profession = input("Profession : ").strip() telephone = input("Téléphone : ").strip() email = input("Email : ").strip() w = max(len(nom), len(profession), len(telephone), len(email)) + 6 print("╔" + "═" * w + "╗") print("║" + " " * w + "║") print(f"║ {nom:<{w-2}}║") print(f"║ {profession:<{w-2}}║") print("║" + " " * w + "║") print(f"║ 📞 {telephone:<{w-5}}║") print(f"║ ✉ {email:<{w-5}}║") print("║" + " " * w + "║") print("╚" + "═" * w + "╝")
Structures de Contrôle
if/elif/else · Opérateurs logiques · while · for · break/continue
Trois cas : âge invalide / mineur (avec années restantes) / majeur.
isdigit() vérifie que la saisie est un entier positif avant la conversion.saisie = input("Entrez votre âge : ") if not saisie.isdigit(): print("❌ Âge invalide (entrez un entier positif).") else: age = int(saisie) if age > 150: print("❌ Âge invalide (trop grand).") elif age < 18: print(f"⏳ Vous êtes mineur. Encore {18 - age} an(s) avant la majorité.") else: print(f"✅ Vous êtes majeur ({age} ans).")
Cinq paliers avec validation de la plage 0-20.
try: note = float(input("Note (/20) : ")) if not (0 <= note <= 20): print("❌ Note invalide (entre 0 et 20).") elif note >= 16: print(f"{note}/20 -> Mention Très Bien 🏆") elif note >= 14: print(f"{note}/20 -> Mention Bien 🥇") elif note >= 12: print(f"{note}/20 -> Mention Assez Bien 🥈") elif note >= 10: print(f"{note}/20 -> Mention Passable ✅") else: print(f"{note}/20 -> Insuffisant ❌") except class>="cls">ValueError: print("❌ Entrez un nombre valide.")
Les seuils doivent être testés du plus grand au plus petit.
montant = float(input("Montant d'achat (FCFA) : ")) if montant >= 100_000: taux = 0.20 elif montant >= 50_000: taux = 0.15 elif montant >= 20_000: taux = 0.10 else: taux = 0.0 reduction = montant * taux total = montant - reduction print(f" Montant initial : {montant:>12,.0f} FCFA") print(f" Réduction ({taux*100:.0f}%) : {reduction:>12,.0f} FCFA") print(f" Total à payer : {total:>12,.0f} FCFA")
Règle exacte : divisible par 4 MAIS pas par 100, SAUF par 400.
% 400 avant (ou via or en dehors).annee = int(input("Entrez une année : ")) if (annee % 4 == 0 and annee % 100 != 0) or (annee % 400 == 0): print(f"✅ {annee} est une année bissextile.") else: print(f"❌ {annee} n'est pas une année bissextile.") # Tests : 2000 ✅ | 1900 ❌ | 2024 ✅ | 2025 ❌
random.choice() pour l'ordinateur, if/elif/else pour déterminer le gagnant.
import random choix_valides = ["pierre", "feuille", "ciseaux"] choix_ordi = random.choice(choix_valides) choix_joueur = input("Pierre, Feuille ou Ciseaux ? ").strip().lower() if choix_joueur not in choix_valides: print("❌ Choix invalide !") else: print(f" Vous : {choix_joueur}") print(f" Ordinateur : {choix_ordi}") if choix_joueur == choix_ordi: print(" 🤝 Égalité !") elif ((choix_joueur == "pierre" and choix_ordi == "ciseaux") or (choix_joueur == "feuille" and choix_ordi == "pierre") or (choix_joueur == "ciseaux" and choix_ordi == "feuille")): print(" 🏆 Vous gagnez !") else: print(" 💻 L'ordinateur gagne !")
Boucle infinie + isdigit() + vérification de plage.
isdigit() retourne True si tous les caractères sont des chiffres.while True: saisie = input("Entrez votre âge (0-120) : ") if not saisie.isdigit(): print(" ❌ Entrez un nombre entier positif.") continue age = int(saisie) if 0 <= age <= 120: print(f" ✅ Âge valide : {age} ans") break else: print(" ❌ L'âge doit être entre 0 et 120.")
randint(1, 100) + indices Plus grand / Plus petit + compteur de tentatives.
else du while s'exécute quand la boucle se termine sans break.import random secret = random.randint(1, 100) tentatives = 0 MAX_TENTATIVES = 10 print("🎯 Devinez le nombre entre 1 et 100 !") while tentatives < MAX_TENTATIVES: try: guess = int(input(f"Tentative {tentatives+1}/{MAX_TENTATIVES} : ")) tentatives += 1 if guess == secret: print(f"🏆 Bravo ! Trouvé en {tentatives} tentative(s) !") break elif guess < secret: print(" 📈 Plus grand !") else: print(" 📉 Plus petit !") except class>="cls">ValueError: print(" ❌ Entrez un nombre entier.") else: print(f"😞 Perdu ! Le nombre était {secret}.")
Boucle infinie avec break sur l'option Quitter.
while True: print("\n" + "─" * 28) print(" MENU PRINCIPAL") print("─" * 28) print(" 1. Afficher un message") print(" 2. Calculer le carré") print(" 3. Compter jusqu'à 10") print(" 4. Quitter") print("─" * 28) choix = input("Choix (1-4) : ").strip() if choix == "1": print(f" 📢 {input('Message : ')}") elif choix == "2": try: n = float(input("Nombre : ")) print(f" {n}² = {n**2}") except class>="cls">ValueError: print(" ❌ Nombre invalide.") elif choix == "3": print(" ", end="") for i in range(1, 11): print(i, end=" ") print() elif choix == "4": print(" 👋 Au revoir !") break else: print(" ❌ Choix invalide.")
range(1, 11) pour itérer de 1 à 10, affichage formaté avec :.
n = int(input("Entrez un nombre : ")) print(f"\n{'─'*24}") print(f" TABLE DE {n}") print(f"{'─'*24}") for i in range(1, 11): print(f" {n:3d} × {i:2d} = {n * i:5d}") print(f"{'─'*24}")
Accumulateur initialisé à 1 multiplié à chaque tour de boucle.
range(1, n+1) va bien jusqu'à n inclus.n = int(input("Entrez N : ")) if n < 0: print("❌ La factorielle n'est pas définie pour les négatifs.") else: factorielle = 1 for i in range(1, n + 1): factorielle *= i print(f"{n}! = {factorielle}") # Vérifications : 0!=1 | 5!=120 | 10!=3628800
Formule : espaces = h - i et étoiles = 2*i - 1.
i : h-i espaces devant, 2i-1 étoiles.h = int(input("Hauteur : ")) for i in range(1, h + 1): print(" " * (h - i) + "*" * (2 * i - 1)) # Pour h=5 : # * # *** # ***** # ******* # *********
Tester d'abord % 15 (divisible par 3 ET 5) avant les cas simples.
% 3 en premier, les multiples de 15 afficheraient juste "Fizz" et jamais "FizzBuzz".for i in range(1, 101): if i % 15 == 0: print("FizzBuzz") elif i % 3 == 0: print("Fizz") elif i % 5 == 0: print("Buzz") else: print(i)
Fonctions
def · Paramètres · return · Scope · Lambda · *args/**kwargs
4 fonctions distinctes, la division gère le cas division par zéro.
def additionner(a, b): return a + b def soustraire(a, b): return a - b def multiplier(a, b): return a * b def diviser(a, b): if b == 0: return "Erreur : division par zéro !" return a / b a = float(input("Premier nombre : ")) b = float(input("Deuxième nombre : ")) print(f"{a} + {b} = {additionner(a, b)}") print(f"{a} - {b} = {soustraire(a, b)}") print(f"{a} * {b} = {multiplier(a, b)}") print(f"{a} / {b} = {diviser(a, b)}")
*notes capte n'importe combien d'arguments dans un tuple.
if not notes est vrai quand le tuple est vide.def calculer_moyenne(*notes): """Retourne la moyenne d'un nombre quelconque de notes.""" if not notes: return "Aucune note fournie." return sum(notes) / len(notes) print(calculer_moyenne(15, 18, 12, 16)) # 15.25 print(calculer_moyenne(10)) # 10.0 print(calculer_moyenne()) # message d'erreur
Quatre règles vérifiées avec any() et des expressions génératrices.
any(c.isupper() for c in mdp) retourne True dès qu'une majuscule est trouvée.def valider_mot_de_passe(mdp): """Vérifie : >=8 chars, >=1 maj, >=1 min, >=1 chiffre.""" if len(mdp) < 8: return False, "❌ Trop court (minimum 8 caractères)" if not any(c.isupper() for c in mdp): return False, "❌ Aucune lettre majuscule" if not any(c.islower() for c in mdp): return False, "❌ Aucune lettre minuscule" if not any(c.isdigit() for c in mdp): return False, "❌ Aucun chiffre" return True, "✅ Mot de passe valide !" for test in ["abc", "password", "Password", "Password1"]: ok, msg = valider_mot_de_passe(test) print(f" '{test:<12}' -> {msg}")
Initialisation avec [0, 1] puis ajout de la somme des deux derniers.
suite[-1] = dernier élément, suite[-2] = avant-dernier.def fibonacci(n): """Retourne les n premiers termes de Fibonacci.""" if n <= 0: return [] if n == 1: return [0] suite = [0, 1] for _ in range(2, n): suite.append(suite[-1] + suite[-2]) return suite print(fibonacci(10)) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] print(fibonacci(1)) # [0] print(fibonacci(0)) # []
Listes & Tuples
Listes · Méthodes · Slicing · List Comprehensions · Tuples
insert() ajoute à un index précis, del supprime par index.
courses = ["Riz", "Sucre", "Huile", "Farine", "Sel"] print("Initial :", courses) courses.insert(1, "Lait") # Insère en position 1 print("+ Lait idx1 :", courses) del courses[2] # Supprime le 3ème élément print("- idx2 :", courses) print("'Eau' présent ?", "Eau" in courses) # False
Tri, statistiques avec les fonctions intégrées Python.
nombres = [12, 5, 23, 7, 15, 8, 30, 4] nombres.sort() print(f"Triée : {nombres}") print(f"Max : {max(nombres)}") print(f"Min : {min(nombres)}") print(f"Somme : {sum(nombres)}") print(f"Moyenne : {sum(nombres)/len(nombres):.2f}")
4 comprehensions : carrés, multiples, conversion, booléens.
# Carrés de 0 à 9 carres = [x**2 for x in range(10)] print("Carrés :", carres) # Multiples de 3 jusqu'à 30 mult3 = [x for x in range(0, 31, 3)] print("Multiples 3 :", mult3) # Conversion ["1","2","3"] -> [1, 2, 3] int_nums = [int(x) for x in ["1", "2", "3"]] print("Conversion :", int_nums) # Booléens (> 5) valeurs = [3, 7, 1, 9, 4, 6] bool_lst = [x > 5 for x in valeurs] print("Booléens >5 :", bool_lst)
Une fonction retourne un tuple que l'on déstructure à l'appel.
def calculer_stats_liste(nombres): """Retourne (min, max, somme, moyenne) sous forme de tuple.""" if not nombres: return None return (min(nombres), max(nombres), sum(nombres), sum(nombres) / len(nombres)) stats = calculer_stats_liste([12, 5, 23, 7, 15, 8, 30, 4]) mini, maxi, somme, moyenne = stats # unpacking du tuple print(f"Min={mini}, Max={maxi}, Somme={somme}, Moy={moyenne:.2f}")
Dictionnaires & Sets
Paires clé-valeur · Méthodes · Dict Comprehensions · Ensembles
dict.get(mot, 0) + 1 : valeur par défaut 0 si le mot est absent.
phrase = "le chien mange le repas et le chat mange aussi"
mots = phrase.lower().split()
compteur = {}
for mot in mots:
compteur[mot] = compteur.get(mot, 0) + 1
# Tri par fréquence décroissante
for mot, nb in sorted(compteur.items(), key=lambda x: x[1], reverse=True):
print(f" {mot:<12} : {nb}")
Les 4 opérations sur les ensembles Python : union, intersection, différence, symétrique.
groupe_a = {"Alice", "Bob", "Charlie", "Diana", "Eve"}
groupe_b = {"Charlie", "Diana", "Frank", "Grace", "Heidi"}
print("Union :", groupe_a | groupe_b)
print("Intersection :", groupe_a & groupe_b)
print("Uniquement A :", groupe_a - groupe_b)
print("Uniquement B :", groupe_b - groupe_a)
print("Dans un seul :", groupe_a ^ groupe_b)
Un set() suit les éléments vus ; list conserve l'ordre.
list(set(liste)) supprimerait bien les doublons mais perdrait l'ordre.def dedoublonner(liste): """Enlève les doublons EN PRÉSERVANT l'ordre d'apparition.""" vus = set() resultat = [] for element in liste: if element not in vus: vus.add(element) resultat.append(element) return resultat test = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] print("Original :", test) print("Dédoublonné :", dedoublonner(test)) # [3, 1, 4, 5, 9, 2, 6] — ordre préservé !
Fichiers & Exceptions
Lecture/Écriture · CSV · JSON · try/except · pathlib
Mode "a" pour ajouter sans écraser, "r" pour lire.
with open(...) — le fichier est fermé automatiquement.from class>="cls">datetime import class>="cls">datetime def ajouter_entree(fichier="journal.txt"): entree = input("Note du jour : ") date = class>="cls">datetime.now().strftime("%d/%m/%Y %H:%M") with open(fichier, "a", encoding="utf-8") as f: f.write(f"[{date}] {entree}\n") print("✅ Entrée ajoutée !") def lire_journal(fichier="journal.txt"): try: with open(fichier, "r", encoding="utf-8") as f: contenu = f.read() print("─── JOURNAL ───") print(contenu if contenu else "📔 Journal vide.") except class>="cls">FileNotFoundError: print("📔 Aucun journal trouvé.") ajouter_entree() lire_journal()
Lecture complète puis comptage avec splitlines() et split().
def analyser_fichier(chemin): """Retourne {lignes, mots, caracteres}.""" try: with open(chemin, "r", encoding="utf-8") as f: contenu = f.read() return { "lignes" : len(contenu.splitlines()), "mots" : len(contenu.split()), "caracteres": len(contenu) } except class>="cls">FileNotFoundError: print(f"❌ Fichier '{chemin}' introuvable.") return None stats = analyser_fichier("mon_texte.txt") if stats: print(f"Lignes : {stats['lignes']}") print(f"Mots : {stats['mots']}") print(f"Caractères : {stats['caracteres']}")
DictWriter/DictReader pour lire et écrire des CSV structurés.
import csv from pathlib import class>="cls">Path FICHIER = "notes.csv" def ajouter_note_csv(nom, matiere, note): existe = class>="cls">Path(FICHIER).exists() with open(FICHIER, "a", newline="", encoding="utf-8") as f: w = csv.writer(f) if not existe: w.writerow(["Nom", "Matiere", "Note"]) w.writerow([nom, matiere, note]) def lire_notes_csv(): try: with open(FICHIER, "r", encoding="utf-8") as f: for ligne in csv.DictReader(f): print(f" {ligne['Nom']:<15} {ligne['Matiere']:<15} {ligne['Note']}") except class>="cls">FileNotFoundError: print("❌ Aucun fichier de notes.") def calculer_moyenne_etudiant(nom): notes = [] with open(FICHIER, "r", encoding="utf-8") as f: for l in csv.DictReader(f): if l["Nom"] == nom: notes.append(float(l["Note"])) return sum(notes) / len(notes) if notes else None ajouter_note_csv("Alice", "Maths", 16) ajouter_note_csv("Alice", "Physique", 14) lire_notes_csv() print(f"Moyenne Alice : {calculer_moyenne_etudiant('Alice'):.2f}")
json.load() au chargement, json.dump() à la sauvegarde.
ensure_ascii=False permet d'enregistrer les caractères accentués correctement.import json from pathlib import class>="cls">Path FICHIER = "contacts.json" def charger_base(): if class>="cls">Path(FICHIER).exists(): with open(FICHIER, "r", encoding="utf-8") as f: return json.load(f) return {} def sauvegarder_base(base): with open(FICHIER, "w", encoding="utf-8") as f: json.dump(base, f, indent=4, ensure_ascii=False) def ajouter_personne(nom, age, ville): base = charger_base() base[nom] = {"age": age, "ville": ville} sauvegarder_base(base) print(f"✅ {nom} ajouté(e).") def rechercher_personne(nom): base = charger_base() if nom in base: p = base[nom] print(f"✅ {nom} : {p['age']} ans, {p['ville']}") else: print(f"❌ '{nom}' non trouvé(e).") ajouter_personne("Alice", 25, "Libreville") rechercher_personne("Alice") rechercher_personne("Charlie")
try/except/else/finally : chaque bloc a un rôle précis.
else s'exécute uniquement si aucune exception n'a été levée. finally s'exécute dans tous les cas.def calculatrice_securisee(): try: a = float(input("Premier nombre : ")) op = input("Opération (+,-,*,/) : ").strip() b = float(input("Deuxième nombre : ")) if op == "+": resultat = a + b elif op == "-": resultat = a - b elif op == "*": resultat = a * b elif op == "/": resultat = a / b else: raise class>="cls">ValueError(f"Opération '{op}' inconnue.") except class>="cls">ValueError as e: print(f"❌ Saisie invalide : {e}") except class>="cls">ZeroDivisionError: print("❌ Division par zéro impossible !") else: print(f"✅ {a} {op} {b} = {resultat}") # si aucune erreur finally: print("🔄 Calcul terminé.") # toujours calculatrice_securisee()
Trois types d'erreurs différents → trois messages différents.
def lire_fichier_securise(chemin): try: with open(chemin, "r", encoding="utf-8") as f: contenu = f.read() if not contenu: print("⚠️ Le fichier est vide.") return None return contenu except class>="cls">FileNotFoundError: print(f"❌ Fichier '{chemin}' introuvable.") except class>="cls">PermissionError: print(f"❌ Permission refusée pour '{chemin}'.") except class>="cls">UnicodeDecodeError: print(f"❌ Erreur d'encodage — essayez encoding='latin-1'.") return None contenu = lire_fichier_securise("mon_fichier.txt") if contenu: print(contenu[:200])
Filtrage par mots-clés avec in, dédoublonnage avec set().
def analyser_log(chemin): try: with open(chemin, "r", encoding="utf-8") as f: lignes = f.readlines() except class>="cls">FileNotFoundError: print("❌ Fichier log introuvable.") return erreurs = [l for l in lignes if "ERROR" in l] warnings = [l for l in lignes if "WARNING" in l] msgs_uniq = set(l.strip() for l in erreurs) print(f" Total lignes : {len(lignes)}") print(f" Erreurs : {len(erreurs)}") print(f" Avertissements : {len(warnings)}") print(f" Erreurs uniques: {len(msgs_uniq)}") for m in msgs_uniq: print(f" -> {m}") analyser_log("app.log")
Boucle sur la liste de fichiers, gestion individuelle de chaque erreur.
def fusionner_fichiers(fichiers, sortie): """Fusionne plusieurs fichiers texte en un seul.""" with open(sortie, "w", encoding="utf-8") as f_out: for chemin in fichiers: try: with open(chemin, "r", encoding="utf-8") as f_in: f_out.write(f"=== {chemin} ===\n") f_out.write(f_in.read()) f_out.write("\n\n") print(f" ✅ '{chemin}' fusionné.") except class>="cls">FileNotFoundError: print(f" ⚠️ '{chemin}' introuvable — ignoré.") except class>="cls">PermissionError: print(f" ⚠️ Permission refusée pour '{chemin}' — ignoré.") print(f" ✅ Fusion terminée -> '{sortie}'") fusionner_fichiers(["fichier1.txt", "fichier2.txt"], "fusion.txt")
Programmation Orientée Objet
Classes · __init__ · Héritage · Encapsulation · Polymorphisme
__init__ initialise les attributs, les méthodes agissent sur self.
__str__ est appelé automatiquement par print().class class>="cls">Voiture: def __init__(self, marque, modele, annee): self.marque = marque self.modele = modele self.annee = annee def afficher_info(self): print(f" 🚗 {self.marque} {self.modele} ({self.annee})") def calculer_age(self): return 2025 - self.annee def __str__(self): return f"class>="cls">Voiture({self.marque} {self.modele}, {self.annee})" v1 = class>="cls">Voiture("Toyota", "Corolla", 2018) v1.afficher_info() print(f" Âge : {v1.calculer_age()} ans") print(v1) # appelle __str__
Trois méthodes + vérification carré avec comparaison des dimensions.
class class>="cls">Rectangle: def __init__(self, longueur, largeur): self.longueur = longueur self.largeur = largeur def calculer_aire(self): return self.longueur * self.largeur def calculer_perimetre(self): return 2 * (self.longueur + self.largeur) def est_carre(self): return self.longueur == self.largeur def __str__(self): return f"class>="cls">Rectangle({self.longueur} x {self.largeur})" r = class>="cls">Rectangle(6, 4) print(f" {r}") print(f" Aire : {r.calculer_aire()} cm²") print(f" Périmètre : {r.calculer_perimetre()} cm") print(f" Carré ? : {r.est_carre()}") print(f" Carré(5,5) : {class>="cls">Rectangle(5, 5).est_carre()}")
Attribut de classe partagé + @classmethod pour y accéder.
class class>="cls">Etudiant: nombre_etudiants = 0 # attribut de CLASSE (partagé) def __init__(self, nom, prenom): self.nom = nom self.prenom = prenom self.notes = [] class>="cls">Etudiant.nombre_etudiants += 1 # incrémente à chaque création def ajouter_note(self, note): if 0 <= note <= 20: self.notes.append(note) else: print(f" ❌ Note {note} invalide.") def calculer_moyenne(self): return sum(self.notes) / len(self.notes) if self.notes else None class>="fn">@classmethod def afficher_total(cls): print(f" Total étudiants : {cls.nombre_etudiants}") def __str__(self): moy = self.calculer_moyenne() return f"{self.prenom} {self.nom} — Moy: {moy:.2f}" if moy else f"{self.prenom} {self.nom}" e1 = class>="cls">Etudiant("Dupont", "Alice") e1.ajouter_note(15) e1.ajouter_note(18) e1.ajouter_note(25) # refusée print(e1) class>="cls">Etudiant.afficher_total()
@property pour le getter, @prix.setter pour la validation.
_ signale un attribut protégé par convention (pas d'accès direct).class class>="cls">Produit: def __init__(self, nom, prix, stock=0): self.nom = nom self._prix = prix # attribut "protégé" self._stock = stock class>="fn">@property def prix(self): # getter return self._prix class>="fn">@prix.setter def prix(self, valeur): # setter avec validation if valeur <= 0: raise class>="cls">ValueError("Le prix doit être positif.") self._prix = valeur class>="fn">@property def stock(self): return self._stock def ajouter_stock(self, qte): if qte > 0: self._stock += qte print(f" ✅ +{qte}. Stock : {self._stock}") def vendre(self, qte): if qte > self._stock: print(f" ❌ Stock insuffisant ({self._stock} dispo).") else: self._stock -= qte print(f" ✅ {qte} vendu(s). Restant : {self._stock}") p = class>="cls">Produit("Téléphone", 150_000, 10) p.vendre(3) p.ajouter_stock(5) print(f" Prix : {p.prix:,} FCFA | Stock : {p.stock}")
super().__init__() appelle le constructeur parent avant d'ajouter les attributs enfant.
class class>="cls">Vehicule: def __init__(self, marque, vitesse_max): self.marque = marque self.vitesse_max = vitesse_max def demarrer(self): print(f" Véhicule {self.marque} démarre.") class class>="cls">Voiture(class>="cls">Vehicule): def __init__(self, marque, vitesse_max, nb_portes): super().__init__(marque, vitesse_max) # appel parent self.nb_portes = nb_portes def demarrer(self): # override print(f" 🚗 {self.marque} ({self.nb_portes} portes) : moteur lancé !") class class>="cls">Moto(class>="cls">Vehicule): def __init__(self, marque, vitesse_max, cylindree): super().__init__(marque, vitesse_max) self.cylindree = cylindree def demarrer(self): # override print(f" 🏍️ {self.marque} {self.cylindree}cc : VROOOOM !") # Polymorphisme : même appel, comportements différents for v in [class>="cls">Voiture("Toyota", 180, 4), class>="cls">Moto("Honda", 200, 600), class>="cls">Vehicule("Vélo", 30)]: v.demarrer()
Simplification automatique par le PGCD, surcharge des opérateurs + et *.
gcd(a, b) (from math) retourne le plus grand commun diviseur.from math import gcd class class>="cls">Fraction: def __init__(self, numerateur, denominateur): if denominateur == 0: raise class>="cls">ValueError("Dénominateur ne peut pas être zéro.") commun = gcd(abs(numerateur), abs(denominateur)) self.num = numerateur // commun self.den = denominateur // commun if self.den < 0: # signe toujours au numérateur self.num, self.den = -self.num, -self.den def __str__(self): return str(self.num) if self.den == 1 else f"{self.num}/{self.den}" def __add__(self, other): return class>="cls">Fraction(self.num * other.den + other.num * self.den, self.den * other.den) def __mul__(self, other): return class>="cls">Fraction(self.num * other.num, self.den * other.den) def __eq__(self, other): return self.num == other.num and self.den == other.den f1, f2 = class>="cls">Fraction(1, 2), class>="cls">Fraction(1, 3) print(f"{f1} + {f2} = {f1 + f2}") # 1/2 + 1/3 = 5/6 print(f"{f1} * {f2} = {f1 * f2}") # 1/2 * 1/3 = 1/6 print(f"6/4 = {class>="cls">Fraction(6, 4)}") # simplifié -> 3/2
Modules & NumPy
Modules standards · Créer ses modules · NumPy arrays · Broadcasting
Un module Python = un fichier .py avec des fonctions réutilisables.
if __name__ == "__main__" : ce bloc ne s'exécute PAS quand on fait import calculs.# calculs.py — Sauvegardez ce fichier, puis : import calculs def factorielle(n): """Factorielle de n (n >= 0).""" if n < 0: raise class>="cls">ValueError("n doit être >= 0") if n == 0: return 1 resultat = 1 for i in range(1, n + 1): resultat *= i return resultat def pgcd(a, b): """PGCD par l'algorithme d'Euclide.""" a, b = abs(a), abs(b) while b: a, b = b, a % b return a def est_premier(n): """True si n est premier.""" if n < 2: return False for i in range(2, int(n**0.5) + 1): if n % i == 0: return False return True def fibonacci(n): """n premiers termes de la suite de Fibonacci.""" if n <= 0: return [] if n == 1: return [0] s = [0, 1] for _ in range(2, n): s.append(s[-1] + s[-2]) return s if __name__ == "__main__": # s'exécute uniquement si lancé directement print(factorielle(5)) # 120 print(pgcd(48, 18)) # 6 print(est_premier(17)) # True print(fibonacci(10)) # [0,1,1,2,3,5,8,13,21,34]
Génération aléatoire + toutes les fonctions statistiques NumPy en quelques lignes.
notes[notes >= 10] filtre sans boucle — c'est la puissance NumPy.import numpy as np notes = np.random.randint(0, 21, 100) # 100 notes entre 0 et 20 print(f"Moyenne : {np.mean(notes):.2f}") print(f"Médiane : {np.median(notes):.1f}") print(f"Écart-type : {np.std(notes):.2f}") print(f"Min / Max : {np.min(notes)} / {np.max(notes)}") admis = np.sum(notes >= 10) print(f"Notes >= 10 : {admis}/100 ({admis}%)") print(f" < 10 : {np.sum(notes < 10)}") print(f" 10-14 : {np.sum((notes >= 10) & (notes < 15))}") print(f" >= 15 : {np.sum(notes >= 15)}")
Points aléatoires dans un carré [0,1] × [0,1] : proportion dans le quart de cercle ≈ π/4.
n est grand, plus l'estimation est précise — c'est la loi des grands nombres.import numpy as np def estimer_pi(n=100_000): """Estime pi par la méthode de Monte Carlo.""" x = np.random.rand(n) y = np.random.rand(n) dans_cercle = (x**2 + y**2) < 1 # indexation booléenne return 4 * np.sum(dans_cercle) / n print("Estimation de π par Monte Carlo :") for n in [1_000, 10_000, 100_000, 1_000_000]: pi_est = estimer_pi(n) erreur = abs(pi_est - np.pi) print(f" n={n:>8,} : π ≈ {pi_est:.6f} (erreur: {erreur:.6f})")
Pandas & Analyse de Données
Series · DataFrames · Filtrage · Groupby · Valeurs manquantes
info(), describe(), unique(), value_counts() — les 4 commandes d'exploration.
import pandas as pd data = { "nom" : ["Alice", "Bob", "Charlie", "Diana", "Eve"], "age" : [22, 25, 21, 23, 24], "ville" : ["Libreville", "Port-Gentil", "Libreville", "Oyem", "Libreville"], "note_maths" : [15, 12, 18, 9, 14], "note_physique": [14, 16, 13, 11, 17], } df = pd.DataFrame(data) print("=== info() ===") df.info() print("\n=== describe() ===") print(df.describe()) print("\n=== Villes uniques ===") print(df["ville"].unique()) print("\n=== Répartition par ville ===") print(df["ville"].value_counts())
Opérateurs booléens & et | pour combiner des conditions de filtrage.
(cond1) & (cond2).import pandas as pd data = { "nom" : ["Alice", "Bob", "Charlie", "Diana", "Eve"], "note_maths" : [15, 12, 18, 9, 14], "note_physique": [14, 16, 13, 11, 17], "note_info" : [16, 14, 15, 10, 13], } df = pd.DataFrame(data) df["moyenne"] = df[["note_maths", "note_physique", "note_info"]].mean(axis=1) print("=== Maths > 15 ===") print(df[df["note_maths"] > 15][["nom", "note_maths"]]) print("\n=== Maths > 15 ET Physique > 15 ===") masque = (df["note_maths"] > 15) & (df["note_physique"] > 15) print(df[masque][["nom", "note_maths", "note_physique"]]) print("\n=== Moyenne >= 15 ===") print(df[df["moyenne"] >= 15][["nom", "moyenne"]].round(2)) print("\n=== Meilleur en Informatique ===") print(df.loc[df["note_info"].idxmax(), ["nom", "note_info"]])
groupby() + agg() pour des analyses multi-colonnes.
idxmax() retourne l'index (= le nom du produit) correspondant à la valeur maximale.import pandas as pd data = { "produit" : ["Riz","Farine","Riz","Sucre","Farine","Riz","Sucre"], "ville" : ["Lib","Lib","PG","Lib","PG","Lib","PG"], "quantite": [50, 30, 40, 25, 20, 60, 15], "prix" : [500, 400, 500, 800, 400, 500, 800], } df = pd.DataFrame(data) df["total"] = df["quantite"] * df["prix"] print("=== Total par produit ===") print(df.groupby("produit")["total"].sum().sort_values(ascending=False)) print("\n=== Total par ville ===") print(df.groupby("ville")["total"].sum()) print("\n=== Quantité moyenne par produit ===") print(df.groupby("produit")["quantite"].mean().round(1)) produit_top = df.groupby("produit")["quantite"].sum().idxmax() print(f"\n=== class>="cls">Produit le plus vendu : {produit_top} ===")