Accueil

Corrigé Sujet N°18

- Analyse des Températures Océaniques en Polynésie Française -

Vous pouvez télécharger les éléments suivants en cliquant sur les boutons associés :
Sujet (PDF) Fichier Python Initial
Fichier Python Corrigé

Question 1

Écrire la fonction temperature_moyenne(zone, donnees) qui renvoie la température moyenne pour la zone donnée, ou None si aucun relevé n'existe pour cette zone.
Correction : On filtre les relevés correspondant à la zone, puis on calcule la moyenne si la liste n'est pas vide, sinon on retourne None.

def temperature_moyenne(zone, donnees):
    """Renvoie la température moyenne de la zone, ou None si absente."""
    releves = [r['temperature'] for r in donnees if r['zone'] == zone]
    if not releves:
        return None
    return sum(releves) / len(releves)

# Tests
# 'Societe' : (27.0 + 26.5 + 27.5 + 28.0 + 28.5 + 29.0) / 6 = 27.75
assert temperature_moyenne('Societe', donnees_test) == 27.75
assert temperature_moyenne('Inconnu', donnees_test) is None
                

Question 2

Écrire la fonction detecter_anomalies(zone, seuil, donnees) qui renvoie la liste des dates où la température s'écarte de plus de seuil degrés (en valeur absolue) de la moyenne de la zone.
Correction : On réutilise temperature_moyenne pour obtenir la référence, puis on filtre les relevés dont l'écart absolu dépasse le seuil. Si la zone n'existe pas, temperature_moyenne renvoie None et on retourne une liste vide.

def detecter_anomalies(zone, seuil, donnees):
    """Renvoie les dates des relevés anormaux (écart > seuil par rapport à la moyenne)."""
    moy = temperature_moyenne(zone, donnees)
    if moy is None:
        return []
    return [
        r['date']
        for r in donnees
        if r['zone'] == zone and abs(r['temperature'] - moy) > seuil
    ]
                

Question 3

Compléter les trois fonctions de test pour evolution_par_decennie afin d'identifier le bug présent dans le code.
Correction des tests : Les tests doivent vérifier que les clés du dictionnaire retourné sont bien des décennies complètes (2010, 2020) et non des entiers tronqués (201, 202), ce qui révèle le bug du calcul de décennie.

def test_zone_inexistante():
    """Zone inexistante → dictionnaire vide."""
    resultat = evolution_par_decennie('Australes', donnees_test)
    assert resultat == {}
    print("test_zone_inexistante : OK")

def test_une_seule_decennie():
    """Marquises : données à partir de 2020 uniquement → une seule clé 2020."""
    resultat = evolution_par_decennie('Marquises', donnees_test)
    assert len(resultat) == 1
    assert 2020 in resultat          # révèle le bug si la clé est 202 au lieu de 2020
    assert resultat[2020] == 26.0    # (25.5 + 26.0 + 26.5) / 3
    print("test_une_seule_decennie : OK")

def test_plusieurs_decennies():
    """Société : 2010 et 2020 → deux clés distinctes."""
    resultat = evolution_par_decennie('Societe', donnees_test)
    assert 2010 in resultat and 2020 in resultat
    assert resultat[2010] == 27.0    # (27.0 + 26.5 + 27.5) / 3
    assert resultat[2020] == 28.5    # (28.0 + 28.5 + 29.0) / 3
    print("test_plusieurs_decennies : OK")
                

Bug détecté : Le calcul decennie = (annee // 10) produit 201 pour les années 2010–2019 et 202 pour les années 2020–2029, au lieu de 2010 et 2020. Les tests assert 2020 in resultat échouent, ce qui met immédiatement le bug en évidence.

Question 4

Après avoir identifié le bug grâce aux tests, corriger la fonction evolution_par_decennie.
Correction : Il suffit de multiplier le résultat de la division entière par 10 pour retrouver la décennie correcte : (annee // 10) * 10. Ainsi 2013 → 201 → 2010, et 2024 → 202 → 2020.

def evolution_par_decennie(zone, donnees):
    releves_zone = [r for r in donnees if r['zone'] == zone]
    if not releves_zone:
        return {}

    temperatures_par_decennie = {}
    for releve in releves_zone:
        annee = int(releve['date'].split('-')[0])
        decennie = (annee // 10) * 10   # CORRECTION : * 10 pour obtenir 2010, 2020...

        if decennie not in temperatures_par_decennie:
            temperatures_par_decennie[decennie] = []
        temperatures_par_decennie[decennie].append(releve['temperature'])

    moyennes = {}
    for decennie, temperatures in temperatures_par_decennie.items():
        moyennes[decennie] = round(sum(temperatures) / len(temperatures), 2)
    return moyennes