Aller au contenu principal

Ch. 00 · Leçon 3

Mini-projet 2 — Classement d'élèves au bac

90 minanalyse · python
Affichage du code

Ce que vous saurez faire

  • Calculer une mention à partir d'une moyenne
  • Trier des élèves par moyenne décroissante
  • Produire des statistiques sur une classe (admis, échec, moyenne globale)
  • Combiner conditions, tableaux, tri et fonctions

25 élèves, 1 classement, 4 chapitres mobilisés

Ce mini-projet rejoue un classique du bac : produire un bulletin de classe complet à partir d'une liste de moyennes.


Énoncé

Un professeur saisit les noms et moyennes de 25 élèves de sa classe. Le programme doit :

  1. Calculer la mention de chaque élève selon :

    • Très Bien : moyenne ≥ 16
    • Bien : 14 ≤ moyenne < 16
    • Assez Bien : 12 ≤ moyenne < 14
    • Passable : 10 ≤ moyenne < 12
    • Refusé : moyenne < 10
  2. Afficher la liste classée par moyenne décroissante (avec nom, moyenne, mention).

  3. Calculer et afficher les statistiques :

    • Moyenne globale de la classe.
    • Nombre d'admis (moyenne ≥ 10) et taux de réussite (%).
    • Nombre d'élèves par mention.
    • Meilleur et pire élève (nom + moyenne).

Travail demandé

  • Arbre d'analyse modulaire (au moins 5 modules).
  • T.D.O complet.
  • Algorithme détaillé.
  • Traduction Python 3.
  • Justification des structures de boucle et de l'algorithme de tri.

Pistes

💡 Indice 1 — Structure de stockage

Deux tableaux parallèles noms[25] et moyennes[25]. La cohérence d'indice doit être préservée à tout moment.

💡 Indice 2 — Fonction determiner_mention

Cascade de Si…Sinon Si… du plus restrictif (≥ 16) au plus large (< 10). Le piège classique : tester ≥ 10 en premier classe tout le monde « Passable ».

💡 Indice 3 — Tri parallèle

Choisir tri par sélection ou par bulles, peu importe pour 25 éléments. Échange des deux tableaux à chaque permutation, sinon l'association nom/moyenne est perdue.


Corrigé

📘 Voir le corrigé

Arbre d'analyse

                  ProgrammeClassement
                          │
   ┌────────┬──────┬──────┴──────┬───────────────┬──────────────┐
   ▼        ▼      ▼             ▼               ▼              ▼
saisir_  trier_  determiner_  afficher_     stats_         afficher_
classe   moyennes_ mention    classement   admis_par_     extremes
         decroissant                       mention

Code Python complet

def determiner_mention(m: float) -> str:
    """Retourne la mention selon la moyenne."""
    if m >= 16:
        return "Très Bien"
    elif m >= 14:
        return "Bien"
    elif m >= 12:
        return "Assez Bien"
    elif m >= 10:
        return "Passable"
    else:
        return "Refusé"

def saisir_classe(N: int) -> tuple[list[str], list[float]]:
    noms = [""] * N
    moyennes = [0.0] * N
    for i in range(N):
        noms[i] = input(f"Nom élève {i + 1} : ").strip()
        # Validation moyenne ∈ [0, 20]
        while True:
            try:
                m = float(input(f"Moyenne de {noms[i]} : "))
                if 0 <= m <= 20:
                    moyennes[i] = m
                    break
            except ValueError:
                pass
            print("Moyenne invalide, doit être ∈ [0, 20].")
    return noms, moyennes

def trier_moyennes_decroissant(noms: list[str], moyennes: list[float]) -> None:
    """Tri par sélection décroissant des deux tableaux en parallèle."""
    N = len(noms)
    for i in range(N - 1):
        idx_max = i
        for j in range(i + 1, N):
            if moyennes[j] > moyennes[idx_max]:
                idx_max = j
        noms[i], noms[idx_max] = noms[idx_max], noms[i]
        moyennes[i], moyennes[idx_max] = moyennes[idx_max], moyennes[i]

def afficher_classement(noms: list[str], moyennes: list[float]) -> None:
    print("\n--- Classement ---")
    print(f"{'Rang':>4} | {'Nom':<25} | {'Moy.':>6} | Mention")
    print("-" * 60)
    for i in range(len(noms)):
        mention = determiner_mention(moyennes[i])
        print(f"{i + 1:>4} | {noms[i]:<25} | {moyennes[i]:>6.2f} | {mention}")

def moyenne_globale(moyennes: list[float]) -> float:
    if not moyennes:
        return 0.0
    return sum(moyennes) / len(moyennes)

def stats_admission(moyennes: list[float]) -> tuple[int, float]:
    nb_admis = sum(1 for m in moyennes if m >= 10)
    taux = (nb_admis / len(moyennes)) * 100 if moyennes else 0.0
    return nb_admis, taux

def stats_par_mention(moyennes: list[float]) -> dict[str, int]:
    compteurs = {
        "Très Bien": 0, "Bien": 0, "Assez Bien": 0,
        "Passable": 0, "Refusé": 0,
    }
    for m in moyennes:
        compteurs[determiner_mention(m)] += 1
    return compteurs

def extremes(noms: list[str], moyennes: list[float]) -> tuple[str, float, str, float]:
    """Retourne (meilleur_nom, meilleure_moy, pire_nom, pire_moy)."""
    idx_max = 0
    idx_min = 0
    for i in range(1, len(moyennes)):
        if moyennes[i] > moyennes[idx_max]:
            idx_max = i
        if moyennes[i] < moyennes[idx_min]:
            idx_min = i
    return noms[idx_max], moyennes[idx_max], noms[idx_min], moyennes[idx_min]

# === Programme principal ===
N = 25
noms, moyennes = saisir_classe(N)
trier_moyennes_decroissant(noms, moyennes)
afficher_classement(noms, moyennes)

print("\n--- Statistiques ---")
print(f"Moyenne globale : {moyenne_globale(moyennes):.2f} / 20")

nb, taux = stats_admission(moyennes)
print(f"Admis : {nb} / {N} ({taux:.1f}%)")

print("Par mention :")
for mention, n in stats_par_mention(moyennes).items():
    print(f"  {mention:<12} : {n}")

best_nom, best_moy, worst_nom, worst_moy = extremes(noms, moyennes)
print(f"\nMeilleur : {best_nom} ({best_moy})")
print(f"Pire     : {worst_nom} ({worst_moy})")

Justifications

  • Tableaux parallèles : pas de structure composée au programme. Garder l'index aligné.
  • Tri par sélection décroissant : modifier la comparaison > au lieu de <. O(n²) acceptable pour 25 éléments.
  • determiner_mention séparée : réutilisable par stats_par_mention. Principe DRY (Don't Repeat Yourself).
  • Boucle de validation while True pour la saisie de moyenne (correspond à Répéter…Jusqu'à algorithmique).

Auto-évaluation

  • Arbre d'analyse avec au moins 5 modules
  • T.D.O complet
  • determiner_mention correcte (ordre des conditions !)
  • Tri par sélection décroissant sur les deux tableaux
  • Statistiques (admis, mentions, extrêmes)
  • Validation de saisie pour les moyennes

Bravo d'être arrivé jusqu'ici. Marquez la leçon terminée pour ancrer le progrès.