ajout de tous les cours et TP préparés cet été

This commit is contained in:
2026-01-17 23:10:49 +01:00
parent ed9415bc81
commit 301cf5a98f
125 changed files with 21614 additions and 542 deletions

View File

@@ -0,0 +1,320 @@
# Corrigé de l'exercice — Cuisson des pâtes
---
## Énoncé
Nous voulons faire cuire des pâtes. Écrire la recette sous forme de code Python selon trois paradigmes différents.
---
## Version impérative
Liste d'instructions étape par étape, avec modification d'état.
```python
# Version impérative : liste d'instructions étape par étape
def cuire_pates_imperatif():
"""Fait cuire des pâtes de manière impérative."""
# État initial
eau = "froide"
pates = "crues"
sel = False
# Étape 1 : Remplir la casserole
print("Remplissage de la casserole...")
quantite_eau = 1.5 # litres
# Étape 2 : Faire chauffer l'eau
print("Chauffage de l'eau...")
eau = "chaude"
# Étape 3 : Attendre l'ébullition
print("Attente de l'ébullition...")
eau = "bouillante"
# Étape 4 : Saler l'eau
print("Ajout du sel...")
sel = True
# Étape 5 : Ajouter les pâtes
print("Ajout des pâtes...")
pates = "en cuisson"
# Étape 6 : Attendre le temps de cuisson
temps_cuisson = 10 # minutes
print(f"Cuisson pendant {temps_cuisson} minutes...")
# Étape 7 : Égoutter
print("Égouttage des pâtes...")
pates = "cuites"
print(f"Résultat : pâtes {pates}")
return pates
# Exécution
resultat = cuire_pates_imperatif()
```
**Caractéristiques :**
- Modification d'état (variables `eau`, `pates`, `sel`)
- Instructions séquentielles
- Effets de bord (print)
---
## Version fonctionnelle
Une fonction pure qui prend un état et retourne un nouvel état, sans modification.
```python
# Version fonctionnelle : fonctions pures et composition
def remplir_casserole(etat):
"""Retourne un nouvel état avec la casserole remplie."""
return {**etat, "eau": "froide", "quantite_eau": 1.5}
def chauffer_eau(etat):
"""Retourne un nouvel état avec l'eau chauffée."""
return {**etat, "eau": "chaude"}
def faire_bouillir(etat):
"""Retourne un nouvel état avec l'eau bouillante."""
return {**etat, "eau": "bouillante"}
def saler(etat):
"""Retourne un nouvel état avec le sel ajouté."""
return {**etat, "sel": True}
def ajouter_pates(etat):
"""Retourne un nouvel état avec les pâtes en cuisson."""
return {**etat, "pates": "en cuisson"}
def cuire(etat, duree):
"""Retourne un nouvel état après cuisson."""
return {**etat, "temps_cuisson": duree, "pates": "cuites"}
def egoutter(etat):
"""Retourne un nouvel état avec les pâtes égouttées."""
return {**etat, "egouttees": True}
# Composition de fonctions
def cuire_pates_fonctionnel(etat_initial):
"""
Fait cuire des pâtes de manière fonctionnelle.
Chaque étape retourne un nouvel état sans modifier l'ancien.
"""
etat = remplir_casserole(etat_initial)
etat = chauffer_eau(etat)
etat = faire_bouillir(etat)
etat = saler(etat)
etat = ajouter_pates(etat)
etat = cuire(etat, 10)
etat = egoutter(etat)
return etat
# Version encore plus fonctionnelle avec reduce
import functools
def cuire_pates_reduce(etat_initial):
"""Version avec reduce pour composer les fonctions."""
etapes = [
remplir_casserole,
chauffer_eau,
faire_bouillir,
saler,
ajouter_pates,
lambda e: cuire(e, 10),
egoutter
]
return functools.reduce(lambda etat, f: f(etat), etapes, etat_initial)
# Exécution
etat_initial = {"pates": "crues", "sel": False}
resultat = cuire_pates_fonctionnel(etat_initial)
print(f"État final : {resultat}")
# Vérification : l'état initial n'a pas été modifié
print(f"État initial préservé : {etat_initial}")
```
**Caractéristiques :**
- Pas de modification d'état (immutabilité)
- Fonctions pures (même entrée → même sortie)
- Composition de fonctions
- L'état initial n'est jamais modifié
---
## Version orientée objet
Une classe `Pates` avec des attributs et une méthode `cuire()`.
```python
# Version orientée objet : classe Pates avec méthode cuire()
class Casserole:
"""Représente une casserole pour la cuisson."""
def __init__(self):
self.eau = None
self.temperature = "froide"
self.sel = False
def remplir(self, quantite=1.5):
"""Remplit la casserole d'eau."""
self.eau = quantite
print(f"Casserole remplie avec {quantite}L d'eau")
def chauffer(self):
"""Chauffe l'eau jusqu'à ébullition."""
self.temperature = "chaude"
print("Chauffage en cours...")
self.temperature = "bouillante"
print("L'eau bout !")
def saler(self):
"""Ajoute du sel dans l'eau."""
self.sel = True
print("Sel ajouté")
class Pates:
"""Représente des pâtes à cuire."""
def __init__(self, type_pates="spaghetti", quantite=500):
self.type = type_pates
self.quantite = quantite # en grammes
self.etat = "crues"
self.temps_cuisson = 0
def cuire(self, casserole, duree=10):
"""
Fait cuire les pâtes dans une casserole.
:param casserole: (Casserole) la casserole à utiliser
:param duree: (int) temps de cuisson en minutes
"""
# Vérifications
if casserole.eau is None:
raise ValueError("La casserole doit contenir de l'eau !")
if casserole.temperature != "bouillante":
raise ValueError("L'eau doit être bouillante !")
print(f"Ajout de {self.quantite}g de {self.type} dans la casserole")
self.etat = "en cuisson"
print(f"Cuisson pendant {duree} minutes...")
self.temps_cuisson = duree
self.etat = "cuites"
print(f"Les {self.type} sont cuites !")
def egoutter(self):
"""Égoutte les pâtes."""
if self.etat != "cuites":
raise ValueError("Les pâtes doivent être cuites avant d'être égouttées !")
print("Égouttage des pâtes...")
self.etat = "prêtes"
def __str__(self):
return f"Pates({self.type}, {self.quantite}g, état={self.etat})"
# Exécution
def preparer_pates_oo():
"""Prépare des pâtes en utilisant la POO."""
# Création des objets
casserole = Casserole()
pates = Pates("fusilli", 400)
print(f"Début : {pates}")
# Préparation de la casserole
casserole.remplir(2.0)
casserole.chauffer()
casserole.saler()
# Cuisson des pâtes
pates.cuire(casserole, duree=12)
pates.egoutter()
print(f"Fin : {pates}")
return pates
resultat = preparer_pates_oo()
```
**Caractéristiques :**
- Encapsulation (attributs et méthodes regroupés)
- Objets avec état interne
- Interactions entre objets (Pates et Casserole)
- Méthodes qui modifient l'état de l'objet
---
## Tableau comparatif
| Aspect | Impératif | Fonctionnel | Orienté Objet |
|--------|-----------|-------------|---------------|
| **État** | Variables modifiées | États immuables | Attributs d'objets |
| **Données** | Variables simples | Dictionnaires/tuples | Objets |
| **Actions** | Instructions séquentielles | Fonctions composées | Méthodes |
| **Modification** | Sur place | Nouvel état retourné | Via méthodes |
| **Réutilisabilité** | Faible | Moyenne | Forte |
| **Testabilité** | Difficile | Facile | Moyenne |
---
## Bonus : Version lambda
```python
# Version ultra-fonctionnelle avec lambdas et reduce
import functools
# Chaque étape est une lambda qui transforme l'état
etapes = [
lambda e: {**e, "eau": 1.5},
lambda e: {**e, "temperature": "bouillante"},
lambda e: {**e, "sel": True},
lambda e: {**e, "pates": "en cuisson"},
lambda e: {**e, "temps": 10, "pates": "cuites"},
lambda e: {**e, "egouttees": True}
]
# Composition avec reduce
cuire_pates_lambda = lambda etat: functools.reduce(
lambda e, f: f(e),
etapes,
etat
)
# Exécution
resultat = cuire_pates_lambda({"pates": "crues"})
print(resultat)
# {'pates': 'cuites', 'eau': 1.5, 'temperature': 'bouillante',
# 'sel': True, 'temps': 10, 'egouttees': True}
```
---
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
Licence CC BY NC
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.