12 - Fichiers
Exercice 0 : QCM – vérification des prérequis
Pour chaque question, une seule réponse est correcte.
1. Quel mode d’ouverture permet d’écrire dans un fichier en effaçant son contenu précédent ?
- A.
open("f.txt", "r") - B.
open("f.txt", "w") - C.
open("f.txt", "a") - D.
open("f.txt", "x")
Correction
Réponse : B. Le mode "w" (write) ouvre le fichier en écriture et écrase tout contenu existant. Si le fichier n’existe pas, il est créé.
- A est faux :
"r"(read) ouvre en lecture seule ; toute tentative d’écriture lève une erreur. - C est faux :
"a"(append) ouvre en écriture mais ajoute à la fin du fichier sans effacer le contenu existant. - D est faux :
"x"crée un nouveau fichier, mais lève une erreur si le fichier existe déjà.
2. Que fait l’instruction with open("f.txt", "r") as f: ?
- A. Elle crée un nouveau fichier
f.txt - B. Elle ouvre
f.txten lecture et le ferme automatiquement à la fin du bloc - C. Elle ouvre
f.txten écriture - D. Elle supprime le fichier
f.txt
Correction
Réponse : B. Le mot-clé with est un gestionnaire de contexte : il ouvre le fichier et garantit sa fermeture automatique à la sortie du bloc indenté, même en cas d’erreur. Le mode "r" indique la lecture.
- A est faux : le mode
"r"n’écrit pas, il lit (et lève une erreur si le fichier n’existe pas). - C est faux : l’écriture nécessite le mode
"w"ou"a". - D est faux :
openne supprime jamais de fichier.
3. Après ligne = f.readline(), que contient ligne ?
- A. Toutes les lignes du fichier sous forme de liste
- B. Une seule ligne du fichier, avec le caractère
\nà la fin - C. Une seule ligne du fichier, sans le caractère
\n - D. Le fichier entier sous forme de chaîne
Correction
Réponse : B. readline() lit une seule ligne et conserve le caractère de fin de ligne \n. Pour le supprimer, on utilise ligne.strip() ou ligne.rstrip("\n").
- A est faux : c’est le rôle de
readlines()(avec un « s »), qui renvoie une liste de lignes. - C est faux :
readline()conserve le\n(piège classique). - D est faux : c’est le rôle de
read()(sans « line »).
4. Que se passe-t-il si on exécute f.write("Bonjour") puis f.write("monde") sans rien entre les deux ?
- A. Le fichier contient
Bonjour\nmonde - B. Le fichier contient
Bonjourmonde - C. Le fichier contient
Bonjour monde - D. Python lève une erreur
Correction
Réponse : B. write() n’ajoute aucun séparateur automatique (ni espace, ni retour à la ligne). Les deux chaînes sont concaténées : Bonjourmonde.
- A est faux :
writen’ajoute pas de\n; il faut l’écrire explicitement avecf.write("Bonjour\n"). - C est faux :
writen’ajoute pas d’espace. - D est faux : l’instruction est parfaitement valide (en mode écriture).
Exercice 1 : écriture simple
- Écrire un programme qui crée un fichier
fruits.txtcontenant les noms de cinq fruits, un par ligne. - Vérifier le contenu du fichier en l’ouvrant avec un éditeur de texte.
- Modifier le programme pour ajouter trois fruits supplémentaires au fichier existant (sans effacer les cinq premiers).
Correction
1.
with open("fruits.txt", "w") as f:
f.write("Pomme\n")
f.write("Banane\n")
f.write("Cerise\n")
f.write("Orange\n")
f.write("Fraise\n")
3. Pour ajouter sans effacer, on utilise le mode "a" (append) :
with open("fruits.txt", "a") as f:
f.write("Kiwi\n")
f.write("Mangue\n")
f.write("Ananas\n")
Le fichier contient maintenant huit fruits. Si on avait utilisé "w" au lieu de "a", les cinq premiers auraient été effacés.
Exercice 2 : lecture et affichage
On dispose du fichier fruits.txt créé à l’exercice précédent.
Écrire un programme qui lit le fichier et affiche chaque fruit précédé de son numéro :
1. Pomme 2. Banane 3. Cerise ...Écrire un programme qui lit le fichier et affiche le nombre total de fruits.
Correction
1.
with open("fruits.txt", "r") as f:
numero = 1
for ligne in f:
print(f"{numero}. {ligne.strip()}")
numero += 1
On utilise strip() pour retirer le \n en fin de ligne, sinon il y aurait un saut de ligne parasite dans l’affichage.
Variante avec enumerate :
with open("fruits.txt", "r") as f:
for i, ligne in enumerate(f, start=1):
print(f"{i}. {ligne.strip()}")
2.
with open("fruits.txt", "r") as f:
lignes = f.readlines()
print(f"Nombre de fruits : {len(lignes)}")
Exercice 3 : le caractère \n
On crée le fichier suivant :
with open('test.txt', 'w') as f:
f.write('Bonjour')
f.write('le')
f.write('monde')
- Sans exécuter le code, prédire le contenu du fichier
test.txt. - Vérifier en exécutant le programme.
- Modifier le programme pour que chaque mot apparaisse sur une ligne distincte.
Correction
1. Le fichier contient Bonjourlemonde sur une seule ligne. En effet, write ne rajoute ni espace ni retour à la ligne.
3. On ajoute \n à la fin de chaque chaîne :
with open('test.txt', 'w') as f:
f.write('Bonjour\n')
f.write('le\n')
f.write('monde\n')
Le fichier contient alors :
Bonjour
le
monde
Exercice 4 : traitement de données
On dispose d’un fichier mesures.txt contenant une température par ligne :
18.5
21.3
19.7
22.1
17.8
20.4
Écrire un programme qui :
- lit toutes les températures ;
- affiche la température minimale, la température maximale et la moyenne (arrondie à un chiffre après la virgule).
Correction
with open("mesures.txt", "r") as f:
temperatures = []
for ligne in f:
temperatures.append(float(ligne.strip()))
t_min = min(temperatures)
t_max = max(temperatures)
moyenne = sum(temperatures) / len(temperatures)
print(f"Minimum : {t_min} °C")
print(f"Maximum : {t_max} °C")
print(f"Moyenne : {round(moyenne, 1)} °C")
Résultat : minimum = 17,8 °C ; maximum = 22,1 °C ; moyenne = \(\frac{18{,}5 + 21{,}3 + 19{,}7 + 22{,}1 + 17{,}8 + 20{,}4}{6} = \frac{119{,}8}{6} \approx 20{,}0\) °C.
Point clé : on convertit chaque ligne en float après avoir retiré le \n avec strip().
Exercice 5 : fichier structuré
On dispose d’un fichier eleves.txt dont chaque ligne contient un nom et une note séparés par un point-virgule :
Alice Martin;16
Bob Dupont;12
Charlie Moreau;8
Diana Petit;14
Eve Bernard;18
Écrire un programme qui :
- affiche le nom et la note de chaque élève ;
- calcule et affiche la moyenne de la classe ;
- affiche les noms des élèves ayant une note supérieure ou égale à la moyenne.
Correction
with open("eleves.txt", "r") as f:
eleves = []
for ligne in f:
parties = ligne.strip().split(";")
nom = parties[0]
note = int(parties[1])
eleves.append((nom, note))
# 1. Affichage
for nom, note in eleves:
print(f"{nom} : {note}/20")
# 2. Moyenne
somme = sum(note for nom, note in eleves)
moyenne = somme / len(eleves)
print(f"\nMoyenne de la classe : {moyenne:.1f}/20")
# 3. Au-dessus de la moyenne
print("\nÉlèves au-dessus de la moyenne :")
for nom, note in eleves:
if note >= moyenne:
print(f" {nom} ({note}/20)")
Résultat : moyenne = \(\frac{16 + 12 + 8 + 14 + 18}{5} = \frac{68}{5} = 13{,}6\). Les élèves au-dessus : Alice (16), Diana (14), Eve (18).
Point clé : split(";") découpe la ligne au niveau du point-virgule et renvoie une liste de deux éléments.
Exercice 6 : copie filtrée
Écrire un programme qui lit le fichier eleves.txt de l’exercice précédent et crée un fichier reussite.txt contenant uniquement les lignes des élèves ayant obtenu 10 ou plus.
Correction
with open("eleves.txt", "r") as source:
with open("reussite.txt", "w") as dest:
for ligne in source:
parties = ligne.strip().split(";")
note = int(parties[1])
if note >= 10:
dest.write(ligne)
Le fichier reussite.txt contient :
Alice Martin;16
Bob Dupont;12
Diana Petit;14
Eve Bernard;18
Charlie Moreau (note 8) est exclu car sa note est inférieure à 10.
Remarque : on écrit ligne (et non ligne.strip()) pour conserver le \n et garder une ligne par élève dans le fichier de sortie.
Exercice 7 : statistiques de texte
Écrire une fonction statistiques(nom_fichier) qui reçoit le nom d’un fichier texte et renvoie un dictionnaire contenant le nombre de lignes, le nombre de mots (en utilisant split()) et le nombre de caractères (espaces compris).
stats = statistiques('eleves.txt')
print(stats)
# {'lignes': 5, 'mots': 10, 'caracteres': 77}
Correction
def statistiques(nom_fichier):
"""Renvoie un dictionnaire avec le nombre de lignes, mots et caractères."""
nb_lignes = 0
nb_mots = 0
nb_caracteres = 0
with open(nom_fichier, "r") as f:
for ligne in f:
nb_lignes += 1
nb_mots += len(ligne.split())
nb_caracteres += len(ligne)
return {
"lignes": nb_lignes,
"mots": nb_mots,
"caracteres": nb_caracteres
}
# Test
stats = statistiques("eleves.txt")
print(stats)
Détail : split() sans argument découpe la ligne sur les espaces (et les tabulations, retours à la ligne). len(ligne) compte tous les caractères, y compris \n. Si on souhaite exclure les retours à la ligne, on peut utiliser len(ligne.rstrip("\n")).