Un corrigé pédagogique pour comprendre et justifier vos réponses. Les conseils de rédaction ne constituent pas un barème officiel détaillé.
Application
Ballon sonde, températures et export cartographique KML
Le ballon sonde s’élève avec un gaz léger, mesure température, altitude et position, puis éclate avant sa descente sous parachute. Le fichier du sujet ne conserve que la montée :20 relevés, altitude en mètres, température en kelvins, longitude et latitude. Le programme doit convertir les températures en°C, retrouver toutes les altitudes du minimum puis exporter les positions dans un document KML. Le schéma de vol du PDF sert au contexte ; les étapes utiles sont : lâcher au sol, montée instrumentée, éclatement, descente sous parachute. Seule la montée est analysée ici.
Le dossier comporte le sujet et les fichiers listés dans les téléchargements. Les codes de départ sont reproduits ci-dessous. Travaillez sur une copie. Les appels professeur signalés dans les questions servent à présenter votre démarche ; vous pouvez aussi demander de l’aide en cas de difficulté.
Code fourni : etude_climatique.py
# ///////////////////////////////////////////////////////////////////////////
# FONCTIONS DONNEES
# ///////////////////////////////////////////////////////////////////////////
def recupere_donnees_fichier_csv(nom_fichier):
""" Fonction qui récupère les données relevées du ballon sonde sans les en-têtes de la 1ère ligne """
altitudes = [] # Initialisation des listes de valeurs relevées
temperatures = []
longitudes = []
latitudes = []
# Ouverture du fichier csv au format releves_ballon_sonde.csv en mode "read"
contenu_fichier = open(nom_fichier, 'r')
# Supprime la 1ère ligne avec les en-têtes
contenu_fichier.readline()
# Parcours des lignes du fichier csv contenant les donnees relevées
for ligne in contenu_fichier.readlines():
# rstrip() supprime les \n et espaces en fin de ligne
ligne = ligne.rstrip()
# création d'une listeValeurs. split(";") sépare les valeurs grâce au ;
listeValeurs = ligne.split(";")
# conversion string en int de l'altitude et insertion dans la liste correspondante
altitudes.append(int(listeValeurs[0]))
# conversion string en float de la température et insertion dans la liste correspondante
temperatures.append(float(listeValeurs[1]))
# conversion string en float de la longitude et insertion dans la liste correspondante
longitudes.append(float(listeValeurs[2]))
# conversion string en float de la latitude et insertion dans la liste correspondante
latitudes.append(float(listeValeurs[3]))
contenu_fichier.close()
return altitudes, temperatures, longitudes, latitudes
def genere_kml(liste_longitudes, liste_latitudes):
""" Fonction qui génère un fichier de données géographiques au format standard international KML
Ce fichier est visionnable ensuite dans différents logiciels
"""
fichier_kml = open(
'ballon sonde.kml', 'w') # Création et ouverture du fichier kml en mode "write"
entete_fichier = '<?xml version="1.0" encoding="UTF-8"?>\n'
entete_fichier += '<kml xmlns="http://www.opengis.net/kml/2.2">\n'
entete_fichier += '<Document>\n'
entete_fichier += '<name>Trajectoire ballon sonde</name>\n'
# Ecriture du contenu de la variable entete_fichier dans le fichier kml
fichier_kml.write(entete_fichier)
for i in range(len(liste_longitudes)):
corps_fichier = '<Placemark>\n'
corps_fichier += f'<name>Point {i}</name>\n'
corps_fichier += '<Point>\n'
corps_fichier += f'<coordinates>{liste_longitudes[i]},{liste_latitudes[i]}</coordinates>\n'
corps_fichier += '</Point>\n'
corps_fichier += '</Placemark>\n'
fichier_kml.write(corps_fichier)
bas_fichier = '</Document>\n'
fichier_kml.write(bas_fichier)
fichier_kml.close() # Fermeture du fichier kml
# ///////////////////////////////////////////////////////////////////////////
# TRAVAIL DEMANDE
# ///////////////////////////////////////////////////////////////////////////
# QUESTION 1
# Compléter ici
# QUESTION 2
def conversion_K_en_C(liste_temperatures):
pass # Ajuster la fonction
# QUESTION 3
def altitude_la_plus_froide(liste_altitudes, liste_temperatures):
pass # Ajuster la fonction
# AUTRES ELEMENTS DE CODE
Question 1
#Utiliser recupere_donnees_fichier_csv pour récupérer les données de releves_ballon_sonde.csv dans quatre listes : altitudes, temperatures, longitudes et latitudes.
Indice
Lire l’ordre du tuple retourné.
Comprendre la correction
altitudes, temperatures, longitudes, latitudes = recupere_donnees_fichier_csv(
'releves_ballon_sonde.csv')Le déballage suit exactement l’ordre du return fourni. Les quatre listes ont 20 éléments dans le fichier réel ; un même indice désigne un même relevé. Échanger longitude et latitude produirait des positions incorrectes, même si le programme s’exécutait sans erreur.
Question 2
#Écrire conversion_K_en_C : convertir une liste de kelvins en degrés Celsius, arrondis à un chiffre après la virgule, puis renvoyer la liste. Écrire un test.
Indice
Soustraire 273,15, puis arrondir.
Comprendre la correction
def conversion_K_en_C(liste_temperatures):
for i in range(len(liste_temperatures)):
liste_temperatures[i] = round(liste_temperatures[i] - 273.15, 1)
return liste_temperaturesassert conversion_K_en_C([273.15,288.15,216.65]) == [0.0,15.0,-56.5]
temperatures_C = conversion_K_en_C(temperatures.copy())La relation est Celsius=kelvins−273,15. La version ci-dessus modifie puis renvoie la liste reçue ; l’appel avec copy conserve les données brutes. Arrondir à un chiffre définit les valeurs comparées dans la question suivante : plusieurs mesures initialement très proches peuvent partager le même minimum après arrondi.
Question 3
#Écrire altitude_la_plus_froide(altitudes, temperatures), qui renvoie la température minimale et toutes les altitudes correspondantes. Les exemples attendus sont (-57.4,[13896,14211]) et (-60.1,[17300]) pour les listes données.
PythonGarder toutes les altitudes les plus froidesÉcrivez votre solution et mettez-la à l’épreuve
Écrivez altitude_la_plus_froide(liste_altitudes, liste_temperatures). Les deux listes sont non vides et de même longueur ; leurs indices se correspondent. Renvoyez un tuple (température minimale, liste de toutes ses altitudes), dans l’ordre des relevés. Contrôlez cette précondition par assertion.
def altitude_la_plus_froide(liste_altitudes, liste_temperatures):
# À vous de jouer
pass
Les cas de test proposés :
- Deux minima, comme dans le sujet : Une égalité doit compléter la sélection.
- Un minimum tardif remplace les anciens : Lorsque le minimum baisse, les anciennes altitudes cessent d’être des solutions.
- Températures toutes positives : Initialiser à zéro donnerait un minimum qui n’a jamais été observé.
- Une seule mesure : La première mesure ne doit pas être oubliée ni dupliquée.
- Indices et ordre : Le résultat suit les relevés, sans trier les altitudes.
- Longueurs incompatibles : Un même indice doit toujours désigner un relevé complet.
Indice
Distinguer strictement plus froid et aussi froid.
Comprendre la correction
def altitude_la_plus_froide(liste_altitudes, liste_temperatures):
assert len(liste_altitudes) == len(liste_temperatures) > 0
minimum = liste_temperatures[0]
altitudes = []
for i in range(len(liste_temperatures)):
temperature = liste_temperatures[i]
if temperature < minimum:
minimum = temperature
altitudes = [liste_altitudes[i]]
elif temperature == minimum:
altitudes.append(liste_altitudes[i])
return minimum, altitudesassert altitude_la_plus_froide([7000,10125,13896,14211],
[-35.2,-52.1,-57.4,-57.4]) == (-57.4,[13896,14211])
assert altitude_la_plus_froide([6000,7250,11542,15214,17300],
[-33.7,-45,-53,-58.5,-60.1]) == (-60.1,[17300])
print(altitude_la_plus_froide(altitudes,temperatures_C))Un nouveau minimum remplace la liste d’altitudes ; une égalité ajoute une altitude. Initialiser le minimum à 0 serait inadapté à une série entièrement positive. Avec les 20 relevés réels, on obtient (-56.5,[15120,17210]). On exige ici des listes non vides et de même longueur : un minimum d’une série vide n’est pas défini.
Suivons l’exemple à quatre altitudes. On commence avec −35,2 comme minimum et une liste vide. Le premier relevé est égal au minimum : son altitude est ajoutée. −52,1 est ensuite plus froid, donc il remplace le minimum et sa liste d’altitudes. −57,4 fait la même chose, puis le dernier −57,4 est une égalité : on ajoute sa seconde altitude. L’état final est donc bien (-57.4, [13896, 14211]). Une simple affectation à chaque égalité ne garderait que la dernière altitude, tandis qu’un ajout sans réinitialisation garderait aussi les anciennes valeurs devenues trop chaudes.
Question 4
#Insérer dans genere_kml une assertion garantissant que liste_longitudes et liste_latitudes ont la même longueur.
Comprendre la correction
assert len(liste_longitudes) == len(liste_latitudes)La placer dès l’entrée de la fonction, avant l’ouverture du fichier. Cela évite de créer un fichier partiellement écrit lorsque le couplage des coordonnées est impossible. Le test de longueur n’atteste pas que les positions sont géographiquement correctes, mais garantit que chaque longitude a une latitude au même indice.
Question 5
#Appeler genere_kml avec les listes obtenues à la question 1, puis ouvrir le fichier produit dans le même répertoire que le programme.
Comprendre la correction
genere_kml(longitudes, latitudes)Le nom imposé par le code est ballon sonde.kml. Ouvrez-le dans un éditeur pour examiner le XML, puis dans un logiciel compatible KML pour visualiser les points. Les coordonnées KML suivent l’ordre longitude, latitude. Le fichier fournit 20 points ; le premier est 4.760467,45.602117 et le dernier 5.766817,45.616383. Il représente des points séparés, pas encore une ligne reliant la trajectoire.
Question 6
#Le fichier pose des problèmes de compatibilité car la balise kml n’est pas fermée. Proposer une amélioration du code.
Indice
Fermer une ressource fichier et fermer une balise sont deux opérations différentes.
Comprendre la correction
La correction minimale ajoute </kml> après </Document>, avant la fermeture du fichier. Le gestionnaire with ferme correctement le fichier même si une exception survient ; cela ne remplace pas la fermeture XML de la balise. Voici la fonction complète :
def genere_kml(liste_longitudes, liste_latitudes):
assert len(liste_longitudes) == len(liste_latitudes)
with open('ballon sonde.kml', 'w', encoding='utf-8') as fichier:
fichier.write('<?xml version="1.0" encoding="UTF-8"?>\n')
fichier.write('<kml xmlns="http://www.opengis.net/kml/2.2">\n<Document>\n')
fichier.write('<name>Trajectoire ballon sonde</name>\n')
for i in range(len(liste_longitudes)):
fichier.write(f'<Placemark><name>Point {i}</name><Point>')
fichier.write(f'<coordinates>{liste_longitudes[i]},{liste_latitudes[i]}</coordinates>')
fichier.write('</Point></Placemark>\n')
fichier.write('</Document>\n</kml>\n')On respecte l’emboîtement : Point dans Placemark, Placemark dans Document, Document dans kml. Les balises se ferment dans l’ordre inverse de leur ouverture. Pour vérifier la structure sans dépendre d’un logiciel cartographique :
import xml.etree.ElementTree as ET
racine = ET.parse('ballon sonde.kml').getroot()
ns = {'k': 'http://www.opengis.net/kml/2.2'}
assert len(racine.findall('.//k:Placemark',ns)) == len(longitudes)Contrôler un document cartographiqueUn atelier pour expérimenter
Choisissez une réponse puis confrontez votre intuition à l’explication. Vous pouvez modifier vos choix.
Lire les réponses et leurs explications
- Quel ordre faut-il dans coordinates ?
Longitude, latitude.. C’est l’ordre employé dans le code et le format.
- with open ferme-t-il la balise kml ?
Non, il ferme le fichier.. La fermeture du flux et celle de la structure XML sont distinctes.
Appuyez votre explication sur les valeurs et les conditions exactes du programme.
Un minimum, plusieurs altitudesUn atelier pour expérimenter
Modifiez les températures aux deux altitudes centrales. L’atelier recherche toutes les occurrences du minimum et montre pourquoi il faut parfois réinitialiser, parfois ajouter.
Lire le résultat de l’expérience initiale
Minimum -57.4°C à 13896 et 14211m.
Une température plus basse efface les anciennes altitudes ; une égalité ajoute une occurrence.
| Altitude (m) | Température (°C) | Minimum ? |
|---|---|---|
| 7000 | -35.2 | Non |
| 10125 | -52.1 | Non |
| 13896 | -57.4 | Oui |
| 14211 | -57.4 | Oui |
La recherche d’un extremum et celle de toutes ses positions doivent évoluer ensemble.
Revoir les notions de cet exercice
Du sujet à la méthode
Votre prochaine séance de révision
- Préserver l’alignement des données issues d’une même ligne CSV.
- Vérifier séparément les nombres, la structure XML et l’affichage cartographique.
Retrouver ces notions dans d’autres sujets
Toutes les annales de NSI · Le guide pour préparer le bac NSI 2027
Énoncé : sujet 26_BCG_NSI_13 (PDF). Corrigé et explications pédagogiques proposés par Sofien.
