Arguments variables (*args)
Une moyenne d'un nombre quelconque de notes
Une fonction calculer_moyenne_generale() qui accepte un nombre variable de notes et retourne la moyenne (ou None si aucune note).
def calculer_moyenne_generale(*notes):
if len(notes) == 0:
return None
return sum(notes) / len(notes)*notes rassemble tous les arguments positionnels dans un tuple. On teste le cas vide avant de diviser.
Tri avancé avec lambda
Classer les étudiants par moyenne décroissante
À partir d'une liste de tuples (nom, n1, n2, n3), trier les étudiants par moyenne décroissante avec une fonction lambda.
etudiants.sort(
key=lambda e: sum(e[1:]) / len(e[1:]),
reverse=True
)La fonction lambda sert de clé de tri : Python l'évalue sur chaque élément et range selon le résultat. reverse=True ⟶ ordre décroissant. (🎓 = boursier)
La lambda fournit la clé de comparaison. L'animation montre un tri à bulles, mais Python utilise un tri bien plus efficace (Timsort).
Gestion de fichiers
Écrire puis relire etudiants.txt
Créer un fichier au format nom;n1;n2;n3, puis le relire pour afficher la moyenne de chaque étudiant.
with open("etudiants.txt", "r") as f:
for ligne in f:
ligne = ligne.strip() # enlève le \n
if ligne:
nom, n1, n2, n3 = ligne.split(";")
moyenne = (int(n1)+int(n2)+int(n3))/3
print(f"{nom}: {moyenne:.2f}")with ferme le fichier automatiquement. strip() enlève le \n, split(";") découpe la ligne, et int() convertit les notes.
Classe & encapsulation
Attributs privés et validation
Une classe Etudiant avec attributs privés, getters via @property, validation des notes (0–20) et méthodes __str__ / __repr__.
Le double __ rend l'attribut privé ; @property expose une lecture contrôlée. La validation est centralisée dans une méthode privée.
class Etudiant:
def __init__(self, nom, n1, n2, n3):
self.__nom = nom
self.__notes = [self.__valider(n)
for n in (n1, n2, n3)]
def __valider(self, note):
if not (0 <= note <= 20):
raise ValueError("note invalide")
return note
@property
def moyenne(self):
return sum(self.__notes) / len(self.__notes)L'encapsulation protège l'état interne : on ne peut pas poser une note invalide « par la porte de derrière ». __str__ est lisible, __repr__ est technique.
Héritage
EtudiantBoursier hérite d'Etudiant
Une classe EtudiantBoursier qui hérite d'Etudiant, avec un attribut montant_bourse et une méthode ajuster_bourse().
class EtudiantBoursier(Etudiant):
def __init__(self, nom, n1, n2, n3, bourse):
super().__init__(nom, n1, n2, n3)
self.__montant_bourse = bourse
def ajuster_bourse(self):
if self.moyenne >= 14: # hérité
self.__montant_bourse *= 1.10
return True
return Falsesuper().__init__() initialise la partie héritée ; la sous-classe ajoute montant_bourseet réutilise self.moyenne du parent.
« Boursier est un Étudiant » : il réutilise tout le parent via super() et n'ajoute que ce qui le distingue.
Polymorphisme & synthèse
Une Promotion qui gère les deux types
Une classe Promotion qui gère une liste d'étudiants : ajout (avec contrôle de type), classement, moyenne de promotion et sauvegarde.
class Promotion:
def ajouter(self, etudiant):
if isinstance(etudiant, Etudiant): # accepte aussi
self.__etudiants.append(etudiant) # les sous-classes
else:
raise TypeError("Doit être un Etudiant")
def afficher_classement(self):
self.__etudiants.sort(key=lambda e: e.moyenne,
reverse=True)Polymorphisme : la liste contient des Etudiant et desEtudiantBoursier sans distinction. e.moyenne et str(e) font « ce qu'il faut » selon le type réel de chaque objet.
La même liste contient Etudiant et EtudiantBoursier. Grâce au polymorphisme, e.moyenne et str(e) s'adaptent au type réel — le code de Promotion n'a pas à savoir lequel est lequel.