Python pour débuter

Découvrez Python, de son histoire à votre premier projet : syntaxe, types, structures de contrôle et bonnes pratiques.

Histoire de Python

Découvrez l'origine et l'évolution du langage créé par Guido van Rossum.

1 La Naissance (1989-1991)

Le Contexte :

  • Fin des années 80 : langages complexes dominent
  • Guido travaille au CWI (Amsterdam)
  • Besoin d'un langage simple et lisible
  • Inspiration d'ABC et Modula-3

Guido van Rossum - Le BDFL :

Guido van Rossum, programmeur néerlandais, crée Python pendant les vacances de Noël 1989.

Le nom "Python" vient des Monty Python, pas du serpent ! Guido était fan de cette troupe de comédiens britanniques.

Chronologie de création :

1 Déc 1989 : Début du développement

2 Fév 1991 : Python 0.9.0 publié

3 Jan 1994 : Python 1.0 sortie

4 2000 : Python 2.0 avec GC

Philosophie Python (PEP 20) :

"Beau est mieux que laid. Explicite est mieux qu'implicite. Simple est mieux que complexe. La lisibilité compte."

2 Évolution et Dates Clés

Les Grandes Étapes :

1994 - Python 1.0

Première version stable avec lambda, map, filter

2000 - Python 2.0

Garbage collector, Unicode, compréhensions de listes

2008 - Python 3.0

Rupture compatibilité, Unicode par défaut, print()

2020 - Python 2 EOL

Fin du support Python 2, migration massive vers Python 3

Python Aujourd'hui :

2024 - Python 3.12+

Performances améliorées, nouveaux opérateurs

Domaines d'application

IA, Data Science, Web, Automation, DevOps

Popularité mondiale

Top 3 des langages les plus utilisés

Statistiques 2024 :
  • 48% des développeurs utilisent Python
  • 400,000+ packages sur PyPI
  • Utilisé par Netflix, Google, Instagram
  • Salaire moyen : 80k€/an en France

Installation et Configuration

Préparez votre environnement de développement Python.

Installation de Python

🪟 Windows

1. Aller sur python.org/downloads

2. Télécharger Python 3.12+

3. ✅ Cocher "Add to PATH"

4. Installer normalement

python

                            python --version

🍎 macOS

1. Installer Homebrew

2. brew install python

3. Ou télécharger depuis python.org

4. Vérifier l'installation

python

                            python3 --version

🐧 Linux

sudo apt update

sudo apt install python3 python3-pip

Fedora: sudo dnf install python3

python

                            python3 --version

Syntaxe Python Essentielle

Maîtrisez les fondamentaux de la syntaxe Python.

1 Variables et Types de Données

Variables Python :

python

# Variables - pas de déclaration
nom = "Alice"
age = 25
taille = 1.70
actif = True
# Python est dynamiquement typé
variable = 42
variable = "Maintenant une string"
# Convention: snake_case
mon_nom_complet = "Jean Dupont"

Types de données :

python

# Types de base
texte = "Hello World" # str
nombre = 42 # int
decimal = 3.14 # float
vrai_faux = True # bool
# Collections
liste = [1, 2, 3]  # list
tuple = (1, 2, 3)  # tuple
dico = {"nom": "Alice"}  # dict
ensemble = {1, 2, 3}  # set
# Vérifier le type
print(type(nom))  # <class 'str'>

2 Fonctions

Définition de fonctions :

python

# Fonction simple
def dire_bonjour(nom):
    return f"Bonjour {nom}!"
# Fonction avec paramètres par défaut
def calculer(a, b, operation="+"):
    if operation == "+":
        return a + b
    elif operation == "-":
        return a - b
    else:
        return "Opération non supportée"

Utilisation :

python

# Appeler des fonctions
message = dire_bonjour("Marie")
print(message)  # Bonjour Marie!
resultat = calculer(10, 5)
print(resultat)  # 15
resultat2 = calculer(10, 5, "-")
print(resultat2)  # 5
# Fonction lambda (anonyme)
carre = lambda x: x ** 2
print(carre(5))  # 25

3 Structures de Contrôle

Conditions :

python

# if/elif/else
age = 20
if age < 18:
    print("Mineur")
elif age < 65:
    print("Adulte")
else:
    print("Senior")
# Opérateurs de comparaison
# ==, !=, <, >, <=, >=
# and, or, not
# in, is

Boucles :

python

# Boucle for
for i in range(5):
    print(f"Nombre: {i}")
# Boucle sur une liste
fruits = ["pomme", "banane", "orange"]
for fruit in fruits:
    print(fruit)
# Boucle while
compteur = 0
while compteur < 3:
    print(compteur)
    compteur += 1

Méthodes des Chaînes de Caractères

Maîtrisez les outils essentiels pour manipuler et transformer le texte en Python.

1 Transformation de la Casse

Méthodes de casse courantes :

python

texte = "Bonjour Le MONDE"
# Tout en minuscules
print(texte.lower())  # "bonjour le monde"
# Tout en majuscules
print(texte.upper())  # "BONJOUR LE MONDE"
# Première lettre en majuscule
print(texte.capitalize())  # "Bonjour le monde"
# Première lettre de chaque mot
print(texte.title())  # "Bonjour Le Monde"
# Inverser la casse
print(texte.swapcase())  # "bONJOUR lE monde"

Cas d'usage pratiques :

python

# Comparaison insensible à la casse
nom1 = "Alice"
nom2 = "ALICE"
if nom1.lower() == nom2.lower():
    print("Même nom!")
# Validation d'entrée utilisateur
reponse = input("Continuer? (O/n): ")
if reponse.lower() in ["o", "oui", "y", "yes"]:
    print("On continue!")
# Formatage de noms propres
nom_utilisateur = "jean-claude VAN DAMME"
nom_formate = nom_utilisateur.title()
print(nom_formate)  # "Jean-Claude Van Damme"

Note importante :

Les chaînes sont immutables ! Ces méthodes retournent une NOUVELLE chaîne, elles ne modifient pas l'originale.

2 Nettoyage et Suppression

Méthodes strip() :

python

texte = "   Bonjour le monde   "
# Supprimer espaces début/fin
print(f"'{texte.strip()}'")  # 'Bonjour le monde'
# Supprimer seulement à gauche
print(f"'{texte.lstrip()}'")  # 'Bonjour le monde   '
# Supprimer seulement à droite
print(f"'{texte.rstrip()}'")  # '   Bonjour le monde'
# Supprimer des caractères spécifiques
url = "https://example.com/"
print(url.rstrip("/"))  # "https://example.com"
# Supprimer plusieurs caractères
donnee = "...!!!Bonjour!!!..."
print(donnee.strip(".!"))  # "Bonjour"

Remplacement :

python

phrase = "J'aime les chats et les chats m'aiment"
# Remplacer toutes les occurrences
nouvelle = phrase.replace("chats", "chiens")
print(nouvelle)
# "J'aime les chiens et les chiens m'aiment"
# Limiter le nombre de remplacements
limite = phrase.replace("chats", "chiens", 1)
print(limite)
# "J'aime les chiens et les chats m'aiment"
# Supprimer des caractères (remplacer par rien)
telephone = "01.23.45.67.89"
propre = telephone.replace(".", "")
print(propre)  # "0123456789"

3 Division et Jonction

split() - Diviser une chaîne :

python

# Division par espaces (défaut)
phrase = "Python est un langage formidable"
mots = phrase.split()
print(mots)
# ['Python', 'est', 'un', 'langage', 'formidable']
# Division avec séparateur personnalisé
email = "user@example.com"
parties = email.split("@")
print(parties)  # ['user', 'example.com']
# Limiter le nombre de divisions
chemin = "home/user/documents/file.txt"
elements = chemin.split("/", 2)
print(elements)  # ['home', 'user', 'documents/file.txt']
# Division par lignes
texte_multi = "Ligne 1\nLigne 2\nLigne 3"
lignes = texte_multi.splitlines()
print(lignes)  # ['Ligne 1', 'Ligne 2', 'Ligne 3']

join() - Joindre une liste :

python

mots = ["Python", "est", "génial"]
# Joindre avec des espaces
phrase = " ".join(mots)
print(phrase)  # "Python est génial"
# Joindre avec d'autres séparateurs
emails = ["a@test.com", "b@test.com", "c@test.com"]
liste_emails = "; ".join(emails)
print(liste_emails)
# "a@test.com; b@test.com; c@test.com"
# Créer un chemin de fichier
dossiers = ["home", "user", "documents", "file.txt"]
chemin = "/".join(dossiers)
print(chemin)  # "home/user/documents/file.txt"
# Attention : join() n'accepte que des chaînes!
nombres = [1, 2, 3]
chaine_nombres = "-".join(str(n) for n in nombres)
print(chaine_nombres)  # "1-2-3"

4 Recherche et Vérification

Méthodes de recherche :

python

texte = "Python est un langage de programmation"
# Trouver la position (find)
position = texte.find("langage")
print(position)  # 14
# find() retourne -1 si pas trouvé
absent = texte.find("Java")
print(absent)  # -1
# index() lève une exception si pas trouvé
try:
    pos = texte.index("Python")
    print(f"Trouvé à la position {pos}")
except ValueError:
    print("Pas trouvé")
# Compter les occurrences
phrase = "Le chat mange, le chat dort"
nb_chat = phrase.count("chat")
print(nb_chat)  # 2

Vérifications (startswith, endswith) :

python

fichier = "document.pdf"
url = "https://example.com"
# Vérifier le début
if url.startswith("https"):
    print("Connexion sécurisée")
# Vérifier la fin
if fichier.endswith(".pdf"):
    print("C'est un PDF")
# Vérifier plusieurs extensions
extensions_images = (".jpg", ".png", ".gif")
nom_fichier = "photo.jpg"
if nom_fichier.endswith(extensions_images):
    print("C'est une image")
# Vérifier la présence (plus simple que find)
email = "test@example.com"
if "@" in email and "." in email:
    print("Email semble valide")

5 Tests de Type de Contenu

Méthodes is... :

python

# Tests sur différents types de chaînes
print("123".isdigit())    # True
print("abc".isalpha())    # True
print("abc123".isalnum())  # True
print("   ".isspace())    # True
# Tests de casse
print("ABC".isupper())     # True
print("abc".islower())     # True
print("Hello World".istitle())  # True
# Tests d'identifiants Python
print("variable_1".isidentifier())  # True
print("123abc".isidentifier())     # False
# Test d'imprimabilité
print("Hello".isprintable())     # True
print("Hello\n".isprintable())   # False

Cas d'usage pratiques :

python

# Validation d'entrée utilisateur
def valider_age(entree):
    if entree.isdigit():
        age = int(entree)
        return 0 <= age <= 120
    return False
# Nettoyer une chaîne
def extraire_lettres(texte):
    lettres = []
    for char in texte:
        if char.isalpha():
            lettres.append(char)
    return "".join(lettres)
# Test
resultat = extraire_lettres("H3ll0 W0rld!")
print(resultat)  # "HllWrld"

6 Exemple Pratique : Nettoyeur de Texte

python

# Nettoyeur de texte - Démonstration des méthodes de chaînes

def nettoyer_texte(texte):
    """
    Nettoie un texte en appliquant plusieurs transformations
    """
    # 1. Supprimer espaces en début/fin
    texte = texte.strip()

    # 2. Remplacer les espaces multiples par un seul
    while "  " in texte:
        texte = texte.replace("  ", " ")

    # 3. Supprimer caractères de ponctuation indésirables
    caracteres_a_supprimer = "!@#$%^&*()_+-=[]{}|;:,.<>?"
    for char in caracteres_a_supprimer:
        texte = texte.replace(char, "")

    return texte

def analyser_texte(texte):
    """
    Analyse un texte et retourne des statistiques
    """
    stats = {
        "longueur_totale": len(texte),
        "mots": texte.split(),
        "nb_mots": len(texte.split()),
        "lignes": texte.splitlines(),
        "nb_lignes": len(texte.splitlines()),
        "voyelles": sum(1 for c in texte.lower() if c in "aeiou"),
        "consonnes": sum(1 for c in texte.lower() if c.isalpha() and c not in "aeiou"),
        "chiffres": sum(1 for c in texte if c.isdigit()),
        "espaces": texte.count(" ")
    }
    return stats

def formater_nom_propre(nom_complet):
    """
    Formate correctement un nom propre
    """
    # Nettoyer et diviser
    nom_complet = nom_complet.strip().lower()
    parties = nom_complet.split()

    # Capitaliser chaque partie
    parties_formatees = [partie.capitalize() for partie in parties]

    # Rejoindre avec des espaces
    return " ".join(parties_formatees)

def extraire_mots_cles(texte, longueur_min=4):
    """
    Extrait les mots-clés d'un texte (mots > longueur_min)
    """
    # Mots vides à ignorer
    mots_vides = {"le", "la", "les", "un", "une", "des", "et", "ou", "de", "du", "dans", "avec", "pour", "sur"}

    # Nettoyer et diviser
    texte_propre = nettoyer_texte(texte)
    mots = texte_propre.lower().split()

    # Filtrer les mots
    mots_cles = [
        mot for mot in mots
        if len(mot) >= longueur_min and mot not in mots_vides
    ]

    return list(set(mots_cles))  # Supprime les doublons

def demo_methodes_chaines():
    """Démonstration complète des méthodes de chaînes"""

    texte_test = """

        Bonjour!!!    Je suis un TEXTE avec des    espaces bizarres.

        J'ai des caractères@#$% indésirables et des MAJUSCULES partout!!

        Python est un LANGAGE formidable pour traiter les chaînes.

    """

    print("🔤 DÉMONSTRATION DES MÉTHODES DE CHAÎNES")
    print("="*50)

    print("📝 Texte original:")
    print(f"'{texte_test}'")

    # Nettoyage
    texte_nettoye = nettoyer_texte(texte_test)
    print(f"\\n🧹 Texte nettoyé: '{texte_nettoye}'")

    # Analyse
    stats = analyser_texte(texte_nettoye)
    print(f"\\n📊 STATISTIQUES:")
    print(f"   Longueur: {stats['longueur_totale']} caractères")
    print(f"   Mots: {stats['nb_mots']}")
    print(f"   Voyelles: {stats['voyelles']}, Consonnes: {stats['consonnes']}")
    print(f"   Chiffres: {stats['chiffres']}, Espaces: {stats['espaces']}")

    # Mots-clés
    mots_cles = extraire_mots_cles(texte_nettoye)
    print(f"\\n🎯 Mots-clés extraits: {mots_cles}")

    # Test formatage nom
    noms_test = ["   jean-CLAUDE van DAMME   ", "marie-antoinette DE FRANCE"]
    print("\\n👤 FORMATAGE DE NOMS:")
    for nom in noms_test:
        nom_formate = formater_nom_propre(nom)
        print(f"   '{nom}' → '{nom_formate}'")

if __name__ == "__main__":
    demo_methodes_chaines()

Récapitulatif des Méthodes

Transformation :

  • .lower() - minuscules
  • .upper() - MAJUSCULES
  • .title() - Titre
  • .capitalize() - Première maj
  • .swapcase() - Inverser

Nettoyage :

  • .strip() - début/fin
  • .lstrip() - début seulement
  • .rstrip() - fin seulement
  • .replace() - remplacer

Division/Jonction :

  • .split() - diviser
  • .splitlines() - par lignes
  • .join() - joindre liste

Recherche :

  • .find() - position (-1 si absent)
  • .index() - position (erreur si absent)
  • .count() - compter occurrences

Vérification :

  • .startswith() - commence par
  • .endswith() - finit par
  • in - contient

Tests de type :

  • .isdigit() - que des chiffres
  • .isalpha() - que des lettres
  • .isalnum() - lettres et chiffres
  • .isspace() - que des espaces

Formatage de Chaînes et F-strings

Maîtrisez le formatage moderne des chaînes de caractères en Python.

1 Qu'est-ce qu'une F-string ?

Définition :

  • F-string = Formatted String Literal
  • Disponible depuis Python 3.6+
  • Syntaxe simple : f"texte {variable}"
  • Plus rapide et lisible que les autres méthodes

Syntaxe de base :

python

# Exemple simple
nom = "Alice"
age = 25
# F-string avec variables
message = f"Bonjour {nom}, tu as {age} ans"
print(message)
# Output: Bonjour Alice, tu as 25 ans

Pourquoi utiliser les f-strings ?

Lisibilité

Code plus clair et facile à comprendre

Performance

Plus rapide que .format() et %

Flexibilité

Support d'expressions complexes

Note importante :

Le préfixe f peut être minuscule ou majuscule : f"..." ou F"..."

2 Expressions et Calculs

Calculs dans les f-strings :

python

a = 10
b = 5
# Opérations mathématiques
print(f"Addition: {a + b}")
print(f"Multiplication: {a * b}")
print(f"Division: {a / b}")
print(f"Puissance: {a ** 2}")
# Conditions ternaires
score = 85
resultat = f"Résultat: {'Réussi' if score >= 50 else 'Échoué'}"
print(resultat)  # Résultat: Réussi

Appels de fonctions et méthodes :

python

nom = "alice"
phrase = "hello world"
nombres = [1, 2, 3, 4, 5]
# Méthodes de chaînes
print(f"Nom: {nom.title()}")
print(f"Majuscules: {phrase.upper()}")
# Fonctions built-in
print(f"Longueur: {len(phrase)}")
print(f"Maximum: {max(nombres)}")
print(f"Somme: {sum(nombres)}")
# Fonctions personnalisées
def saluer(nom):
    return f"Salut {nom}!"
print(f"Message: {saluer('Bob')}")

3 Formatage Numérique et Dates

Nombres décimaux :

python

pi = 3.14159265359
prix = 19.99
pourcentage = 0.751
# Limiter les décimales
print(f"Pi: {pi:.2f}")  # 3.14
print(f"Prix: {prix:.1f}€")  # 20.0€
# Pourcentages
print(f"Taux: {pourcentage:.1%}")  # 75.1%
# Notation scientifique
grand_nombre = 1234567890
print(f"Scientific: {grand_nombre:.2e}")  # 1.23e+09

Alignement et padding :

python

nom = "Alice"
nombre = 42
# Alignement à droite (largeur 10)
print(f"|{nom:>10}|")  # |     Alice|
# Alignement à gauche
print(f"|{nom:<10}|")  # |Alice     |
# Centré
print(f"|{nom:^10}|")  # |  Alice   |
# Zéros de tête
print(f"ID: {nombre:05d}")  # ID: 00042
# Padding avec caractère personnalisé
print(f"{nom:*^15}")  # *****Alice*****

Dates et heures :

python

from datetime import datetime, date
maintenant = datetime.now()
aujourd_hui = date.today()
# Formatage de dates
print(f"Date: {aujourd_hui:%d/%m/%Y}")  # 15/03/2024
print(f"Heure: {maintenant:%H:%M:%S}")  # 14:30:25
print(f"Complet: {maintenant:%A %d %B %Y à %H:%M}")
# Vendredi 15 Mars 2024 à 14:30

4 Comparaison des Méthodes de Formatage

❌ Méthode % (Ancienne)

python

nom = "Alice"
age = 25
message = "Je suis %s et j'ai %d ans" % (nom, age)

  • Syntaxe complexe
  • Erreurs fréquentes
  • Moins lisible

⚠️ Méthode .format()

python

nom = "Alice"
age = 25
message = "Je suis {} et j'ai {} ans".format(nom, age)
# Ou avec des index
message2 = "Je suis {0} et j'ai {1} ans".format(nom, age)

Avantages : Plus lisible que %

Inconvénients : Plus verbeux

✅ F-strings (Moderne)

python

nom = "Alice"
age = 25
message = f"Je suis {nom} et j'ai {age} ans"
# Avec expressions
message2 = f"Dans 10 ans, j'aurai {age + 10} ans"

  • Plus rapide
  • Plus lisible
  • Support d'expressions
Recommandation :

Utilisez toujours les f-strings pour les nouveaux projets Python 3.6+. Elles sont plus rapides, plus lisibles et plus puissantes que les autres méthodes.

5 Exemple Pratique : Générateur de Rapports

python

# Générateur de rapports avec f-strings

from datetime import datetime
import random

def generer_rapport_ventes(vendeur, ventes, objectif):
    """
    Génère un rapport de ventes formaté avec f-strings
    """
    date_actuelle = datetime.now()
    total_ventes = sum(ventes.values())
    nb_ventes = len(ventes)
    moyenne = total_ventes / nb_ventes if nb_ventes > 0 else 0
    taux_reussite = (total_ventes / objectif) * 100

    # En-tête du rapport avec formatage avancé
    largeur = 60
    print(f"{'='*largeur}")
    print(f"{'📊 RAPPORT DE VENTES':^{largeur}}")
    print(f"{'='*largeur}")

    # Informations générales
    print(f"🗓️  Date du rapport  : {date_actuelle:%A %d %B %Y à %H:%M}")
    print(f"👤  Vendeur          : {vendeur.title()}")
    print(f"🎯  Objectif         : {objectif:8,.2f}€")
    print(f"{'-'*largeur}")

    # Statistiques avec alignement
    print("📈 STATISTIQUES:")
    print(f"   Nombre de ventes : {nb_ventes:3d}")
    print(f"   Total des ventes : {total_ventes:8,.2f}€")
    print(f"   Vente moyenne    : {moyenne:8,.2f}€")
    print(f"   Taux de réussite : {taux_reussite:6.1f}%")

    # Statut avec condition ternaire et couleurs
    statut = "✅ OBJECTIF ATTEINT" if taux_reussite >= 100 else "⚠️  OBJECTIF PARTIEL" if taux_reussite >= 75 else "❌ OBJECTIF NON ATTEINT"
    restant = max(0, objectif - total_ventes)

    print(f"{'-'*largeur}")
    print(f"🏆 STATUT: {statut}")
    if restant > 0:
        print(f"💪 Il reste {restant:,.2f}€ à réaliser pour atteindre l'objectif")

    # Détail des ventes
    print(f"\\n💼 DÉTAIL DES VENTES:")
    for produit, montant in ventes.items():
        pourcentage_produit = (montant / total_ventes) * 100
        barre = "█" * int(pourcentage_produit / 5)  # Barre de progression
        print(f"   {produit:15} : {montant:7,.2f}€ ({pourcentage_produit:4.1f}%) {barre}")

    print(f"{'='*largeur}")

def generer_donnees_test():
    """Génère des données de test"""
    produits = ["Laptop", "Smartphone", "Tablette", "Écouteurs", "Montre"]
    ventes = {produit: random.uniform(100, 2000) for produit in produits}
    return ventes

def demo_formatage_avance():
    """Démontre diverses techniques de formatage avec f-strings"""
    nom = "jean-claude"
    prix = 1234.5678
    quantite = 42
    taux = 0.0875

    print("🔤 FORMATAGE DE CHAÎNES:")
    print(f"   Nom original : '{nom}'")
    print(f"   Capitalisé  : '{nom.title()}'")
    print(f"   MAJUSCULES  : '{nom.upper()}'")
    print(f"   Tirets → espaces : '{nom.replace('-', ' ').title()}'")

    print("\\n🔢 FORMATAGE NUMÉRIQUE:")
    print(f"   Prix brut      : {prix}")
    print(f"   Prix formaté   : {prix:,.2f}€")
    print(f"   Quantité (3 digits) : {quantite:03d}")
    print(f"   Taux en %      : {taux:.2%}")

    print("\\n📏 ALIGNEMENT ET PADDING:")
    for produit, prix_prod in [("TV", 899.99), ("Ordinateur", 1299.00), ("Souris", 29.95)]:
        print(f"   {produit:12} | {prix_prod:8.2f}€ | {'='*int(prix_prod/100)}")

# Tests et démonstrations
if __name__ == "__main__":
    print("🐍 DÉMO F-STRINGS AVANCÉES\\n")

    # Démonstration formatage
    demo_formatage_avance()

    # Génération de rapport
    print("\\n" + "="*60)
    ventes_exemple = generer_donnees_test()
    generer_rapport_ventes("alice martin", ventes_exemple, 5000)

    # Exemples pratiques supplémentaires
    print("\\n🎯 EXEMPLES PRATIQUES DIVERS:")

    utilisateurs = ["alice", "bob", "charlie"]
    scores = [87, 92, 78]

    print("\\n🏆 CLASSEMENT:")
    for rang, (user, score) in enumerate(zip(utilisateurs, scores), 1):
        medaille = "🥇" if rang == 1 else "🥈" if rang == 2 else "🥉" if rang == 3 else "  "
        appreciation = "Excellent!" if score >= 90 else "Très bien" if score >= 80 else "Bien"
        print(f"   {medaille} #{rang} - {user.title():10} : {score:2d}/100 ({appreciation})")

    print("\\n✨ Vous maîtrisez maintenant les f-strings!")

6 Bonnes Pratiques et Pièges à Éviter

✅ Bonnes pratiques :

Lisibilité d'abord

python

                                    # Bon

                                    message = f"Bonjour {nom}, vous avez {nb_messages} messages"

Variables explicites dans les f-strings

Formatage cohérent

python

                                    # Cohérent pour les prix

                                    print(f"Prix HT: {prix_ht:.2f}€")

                                    print(f"Prix TTC: {prix_ttc:.2f}€")

Même format pour des données similaires

❌ Pièges à éviter :

Expressions trop complexes

python

                                    # Éviter

                                    result = f"Résultat: {sum([x*2 for x in data if x > 10])}"

                                    # Mieux

                                    valeur = sum([x*2 for x in data if x > 10])

                                    result = f"Résultat: {valeur}"

Oubli des f-strings

python

                                    # Erreur courante

                                    message = "Bonjour {nom}" # Oubli du 'f'

                                    # Affiche: Bonjour {nom}

                                    # Correct

                                    message = f"Bonjour {nom}"

💡 Conseil d'expert :

Les f-strings sont évaluées au moment de l'exécution. Attention aux variables qui peuvent changer entre la définition et l'utilisation de la f-string !

Input Utilisateur et Interaction

Apprenez à créer des programmes interactifs avec la fonction input().

1 La fonction input() - Récupérer des données

Qu'est-ce que input() ?

  • Fonction built-in qui lit une ligne depuis l'entrée standard
  • Affiche un message et attend la saisie utilisateur
  • Retourne toujours une chaîne de caractères (str)
  • Pause l'exécution jusqu'à ce que Enter soit pressé

Syntaxe de base :

python

# Syntaxe simple
nom = input("Votre nom: ")
print(f"Bonjour {nom}!")
# Sans message
reponse = input()
# Toujours une chaîne !
age_str = input("Âge: ")  # "25"
print(type(age_str))  # &lt;class 'str'=""&gt;&lt;/class&gt;

Conversion de types :

python

# Conversion en nombre entier
age_str = input("Votre âge: ")
age = int(age_str)
print(f"Dans 10 ans: {age + 10}")
# Conversion directe
prix = float(input("Prix: "))
quantite = int(input("Quantité: "))
total = prix * quantite
# Validation booléenne
continuer = input("Continuer? (o/n): ")
valide = continuer.lower() == "o"

Attention aux erreurs :

int("abc") génère une ValueError. Utilisez try/except pour une saisie robuste.

2 Validation et Gestion d'Erreurs

Validation simple :

python

# Validation d'âge
while True:
    try:
        age = int(input("Âge: "))
        if 0 <= age <= 120:
            break
        print("Âge invalide!")
    except ValueError:
        print("Entrez un nombre!")
# Choix multiple
choix_valides = ["1", "2", "3"]
while True:
    choix = input("Choisir (1-3): ")
    if choix in choix_valides:
        break
    print("Choix invalide!")

Fonctions de validation :

python

def demander_entier(message, min_val=None, max_val=None):
    """Demande un entier valide"""
    while True:
        try:
            valeur = int(input(message))
            if min_val and valeur < min_val:
                print(f"Minimum: {min_val}")
                continue
            if max_val and valeur > max_val:
                print(f"Maximum: {max_val}")
                continue
            return valeur
        except ValueError:
            print("Entrez un nombre valide!")
# Utilisation
age = demander_entier("Âge: ", 0, 120)

🔧 Méthodes Avancées des Listes

Méthodes de suppression :

python

fruits = ["pomme", "banane", "orange", "kiwi"]
# pop() - Retire ET retourne un élément
dernier = fruits.pop()  # "kiwi"
premier = fruits.pop(0)  # "pomme"
print(fruits)  # ["banane", "orange"]
# remove() - Supprime la première occurrence
nombres = [1, 2, 3, 2, 4]
nombres.remove(2)  # Supprime le premier 2
print(nombres)  # [1, 3, 2, 4]
# clear() - Vide complètement
test = [1, 2, 3]
test.clear()
print(test)  # []

Méthodes utilitaires :

python

nombres = [3, 1, 4, 1, 5]
# index() - Trouve la position
position = nombres.index(4)  # 2
# count() - Compte les occurrences
fois = nombres.count(1)  # 2
# copy() - Crée une copie
copie = nombres.copy()
copie.append(9)
print(nombres)  # [3, 1, 4, 1, 5] (inchangé)
print(copie)  # [3, 1, 4, 1, 5, 9]
# Différence avec l'assignation
ref = nombres # Même objet!
ref.append(0)
print(nombres)  # [3, 1, 4, 1, 5, 0] (modifié!)

pop() vs remove() :
  • pop() retourne l'élément supprimé
  • remove() ne retourne rien
  • pop() par index, remove() par valeur
Gestion d'erreurs :
  • pop() sur liste vide → IndexError
  • remove() élément absent → ValueError
  • index() élément absent → ValueError
Cas d'usage :
  • pop() : pile, file (stack/queue)
  • remove() : suppression conditionnelle
  • copy() : éviter les effets de bord

Conditions et Tests Logiques

Maîtrisez les structures conditionnelles pour créer des programmes intelligents qui prennent des décisions.

1 Opérateurs de Comparaison

Opérateurs disponibles :

== Égal à

Vérifie si deux valeurs sont identiques

!= Différent de

Vérifie si deux valeurs sont différentes

< > <= >= Comparaisons

Inférieur, supérieur, inférieur/égal, supérieur/égal

Exemples pratiques :

python

age = 18
nom = "Alice"
score = 85
# Comparaisons numériques
print(age == 18)      # True
print(age != 21)      # True
print(score >= 80)    # True
print(score < 50)     # False
# Comparaisons de chaînes
print(nom == "Alice")  # True
print(nom != "Bob")    # True
print("a" < "b")      # True (ordre alphabétique)

2 Structure if/elif/else

Syntaxe de base :

python

# Structure simple if
age = 20
if age >= 18:
    print("Vous êtes majeur")
# Structure if/else
if age >= 18:
    print("Majeur")
else:
    print("Mineur")
# Structure complète if/elif/else
note = 15
if note >= 16:
    print("Très bien")
elif note >= 14:
    print("Bien")
elif note >= 10:
    print("Passable")
else:
    print("Insuffisant")

Conditions imbriquées :

python

age = 25
permis = True
voiture = False
if age >= 18:
    print("Majeur :")
    if permis:
        print("✅ A le permis")
        if voiture:
            print("🚗 Peut conduire")
        else:
            print("🚌 Transport en commun")
    else:
        print("❌ Pas de permis")
else:
    print("Mineur - pas de conduite")

Règles importantes :
  • L'indentation définit les blocs de code
  • Les deux-points (:) sont obligatoires
  • elif = "else if" (plusieurs conditions)
  • else est toujours en dernier

3 Opérateurs Logiques

and, or, not :

and (ET logique)

Vrai si TOUTES les conditions sont vraies

python

age >= 18 and permis == True

or (OU logique)

Vrai si AU MOINS une condition est vraie

python

day == "samedi" or day == "dimanche"

not (NON logique)

Inverse la valeur booléenne

python

not est_ferme

Exemples combinés :

python

age = 22
etudiant = True
revenus = 15000
weekend = False
# Condition complexe avec and
if age >= 18 and revenus > 10000:
    print("Éligible au crédit")
# Condition avec or
if etudiant or age >= 65:
    print("Réduction disponible")
# Condition avec not
if not weekend:
    print("Jour de semaine")
# Conditions complexes
if (age >= 18 and age <= 25) or etudiant:
    print("Tarif jeune")

4 Appartenance et Identité

Opérateur 'in' (appartenance) :

python

fruits = ["pomme", "banane", "orange"]
nom = "Alice"
voyelles = "aeiou"
# Tester l'appartenance dans une liste
if "pomme" in fruits:
    print("J'ai des pommes!")
# Tester dans une chaîne
if "Al" in nom:
    print("Nom contient 'Al'")
# Vérifier les voyelles
lettre = "e"
if lettre in voyelles:
    print(f"{lettre} est une voyelle")
# Négation avec not in
if "kiwi" not in fruits:
    print("Pas de kiwi")

Opérateur 'is' (identité) :

python

a = None
b = True
c = False
liste1 = [1, 2, 3]
liste2 = [1, 2, 3]
liste3 = liste1
# Tester None (très fréquent)
if a is None:
    print("a est None")
# Tester booléens
if b is True:
    print("b est True")
# Différence entre == et is
print(liste1 == liste2)  # True (même contenu)
print(liste1 is liste2)  # False (objets différents)
print(liste1 is liste3)  # True (même objet)
# Négation avec is not
if a is not None:
    print("a a une valeur")

Quand utiliser is vs == :
  • is : pour None, True, False
  • == : pour comparer les valeurs
  • is teste l'identité d'objet
  • == teste l'égalité du contenu

5 Conditions Ternaires et Techniques Avancées

Opérateur ternaire :

python

# Syntaxe: valeur_si_vrai if condition else valeur_si_faux
age = 20
statut = "majeur" if age >= 18 else "mineur"
print(statut)  # "majeur"
# Avec calculs
prix = 100
reduction = prix * 0.8 if prix > 50 else prix
# Dans des fonctions
def max_simple(a, b):
    return a if a > b else b
print(max_simple(10, 7))  # 10
# Ternaire imbriqué (à éviter généralement)
note = 15
mention = "TB" if note >= 16 else "B" if note >= 14 else "AB"

Valeurs "truthy" et "falsy" :

python

# Valeurs considérées comme False
# False, None, 0, "", [], {}, set()
liste_vide = []
nom_vide = ""
nombre_zero = 0
valeur_none = None
# Test direct sans comparaison
if liste_vide:
    print("La liste a des éléments")
else:
    print("La liste est vide")  # Ceci s'affiche
if nom_vide:
    print("Nom renseigné")
else:
    print("Nom manquant")  # Ceci s'affiche
# Exemple pratique
def traiter_utilisateur(nom, scores=None):
    if not nom:
        return "Nom requis"
    if scores:
        moyenne = sum(scores) / len(scores)
        return f"{nom}: {moyenne}"
    else:
        return f"{nom}: pas de scores"

Exemple Pratique : Système de Notation

python

# Système de notation et d'évaluation d'étudiants

def evaluer_etudiant(nom, notes, absences=0, bonus_participation=False):
    """
    Évalue un étudiant selon ses notes, absences et participation
    """
    # Vérifications préliminaires
    if not nom:
        return "❌ Nom de l'étudiant requis"

    if not notes:
        return f"❌ {nom} : Aucune note enregistrée"

    # Calcul de la moyenne
    moyenne = sum(notes) / len(notes)

    # Ajustements selon les conditions
    if bonus_participation:
        moyenne += 1 # Bonus de participation
        details_bonus = " (+1 pt participation)"
    else:
        details_bonus = ""

    # Pénalités d'absence
    if absences > 0:
        penalite = min(absences * 0.5, 3)  # Max 3 points de pénalité
        moyenne -= penalite
        details_penalite = f" (-{penalite} pts absences)"
    else:
        details_penalite = ""

    # Limitation de la note
    moyenne = max(0, min(20, moyenne))

    # Détermination de la mention
    if moyenne >= 16:
        mention = "Très Bien"
        emoji = "🏆"
    elif moyenne >= 14:
        mention = "Bien"
        emoji = "🥈"
    elif moyenne >= 12:
        mention = "Assez Bien"
        emoji = "🥉"
    elif moyenne >= 10:
        mention = "Passable"
        emoji = "✅"
    else:
        mention = "Insuffisant"
        emoji = "❌"

    # Recommandations conditionnelles
    if moyenne < 8:
        recommandation = "Soutien scolaire recommandé"
    elif moyenne < 10:
        recommandation = "Travail supplémentaire nécessaire"
    elif absences > 3:
        recommandation = "Améliorer l'assiduité"
    else:
        recommandation = "Continue comme ça!"

    # Construction du résultat
    resultat = f"""
{emoji} {nom.title()} - Évaluation
{"="*40}
📊 Moyenne: {moyenne:.2f}/20{details_bonus}{details_penalite}
🏅 Mention: {mention}
📝 Nombre de notes: {len(notes)}
🚪 Absences: {absences}
💡 Recommandation: {recommandation}
"""

    return resultat

def analyser_classe(etudiants):
    """Analyse les statistiques d'une classe"""
    if not etudiants:
        return "Aucun étudiant dans la classe"

    moyennes = []
    admis = 0
    mentions_tb = 0

    for nom, notes, absences, participation in etudiants:
        moyenne = sum(notes) / len(notes) if notes else 0

        # Ajustements identiques à evaluer_etudiant
        if participation:
            moyenne += 1

        if absences > 0:
            penalite = min(absences * 0.5, 3)
            moyenne -= penalite

        moyenne = max(0, min(20, moyenne))
        moyennes.append(moyenne)

        if moyenne >= 10:
            admis += 1

        if moyenne >= 16:
            mentions_tb += 1

    moyenne_classe = sum(moyennes) / len(moyennes)
    taux_reussite = (admis / len(etudiants)) * 100

    return f"""
📊 STATISTIQUES DE LA CLASSE
{"="*30}
👥 Nombre d'étudiants: {len(etudiants)}
📈 Moyenne de classe: {moyenne_classe:.2f}/20
✅ Taux de réussite: {taux_reussite:.1f}%
🏆 Mentions TB: {mentions_tb} ({mentions_tb/len(etudiants)*100:.0f}%)
"""

def demo_conditions():
    """Démonstration du système de conditions"""
    print("🎓 SYSTÈME D'ÉVALUATION SCOLAIRE\\n")

    # Données d'exemple
    etudiants_exemple = [
        ("alice martin", [18, 17, 19, 16], 0, True),
        ("bob durand", [12, 14, 11, 13], 2, False),
        ("claire bernard", [8, 9, 7, 10], 5, False),
        ("david cohen", [15, 16, 14, 17], 1, True),
    ]

    # Évaluation individuelle
    for nom, notes, absences, participation in etudiants_exemple:
        evaluation = evaluer_etudiant(nom, notes, absences, participation)
        print(evaluation)

    # Analyse de classe
    stats_classe = analyser_classe(etudiants_exemple)
    print(stats_classe)

def demo_operateurs():
    """Démonstration des différents types d'opérateurs"""
    print("🔧 DÉMONSTRATION DES OPÉRATEURS\\n")

    # Variables d'exemple
    a, b = 10, 5
    liste_fruits = ["pomme", "banane", "orange"]
    utilisateur = {"nom": "Alice", "age": 25, "actif": True}

    print(f"Variables: a={a}, b={b}")
    print(f"Liste: {liste_fruits}")
    print(f"Utilisateur: {utilisateur}\\n")

    print("🔢 COMPARAISONS:")
    print(f"  a == b: {a == b}")
    print(f"  a != b: {a != b}")
    print(f"  a > b: {a > b}")
    print(f"  a <= b: {a <= b}")

    print("\\n🧠 OPÉRATEURS LOGIQUES:")
    print(f"  (a > b) and (b > 0): {(a > b) and (b > 0)}")
    print(f"  (a < b) or (a > 0): {(a < b) or (a > 0)}")
    print(f"  not (a == b): {not (a == b)}")

    print("\\n📦 APPARTENANCE:")
    print(f"  'pomme' in liste_fruits: {'pomme' in liste_fruits}")
    print(f"  'kiwi' not in liste_fruits: {'kiwi' not in liste_fruits}")
    print(f"  'nom' in utilisateur: {'nom' in utilisateur}")

    print("\\n🆔 IDENTITÉ:")
    val_none = None
    val_true = True
    print(f"  val_none is None: {val_none is None}")
    print(f"  val_true is True: {val_true is True}")
    print(f"  utilisateur['actif'] is not False: {utilisateur['actif'] is not False}")

# Programme principal
if __name__ == "__main__":
    demo_operateurs()
    print("\\n" + "="*60 + "\\n")
    demo_conditions()

    print("\\n✨ Vous maîtrisez maintenant les conditions en Python!")

Boucles et Listes

Maîtrisez les listes Python et les différents types de boucles pour traiter les données.

1 Les Listes - Collections Modifiables

Qu'est-ce qu'une liste ?

  • Collection ordonnée et modifiable
  • Définie avec des crochets []
  • Peut contenir différents types de données
  • Taille dynamique (s'agrandit/rétrécit)

Création et accès :

python

# Liste vide
vide = []
vide2 = list()
# Liste avec données
fruits = ["pomme", "banane", "orange"]
nombres = [1, 2, 3, 4, 5]
mixte = ["hello", 42, True, [1, 2]]
# Accès par index
print(fruits[0])      # "pomme"
print(fruits[-1])     # "orange" (dernier)
print(fruits[1:3])   # ["banane", "orange"]

Méthodes principales :

python

ma_liste = [1, 2, 3]
# Ajouter des éléments
ma_liste.append(4)          # [1, 2, 3, 4]
ma_liste.insert(0, 0)      # [0, 1, 2, 3, 4]
ma_liste.extend([5, 6])   # [0, 1, 2, 3, 4, 5, 6]
# Supprimer des éléments
ma_liste.remove(0)         # Supprime la première occurrence
dernier = ma_liste.pop()    # Retire et retourne le dernier
del ma_liste[0]             # Supprime par index
# Autres opérations
print(len(ma_liste))      # Longueur
print(3 in ma_liste)     # Vérifier présence
ma_liste.sort()            # Trier
ma_liste.reverse()        # Inverser

2 La Boucle FOR - Parcours de Collections

Syntaxe de base :

python

# Parcourir une liste
fruits = ["pomme", "banane", "orange"]
for fruit in fruits:
    print(f"J'aime les {fruit}s")
# Parcourir une chaîne
for lettre in "Python":
    print(lettre)
# Boucle avec range()
for i in range(5):
    print(f"Nombre: {i}")  # 0 à 4
# Range avec début et fin
for i in range(2, 8, 2):
    print(i)  # 2, 4, 6

Techniques avancées :

python

# enumerate() pour index + valeur
noms = ["Alice", "Bob", "Charlie"]
for index, nom in enumerate(noms):
    print(f"{index + 1}. {nom}")
# zip() pour parcourir plusieurs listes
noms = ["Alice", "Bob"]
ages = [25, 30]
for nom, age in zip(noms, ages):
    print(f"{nom} a {age} ans")
# Break et continue
for i in range(10):
    if i == 3:
        continue # Skip 3
    if i == 7:
        break # Stop à 7
    print(i)

3 La Boucle WHILE - Répétition Conditionnelle

Syntaxe et utilisation :

python

# Boucle while basique
compteur = 0
while compteur < 5:
    print(f"Compteur: {compteur}")
    compteur += 1
# Boucle infinie avec break
while True:
    reponse = input("Tapez 'quit' pour sortir: ")
    if reponse == "quit":
        break
    print(f"Vous avez dit: {reponse}")
# Traitement d'une liste
elements = [1, 2, 3, 4, 5]
while elements:
    element = elements.pop()
    print(f"Traité: {element}")

Cas d'usage pratiques :

python

# Validation d'entrée utilisateur
while True:
    try:
        age = int(input("Votre âge: "))
        if 0 <= age <= 120:
            break
        print("Âge invalide!")
    except ValueError:
        print("Entrez un nombre!")
# Recherche dans une liste
nombres = [10, 25, 30, 42, 55]
cible = 30
index = 0
while index < len(nombres):
    if nombres[index] == cible:
        print(f"Trouvé à l'index {index}")
        break
    index += 1

Attention :

Toujours s'assurer que la condition de la boucle while finira par devenir False, sinon boucle infinie !

4 List Comprehensions et Techniques Avancées

List Comprehensions :

python

# Syntaxe de base
# [expression for item in iterable]
# Créer une liste des carrés
carres = [x**2 for x in range(5)]
# Équivalent à:
carres_classique = []
for x in range(5):
    carres_classique.append(x**2)
# Avec condition (filtrage)
pairs = [x for x in range(10) if x % 2 == 0]
# [0, 2, 4, 6, 8]
# Transformation de chaînes
mots = ["python", "java", "javascript"]
majuscules = [mot.upper() for mot in mots]

Techniques avancées :

python

# Compréhension imbriquée
matrice = [[i*j for j in range(3)] for i in range(3)]
# [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
# Aplatir une liste de listes
listes = [[1, 2], [3, 4], [5, 6]]
aplatie = [item for sous_liste in listes for item in sous_liste]
# [1, 2, 3, 4, 5, 6]
# Fonction filter() et map()
nombres = [1, 2, 3, 4, 5, 6]
pairs = list(filter(lambda x: x % 2 == 0, nombres))
doubles = list(map(lambda x: x * 2, nombres))
# Fonction any() et all()
notes = [15, 12, 18, 16]
tous_admis = all(note >= 10 for note in notes)
au_moins_un_excellent = any(note >= 18 for note in notes)

5 Exemple Pratique : Analyseur de Texte

python

# Analyseur de texte - Démo boucles et listes

def analyser_texte(texte):
    """
    Analyse un texte et retourne des statistiques détaillées.
    Démontre l'utilisation des listes, boucles et techniques Python.
    """

    # Préparation du texte
    texte_nettoye = texte.lower().strip()
    mots = texte_nettoye.split()

    # Statistiques de base avec boucles
    nb_caracteres = len(texte)
    nb_mots = len(mots)
    nb_phrases = texte.count('.') + texte.count('!') + texte.count('?')

    # Compter les voyelles avec une boucle for
    voyelles = "aeiou"
    nb_voyelles = 0
    for caractere in texte_nettoye:
        if caractere in voyelles:
            nb_voyelles += 1

    # Analyse des mots avec list comprehension
    mots_courts = [mot for mot in mots if len(mot) <= 3]
    mots_longs = [mot for mot in mots if len(mot) > 7]
    longueurs_mots = [len(mot) for mot in mots]

    # Fréquence des mots avec une boucle et dictionnaire
    frequence_mots = {}
    for mot in mots:
        # Nettoyer le mot (enlever ponctuation)
        mot_propre = "".join(c for c in mot if c.isalpha())
        if mot_propre:
            frequence_mots[mot_propre] = frequence_mots.get(mot_propre, 0) + 1

    # Trouver les mots les plus fréquents
    mots_frequents = sorted(frequence_mots.items(), key=lambda x: x[1], reverse=True)

    # Calculer moyennes
    longueur_moyenne = sum(longueurs_mots) / len(longueurs_mots) if longueurs_mots else 0

    return {
        "caracteres": nb_caracteres,
        "mots": nb_mots,
        "phrases": nb_phrases,
        "voyelles": nb_voyelles,
        "mots_courts": mots_courts,
        "mots_longs": mots_longs,
        "longueur_moyenne": round(longueur_moyenne, 2),
        "mots_frequents": mots_frequents[:5],  # Top 5
        "mots_uniques": len(frequence_mots)
    }

def afficher_analyse(stats):
    """Affiche les statistiques de manière formatée"""
    print("="*50)
    print("📊 ANALYSE DU TEXTE")
    print("="*50)

    print(f"📝 Caractères: {stats['caracteres']}")
    print(f"🔤 Mots: {stats['mots']}")
    print(f"📄 Phrases: {stats['phrases']}")
    print(f"🎵 Voyelles: {stats['voyelles']}")
    print(f"📏 Longueur moyenne des mots: {stats['longueur_moyenne']} caractères")
    print(f"🎯 Mots uniques: {stats['mots_uniques']}")

    print("\\n🏆 TOP 5 DES MOTS LES PLUS FRÉQUENTS:")
    for i, (mot, freq) in enumerate(stats["mots_frequents"], 1):
        print(f"  {i}. '{mot}' - {freq} fois")

    if stats["mots_courts"]:
        print(f"\\n🤏 Mots courts (≤3 lettres): {len(stats['mots_courts'])}")
        print(f"   Exemples: {', '.join(stats['mots_courts'][:5])}")

    if stats["mots_longs"]:
        print(f"\\n📏 Mots longs (>7 lettres): {len(stats['mots_longs'])}")
        print(f"   Exemples: {', '.join(stats['mots_longs'][:3])}")

def jeu_devinette():
    """Mini-jeu utilisant les boucles while et listes"""
    import random

    mots_mystere = [
        "python", "programmation", "ordinateur",
        "algorithme", "variables", "fonctions"
    ]

    mot_choisi = random.choice(mots_mystere)
    lettres_trouvees = ["_" for _ in mot_choisi]
    lettres_essayees = []
    essais_restants = 6

    print("🎯 JEU DE DEVINETTES - Trouvez le mot mystère!")
    print(f"Mot à trouver: {' '.join(lettres_trouvees)}")

    while 0 and "_" in lettres_trouvees:
        print(f"\\nEssais restants: {essais_restants}")
        print(f"Lettres essayées: {', '.join(lettres_essayees) if lettres_essayees else 'Aucune'}")

        lettre = input("Proposez une lettre: ").lower().strip()

        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.append(lettre)

        if lettre in mot_choisi:
            print(f"✅ Bien joué! La lettre '{lettre}' est dans le mot.")
            for i, caractere in enumerate(mot_choisi):
                if caractere == lettre:
                    lettres_trouvees[i] = lettre
        else:
            essais_restants -= 1
            print(f"❌ Dommage! La lettre '{lettre}' n'est pas dans le mot.")

        print(f"Mot: {' '.join(lettres_trouvees)}")

    if "_" not in lettres_trouvees:
        print(f"🎉 Félicitations! Vous avez trouvé: {mot_choisi}")
    else:
        print(f"💀 Perdu! Le mot était: {mot_choisi}")

# Programme principal
if __name__ == "__main__":
    texte_exemple = """
    Python est un langage de programmation puissant et élégant.
    Il est facile à apprendre et permet de créer des applications
    impressionnantes rapidement. Python est utilisé partout:
    web, data science, intelligence artificielle, automation.
    La communauté Python est formidable et très accueillante!
    """

    print("🐍 Démonstration: Boucles et Listes en Python\\n")

    # Analyser le texte
    resultats = analyser_texte(texte_exemple)
    afficher_analyse(resultats)

    # Proposer le jeu
    jouer = input("\\n🎮 Voulez-vous jouer au jeu de devinettes? (o/n): ")
    if jouer.lower() == 'o':
        jeu_devinette()

Tuples et Dictionnaires

Maîtrisez les structures de données essentielles de Python.

1 Les Tuples - Collections Immutables

Qu'est-ce qu'un tuple ?

  • Collection ordonnée et immutable
  • Défini avec des parenthèses ()
  • Peut contenir différents types de données
  • Plus rapide qu'une liste pour l'accès

Création de tuples :

python

# Tuple vide
vide = ()
# Tuple avec des éléments
coordonnees = (3, 5)
personne = ("Alice", 25, "Paris")
# Tuple d'un seul élément (virgule obligatoire!)
singleton = (42,)
# Sans parenthèses (optionnel)
couleurs = "rouge", "vert", "bleu"

Utilisation des tuples :

python

point = (10, 20)
# Accès par index
x = point[0]  # 10
y = point[1]  # 20
# Déballage (unpacking)
x, y = point
print(f"x={x}, y={y}")
# Méthodes utiles
nombres = (1, 2, 3, 2)
print(nombres.count(2))  # 2
print(nombres.index(3))  # 2
# Immutable : ceci génère une erreur
# point[0] = 15  # TypeError!

Cas d'usage :
  • Coordonnées géographiques
  • Retour multiple de fonction
  • Clés de dictionnaire
  • Données qui ne changent pas

2 Les Dictionnaires - Collections Clé-Valeur

Qu'est-ce qu'un dictionnaire ?

  • Collection de paires clé: valeur
  • Défini avec des accolades {}
  • Mutable : peut être modifié
  • Accès très rapide par clé (O(1))

Création de dictionnaires :

python

# Dictionnaire vide
vide = {}
vide2 = dict()
# Avec des données
personne = {
    "nom": "Alice",
    "age": 25,
    "ville": "Paris"
}
# Différents types de clés
mixte = {
    1: "un",
    "2": "deux",
    (3, 4): "tuple_clé"
}

Manipulation des dictionnaires :

python

etudiant = {"nom": "Bob", "note": 15}
# Accès et modification
print(etudiant["nom"])  # Bob
etudiant["age"] = 20 # Ajouter
etudiant["note"] = 16 # Modifier
# Accès sécurisé avec get()
age = etudiant.get("age", 0)  # 20
ville = etudiant.get("ville", "Inconnue")
# Vérifier l'existence d'une clé
if "nom" in etudiant:
    print("Nom trouvé!")
# Supprimer
del etudiant["note"]
age_supprime = etudiant.pop("age")

3 Méthodes et Techniques Avancées

Méthodes des dictionnaires :

python

produit = {
    "nom": "Laptop",
    "prix": 999,
    "marque": "TechCorp"
}
# Obtenir toutes les clés
cles = produit.keys()
print(list(cles))  # ['nom', 'prix', 'marque']
# Obtenir toutes les valeurs
valeurs = produit.values()
print(list(valeurs))  # ['Laptop', 999, 'TechCorp']
# Obtenir paires clé-valeur
items = produit.items()
for cle, valeur in items:
    print(f"{cle}: {valeur}")

Techniques utiles :

python

# Fusionner des dictionnaires (Python 3.9+)
dict1 = {"a": 1, "b": 2}
dict2 = {"c": 3, "d": 4}
fusionné = dict1 | dict2
# Méthode alternative
fusionné2 = {**dict1, **dict2}
# Dictionary comprehension
carres = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# Filtrer un dictionnaire
notes = {"Alice": 15, "Bob": 12, "Claire": 18}
admis = {k: v for k, v in notes.items() if v >= 15}

4 Exemple Pratique : Gestion d'un Inventaire

python

# Exemple pratique : Gestionnaire d'inventaire

# Inventaire avec tuples comme clés (catégorie, nom)
inventaire = {
    ("electronique", "laptop"): {"prix": 999, "stock": 5, "fournisseur": "TechCorp"},
    ("electronique", "souris"): {"prix": 25, "stock": 20, "fournisseur": "AccessCorp"},
    ("mobilier", "chaise"): {"prix": 150, "stock": 12, "fournisseur": "MobilCorp"}
}

def afficher_inventaire(inventaire):
    """Affiche tout l'inventaire de façon organisée"""
    print("=== INVENTAIRE ===")

    # Grouper par catégorie
    categories = {}
    for (categorie, nom), details in inventaire.items():
        if categorie not in categories:
            categories[categorie] = []
        categories[categorie].append((nom, details))

    for categorie, produits in categories.items():
        print(f"\\n📂 {categorie.upper()}")
        for nom, details in produits:
            print(f"  • {nom}: {details['prix']}€ (stock: {details['stock']})")

def rechercher_produit(inventaire, nom_recherche):
    """Recherche un produit par nom"""
    resultats = []
    for (categorie, nom), details in inventaire.items():
        if nom_recherche.lower() in nom.lower():
            resultats.append((categorie, nom, details))
    return resultats

def calculer_valeur_stock(inventaire):
    """Calcule la valeur totale du stock"""
    valeur_totale = 0
    stats_categorie = {}

    for (categorie, nom), details in inventaire.items():
        valeur_produit = details["prix"] * details["stock"]
        valeur_totale += valeur_produit

        if categorie not in stats_categorie:
            stats_categorie[categorie] = 0
        stats_categorie[categorie] += valeur_produit

    return valeur_totale, stats_categorie

def produits_en_rupture(inventaire, seuil=5):
    """Trouve les produits avec un stock faible"""
    rupture = []
    for (categorie, nom), details in inventaire.items():
        if details["stock"] <= seuil:
            rupture.append((categorie, nom, details["stock"]))
    return rupture

# Tests des fonctions
if __name__ == "__main__":
    # Affichage de l'inventaire
    afficher_inventaire(inventaire)

    # Recherche
    resultats = rechercher_produit(inventaire, "laptop")
    print(f"\\n🔍 Recherche 'laptop': {len(resultats)} résultat(s)")

    # Calcul de la valeur
    valeur_totale, stats = calculer_valeur_stock(inventaire)
    print(f"\\n💰 Valeur totale du stock: {valeur_totale}€")
    for cat, val in stats.items():
        print(f"  {cat}: {val}€")

    # Produits en rupture
    rupture = produits_en_rupture(inventaire)
    if rupture:
        print("\\n⚠️ Produits en stock faible:")
        for cat, nom, stock in rupture:
            print(f"  • {nom} ({cat}): {stock} unités")

Shebang et Encoding

Comprenez les premières lignes importantes de vos scripts Python.

1 Le Shebang #!/usr/bin/env python3

Qu'est-ce que c'est ?

python

#!/usr/bin/env python3

  • Shebang : les caractères #! en début de fichier
  • Indique au système quel interpréteur utiliser
  • Permet d'exécuter le script directement : ./script.py
  • /usr/bin/env python3 : trouve automatiquement Python 3

Pourquoi utiliser env ?

python

                            &lt;p class="text-gray-300 text-sm mb-3"&gt;
                                /usr/bin/env python3 est plus portable que /usr/bin/python3
                                car il cherche Python dans le PATH de l'utilisateur.
                            &lt;/p&gt;
                            &lt;p class="text-gray-300 text-sm"&gt;
                                Cela fonctionne même si Python est installé dans un répertoire personnalisé 
                                ou dans un environnement virtuel.
                            &lt;/p&gt;

Utilisation pratique :

python

# Dans votre script mon_script.py :
#!/usr/bin/env python3
print("Hello World")
# Rendre le script exécutable :
chmod +x mon_script.py
# Exécuter directement :
./mon_script.py
# Au lieu de :
python3 mon_script.py

Note importante :

Le shebang n'est utile que sur Unix/Linux/macOS. Sur Windows, il est ignoré mais ne cause pas d'erreur.

2 L'Encoding # -*- coding: utf-8 -*-

Qu'est-ce que c'est ?

python

# -*- coding: utf-8 -*-

  • Spécifie l'encodage du fichier source
  • UTF-8 permet d'utiliser des caractères accentués
  • Obligatoire dans Python 2, optionnel en Python 3
  • Doit être sur la 1ère ou 2ème ligne du fichier

Autres syntaxes acceptées :

python

# Syntaxe Emacs :
# -*- coding: utf-8 -*-
# Syntaxe Vim :
# vim: set fileencoding=utf-8 :
# Syntaxe simple :
# coding: utf-8

Pourquoi l'utiliser ?

python

# Avec UTF-8, vous pouvez écrire :
nom = "François"
ville = "Montréal"
message = "Héllo Wørld! 🐍"
# Caractères spéciaux :
mathematiques = "π = 3.14159"
monnaie = "Prix: 19.99€"
# Même des emojis :
status = "✅ Terminé avec succès!"

Python 3 vs Python 2 :

Python 3 utilise UTF-8 par défaut. L'encoding est donc optionnel mais recommandé pour la compatibilité et la clarté du code.

Exemple complet d'en-tête

python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Mon Premier Script Python
Auteur: Votre Nom
Date: 2024
Description: Script d'exemple avec en-tête complet
"""

def main():
    """Fonction principale du programme"""
    nom = "François"
    message = f"Bonjour {nom}! 🐍 Bienvenue en Python!"
    print(message)

if __name__ == "__main__":
    main()

Commentaires en Python

Apprenez à documenter efficacement votre code Python.

1 Types de Commentaires

Commentaire simple (#) :

python

# Ceci est un commentaire sur une ligne
x = 5 # Commentaire en fin de ligne
# Vous pouvez avoir plusieurs lignes
# de commentaires consécutifs
# pour expliquer du code complexe
########################################
# Section importante du programme     #
########################################

Commentaires multi-lignes (""") :

python

"""
Ceci est un commentaire
sur plusieurs lignes.
Utile pour de longues explications.
"""
def ma_fonction():
    """
    Ceci est une docstring.
    Elle documente la fonction.
    """
    pass

2 Bonnes Pratiques de Commentaires

✅ À FAIRE :

python

# Explique POURQUOI, pas QUOI
# On utilise cette formule complexe car
# l'algorithme standard est trop lent
result = x * 2 + y ** 3
# TODO: Optimiser cette fonction
# FIXME: Gère mal les nombres négatifs
# NOTE: Compatible Python 3.8+
# Constantes métier importantes
TAUX_TVA = 0.20 # 20% en France
MAX_TENTATIVES = 3 # Limite sécurité

❌ À ÉVITER :

python

# Commentaires évidents (inutiles)
# Incrémente x de 1
x += 1
# Commentaires redondants
# Crée une liste vide
ma_liste = []
# Commentaires obsolètes
# Cette fonction additionne (mais maintenant elle multiplie!)
def additionner(a, b):
    return a * b

Règle d'or :

Le code dit CE QUE vous faites, les commentaires disent POURQUOI vous le faites. Un bon code est auto-documenté, les commentaires ajoutent le contexte.

3 Docstrings - Documentation Professionnelle

python

def calculer_prix_ttc(prix_ht, taux_tva=0.20):
    """
    Calcule le prix TTC à partir du prix HT et du taux de TVA.

    Cette fonction prend un prix hors taxe et applique le taux de TVA
    pour obtenir le prix toutes taxes comprises.

    Args:
        prix_ht (float): Prix hors taxe en euros
        taux_tva (float, optional): Taux de TVA (défaut: 0.20 pour 20%)

    Returns:
        float: Prix TTC arrondi à 2 décimales

    Raises:
        ValueError: Si le prix_ht est négatif
        TypeError: Si les paramètres ne sont pas des nombres

    Example:
        >>> calculer_prix_ttc(100.0)
        120.0
        >>> calculer_prix_ttc(100.0, 0.05)
        105.0

    Note:
        Le taux de TVA standard en France est de 20% (0.20)
    """
    if not isinstance(prix_ht, (int, float)):
        raise TypeError("Le prix doit être un nombre")

    if prix_ht < 0:
        raise ValueError("Le prix ne peut pas être négatif")

    prix_ttc = prix_ht * (1 + taux_tva)
    return round(prix_ttc, 2)


class Produit:
    """
    Classe représentant un produit commercial.

    Cette classe gère les informations d'un produit :
    nom, prix, stock et calculs associés.

    Attributes:
        nom (str): Nom du produit
        prix_ht (float): Prix hors taxe
        stock (int): Quantité en stock
    """

    def __init__(self, nom, prix_ht, stock=0):
        """
        Initialise un nouveau produit.

        Args:
            nom (str): Nom du produit
            prix_ht (float): Prix hors taxe
            stock (int, optional): Quantité initiale (défaut: 0)
        """
        self.nom = nom
        self.prix_ht = prix_ht
        self.stock = stock


# Pour voir la documentation :
help(calculer_prix_ttc)  # Affiche la docstring
print(calculer_prix_ttc.__doc__)  # Accès direct

__name__ == "__main__"

Comprenez ce concept fondamental pour structurer vos programmes Python.

1 Qu'est-ce que __name__ ?

Définition :

  • __name__ est une variable spéciale Python
  • Contient le nom du module actuel
  • Vaut "__main__" si le script est exécuté directement
  • Vaut le nom du fichier si il est importé

Test simple :

python

# Dans n'importe quel fichier Python
print(f"Le nom du module est: {__name__}")
# Si exécuté directement:
# Le nom du module est: __main__
# Si importé depuis un autre fichier:
# Le nom du module est: nom_du_fichier

Pourquoi c'est important ?

Cette distinction permet de créer des fichiers qui peuvent être :

  • Exécutés comme programmes principaux
  • Importés comme modules réutilisables

Avantages :

Code réutilisable

Un même fichier peut servir de programme ET de module

Tests intégrés

Permet d'inclure des tests qui ne s'exécutent qu'en direct

Structure propre

Sépare le code utilitaire du code d'exécution

2 Comment l'utiliser ?

Structure recommandée :

python

# mon_module.py
# 1. Imports
import math
import os
# 2. Constantes
PI = 3.14159
# 3. Fonctions réutilisables
def calculer_aire_cercle(rayon):
    """Calcule l'aire d'un cercle"""
    return PI * rayon ** 2
def saluer(nom):
    """Salue une personne"""
    return f"Bonjour {nom}!"
# 4. Code d'exécution directe
if __name__ == "__main__":
    # Code qui s'exécute seulement
    # si le fichier est lancé directement
    print(saluer("Python"))
    print(calculer_aire_cercle(5))

Utilisation du module :

python

# Dans un autre fichier (main.py)
import mon_module
# Utiliser les fonctions du module
message = mon_module.saluer("Alice")
aire = mon_module.calculer_aire_cercle(10)
print(message)  # "Bonjour Alice!"
print(aire)     # 314.159
# Le code dans if __name__ == "__main__"
# ne s'exécute PAS lors de l'import!

Résultat :
  • python mon_module.py → Exécute le code principal
  • import mon_module → Charge seulement les fonctions
  • Même fichier, deux usages différents !

3 Exemples Pratiques

python

# calculatrice.py - Exemple module + programme

def additionner(a, b):
    """Additionne deux nombres"""
    return a + b

def multiplier(a, b):
    """Multiplie deux nombres"""
    return a * b

def calculatrice_interactive():
    """Interface interactive de calculatrice"""
    print("=== CALCULATRICE INTERACTIVE ===")

    while True:
        operation = input("\\nOpération (+, *, q pour quitter): ")

        if operation == 'q':
            print("Au revoir!")
            break

        try:
            a = float(input("Premier nombre: "))
            b = float(input("Second nombre: "))

            if operation == '+':
                resultat = additionner(a, b)
            elif operation == '*':
                resultat = multiplier(a, b)
            else:
                print("Opération non supportée")
                continue

            print(f"Résultat: {a} {operation} {b} = {resultat}")

        except ValueError:
            print("Erreur: Entrez des nombres valides")

def tests_unitaires():
    """Tests automatiques des fonctions"""
    print("🧪 Exécution des tests...")

    # Tests d'addition
    assert additionner(2, 3) == 5
    assert additionner(-1, 1) == 0
    assert additionner(0, 0) == 0
    print("✅ Tests d'addition: OK")

    # Tests de multiplication
    assert multiplier(3, 4) == 12
    assert multiplier(0, 5) == 0
    assert multiplier(-2, 3) == -6
    print("✅ Tests de multiplication: OK")

    print("🎉 Tous les tests sont passés!")

# Point d'entrée principal
if __name__ == "__main__":
    print("📱 Module calculatrice démarré directement")
    print(f"📛 __name__ = {__name__}")

    # Menu principal
    print("\\nQue voulez-vous faire ?")
    print("1. Tests automatiques")
    print("2. Calculatrice interactive")

    choix = input("Votre choix (1 ou 2): ")

    if choix == "1":
        tests_unitaires()
    elif choix == "2":
        calculatrice_interactive()
    else:
        print("Choix invalide")
else:
    # Ce code s'exécute quand le module est importé
    print(f"📦 Module calculatrice importé (nom: {__name__})")

# =============================================================
# Exemple d'utilisation depuis un autre fichier (app.py):
# =============================================================

# import calculatrice
#
# # Utiliser les fonctions
# somme = calculatrice.additionner(10, 20)  # 30
# produit = calculatrice.multiplier(5, 6)   # 30
#
# print(f"Somme: {somme}")      # Somme: 30
# print(f"Produit: {produit}")  # Produit: 30
#
# # Le menu interactif ne s'exécute PAS !

# =============================================================
# Comportements selon l'exécution :
# =============================================================

# 🚀 python calculatrice.py
# → __name__ = "__main__"
# → Affiche le menu et permet l'interaction

# 📦 import calculatrice (dans un autre fichier)
# → __name__ = "calculatrice"
# → Charge seulement les fonctions
# → Pas d'interface interactive

4 Bonnes Pratiques

Structure recommandée :

1. Imports en haut

Toujours placer les imports au début

2. Fonctions réutilisables

Définir les fonctions avant le code principal

3. Code principal à la fin

Utiliser if __name__ == "__main__": en dernier

4. Fonction main()

Encapsuler le code principal dans une fonction

Pattern optimal :

python

# Structure idéale
import sys
import os
def fonction_utilitaire():
    pass
def main():
    """Point d'entrée principal"""
    print("Programme principal")
    fonction_utilitaire()
if __name__ == "__main__":
    main()

Cas d'usage typiques :
  • Scripts avec tests intégrés
  • Modules réutilisables avec démo
  • Outils en ligne de commande
  • Applications avec interface

Configuration VSCode pour Python

Optimisez VSCode pour le développement Python.

Extensions indispensables

Extensions essentielles :

Python (Microsoft)

Support complet Python, IntelliSense, débogage

python

ms-python.python

Pylance

Serveur de langage Python ultra-rapide

python

ms-python.vscode-pylance

Python Indent

Indentation automatique intelligente

python

kevinrose.vsc-python-indent

Extensions bonus :

autoDocstring

Génération automatique docstrings

python

njpwerner.autodocstring

Python Test Explorer

Interface graphique pour les tests

python

LittleFoxTeam.vscode-python-test-adapter

Jupyter

Support notebooks Jupyter intégré

python

ms-toolsai.jupyter

Configuration settings.json

python

{
    "python.defaultInterpreterPath": "python",
    "python.linting.enabled": true,
    "python.linting.pylintEnabled": true,
    "python.formatting.provider": "black",
    "python.formatting.blackArgs": ["--line-length=88"],
    "python.sortImports.args": ["--profile", "black"],
    "python.testing.unittestEnabled": false,
    "python.testing.pytestEnabled": true,
    "python.testing.pytestArgs": ["tests"],
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
        "source.organizeImports": true
    },
    "editor.rulers": [88],
    "files.exclude": {
        "**/__pycache__": true,
        "**/*.pyc": true
    }
}

Exemples Pratiques

Mettez en pratique vos connaissances avec des exemples concrets.

Gestion de contacts

python

# Gestion simple de contacts

# Liste pour stocker les contacts
contacts = []

def ajouter_contact(nom, telephone, email):
    """Ajoute un nouveau contact à la liste"""
    contact = {
        "nom": nom,
        "telephone": telephone,
        "email": email
    }
    contacts.append(contact)
    print(f"Contact {nom} ajouté avec succès!")

def afficher_contacts():
    """Affiche tous les contacts"""
    if not contacts:
        print("Aucun contact enregistré.")
        return

    print(f"{'='*50}")
    print("LISTE DES CONTACTS")
    print(f"{'='*50}")

    for i, contact in enumerate(contacts, 1):
        print(f"{i}. {contact['nom']}")
        print(f"   Téléphone: {contact['telephone']}")
        print(f"   Email: {contact['email']}")
        print()

def rechercher_contact(nom_recherche):
    """Recherche un contact par nom"""
    contacts_trouves = []
    for contact in contacts:
        if nom_recherche.lower() in contact["nom"].lower():
            contacts_trouves.append(contact)

    if contacts_trouves:
        print(f"Contacts trouvés pour '{nom_recherche}':")
        for contact in contacts_trouves:
            print(f"- {contact['nom']} ({contact['telephone']})")
    else:
        print(f"Aucun contact trouvé pour '{nom_recherche}'")

def menu_principal():
    """Menu principal de l'application"""
    while True:
        print("\\n" + "="*40)
        print("GESTIONNAIRE DE CONTACTS")
        print("="*40)
        print("1. Ajouter un contact")
        print("2. Afficher tous les contacts")
        print("3. Rechercher un contact")
        print("4. Quitter")

        choix = input("\\nVotre choix (1-4): ")

        if choix == "1":
            nom = input("Nom: ")
            telephone = input("Téléphone: ")
            email = input("Email: ")
            ajouter_contact(nom, telephone, email)

        elif choix == "2":
            afficher_contacts()

        elif choix == "3":
            nom_recherche = input("Nom à rechercher: ")
            rechercher_contact(nom_recherche)

        elif choix == "4":
            print("Au revoir!")
            break

        else:
            print("Choix invalide. Veuillez choisir entre 1 et 4.")

# Point d'entrée du programme
if __name__ == "__main__":
    # Ajouter quelques contacts de test
    ajouter_contact("Alice Dupont", "01.23.45.67.89", "alice@example.com")
    ajouter_contact("Bob Martin", "06.98.76.54.32", "bob@example.com")

    # Lancer l'application
    menu_principal()

Premier Projet : Gestionnaire de Tâches

Créez votre première application Python complète avec interface en ligne de commande.

todo_app.py - Application Complète

python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Gestionnaire de Tâches - Premier Projet Python
Créé pour apprendre les bases de Python

Fonctionnalités:
- Ajouter des tâches
- Marquer comme terminées
- Supprimer des tâches
- Sauvegarder dans un fichier
- Interface utilisateur simple
"""

import json
import os
from datetime import datetime

class GestionnaireTaches:
    """Classe principale pour gérer les tâches"""

    def __init__(self, fichier="taches.json"):
        self.fichier = fichier
        self.taches = []
        self.charger_taches()

    def charger_taches(self):
        """Charge les tâches depuis le fichier JSON"""
        try:
            if os.path.exists(self.fichier):
                with open(self.fichier, 'r', encoding='utf-8') as f:
                    self.taches = json.load(f)
                print(f"✅ {len(self.taches)} tâches chargées")
            else:
                print("📝 Nouveau fichier de tâches créé")
        except Exception as e:
            print(f"❌ Erreur lors du chargement: {e}")

    def sauvegarder_taches(self):
        """Sauvegarde les tâches dans le fichier JSON"""
        try:
            with open(self.fichier, 'w', encoding='utf-8') as f:
                json.dump(self.taches, f, ensure_ascii=False, indent=2)
            print("💾 Tâches sauvegardées")
        except Exception as e:
            print(f"❌ Erreur lors de la sauvegarde: {e}")

    def ajouter_tache(self, description, priorite="normale"):
        """Ajoute une nouvelle tâche"""
        tache = {
            "id": len(self.taches) + 1,
            "description": description,
            "priorite": priorite,
            "terminee": False,
            "date_creation": datetime.now().strftime("%Y-%m-%d %H:%M"),
            "date_completion": None
        }
        self.taches.append(tache)
        print(f"✅ Tâche #{tache['id']} ajoutée: {description}")
        self.sauvegarder_taches()

    def afficher_taches(self, filtre="toutes"):
        """Affiche les tâches selon le filtre"""
        if not self.taches:
            print("📝 Aucune tâche enregistrée")
            return

        # Filtrer les tâches
        taches_filtrees = []
        if filtre == "terminées":
            taches_filtrees = [t for t in self.taches if t["terminee"]]
        elif filtre == "en_cours":
            taches_filtrees = [t for t in self.taches if not t["terminee"]]
        else:
            taches_filtrees = self.taches

        if not taches_filtrees:
            print(f"📝 Aucune tâche {filtre}")
            return

        print(f"\\n{'='*60}")
        print(f"📋 TÂCHES ({filtre.upper()}) - {len(taches_filtrees)} tâche(s)")
        print(f"{'='*60}")

        for tache in taches_filtrees:
            statut = "✅" if tache["terminee"] else "⏳"
            priorite_icon = {"haute": "🔥", "normale": "📋", "basse": "📝"}

            print(f"{statut} #{tache['id']} {priorite_icon.get(tache['priorite'], '📋')} {tache['description']}")
            print(f"   🕒 Créée: {tache['date_creation']} | Priorité: {tache['priorite']}")

            if tache["terminee"] and tache["date_completion"]:
                print(f"   ✅ Terminée: {tache['date_completion']}")
            print()

    def marquer_terminee(self, id_tache):
        """Marque une tâche comme terminée"""
        for tache in self.taches:
            if tache["id"] == id_tache:
                if tache["terminee"]:
                    print(f"⚠️ La tâche #{id_tache} est déjà terminée")
                else:
                    tache["terminee"] = True
                    tache["date_completion"] = datetime.now().strftime("%Y-%m-%d %H:%M")
                    print(f"✅ Tâche #{id_tache} marquée comme terminée")
                    self.sauvegarder_taches()
                return
        print(f"❌ Tâche #{id_tache} non trouvée")

    def supprimer_tache(self, id_tache):
        """Supprime une tâche"""
        for i, tache in enumerate(self.taches):
            if tache["id"] == id_tache:
                tache_supprimee = self.taches.pop(i)
                print(f"🗑️ Tâche #{id_tache} supprimée: {tache_supprimee['description']}")
                self.sauvegarder_taches()
                return
        print(f"❌ Tâche #{id_tache} non trouvée")

    def statistiques(self):
        """Affiche les statistiques des tâches"""
        total = len(self.taches)
        terminees = sum(1 for t in self.taches if t["terminee"])
        en_cours = total - terminees
        pourcentage = (terminees / total * 100) if total > 0 else 0

        print(f"\\n📊 STATISTIQUES")
        print(f"{'='*30}")
        print(f"📝 Total: {total} tâche(s)")
        print(f"✅ Terminées: {terminees}")
        print(f"⏳ En cours: {en_cours}")
        print(f"📈 Progression: {pourcentage:.1f}%")

def menu_principal():
    """Menu principal de l'application"""
    gestionnaire = GestionnaireTaches()

    while True:
        print("\\n" + "="*50)
        print("🐍 GESTIONNAIRE DE TÂCHES PYTHON")
        print("="*50)
        print("1. ➕ Ajouter une tâche")
        print("2. 📋 Voir toutes les tâches")
        print("3. ⏳ Voir tâches en cours")
        print("4. ✅ Voir tâches terminées")
        print("5. ✔️ Marquer comme terminée")
        print("6. 🗑️ Supprimer une tâche")
        print("7. 📊 Statistiques")
        print("8. 🚪 Quitter")

        choix = input("\\n👉 Votre choix (1-8): ").strip()

        if choix == "1":
            description = input("📝 Description de la tâche: ").strip()
            if description:
                print("🔥 Priorité: haute | 📋 normale | 📝 basse")
                priorite = input("⚡ Priorité (normale): ").strip() or "normale"
                if priorite not in ["haute", "normale", "basse"]:
                    priorite = "normale"
                gestionnaire.ajouter_tache(description, priorite)
            else:
                print("❌ Description requise")

        elif choix == "2":
            gestionnaire.afficher_taches()

        elif choix == "3":
            gestionnaire.afficher_taches("en_cours")

        elif choix == "4":
            gestionnaire.afficher_taches("terminées")

        elif choix == "5":
            try:
                id_tache = int(input("🆔 ID de la tâche à terminer: "))
                gestionnaire.marquer_terminee(id_tache)
            except ValueError:
                print("❌ ID invalide")

        elif choix == "6":
            try:
                id_tache = int(input("🆔 ID de la tâche à supprimer: "))
                confirmation = input(f"⚠️ Supprimer la tâche #{id_tache} ? (o/N): ")
                if confirmation.lower() == 'o':
                    gestionnaire.supprimer_tache(id_tache)
            except ValueError:
                print("❌ ID invalide")

        elif choix == "7":
            gestionnaire.statistiques()

        elif choix == "8":
            print("👋 Merci d'avoir utilisé le gestionnaire de tâches !")
            print("🐍 Continuez à coder en Python !")
            break

        else:
            print("❌ Choix invalide. Choisissez entre 1 et 8.")

if __name__ == "__main__":
    print("🐍 Bienvenue dans votre gestionnaire de tâches Python!")
    print("🎯 Votre premier projet Python est lancé!")
    menu_principal()

Instructions d'utilisation

  • 1. Créer le fichier : Créez todo_app.py
  • 2. Copier le code : Collez tout le code Python
  • 3. Exécuter : python todo_app.py
  • 4. Tester : Ajoutez des tâches, marquez-les comme terminées
  • 5. Fichier JSON : Un fichier taches.json sera créé automatiquement

Concepts Python maîtrisés

Classes et objets

Programmation orientée objet, __init__, méthodes

Gestion de fichiers

JSON, lecture/écriture, sauvegarde persistante

Structures de données

Listes, dictionnaires, manipulation de données

Gestion d'erreurs

try/except, validation, robustesse

Interface utilisateur

Menus, input/output, expérience utilisateur

Travaux Pratiques - Améliorations

Niveau Débutant :

  • 🟡 Ajouter une catégorie aux tâches
  • 🟡 Modifier une tâche existante
  • 🟡 Rechercher par mot-clé
  • 🟡 Tri par priorité/date

Niveau Intermédiaire :

  • 🟠 Interface graphique avec Tkinter
  • 🟠 Export vers CSV/Excel
  • 🟠 Notifications système
  • 🟠 Base de données SQLite

Niveau Avancé :

  • 🔴 API REST avec Flask
  • 🔴 Application web complète
  • 🔴 Tests unitaires
  • 🔴 Déploiement sur le cloud

Bravo ! Vous maîtrisez les bases de Python

Vous avez appris les concepts fondamentaux de Python et créé votre première application. Il est temps d'explorer les domaines d'expertise !

🚀 Prochaines étapes recommandées :

1. Maîtriser les librairies populaires • 2. Choisir une spécialisation • 3. Contribuer à des projets open source • 4. Créer un portfolio

Vous maîtrisez les bases de Python

Syntaxe, chaînes, conditions, boucles et collections : vous avez de quoi écrire vos premiers programmes. Passez à la pratique avec les exercices.