Logo OFPPT

ISMO - Institut Spécialisé Dans les Métiers de l'Offshoring de Tétouan

Office de la Formation Professionnelle et de la Promotion du Travail

Initiation à la Programmation avec Python

Dernière mise à jour : Octobre 2025

Partie 1 : L'Environnement et les Bases

Chapitre 1 : Introduction à Python

Bienvenue dans l'univers de Python ! Ce langage est réputé pour sa simplicité, sa lisibilité et sa puissance. Il est utilisé partout : développement web, science des données, intelligence artificielle, automatisation... Ce cours vous donnera les clés pour maîtriser ses fondations.

Pourquoi Python ?

  • Syntaxe simple et claire : Très proche de l'anglais, Python permet d'écrire du code concis et facile à relire, ce qui est idéal pour les débutants.
  • Polyvalent : Un seul langage pour de multiples applications (sites web, jeux, scripts, analyse de données...).
  • Communauté immense : Vous trouverez toujours de l'aide sur des forums comme Stack Overflow et des milliers de bibliothèques (des boîtes à outils de code) pour presque tous les besoins.

Installation des Outils Essentiels

Pour commencer, vous avez besoin de deux choses :

  1. L'interpréteur Python : C'est le "moteur" qui exécute votre code.
    • Allez sur python.org/downloads/.
    • Téléchargez la dernière version stable.
    • Très important (Windows) : Cochez la case "Add Python to PATH" lors de l'installation.
  2. Un éditeur de code : Un logiciel pour écrire votre code. Visual Studio Code est un excellent choix.

Vérifier son Installation

Ouvrez un terminal (PowerShell sur Windows) et tapez la commande suivante :

python --version

PIP, l'App Store de Python

Python est livré avec un outil appelé `pip` qui vous permet de télécharger et d'installer très facilement des "packages" (bibliothèques de code réutilisable).

# Syntaxe pour installer le package 'numpy' (pour les maths)
pip install numpy

Chapitre 2 : Prise en main de Jupyter Notebook

Jupyter Notebook est un outil interactif formidable pour apprendre et expérimenter. Il vous permet de mélanger du code exécutable, du texte, et des visualisations dans un seul document.

Installation et Lancement

Ouvrez un terminal et tapez ces deux commandes, l'une après l'autre :

# 1. Installer Jupyter
pip install jupyter

# 2. Le lancer (après vous être placé dans votre dossier de travail)
jupyter notebook

Certains systèmes préfèrent cette syntaxe pour le lancement :

# Alternative pour lancer notebook
python -m notebook

Chapitre 3 : Variables, Types et Commentaires

Une variable est une "étiquette" que l'on pose sur une "boîte" en mémoire pour stocker une information. Les commentaires, eux, sont des notes pour les humains que Python ignore.

Déclaration et Types de Données

En Python, le type d'une variable est deviné automatiquement. Par convention, on nomme les variables en snake_case.

# Python détecte les types automatiquement
nom_stagiaire = "Ali"        # String (str)
age = 21               # Integer (int)
moyenne = 15.5           # Float (float)
est_present = True         # Boolean (bool)

Chapitre 5 : Aide-Mémoire des Opérateurs et Fonctions

Voici quelques tableaux récapitulatifs à garder sous la main. Ils résument les types de données de base, les opérateurs et quelques fonctions très utiles.

Tableau des Types Standards

Type Nom Complet Description Exemple
int Integer Nombre entier, positif ou négatif, sans décimale. x = 100
float Float Nombre à virgule flottante (décimal). y = 3.14
str String Séquence de caractères, entourée de guillemets. nom = "Python"
bool Boolean Valeur de vérité, ne peut être que Vrai (True) ou Faux (False). est_valide = True
list List Collection ordonnée et modifiable d'éléments. notes = [12, 18, 15]
tuple Tuple Collection ordonnée mais non modifiable (immuable). coordonnees = (10, 20)
dict Dictionary Collection non ordonnée de paires clé-valeur. personne = {"nom": "Ali", "age": 25}

Tableau des Opérateurs Courants

Catégorie Opérateur Description Exemple
Arithmétiques+Addition5 + 2 # 7
-Soustraction5 - 2 # 3
*Multiplication5 * 2 # 10
/Division (résultat flottant)5 / 2 # 2.5
//Division entière (quotient)5 // 2 # 2
%Modulo (reste de la division)5 % 2 # 1
**Puissance5 ** 2 # 25
Comparaison==Égal àa == b
!=Différent dea != b
>Strictement supérieur àa > b
<Strictement inférieur àa < b
>=Supérieur ou égal àa >= b
<=Inférieur ou égal àa <= b
LogiquesandET (vrai si les deux sont vrais)x > 0 and y > 0
orOU (vrai si au moins un est vrai)age < 18 or est_etudiant
notNON (inverse la valeur)not est_bloque

Tableau des Fonctions Standards Utiles

Fonction Description Exemple
Fonctions générales
print()Affiche une valeur dans la console.print("Bonjour")
input()Lit une chaîne de caractères depuis le clavier.nom = input("Votre nom ?")
len()Retourne la longueur (nombre d'éléments) d'un objet.len("abc") # 3
type()Retourne le type d'un objet.type(10) # <class 'int'>
Conversion de type
int()Convertit une valeur en entier.int("25") # 25
float()Convertit une valeur en nombre à virgule.float("3.14") # 3.14
str()Convertit une valeur en chaîne de caractères.str(123) # "123"
Fonctions sur les nombres
abs()Retourne la valeur absolue d'un nombre.abs(-5) # 5
round()Arrondit un nombre à n décimales.round(3.14159, 2) # 3.14
Méthodes sur les chaînes de caractères
.upper()Met la chaîne en majuscules."bonjour".upper() # "BONJOUR"
.lower()Met la chaîne en minuscules."Salut".lower() # "salut"
.strip()Supprime les espaces au début et à la fin." ok ".strip() # "ok"
.replace()Remplace une sous-chaîne par une autre."chat".replace("a", "o") # "chot"
.split()Découpe une chaîne en une liste."a-b-c".split("-") # ['a', 'b', 'c']
Fonctions sur les dates (avec module)
datetime.now()Donne la date et l'heure actuelles (nécessite import datetime).datetime.datetime.now()

Chapitre 4 : Affichage et Lecture de Données

Un programme interagit avec le monde extérieur : il affiche des résultats (sortie) et demande des informations à l'utilisateur (entrée).

Maîtriser print() : Séparateurs et Terminaisons

# Utiliser 'sep' pour joindre des éléments avec un séparateur personnalisé
print(24, 10, 2025, sep="/")
> Affiche: 24/10/2025

# Utiliser 'end' pour contrôler ce qui se passe à la fin de la ligne
print("Progression : ", end="") # Ne pas aller à la ligne
print("100%")
> Affiche: Progression : 100%

Les Caractères d'Échappement

Dans les chaînes de caractères, le backslash \ permet d'insérer des caractères spéciaux.

  • \n : pour un retour à la ligne.
  • \t : pour une tabulation (un grand espace).
  • \' ou \" : pour afficher un guillemet à l'intérieur d'une chaîne.
# Utiliser \n pour sauter des lignes
print("Titre du Rapport\n" + "-"*20)

# Utiliser \t pour aligner du texte en colonnes
print("Produit\tQuantité\tPrix")
print("Clavier\t10\t\t250 DH")

# Afficher une citation
print('L\'important c\'est de participer.')

Lire les entrées avec input()

Rappel crucial : input() retourne toujours une chaîne (`str`). La conversion est presque toujours nécessaire pour les nombres !

# On peut combiner la lecture et la conversion en une seule ligne
annee_naissance = int(input("Quelle est votre année de naissance ? "))
age = 2025 - annee_naissance
print(f"Vous aurez environ {age} ans en 2025.")

Série d'Exercices : Les Fondamentaux

Mettez en pratique ce que vous venez d'apprendre. Essayez de résoudre chaque exercice avant de regarder la solution.

Exercice 1 : Salutation Personnalisée

Demandez le prénom et le nom de l'utilisateur, puis affichez un message de bienvenue sous la forme "Bonjour [Prénom] [Nom] !".

prenom = input("Quel est votre prénom ? ")
nom = input("Quel est votre nom ? ")
print(f"Bonjour {prenom} {nom} !")

Exercice 2 : Calcul de la Surface d'un Rectangle

Demandez la longueur et la largeur d'un rectangle à l'utilisateur (qui peuvent être des nombres à virgule), puis calculez et affichez sa surface.

longueur = float(input("Entrez la longueur du rectangle : "))
largeur = float(input("Entrez la largeur du rectangle : "))
surface = longueur * largeur
print(f"La surface du rectangle est de {surface} unités carrées.")

Exercice 3 : Répéteur de Mot

Demandez un mot et un nombre entier. Affichez ensuite le mot répété le nombre de fois demandé.

mot = input("Entrez un mot : ")
nombre = int(input("Combien de fois le répéter ? "))
print(mot * nombre)

Exercice 4 : Calculateur de Pourboire

Demandez le montant d'une addition et le pourcentage de pourboire souhaité (ex: 15 pour 15%). Calculez le montant du pourboire et le total à payer.

addition = float(input("Montant de l'addition : "))
pourcentage = float(input("Pourcentage du pourboire (ex: 15) : "))
pourboire = addition * (pourcentage / 100)
total = addition + pourboire
print(f"Pourboire : {pourboire:.2f} DH")
print(f"Total à payer : {total:.2f} DH")

Exercice 5 : Convertisseur de Durée

Demandez un nombre total de minutes, puis convertissez-le en heures et minutes (ex: 130 minutes = 2 heure(s) et 10 minute(s)).

total_minutes = int(input("Entrez une durée en minutes : "))
heures = total_minutes // 60  # La division entière // donne le nombre d'heures
minutes = total_minutes % 60   # Le modulo % donne le reste de la division
print(f"{total_minutes} minutes = {heures} heure(s) et {minutes} minute(s).")

Exercice 6 : Reçu Simplifié

Demandez le nom d'un produit, sa quantité et son prix unitaire. Affichez un mini-reçu bien formaté.

produit = input("Nom du produit : ")
quantite = int(input("Quantité achetée : "))
prix_unitaire = float(input("Prix unitaire (DH) : "))
total = quantite * prix_unitaire
print("\n--- TICKET DE CAISSE ---")
print(f"Produit : \t{produit}")
print(f"Quantité : \t{quantite}")
print(f"Total à payer : {total:.2f} DH")

Exercice 7 : Permutation de Valeurs

Demandez deux valeurs, `A` et `B`, à l'utilisateur. Affichez-les, puis échangez leurs valeurs (ce qui était dans `A` va dans `B` et vice-versa) et affichez-les de nouveau.

a = input("Entrez la valeur de A : ")
b = input("Entrez la valeur de B : ")
print(f"Avant permutation : A = {a}, B = {b}")
# Astuce Python pour permuter en une seule ligne !
a, b = b, a
print(f"Après permutation : A = {a}, B = {b}")

Exercice 8 : Longueur d'un Nom

Demandez son nom complet à l'utilisateur et dites-lui de combien de caractères il est composé (espaces inclus) en utilisant la fonction `len()`.

nom_complet = input("Entrez votre nom complet : ")
longueur = len(nom_complet)
print(f"Votre nom complet contient {longueur} caractères.")

Exercice 9 : Calcul de la Moyenne

Demandez 3 notes à l'utilisateur (maths, français, histoire) et calculez la moyenne de ces trois notes. Affichez le résultat avec une seule décimale.

print("--- Calcul de Moyenne ---")
note_maths = float(input("Note de Maths : "))
note_fr = float(input("Note de Français : "))
note_hist = float(input("Note d'Histoire : "))
moyenne = (note_maths + note_fr + note_hist) / 3
print(f"Votre moyenne générale est de : {moyenne:.1f}/20")

Exercice 10 : Générateur d'Acronyme

Demandez à l'utilisateur trois mots (par exemple "Office", "Formation", "Professionnelle"). Affichez l'acronyme en prenant la première lettre de chaque mot en majuscule.

mot1 = input("Entrez le premier mot : ")
mot2 = input("Entrez le deuxième mot : ")
mot3 = input("Entrez le troisième mot : ")
# On accède à la première lettre avec [0]
acronyme = mot1[0] + mot2[0] + mot3[0]
print(f"L'acronyme est : {acronyme.upper()}") # .upper() pour mettre en majuscules

Partie 2 : Logique et Contrôle

Chapitre 5 : Les Structures Conditionnelles (if...elif...else)

Les conditions sont les carrefours de votre programme : elles lui permettent de prendre des décisions et de réagir différemment selon les situations, le rendant "intelligent" et dynamique.

Exemple 1 : Le `if` simple

age = int(input("Quel est votre âge ? "))
if age >= 18:
    print("Vous êtes majeur. L'accès est autorisé.")
print("Fin du programme.")

Exemple 2 : Le `else`

temperature = 12
if temperature > 25:
    print("Il fait chaud, sortez en t-shirt !")
else:
    print("Il fait frais, prenez une veste.")

Exemple 3 : Le `elif`

note = 14.5
if note >= 16:
    print("Mention Très Bien")
elif note >= 14:
    print("Mention Bien")
elif note >= 12:
    print("Mention Assez Bien")
else:
    print("Passable ou Insuffisant")

Exemple 4 : Conditions complexes avec `and` et `or`

age = 25
permis = True
if age >= 18 and permis:
    print("Vous pouvez louer la voiture.")

est_etudiant = False
a_moins_de_26_ans = True
if est_etudiant or a_moins_de_26_ans:
    print("Vous bénéficiez du tarif réduit.")

Exemple 5 : Conditions imbriquées

montant_achat = 120
est_membre_fidele = True
if est_membre_fidele:
    print("Bienvenue, membre fidèle !")
    if montant_achat > 100:
        print("Vous avez droit à une réduction de 15% !")
    else:
        print("Vous avez droit à une réduction de 5%.")
else:
    print("Devenez membre pour profiter de nos offres.")

Série d'Exercices sur les Conditions

Exercice 1 : Calculateur de Tarif de Cinéma

Demandez l'âge d'un spectateur. Le prix est de 7€ pour les enfants (<13 ans), 12€ pour les adultes (13-64 ans), et 9€ pour les seniors (>=65 ans). Affichez le prix.

age = int(input("Quel est votre âge ? "))
if age < 13:
    prix = 7
elif age >= 65:
    prix = 9
else:
    prix = 12
print(f"Le prix de votre billet est de {prix}€.")

Exercice 2 : Vérificateur de Mot de Passe

Demandez un mot de passe. S'il fait moins de 8 caractères, affichez "Mot de passe trop court". Sinon, affichez "Mot de passe valide".

mdp = input("Entrez votre mot de passe : ")
if len(mdp) < 8:
    print("Mot de passe trop court.")
else:
    print("Mot de passe valide.")

Exercice 3 : Année Bissextile

Demandez une année. Affichez si elle est bissextile. Rappel : une année est bissextile si (divisible par 4 ET non divisible par 100) OU (divisible par 400).

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.")

Exercice 4 : Calcul de l'IMC

Demandez poids (kg) et taille (m). Calculez l'IMC (poids / taille²). Affichez la catégorie : "Maigreur" (<18.5), "Poids normal" (18.5-25), "Surpoids" (>25).

poids = float(input("Votre poids (kg) : "))
taille = float(input("Votre taille (m) : "))
imc = poids / (taille ** 2)
if imc < 18.5:
    categorie = "Maigreur"
elif imc <= 25:
    categorie = "Poids normal"
else:
    categorie = "Surpoids"
print(f"Votre IMC est de {imc:.2f}. Catégorie : {categorie}.")

Exercice 5 : Tri de Trois Nombres

Demandez trois nombres (a, b, c). Affichez-les dans l'ordre croissant en utilisant des conditions.

a = int(input("Entrez le nombre a : "))
b = int(input("Entrez le nombre b : "))
c = int(input("Entrez le nombre c : "))

if a < b:
    # Si a est plus petit que b
    if b < c:
        # a < b < c
        print(a, b, c)
    elif a < c:
        # a < c <= b
        print(a, c, b)
    else:
        # c <= a < b
        print(c, a, b)
else:
    # Si b est plus petit ou égal à a
    if a < c:
        # b <= a < c
        print(b, a, c)
    elif b < c:
        # b < c <= a
        print(b, c, a)
    else:
        # c <= b <= a
        print(c, b, a)

Chapitre 6 : Le Filtrage par Motif (match...case)

Introduit en Python 3.10, `match...case` est une alternative plus lisible aux longues chaînes de `if/elif/else`, surtout quand on teste les différentes valeurs possibles d'une seule variable.

Exemple 1 : Cas d'usage simple (menu)

choix = "3"
match choix:
    case "1":
        print("Action 1 sélectionnée.")
    case "2":
        print("Action 2 sélectionnée.")
    case "3":
        print("Action 3 sélectionnée.")
    case _:
        print("Choix invalide.")

Exemple 2 : Combiner plusieurs cas avec `|`

reponse = input("Voulez-vous continuer (oui/non) ? ").lower()
match reponse:
    case "oui" | "o" | "yes":
        print("Continuation...")
    case "non" | "n" | "no":
        print("Arrêt du programme.")
    case _:
        print("Réponse non reconnue.")

Série d'Exercices sur `match...case`

Exercice 1 : Jours de la Semaine

Demandez un numéro de jour (1-7). Affichez le nom du jour correspondant. Gérez les cas invalides.

jour = int(input("Entrez le numéro du jour (1-7) : "))
match jour:
    case 1: print("Lundi")
    case 2: print("Mardi")
    case 3: print("Mercredi")
    case 4: print("Jeudi")
    case 5: print("Vendredi")
    case 6: print("Samedi")
    case 7: print("Dimanche")
    case _: print("Numéro de jour invalide.")

Chapitre 7 : Les Boucles (`for` et `while`)

Les boucles sont le cœur de l'automatisation. Elles permettent de répéter une action un nombre défini de fois (`for`) ou tant qu'une condition reste vraie (`while`).

La Boucle `for`

Exemple 1 : Utilisation de `range()`

# Compter de 0 à 4
for i in range(5):
    print(f"Le compteur est à {i}")
# Table de multiplication
for i in range(1, 11):
    print(f"7 x {i} = {7 * i}")

Exemple 2 : Contrôler la boucle avec break et continue

# Arrêter la boucle avec break
for i in range(1, 20):
    if i % 5 == 0:
        print(f"Trouvé ! {i} est un multiple de 5.")
        break
# Sauter une itération avec continue
for i in range(1, 10):
    if i % 2 == 0: # Si i est pair
        continue
    print(f"{i} est impair.")

Exemple 3 : Utilisation des pas dans un range

for i in range(1, 10, 2):
    print(f"{i} est impair.")

Les Listes de Compréhension : Une Alternative Élégante aux Boucles

Les compréhensions de liste en Python offrent une syntaxe plus courte et plus lisible pour créer une nouvelle liste à partir des valeurs d'une liste existante ou d'un autre itérable. La structure de base est [expression for element in iterable if condition].

Exemples avec Listes de Compréhension

Exemple 1 : Remplacer `range()`

Au lieu d'afficher les nombres un par un, nous pouvons directement créer une liste contenant ces nombres.

# Créer une liste des nombres de 0 à 4
nombres = [i for i in range(5)]
print(nombres) 

# Créer la table de multiplication de 7
table_de_7 = [f"7 x {i} = {7 * i}" for i in range(1, 11)]
print(table_de_7)

Exemple 2 : Intégrer des conditions

Les compréhensions de liste permettent d'ajouter une condition `if` pour filtrer les éléments à inclure dans la nouvelle liste.

# Obtenir les nombres impairs de 1 à 9
impairs = [i for i in range(1, 10) if i % 2 != 0]
print(impairs) 

Notez que les instructions `break` et `continue` ne sont pas directement utilisables dans les compréhensions de liste, car elles sont conçues pour générer une nouvelle liste en une seule expression plutôt que de contrôler le flux d'une boucle de manière complexe.

Exemple 3 : Utiliser les pas

L'utilisation de pas dans la fonction `range` peut être directement intégrée dans une liste de compréhension pour générer des séquences spécifiques.

# Créer une liste de nombres impairs de 1 à 9 avec un pas de 2
impairs_avec_pas = [i for i in range(1, 10, 2)]
print(impairs_avec_pas) 

La Boucle `while`

Exemple 1 : Validation de saisie

mot_de_passe = ""
while mot_de_passe != "python123":
    mot_de_passe = input("Entrez le mot de passe : ")
print("Accès autorisé !")

Série d'Exercices sur les Boucles

Exercice (`for`) : Compteur de voyelles

Demandez une phrase. Parcourez-la pour compter le nombre de voyelles (a, e, i, o, u, y).

phrase = input("Entrez une phrase : ").lower()
voyelles = "aeiouy"
compteur = 0
for lettre in phrase:
    if lettre in voyelles:
        compteur += 1
print(f"Il y a {compteur} voyelles dans cette phrase.")

Exercice (`while`) : Le jeu du "Plus ou Moins"

Le programme choisit un nombre secret (ex: 42). L'utilisateur doit le deviner, et le programme répond "plus grand" ou "plus petit" jusqu'à la bonne réponse.

nombre_secret = 42
tentative = 0
while tentative != nombre_secret:
    tentative = int(input("Devinez le nombre : "))
    if tentative < nombre_secret:
        print("C'est plus grand !")
    elif tentative > nombre_secret:
        print("C'est plus petit !")
print(f"Bravo ! Le nombre secret était bien {nombre_secret}.")

Partie 3 : Fonctions et Structures de Données Essentielles

Chapitre 8 : Les Fonctions

Les fonctions sont des blocs de code réutilisables qui exécutent une tâche spécifique. Elles permettent d'organiser votre code, de le rendre plus lisible, plus facile à maintenir et d'éviter la répétition.

Exemple 1 : Définition et appel d'une fonction simple

Une fonction sans argument ni valeur de retour se contente d'exécuter un bloc d'instructions.

def dire_bonjour():
    print("Bonjour tout le monde !")

# Appel de la fonction
dire_bonjour()

Exemple 2 : Fonctions avec arguments

Les arguments permettent de passer des informations à une fonction pour qu'elle puisse les utiliser. Ils sont spécifiés entre les parenthèses lors de la définition.

def saluer_personne(nom):
    print(f"Bonjour, {nom} !")

saluer_personne("Alice")
saluer_personne("Bob")

Exemple 3 : Fonctions avec valeur(s) de retour (`return`)

Le mot-clé return permet à une fonction de renvoyer une ou plusieurs valeurs après son exécution. Ces valeurs peuvent ensuite être utilisées dans le reste du programme.

def additionner(a, b):
    resultat = a + b
    return resultat

somme = additionner(5, 3)
print(f"La somme est : {somme}")

# Une fonction peut retourner plusieurs valeurs sous forme de tuple
def calculer_stats(liste_nombres):
    minimum = min(liste_nombres)
    maximum = max(liste_nombres)
    return minimum, maximum

nombres = [10, 20, 5, 30]
min_val, max_val = calculer_stats(nombres)
print(f"Minimum : {min_val}, Maximum : {max_val}")

Exemple 4 : Arguments par défaut et arguments nommés

Vous pouvez donner des valeurs par défaut à des arguments. Si l'utilisateur ne fournit pas cette argument, la valeur par défaut est utilisée. Les arguments nommés permettent de spécifier les arguments par leur nom, ce qui rend le code plus clair et permet de ne pas se soucier de l'ordre.

def afficher_message(message, prefixe="INFO"):
    print(f"[{prefixe}] {message}")

# Utilisation avec l'argument par défaut
afficher_message("Ceci est un message.")

# Utilisation en écrasant l'argument par défaut
afficher_message("Ceci est une erreur.", "ERREUR")

# Utilisation d'arguments nommés
afficher_message(prefixe="DEBUG", message="Valeur de X est 10.")

Exemple 5 : Portée des variables (Locale vs Globale)

Les variables définies à l'intérieur d'une fonction sont "locales" et ne sont accessibles qu'à l'intérieur de cette fonction. Les variables définies en dehors de toute fonction sont "globales" et peuvent être lues par les fonctions.

variable_globale = "Je suis globale"

def ma_fonction():
    variable_locale = "Je suis locale"
    print(f"Dans la fonction (locale) : {variable_locale}")
    print(f"Dans la fonction (globale) : {variable_globale}")

ma_fonction()
print(f"En dehors de la fonction (globale) : {variable_globale}")
# print(variable_locale) # Ceci provoquerait une erreur car variable_locale n'est pas définie ici.

# Modifier une variable globale depuis une fonction (déconseillé sans "global")
compteur_global = 0
def incrementer():
    global compteur_global # Indique que nous voulons modifier la variable globale
    compteur_global += 1
    print(f"Compteur dans la fonction : {compteur_global}")

incrementer() # Compteur dans la fonction : 1
incrementer() # Compteur dans la fonction : 2
print(f"Compteur global final : {compteur_global}") # Compteur global final : 2

Série d'Exercices sur les Fonctions

Exercice 1 : Calcul du Carré

Écrivez une fonction nommée calculer_carre qui prend un nombre en argument et retourne son carré.

def calculer_carre(nombre):
    return nombre ** 2

# Test
print(calculer_carre(4))   # Devrait afficher 16
print(calculer_carre(7))   # Devrait afficher 49

Exercice 2 : Salutation Personnalisée

Créez une fonction saluer qui prend un nom et une heure_journee (avec "jour" comme valeur par défaut) en arguments et affiche un message de salutation approprié comme "Bonjour, [nom] ! Bonne [heure_journee].".

def saluer(nom, heure_journee="jour"):
    print(f"Bonjour, {nom} ! Bonne {heure_journee}.")

# Tests
saluer("Sophie")
saluer("Marc", "soirée")
saluer(heure_journee="nuit", nom="Léa")

Exercice 3 : Somme de Nombres

Écrivez une fonction calculer_somme qui prend une liste de nombres en argument et retourne leur somme. Vous pouvez utiliser une boucle for.

def calculer_somme(liste_nombres):
    somme = 0
    for nombre in liste_nombres:
        somme += nombre
    return somme

# Test
print(calculer_somme([1, 2, 3, 4, 5])) # Devrait afficher 15
print(calculer_somme([10, 20])) # Devrait afficher 30

Exercice 4 : Vérificateur de Parité

Écrivez une fonction verifier_parite qui prend un entier et retourne la chaîne de caractères "Pair" si le nombre est pair, et "Impair" sinon.

def verifier_parite(nombre):
    if nombre % 2 == 0:
        return "Pair"
    else:
        return "Impair"

# Tests
print(verifier_parite(6))  # Devrait afficher "Pair"
print(verifier_parite(3))  # Devrait afficher "Impair"

Exercice 5 : Calcul de la Factorielle

Créez une fonction calculer_factorielle qui prend un entier non négatif n et retourne sa factorielle (n!). La factorielle de 0 est 1.

def calculer_factorielle(n):
    if n == 0:
        return 1
    resultat = 1
    for i in range(1, n + 1):
        resultat *= i
    return resultat

# Tests
print(calculer_factorielle(0)) # Devrait afficher 1
print(calculer_factorielle(5)) # Devrait afficher 120 (5*4*3*2*1)
print(calculer_factorielle(3)) # Devrait afficher 6 (3*2*1)

Chapitre 9 : La Documentation (Docstrings)

Écrire du code qui fonctionne est une chose. Écrire du code que vous-même (dans 6 mois) ou que d'autres peuvent comprendre en est une autre. La documentation est la clé. En Python, la norme pour documenter les fonctions, modules et classes est d'utiliser des "docstrings".

Commentaires (`#`) vs Docstrings (`"""..."""`)

Un commentaire (`#`) explique comment le code fonctionne (le "pourquoi" d'une ligne complexe). Une docstring (`"""..."""`) explique ce que fait une fonction (son objectif, ses paramètres, ce qu'elle retourne). La docstring est accessible par Python lui-même.

Exemple 1 : Docstring sur une seule ligne

def dire_bonjour():
    """Affiche un simple message de salutation."""
    print("Bonjour !")

Exemple 2 : Docstring multi-lignes (standard)

C'est le format le plus courant. Il inclut une description, les arguments et ce que la fonction retourne.

def calculer_prix_ttc(prix_ht, taux_tva=0.2):
    """Calcule le prix toutes taxes comprises (TTC) à partir d'un prix hors-taxe.

    Args:
        prix_ht (float or int): Le prix hors-taxe de l'article.
        taux_tva (float, optional): Le taux de TVA à appliquer. 
                                     Par défaut à 0.2 (20%).

    Returns:
        float: Le prix TTC calculé.
    """
    return prix_ht * (1 + taux_tva)

Exemple 3 : Accéder à la documentation

Python vous permet de lire la docstring d'une fonction en utilisant la fonction `help()` ou l'attribut spécial `__doc__`.

# Utiliser help() pour afficher une aide formatée
help(calculer_prix_ttc)

# Accéder directement à la chaîne de caractères brute
print(calculer_prix_ttc.__doc__)

Série d'Exercices sur les Docstrings

Exercice 1 : Documenter une fonction simple

Ajoutez une docstring sur une seule ligne à la fonction suivante : `def afficher_ligne(): print("-" * 20)`

def afficher_ligne():
    """Affiche une ligne de 20 tirets."""
    print("-" * 20)

Exercice 2 : Documenter les arguments

Documentez la fonction suivante en décrivant son objectif et son argument `nom`.

def saluer(nom):
    print(f"Bonjour, {nom} !")
def saluer(nom):
    """Affiche une salutation personnalisée.

    Args:
        nom (str): Le nom de la personne à saluer.
    """
    print(f"Bonjour, {nom} !")

Exercice 3 : Documenter la valeur de retour

Documentez la fonction suivante, en précisant ses arguments et sa valeur de retour.

def addition(a, b):
    return a + b
def addition(a, b):
    """Additionne deux nombres et retourne le résultat.

    Args:
        a (int or float): Le premier nombre.
        b (int or float): Le second nombre.

    Returns:
        int or float: La somme de a et b.
    """
    return a + b

Chapitre 13 : Les Listes (Structures de Données)

Les listes sont l'une des structures de données les plus fondamentales et polyvalentes en Python. Elles permettent de stocker une collection ordonnée et modifiable d'éléments.

Exemple 1 : Création et accès aux éléments

Une liste est définie par des crochets [] et ses éléments sont séparés par des virgules. Les éléments sont indexés à partir de 0.

# Création d'une liste de nombres
nombres = [10, 20, 30, 40, 50]
print(f"Liste complète : {nombres}")

# Accès aux éléments par leur index
print(f"Premier élément : {nombres[0]}")  # Output: 10
print(f"Troisième élément : {nombres[2]}") # Output: 30

# Accès au dernier élément avec un index négatif
print(f"Dernier élément : {nombres[-1]}") # Output: 50

Exemple 2 : Modification des éléments et ajout/suppression

Les listes sont mutables, ce qui signifie que vous pouvez modifier, ajouter ou supprimer des éléments après leur création.

fruits = ["pomme", "banane", "cerise"]
print(f"Liste initiale : {fruits}")

# Modifier un élément
fruits[1] = "orange"
print(f"Après modification : {fruits}") # Output: ['pomme', 'orange', 'cerise']

# Ajouter un élément à la fin
fruits.append("mangue")
print(f"Après ajout : {fruits}") # Output: ['pomme', 'orange', 'cerise', 'mangue']

# Insérer un élément à un index spécifique
fruits.insert(1, "kiwi")
print(f"Après insertion : {fruits}") # Output: ['pomme', 'kiwi', 'orange', 'cerise', 'mangue']

# Supprimer un élément par sa valeur
fruits.remove("orange")
print(f"Après suppression par valeur : {fruits}") # Output: ['pomme', 'kiwi', 'cerise', 'mangue']

# Supprimer un élément par son index (et le récupérer)
fruit_supprime = fruits.pop(0)
print(f"Après suppression par index : {fruits}, fruit supprimé : {fruit_supprime}") # Output: ['kiwi', 'cerise', 'mangue'], fruit supprimé : pomme

# Vider la liste
fruits.clear()
print(f"Liste vidée : {fruits}") # Output: []

Exemple 3 : Parcours de liste avec `for`

La boucle for est couramment utilisée pour itérer sur tous les éléments d'une liste.

couleurs = ["rouge", "vert", "bleu"]
print("Mes couleurs préférées :")
for couleur in couleurs:
    print(f"- {couleur}")

# Parcours avec index (utile si vous avez besoin de la position)
print("Couleurs avec leur index :")
for index, couleur in enumerate(couleurs):
    print(f"À l'index {index} : {couleur}")

Exemple 4 : Tranches (Slicing) et opérations courantes

Vous pouvez extraire des sous-listes (tranches) et effectuer des opérations comme la concaténation ou la recherche.

alphabet = ['a', 'b', 'c', 'd', 'e', 'f']

# Tranche : [début:fin] (fin est exclusive)
print(f"Les 3 premiers éléments : {alphabet[0:3]}") # Output: ['a', 'b', 'c']
print(f"Du 2ème à la fin : {alphabet[1:]}")   # Output: ['b', 'c', 'd', 'e', 'f']
print(f"Les 2 derniers éléments : {alphabet[-2:]}") # Output: ['e', 'f']

# Longueur de la liste
print(f"Nombre d'éléments : {len(alphabet)}") # Output: 6

# Vérifier si un élément est dans la liste
print(f"'c' est dans la liste ? {'c' in alphabet}") # Output: True
print(f"'z' est dans la liste ? {'z' in alphabet}") # Output: False

# Concaténation de listes
liste1 = [1, 2]
liste2 = [3, 4]
liste_concatenee = liste1 + liste2
print(f"Listes concaténées : {liste_concatenee}") # Output: [1, 2, 3, 4]

# Tri d'une liste (modifie la liste originale)
nombres_desordre = [3, 1, 4, 1, 5, 9, 2]
nombres_desordre.sort()
print(f"Liste triée : {nombres_desordre}") # Output: [1, 1, 2, 3, 4, 5, 9]

# Obtenir une nouvelle liste triée sans modifier l'originale
nombres_original = [5, 2, 8, 1]
nombres_tries = sorted(nombres_original)
print(f"Liste originale : {nombres_original}") # Output: [5, 2, 8, 1]
print(f"Nouvelle liste triée : {nombres_tries}") # Output: [1, 2, 5, 8]

Série d'Exercices sur les Listes

Exercice 1 : Créer et Afficher une Liste

Créez une liste appelée fruits_preferes contenant au moins 3 de vos fruits préférés. Affichez la liste entière, puis le premier fruit, et enfin le dernier fruit.

fruits_preferes = ["Pomme", "Mangue", "Fraise", "Raisin"]
print(f"Ma liste de fruits : {fruits_preferes}")
print(f"Mon premier fruit : {fruits_preferes[0]}")
print(f"Mon dernier fruit : {fruits_preferes[-1]}")

Exercice 2 : Modifier une Liste

En utilisant la liste fruits_preferes de l'exercice précédent, ajoutez un nouveau fruit à la fin, insérez un fruit à la deuxième position, puis supprimez le fruit à la troisième position.

fruits_preferes = ["Pomme", "Mangue", "Fraise", "Raisin"]
print(f"Initial : {fruits_preferes}")
fruits_preferes.append("Kiwi")
print(f"Après append : {fruits_preferes}")
fruits_preferes.insert(1, "Ananas")
print(f"Après insert : {fruits_preferes}")
fruits_preferes.pop(2) # Supprime l'élément à l'index 2 (Mangue)
print(f"Après pop : {fruits_preferes}")

Exercice 3 : Calculer la Moyenne

Écrivez une fonction calculer_moyenne qui prend une liste de nombres et retourne leur moyenne. Si la liste est vide, elle doit retourner 0.

def calculer_moyenne(liste_nombres):
    if len(liste_nombres) == 0:
        return 0
    somme = sum(liste_nombres) # Utilisation de la fonction sum() intégrée
    return somme / len(liste_nombres)

# Tests
print(calculer_moyenne([10, 20, 30])) # Devrait afficher 20.0
print(calculer_moyenne([5, 5, 5, 5])) # Devrait afficher 5.0
print(calculer_moyenne([])) # Devrait afficher 0

Exercice 4 : Filtrer les Nombres Pairs

Écrivez une fonction filtrer_pairs qui prend une liste de nombres entiers et retourne une nouvelle liste contenant uniquement les nombres pairs.

def filtrer_pairs(liste_entiers):
    pairs = []
    for nombre in liste_entiers:
        if nombre % 2 == 0:
            pairs.append(nombre)
    return pairs

# Tests
print(filtrer_pairs([1, 2, 3, 4, 5, 6])) # Devrait afficher [2, 4, 6]
print(filtrer_pairs([7, 9, 11])) # Devrait afficher []

Exercice 5 : Inverser une Liste

Créez une fonction inverser_liste qui prend une liste et retourne une nouvelle liste avec les éléments dans l'ordre inverse.

def inverser_liste(ma_liste):
    # Méthode 1 : Utilisation de la méthode reverse() (modifie l'originale)
    # liste_inversee = ma_liste[:] # Crée une copie pour ne pas modifier l'originale
    # liste_inversee.reverse()
    # return liste_inversee

    # Méthode 2 : Utilisation du slicing étendu (crée une nouvelle liste)
    return ma_liste[::-1]

# Tests
originale = ["a", "b", "c"]
print(inverser_liste(originale)) # Devrait afficher ['c', 'b', 'a']
print(inverser_liste([1, 2, 3, 4])) # Devrait afficher [4, 3, 2, 1]
print(f"Liste originale après inversion : {originale}") # Vérifier que l'originale n'est pas modifiée

Chapitre 10 : Les Tuples

Les tuples sont similaires aux listes, mais avec une différence cruciale : ils sont immuables. Cela signifie qu'une fois créés, vous ne pouvez pas modifier, ajouter ou supprimer leurs éléments. Ils sont souvent utilisés pour stocker des collections d'éléments hétérogènes qui ne devraient pas changer.

Exemple 1 : Création et accès aux éléments

Les tuples sont définis par des parenthèses (). L'accès aux éléments se fait comme pour les listes, par index.

# Création d'un tuple
point_3d = (10, 20, 30)
informations_personne = ("Alice", 30, "Développeuse")

print(f"Point 3D : {point_3d}")
print(f"Nom : {informations_personne[0]}")
print(f"Âge : {informations_personne[1]}")

# Tuple d'un seul élément (nécessite une virgule)
mon_tuple_seul = ("seul element",)
print(f"Tuple d'un seul élément : {mon_tuple_seul}, type : {type(mon_tuple_seul)}")

# Sans la virgule, ce ne serait pas un tuple
pas_un_tuple = ("un string")
print(f"Pas un tuple : {pas_un_tuple}, type : {type(pas_un_tuple)}")

Exemple 2 : Immutabilité

Tenter de modifier un tuple provoquera une erreur.

coordonnees = (10, 20)
print(f"Coordonnées initiales : {coordonnees}")

# Tenter de modifier un élément (décommenter pour voir l'erreur)
# coordonnees[0] = 15 # Cela lèvera une TypeError
# print(coordonnees)

# Tenter d'ajouter un élément (décommenter pour voir l'erreur)
# coordonnees.append(30) # Cela lèvera une AttributeError
# print(coordonnees)

Exemple 3 : Opérations courantes sur les tuples

Bien que non modifiables, les tuples supportent de nombreuses opérations similaires aux listes pour la lecture et la manipulation.

jours_semaine = ("Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche")

# Longueur du tuple
print(f"Nombre de jours : {len(jours_semaine)}")

# Concaténation de tuples
tuple1 = (1, 2)
tuple2 = (3, 4)
tuple_concatene = tuple1 + tuple2
print(f"Tuple concaténé : {tuple_concatene}")

# Répétition de tuple
print(f"Tuple répété : {tuple1 * 3}")

# Vérifier la présence d'un élément
print(f"'Lundi' est dans le tuple ? {'Lundi' in jours_semaine}")

# Parcours d'un tuple
print("Jours de la semaine :")
for jour in jours_semaine:
    print(jour)

# Dépaquetage (unpacking) de tuple
x, y, z = point_3d
print(f"Dépaquetage : x={x}, y={y}, z={z}")

Série d'Exercices sur les Tuples

Exercice 1 : Créer et Afficher un Tuple

Créez un tuple informations_livre contenant le titre, l'auteur et l'année de publication d'un livre. Affichez chaque information séparément.

informations_livre = ("Le Seigneur des Anneaux", "J.R.R. Tolkien", 1954)
print(f"Titre : {informations_livre[0]}")
print(f"Auteur : {informations_livre[1]}")
print(f"Année : {informations_livre[2]}")

Exercice 2 : Dépaquetage de Tuple

Créez un tuple coleurs_rgb avec trois valeurs (par exemple 255, 0, 0 pour le rouge). Dépaquetez ce tuple en trois variables r, g, b et affichez-les.

couleurs_rgb = (255, 0, 0) # Rouge
r, g, b = couleurs_rgb
print(f"Composante Rouge : {r}")
print(f"Composante Verte : {g}")
print(f"Composante Bleue : {b}")

Exercice 3 : Fusion de Tuples

Créez deux tuples, tuple_a avec (1, 2) et tuple_b avec (3, 4). Concaténez-les pour former un nouveau tuple et affichez-le.

tuple_a = (1, 2)
tuple_b = (3, 4)
tuple_fusionne = tuple_a + tuple_b
print(f"Tuple fusionné : {tuple_fusionne}") # Devrait afficher (1, 2, 3, 4)

Exercice 4 : Compter les Occurrences

Créez un tuple nombres_tuple avec des nombres répétés (par exemple (1, 2, 2, 3, 1, 4)). Utilisez la méthode count() pour compter combien de fois le nombre 1 apparaît.

nombres_tuple = (1, 2, 2, 3, 1, 4)
nombre_occurrences_1 = nombres_tuple.count(1)
print(f"Le nombre 1 apparaît {nombre_occurrences_1} fois.") # Devrait afficher 2

Exercice 5 : Tuple et Fonction

Écrivez une fonction min_max_tuple qui prend un tuple de nombres et retourne un nouveau tuple contenant le nombre minimum et le nombre maximum de l'original. Gérez le cas d'un tuple vide.

def min_max_tuple(t_nombres):
    if len(t_nombres) == 0:
        return (None, None) # Retourne un tuple de None pour un tuple vide
    minimum = min(t_nombres)
    maximum = max(t_nombres)
    return (minimum, maximum)

# Tests
print(min_max_tuple((10, 5, 20, 15))) # Devrait afficher (5, 20)
print(min_max_tuple((7,))) # Devrait afficher (7, 7)
print(min_max_tuple(())) # Devrait afficher (None, None)

Chapitre 11 : Les Dictionnaires

Les dictionnaires sont des collections non ordonnées de paires clé-valeur. Chaque clé est unique et est utilisée pour accéder à sa valeur associée. Ils sont extrêmement utiles pour stocker des données structurées et sont souvent appelés "tableaux associatifs" ou "cartes" dans d'autres langages.

Exemple 1 : Création et accès aux éléments

Un dictionnaire est défini par des accolades {}, où chaque élément est une paire clé: valeur.

# Création d'un dictionnaire d'informations sur une personne
personne = {
    "nom": "Alice",
    "age": 30,
    "ville": "Paris"
}
print(f"Dictionnaire complet : {personne}")

# Accès aux valeurs par leur clé
print(f"Nom : {personne["nom"]}")
print(f"Ville : {personne["ville"]}")

# Utilisation de get() pour accéder (évite les erreurs si la clé n'existe pas)
print(f"Age (avec get) : {personne.get("age")}")
print(f"Pays (avec get, valeur par défaut) : {personne.get("pays", "Non spécifié")}")

Exemple 2 : Ajout, modification et suppression d'éléments

Les dictionnaires sont mutables. Vous pouvez ajouter de nouvelles paires clé-valeur, modifier des valeurs existantes ou supprimer des éléments.

notes = {"Maths": 15, "Physique": 12}
print(f"Notes initiales : {notes}")

# Ajouter un nouvel élément
notes["Chimie"] = 18
print(f"Après ajout : {notes}")

# Modifier une valeur existante
notes["Physique"] = 14
print(f"Après modification : {notes}")

# Supprimer un élément avec del
del notes["Maths"]
print(f"Après suppression de Maths : {notes}")

# Supprimer un élément avec pop() (et récupérer sa valeur)
note_chimie = notes.pop("Chimie")
print(f"Après pop de Chimie : {notes}, valeur supprimée : {note_chimie}")

# Vider le dictionnaire
notes.clear()
print(f"Dictionnaire vidé : {notes}")

Exemple 3 : Parcours de dictionnaire

Vous pouvez itérer sur les clés, les valeurs, ou les paires clé-valeur d'un dictionnaire.

produits = {
    "Ordinateur": 1200,
    "Souris": 25,
    "Clavier": 75
}

# Parcours des clés (par défaut)
print("Clés des produits :")
for produit in produits:
    print(produit)

# Parcours des valeurs
print("Prix des produits :")
for prix in produits.values():
    print(prix)

# Parcours des paires clé-valeur
print("Produits et leurs prix :")
for produit, prix in produits.items():
    print(f"- {produit} : {prix} €")

Série d'Exercices sur les Dictionnaires

Exercice 1 : Créer et Accéder

Créez un dictionnaire capitale_pays où les clés sont des noms de pays (ex: "France") et les valeurs leurs capitales (ex: "Paris"). Ajoutez au moins 3 pays. Affichez la capitale d'un pays de votre choix, puis la capitale d'un pays qui n'est pas dans le dictionnaire en utilisant .get() avec une valeur par défaut.

capitale_pays = {
    "France": "Paris",
    "Allemagne": "Berlin",
    "Espagne": "Madrid"
}
print(f"Capitale de la France : {capitale_pays["France"]}")
print(f"Capitale de l'Italie : {capitale_pays.get("Italie", "Non trouvée")}")

Exercice 2 : Mettre à Jour un Dictionnaire

En utilisant le dictionnaire capitale_pays, ajoutez "Italie" avec "Rome" comme capitale. Modifiez la capitale de l'Allemagne en "Bonn" (juste pour l'exercice !) puis supprimez l'Espagne.

capitale_pays = {
    "France": "Paris",
    "Allemagne": "Berlin",
    "Espagne": "Madrid"
}
print(f"Initial : {capitale_pays}")
capitale_pays["Italie"] = "Rome"
print(f"Après ajout Italie : {capitale_pays}")
capitale_pays["Allemagne"] = "Bonn"
print(f"Après modification Allemagne : {capitale_pays}")
del capitale_pays["Espagne"]
print(f"Après suppression Espagne : {capitale_pays}")

Exercice 3 : Parcourir un Dictionnaire

Créez un dictionnaire inventaire avec des articles et leur quantité (ex: {"pommes": 50, "bananes": 30, "oranges": 70}). Parcourez le dictionnaire et affichez chaque article et sa quantité de la manière suivante : "Il y a X [article] en stock."

inventaire = {"pommes": 50, "bananes": 30, "oranges": 70}
for article, quantite in inventaire.items():
    print(f"Il y a {quantite} {article} en stock.")

Exercice 4 : Compter les Fréquences

Écrivez une fonction compter_frequences qui prend une liste de mots et retourne un dictionnaire où les clés sont les mots et les valeurs sont le nombre de fois où chaque mot apparaît dans la liste.

def compter_frequences(liste_mots):
    frequences = {}
    for mot in liste_mots:
        # Si le mot est déjà dans le dictionnaire, incrémenter son compteur
        # Sinon, l'ajouter avec un compteur de 1
        frequences[mot] = frequences.get(mot, 0) + 1
    return frequences

# Test
mots = ["pomme", "banane", "pomme", "orange", "banane", "pomme"]
print(compter_frequences(mots)) # Devrait afficher {'pomme': 3, 'banane': 2, 'orange': 1}

Exercice 5 : Fusionner deux Dictionnaires

Créez deux dictionnaires dict1 et dict2. Fusionnez-les en un nouveau dictionnaire dict_fusionne. Si une clé est présente dans les deux dictionnaires, la valeur du second dictionnaire doit être conservée.

dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}

# Méthode 1 : Utilisation de l'opérateur ** (Python 3.5+)
dict_fusionne_1 = {**dict1, **dict2}
print(f"Fusion (méthode **) : {dict_fusionne_1}") # Devrait afficher {'a': 1, 'b': 3, 'c': 4}

# Méthode 2 : Utilisation de update()
dict_fusionne_2 = dict1.copy() # Crée une copie pour ne pas modifier dict1
dict_fusionne_2.update(dict2)
print(f"Fusion (méthode update) : {dict_fusionne_2}") # Devrait afficher {'a': 1, 'b': 3, 'c': 4}

Chapitre 12 : Les Ensembles (Sets)

Les ensembles (sets) sont des collections non ordonnées d'éléments uniques. Ils sont particulièrement utiles pour des opérations mathématiques sur les ensembles (union, intersection, différence) et pour éliminer les doublons d'une liste.

Exemple 1 : Création et propriétés

Un ensemble est créé avec des accolades {} (attention, un dictionnaire vide est aussi {}) ou avec la fonction set(). Les doublons sont automatiquement supprimés.

# Création d'un ensemble avec des doublons
nombres_dupliques = [1, 2, 2, 3, 1, 4]
mon_ensemble = set(nombres_dupliques)
print(f"Ensemble à partir d'une liste : {mon_ensemble}") # Output: {1, 2, 3, 4} (ordre non garanti)

# Création directe
fruits_uniques = {"pomme", "banane", "cerise", "pomme"}
print(f"Ensemble de fruits : {fruits_uniques}") # Output: {'pomme', 'banane', 'cerise'}

# Créer un ensemble vide
ensemble_vide = set()
print(f"Ensemble vide : {ensemble_vide}")

Exemple 2 : Ajout et suppression d'éléments

Les ensembles sont mutables. Vous pouvez ajouter et supprimer des éléments.

lettres = {'a', 'b', 'c'}
print(f"Ensemble initial : {lettres}")

# Ajouter un élément
lettres.add('d')
print(f"Après ajout de 'd' : {lettres}")

# Ajouter un élément déjà présent (n'a aucun effet)
lettres.add('a')
print(f"Après ajout de 'a' (inchangé) : {lettres}")

# Supprimer un élément avec remove() (lève une erreur si l'élément n'existe pas)
lettres.remove('c')
print(f"Après suppression de 'c' : {lettres}")

# Supprimer un élément avec discard() (ne lève pas d'erreur si l'élément n'existe pas)
lettres.discard('z')
print(f"Après discard de 'z' (inchangé) : {lettres}")

# Supprimer un élément aléatoire (et le récupérer)
element_retire = lettres.pop()
print(f"Après pop : {lettres}, élément retiré : {element_retire}")

Exemple 3 : Opérations ensemblistes

Les sets sont optimisés pour les opérations mathématiques d'ensembles.

set_a = {1, 2, 3, 4}
set_b = {3, 4, 5, 6}

# Union (éléments présents dans A ou B)
union_sets = set_a.union(set_b)
print(f"Union : {union_sets}") # Output: {1, 2, 3, 4, 5, 6}

# Intersection (éléments présents dans A ET B)
intersection_sets = set_a.intersection(set_b)
print(f"Intersection : {intersection_sets}") # Output: {3, 4}

# Différence (éléments présents dans A MAIS PAS dans B)
difference_sets_ab = set_a.difference(set_b)
print(f"Différence (A - B) : {difference_sets_ab}") # Output: {1, 2}

# Différence symétrique (éléments présents dans A ou B, mais pas dans les deux)
sym_difference_sets = set_a.symmetric_difference(set_b)
print(f"Différence symétrique : {sym_difference_sets}") # Output: {1, 2, 5, 6}

# Sous-ensemble et super-ensemble
set_c = {1, 2}
print(f"Set C est un sous-ensemble de A ? {set_c.issubset(set_a)}") # Output: True
print(f"Set A est un super-ensemble de C ? {set_a.issuperset(set_c)}") # Output: True

Série d'Exercices sur les Ensembles

Exercice 1 : Éliminer les Doublons

Vous avez une liste de nombres avec des doublons : [1, 2, 2, 3, 4, 4, 5, 1]. Utilisez un ensemble pour obtenir une nouvelle liste sans doublons et affichez-la.

liste_avec_doublons = [1, 2, 2, 3, 4, 4, 5, 1]
ensemble_unique = set(liste_avec_doublons)
liste_sans_doublons = list(ensemble_unique)
print(f"Liste sans doublons : {liste_sans_doublons}") # L'ordre peut varier

Exercice 2 : Éléments Communs

Vous avez deux listes de participants à des événements. participants_a = ["Alice", "Bob", "Charlie", "David"] et participants_b = ["Charlie", "Eve", "Frank", "David"]. Trouvez et affichez les participants qui sont inscrits aux deux événements.

participants_a = ["Alice", "Bob", "Charlie", "David"]
participants_b = ["Charlie", "Eve", "Frank", "David"]

set_a = set(participants_a)
set_b = set(participants_b)

communs = set_a.intersection(set_b)
print(f"Participants communs aux deux événements : {communs}") # Devrait afficher {'Charlie', 'David'}

Exercice 3 : Éléments Uniques au Total

En utilisant les mêmes listes de participants que l'exercice précédent, trouvez et affichez tous les participants uniques (sans doublons) présents dans l'un ou l'autre des événements.

participants_a = ["Alice", "Bob", "Charlie", "David"]
participants_b = ["Charlie", "Eve", "Frank", "David"]

set_a = set(participants_a)
set_b = set(participants_b)

tous_uniques = set_a.union(set_b)
print(f"Tous les participants uniques : {tous_uniques}") # Devrait afficher {'Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank'}

Exercice 4 : Différence de Groupes

Un groupe d'étudiants suit le cours de Python : {'Alice', 'Bob', 'Charlie'}. Un autre groupe suit le cours de Java : {'Charlie', 'David', 'Eve'}. Trouvez et affichez les étudiants qui suivent Python mais pas Java.

etudiants_python = {'Alice', 'Bob', 'Charlie'}
etudiants_java = {'Charlie', 'David', 'Eve'}

seulement_python = etudiants_python.difference(etudiants_java)
print(f"Étudiants qui suivent Python mais pas Java : {seulement_python}") # Devrait afficher {'Alice', 'Bob'}

Exercice 5 : Vérifier si un mot est un anagramme

Écrivez une fonction sont_anagrammes qui prend deux chaînes de caractères et retourne True si elles sont des anagrammes l'une de l'autre (utilisez les sets pour cela), False sinon. Les espaces et la casse doivent être ignorés.

def sont_anagrammes(mot1, mot2):
    # Nettoyer les mots : passer en minuscules et retirer les espaces
    mot1_nettoye = mot1.lower().replace(' ', '')
    mot2_nettoye = mot2.lower().replace(' ', '')
    
    # Convertir en ensembles de caractères et comparer
    return set(mot1_nettoye) == set(mot2_nettoye) and len(mot1_nettoye) == len(mot2_nettoye)

# Tests
print(sont_anagrammes("chien", "niche")) # Devrait afficher True
print(sont_anagrammes("écouter", "retouche")) # Devrait afficher True
print(sont_anagrammes("Python", "Typhon")) # Devrait afficher False (car 'P' != 'T' etc.) - correction: should be True as order doesn't matter for sets, but length does.
print(sont_anagrammes("A gentleman", "Elegant man")) # Devrait afficher True
print(sont_anagrammes("hello", "world")) # Devrait afficher False

Partie 4 : Aller Plus Loin

Chapitre 14 : La Gestion des Exceptions (try...except)

Un programme robuste ne doit pas "planter" à la moindre erreur inattendue (une saisie utilisateur incorrecte, un fichier manquant...). La gestion des exceptions est le mécanisme de Python qui permet d'anticiper ces erreurs, de les "attraper" (catch) et d'exécuter un plan B pour que le programme continue de fonctionner ou se termine proprement.

Exemple 1 : Attraper une erreur de saisie (`ValueError`)

Sans `try...except`, si l'utilisateur tape "abc" au lieu d'un nombre, le programme plante. Voici comment l'éviter.

try:
    age = int(input("Entrez votre âge : "))
    print(f"Vous avez {age} ans.")
except ValueError:
    print("Erreur : Vous n'avez pas entré un nombre valide.")

print("Le programme continue...")

Exemple 2 : Gérer plusieurs exceptions

On peut anticiper plusieurs types d'erreurs, comme une division par zéro.

try:
    numerateur = int(input("Entrez le numérateur : "))
    denominateur = int(input("Entrez le dénominateur : "))
    resultat = numerateur / denominateur
    print(f"Le résultat est {resultat}")
except ValueError:
    print("Erreur : Veuillez entrer des nombres entiers.")
except ZeroDivisionError:
    print("Erreur : La division par zéro est impossible.")

Exemple 3 : Les blocs `else` et `finally`

Le bloc `else` s'exécute uniquement si aucune exception n'est levée dans le `try`. Le bloc `finally` s'exécute toujours, qu'il y ait eu une erreur ou non (parfait pour nettoyer des ressources).

try:
    num = int(input("Entrez un nombre : "))
except ValueError:
    print("Saisie invalide.")
else:
    print(f"Le carré de {num} est {num ** 2}")
finally:
    print("Fin de la tentative de calcul.")

Série d'Exercices sur les Exceptions

Exercice 1 : Calculatrice sécurisée

Demandez deux nombres à l'utilisateur et affichez le résultat de leur division. Gérez les cas où la saisie n'est pas un nombre et où le deuxième nombre est zéro.

try:
    a = float(input("Premier nombre : "))
    b = float(input("Second nombre : "))
    print(f"{a} / {b} = {a / b}")
except ValueError:
    print("Erreur, veuillez entrer des nombres valides.")
except ZeroDivisionError:
    print("Erreur, division par zéro impossible.")

Exercice 2 : Accès à une liste

Créez une liste `couleurs = ["rouge", "vert", "bleu"]`. Demandez à l'utilisateur un index et affichez la couleur correspondante. Gérez l'erreur `IndexError` si l'index est en dehors des limites.

couleurs = ["rouge", "vert", "bleu"]
try:
    index = int(input(f"Entrez un index entre 0 et {len(couleurs)-1} : "))
    print(f"La couleur est : {couleurs[index]}")
except IndexError:
    print("Erreur : cet index n'existe pas dans la liste.")
except ValueError:
    print("Erreur : veuillez entrer un nombre entier.")

Exercice 3 : Accès à un dictionnaire

Soit le dictionnaire `capitales = {"France": "Paris", "Allemagne": "Berlin"}`. Demandez un pays à l'utilisateur et affichez sa capitale. Gérez l'erreur `KeyError` si le pays n'est pas dans le dictionnaire.

capitales = {"France": "Paris", "Allemagne": "Berlin"}
pays = input("Entrez un nom de pays : ")
try:
    print(f"La capitale de {pays} est {capitales[pays]}.")
except KeyError:
    print(f"Désolé, je ne connais pas la capitale de {pays}.")

Chapitre 15 : Manipulation de Fichiers Texte (.txt)

La manipulation de fichiers est essentielle car elle permet de sauvegarder des données de manière permanente (persistance), de lire des configurations, de traiter de grands volumes d'informations et de faire communiquer vos programmes avec le monde extérieur.

Syntaxe générale

with open("nom_du_fichier.txt", "mode") as variable_fichier:
    # Opérations sur le fichier (lecture, écriture...)
    variable_fichier.read()  # Exemple de lecture

Les modes d'ouverture les plus courants sont :

  • 'r' (read) : Lecture seule. C'est le mode par défaut. Le fichier doit exister.
  • 'w' (write) : Écriture seule. Crée le fichier s'il n'existe pas, ou l'écrase complètement s'il existe.
  • 'a' (append) : Ajout. Ajoute du contenu à la fin du fichier sans l'écraser. Crée le fichier s'il n'existe pas.
  • 'r+' : Lecture et écriture. Le fichier doit exister.

Exemple 1 : Lecture d'un fichier existant

Supposons que nous ayons un fichier poeme.txt avec le contenu suivant :
Le ciel est bleu.
Les oiseaux chantent.

with open("poeme.txt", "r") as fichier:
    for ligne in fichier:
        print(ligne.strip()) # .strip() retire les sauts de ligne invisibles

Exemple 2 : Écrire dans un fichier (mode `'w'`)

articles = ["Pommes", "Lait", "Pain"]
with open("liste_courses.txt", "w") as fichier:
    for article in articles:
        fichier.write(f"{article}\n") # \n est crucial pour le saut de ligne

Exemple 3 : Ajouter du contenu à un fichier (mode `'a'`)

with open("liste_courses.txt", "a") as fichier:
    fichier.write("Beurre\n")

Chapitre 16 : Travailler avec les Fichiers CSV

Le format CSV (Comma-Separated Values) est un standard pour stocker des données tabulaires (comme dans un tableur Excel). Python dispose d'un module intégré csv qui rend la lecture et l'écriture de ces fichiers très simples et fiables.

Exemple 1 : Lire un fichier CSV

Supposons un fichier utilisateurs.csv :
nom,email,ville
Alice,alice@email.com,Paris
Bob,bob@email.com,Lyon

La meilleure façon de le lire est avec csv.DictReader, qui traite chaque ligne comme un dictionnaire.

import csv

with open('utilisateurs.csv', 'r', newline='') as fichier_csv:
    lecteur = csv.DictReader(fichier_csv)
    print("Liste des utilisateurs :")
    for ligne in lecteur:
        # Chaque ligne est un dictionnaire
        print(f"- {ligne['nom']} de {ligne['ville']} ({ligne['email']})")

Exemple 2 : Écrire dans un fichier CSV

Nous allons écrire une liste de dictionnaires dans un nouveau fichier produits.csv.

import csv

donnees_produits = [
    {'produit': 'Laptop', 'prix': 1200, 'stock': 50},
    {'produit': 'Souris', 'prix': 25, 'stock': 200},
    {'produit': 'Clavier', 'prix': 75, 'stock': 150}
]
noms_colonnes = ['produit', 'prix', 'stock']

with open('produits.csv', 'w', newline='') as fichier_csv:
    ecrivain = csv.DictWriter(fichier_csv, fieldnames=noms_colonnes)
    
    ecrivain.writeheader() # Écrit la ligne d'en-tête (produit,prix,stock)
    ecrivain.writerows(donnees_produits) # Écrit toutes les lignes de données

print("Le fichier produits.csv a été créé.")

Chapitre 17 : Travailler avec les Fichiers JSON

Le format JSON (JavaScript Object Notation) est le standard du web pour l'échange de données structurées. Sa syntaxe est très proche des dictionnaires et listes Python, ce qui le rend extrêmement facile à manipuler avec le module intégré json.

Exemple 1 : Lire un fichier JSON

Supposons un fichier config.json :
{ "user": "admin", "theme": "dark", "notifications_enabled": true }

La fonction json.load() lit le fichier et le convertit directement en dictionnaire Python.

import json

with open('config.json', 'r') as fichier_json:
    config = json.load(fichier_json) # Charge les données en dictionnaire

print("Configuration chargée :")
print(f"Utilisateur : {config['user']}")
print(f"Thème : {config['theme']}")

Exemple 2 : Écrire dans un fichier JSON

Nous allons créer un dictionnaire Python et le sauvegarder dans un fichier data.json de manière lisible.

import json

user_profile = {
    "id": 123,
    "nom": "Léa Martin",
    "active": True,
    "competences": ["Python", "Data Analysis", "SQL"],
    "adresse": None
}

with open('data.json', 'w') as fichier_json:
    # json.dump() écrit l'objet Python dans le fichier au format JSON
    # indent=4 rend le fichier joliment formaté et lisible
    json.dump(user_profile, fichier_json, indent=4)

print("Le fichier data.json a été créé.")

Série d'Exercices sur les Fichiers

Exercice (Texte) : Journal d'Événements

Créez une fonction log_event(message). Chaque fois qu'elle est appelée, elle doit ajouter une ligne au fichier app.log au format : [AAAA-MM-JJ HH:MM:SS] - message. (Indice : utilisez le module datetime).

import datetime
def log_event(message):
    timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    with open('app.log', 'a') as f:
        f.write(f"[{timestamp}] - {message}\n")
log_event("Démarrage de l'application.")
print("Événement enregistré dans app.log.")

Exercice (CSV) : Calcul de la valeur du stock

En utilisant le fichier produits.csv créé précédemment, écrivez un script qui lit le fichier et calcule la valeur totale du stock (somme de `prix * stock` pour chaque produit).

import csv
valeur_totale = 0
with open('produits.csv', 'r') as f:
    lecteur = csv.DictReader(f)
    for ligne in lecteur:
        prix = float(ligne['prix'])
        stock = int(ligne['stock'])
        valeur_totale += prix * stock
print(f"La valeur totale du stock est de : {valeur_totale}€")

Exercice (JSON) : Mettre à jour une configuration

Écrivez une fonction update_theme(nouveau_theme) qui lit le fichier config.json, change la valeur de la clé "theme", puis réécrit le fichier entier avec la nouvelle configuration.

import json
def update_theme(nouveau_theme):
    nom_fichier = 'config.json'
    # Étape 1 : Lire les données actuelles
    with open(nom_fichier, 'r') as f:
        data = json.load(f)
    
    # Étape 2 : Modifier les données
    data['theme'] = nouveau_theme
    
    # Étape 3 : Réécrire le fichier complet
    with open(nom_fichier, 'w') as f:
        json.dump(data, f)
    print(f"Thème mis à jour à '{nouveau_theme}' dans {nom_fichier}")

# Test
update_theme('light')

Partie 5 : Modules, Bibliothèques et l'Écosystème Python

Chapitre 16 : Utiliser des Bibliothèques (Standard & Externe)

Personne ne réinvente la roue en programmation. Python est livré avec une vaste "boîte à outils" appelée la **Bibliothèque Standard**, et vous donne accès à des centaines de milliers d'outils supplémentaires créés par la communauté. Apprendre à les utiliser est la compétence la plus importante pour devenir efficace en Python.

Le mot-clé `import`

Pour utiliser les fonctions d'une bibliothèque (aussi appelée module ou paquet), vous devez d'abord l'importer dans votre script. Il y a plusieurs façons de le faire :

# 1. Importer le module entier (le plus courant)
import math
print(math.sqrt(16)) # On utilise le nom du module comme préfixe

# 2. Importer une fonction spécifique d'un module
from random import randint
print(randint(1, 10)) # La fonction est directement utilisable

# 3. Importer un module avec un alias (un surnom plus court)
import datetime as dt
print(dt.date.today())

La Bibliothèque Standard ("Batteries incluses")

Voici quelques-uns des modules les plus utiles inclus par défaut avec Python.

Le module `math`

Fournit l'accès aux fonctions mathématiques de base.

import math
print(f"Racine carrée de 81 : {math.sqrt(81)}")
print(f"Valeur de Pi : {math.pi}")
print(f"Arrondi supérieur de 2.3 : {math.ceil(2.3)}")

Le module `random`

Permet de générer des nombres pseudo-aléatoires, de faire des choix au hasard, etc.

import random
print(f"Nombre entier aléatoire entre 1 et 100 : {random.randint(1, 100)}")
joueurs = ['Alice', 'Bob', 'Charlie']
print(f"Le gagnant est : {random.choice(joueurs)}")

Le module `datetime`

Pour manipuler les dates et les heures.

import datetime as dt
maintenant = dt.datetime.now()
print(f"Date et heure actuelles : {maintenant}")
print(f"Format personnalisé : {maintenant.strftime('%d/%m/%Y %H:%M')}")

Installer des Bibliothèques Externes avec `pip`

L'immense majorité des bibliothèques Python se trouvent sur un dépôt public appelé PyPI (Python Package Index). On les installe avec un outil en ligne de commande appelé pip.

$ pip install nom_de_la_bibliotheque

$ pip uninstall nom_de_la_bibliotheque

$ pip list # Pour voir ce qui est déjà installé

Présentation de quelques bibliothèques incontournables

  • Requests : Pour faire des requêtes HTTP et interagir avec des sites web ou des APIs. C'est le standard de facto.
  • Pillow (PIL Fork) : Pour manipuler des images (redimensionner, appliquer des filtres, etc.).
  • NumPy : La base du calcul scientifique en Python. Fournit des tableaux multi-dimensionnels ultra-performants.
  • Pandas : Pour l'analyse et la manipulation de données. Structure les données dans des "DataFrames", des tableaux intelligents et faciles à utiliser.
  • Matplotlib : Pour créer des graphiques et des visualisations de données.

Série d'Exercices sur les Bibliothèques

Exercice 1 : Le jeu du "Plus ou Moins" (amélioré)

Reprenez le jeu du "Plus ou Moins", mais cette fois, faites en sorte que le nombre secret soit un nombre aléatoire entre 1 et 100, choisi par l'ordinateur à chaque nouvelle partie. Utilisez le module `random`.

import random
nombre_secret = random.randint(1, 100)
# ... le reste de la logique du jeu ...

Exercice 2 : Calculer l'aire d'un cercle

Écrivez une fonction qui demande à l'utilisateur le rayon d'un cercle, et qui calcule et affiche son aire. Utilisez la constante `pi` du module `math` pour le calcul (Aire = π * rayon²).

import math
def aire_cercle():
    try:
        rayon = float(input("Entrez le rayon du cercle : "))
        aire = math.pi * (rayon ** 2)
        print(f"L'aire du cercle est : {aire:.2f}")
    except ValueError:
        print("Veuillez entrer un nombre.")
aire_cercle()

Exercice 3 : Compte à rebours

Écrivez un programme qui affiche le nombre de jours restants jusqu'à Noël prochain. Utilisez le module `datetime`.

import datetime as dt
aujourdhui = dt.date.today()
noel = dt.date(aujourdhui.year, 12, 25)
if noel < aujourdhui: # Si Noël est déjà passé cette année
    noel = dt.date(aujourdhui.year + 1, 12, 25)
difference = noel - aujourdhui
print(f"Il reste {difference.days} jours avant Noël.")

Exercice 4 : Installer et utiliser `requests`

Ouvrez un terminal, installez la bibliothèque `requests` (`pip install requests`). Ensuite, écrivez un script qui récupère et affiche les informations d'un utilisateur aléatoire depuis l'API de test JSONPlaceholder.

import requests
import random

user_id = random.randint(1, 10)
url = f"https://jsonplaceholder.typicode.com/users/{user_id}"

try:
    reponse = requests.get(url)
    reponse.raise_for_status() # Lève une exception si la requête a échoué
    user_data = reponse.json() # Convertit la réponse JSON en dictionnaire

    print(f"Nom : {user_data['name']}")
    print(f"Email : {user_data['email']}")
    print(f"Ville : {user_data['address']['city']}")
except requests.exceptions.RequestException as e:
    print(f"Erreur de réseau : {e}")

Conclusion & Perspectives

Félicitations pour avoir terminé ce parcours intensif sur Python !

Vous avez construit un socle de compétences solide. De la simple variable aux structures de données complexes, en passant par la logique de contrôle, les fonctions, la gestion des erreurs et la manipulation de fichiers, vous possédez désormais les outils fondamentaux de tout développeur Python. Votre aventure ne fait que commencer.

Continuez à pratiquer, car c'est en forgeant que l'on devient forgeron !

Prochaine Étape : La Programmation Orientée Objet (POO)

Jusqu'à présent, nous avons écrit du code de manière "procédurale". Le prochain cours vous introduira à un paradigme qui a révolutionné le développement logiciel : la Programmation Orientée Objet. C'est la méthode utilisée pour construire des applications vastes, maintenables et réutilisables.

Nous explorerons comment modéliser le monde réel en utilisant :

  • Les Classes : des "plans" ou des "moules" pour créer des objets.
  • Les Objets : des instances de classes avec leurs propres données et comportements.
  • L'Héritage, l'Encapsulation et le Polymorphisme : les piliers qui rendent la POO si puissante.

Horizon Final : Plongée dans la Data Science

Une fois la POO maîtrisée, vous serez parfaitement équipé pour aborder le domaine passionnant de la Data Science. Python est le langage roi dans ce secteur grâce à son écosystème de bibliothèques spécialisées. Nous verrons comment utiliser :

  • NumPy : pour les calculs numériques et matriciels à haute performance.
  • Pandas : pour la manipulation et l'analyse de données tabulaires (pensez à un Excel sous stéroïdes).
  • Matplotlib & Seaborn : pour créer des visualisations de données et des graphiques percutants.

Vous apprendrez à analyser des millions de lignes de données, à en extraire des informations précieuses et à communiquer vos résultats de manière visuelle. C'est une compétence extrêmement recherchée sur le marché du travail.