Vous êtes sur la page 1sur 5

Université Clermont Auvergne Portail Maths Info, LAS Maths-Info, PASS Info

Algorithmique et Programmation en Python - Semestre 1

Algorithmique et Programmation en Python


TD09 : Lire/écrire dans un fichier et traitement de données
Quelques fonctions utiles pour traiter des fichiers textes :
• strip , pour se débarrasser notamment des retours à la ligne qui existent naturellement en fin de ligne dans
un fichier : si ligne est une variable qui contient la chaîne de caractère " une phrase ici \n" alors
ligne.strip() renvoie la chaîne de caractère débarassée de tous les caractères blancs (espaces, retours à la
ligne, ...) en début et fin de chaîne, ce qui donnerait ici "une phrase ici".
• split, pour découper une ligne en plusieurs morceaux :
 sans argument : si ligne est une variable qui contient la chaîne de caractère " un mot puis deux
\n " alors ligne.split() découpe la chaîne à chaque groupe de caractères blancs (espaces, retours à la
ligne, ...) et renvoie une liste des morceaux ainsi obtenus, en enlevant les morceaux vides, c’est-à-dire que
ligne.split() renvoie ["un", "mot", "puis", "deux"].
 avec un argument : si ligne est une variable qui contient la chaîne de caractère "un;deux;trois\n" alors
ligne.split(";") découpe la chaîne à chaque point-virgule et renvoie une liste des morceaux ainsi obtenus
(en gardant cette fois-ci les caractères blancs et les morceaux vides), c’est-à-dire que ligne.split(";") ren-
voie ["un", "deux", "trois\n"]. Si ligne2 vaut "un;deux;trois;" alors ligne2.split(";") renvoie
["un", "deux", "trois", ""]

Exercice 1 : Parfum
On a obtenu d’un parfumeur la composition générale de plusieurs de ses parfums, sous la forme d’un fichier.
La composition de chaque parfum se trouve sur une ligne. Les éléments sont séparés par un espace. Tout est écrit
en caractères minuscules.

#Contenu du fichier parfum.txt


bergamote clementine jasmin musc rose ylang-ylang
cedre patchouli rose violette
bergamote musc myrrhe thym vanille

Les éléments composant un parfum s’appellent des fragrances (odeurs). Chaque parfum doit comporter différents
types de fragrances :
— Celles que l’on détecte en premier, puis qui se dissipent (tête).
— Celles que l’on perçoit immédiatement après (cœur).
— Celles qui forment la base du parfum ; ce sont des molécules plus lourdes et donc plus persistantes (fond).
On veut créer une copie du fichier initial avec une disposition différente. Pour chaque parfum, on veut écrire
quatre lignes : la première correspond au numéro du parfum, la deuxième correspond aux fragrances de tête, la
troisième aux fragrances de cœur, et la quatrième aux fragrances de fond qui entrent dans sa composition.

#Contenu du fichier parfum2.txt


Parfum 1
bergamote clementine
jasmin rose ylang-ylang
musc

Parfum 2
violette
rose
cedre patchouli
...

Pour cela, on dispose de trois fichiers texte Tete.txt, Coeur.txt et Fond.txt qui contiennent chacun respec-
tivement les fragrances de Tete, Cœur et Fond, une par ligne. Chaque fragrance apparaît dans exactement un de
ces fichiers.

Exemple :

UCA - Licence N1 / LAS / PASS - UE Info. - Python 1


Contenu de Tete.txt Contenu de Coeur.txt
Contenu de Fond.txt
bergamote camomille
jasmin cedre
citron
muscade cypres
clementine
myrrhe musc
lavande
rose patchouli
menthe
sapin pin
thym
ylang-ylang vanille
violette
1. Écrire une fonction getParfums qui prend en argument un nom de fichier supposé formatté de la même façon
que l’exemple parfum.txt, et qui renvoie la liste des parfums contenus dans le fichier, sous la forme d’une
liste de liste de chaîne de caractères : le premier élément de la liste sera la liste des fragrances composant le
premier parfum, le deuxième élément de la liste sera la liste des fragrance composant le deuxième parfum,
etc...
Sur l’exemple parfum.txt, on doit obtenir

[['bergamote', 'clementine', 'jasmin', 'musc', 'rose', 'ylang-ylang'],


['cedre', 'patchouli', 'rose', 'violette'],
['bergamote', 'musc', 'myrrhe', 'thym', 'vanille']]

2. Écrire une fonction getFragrances qui prend en argument un nom de fichier, supposé formatté comme
Tete.txt, Coeur.txt ou Fond.txt, et qui renvoie la liste des fragrances contenues dans ce fichier.
3. Écrire une fonction ecritParfums qui prend en argument un nom de fichier supposé contenir la composition
des parfums au même format que l’exemple parfum.txt, et un nom de fichier de destination, et qui écrit la
composition des parfums dans le fichier de destination au format voulu avec 4 lignes par parfum (une ligne
avec la numérotation, une ligne avec seulement les fragrances de tête, une ligne avec seulement les fragrances
de cœur et une ligne avec seulement les fragrances de fond), en supposant que l’on dispose dans le même
dossier des fichiers Tete.txt, Coeur.txt et Fond.txt. On laissera une ligne blanche entre deux parfums. On
s’autorisera à écrire des espaces supplémentaires en fin de ligne si cela simplifie l’algorithme.

Exercice 2 : Fichier CSV


Le format CSV (Comma-separated values, valeurs séparées par des virgules) est un format de fichier texte
permettant de stocker des données tabulaires, sous forme de valeurs séparées par un caractère spécial, souvent
une virgule ou un point-virgule. Chaque ligne du texte correspond à une ligne du tableau, et le séparateur CSV
(par exemple, les virgules) correspondent aux séparations entre colonnes. Chaque portion de texte entre deux
séparateurs CSV correspond donc à une cellule du tableau.
1. Écrire une fonction listeCSV qui reçoit le nom d’un fichier CSV contenant des entiers, et un argument
optionnel separateurCSV valant par défaut une virgule, et qui renvoie une liste à 2 dimensions (liste de
listes) représentant son contenu : chaque ligne sera représentée par une liste d’entiers. Ne pas oublier de
fermer le fichier après usage.

1,2,3
2,4,9 ==> [[1,2,3],[2,4,9],[3,8,27]]
3,8,27
2. On suppose maintenant que l’on va travailler avec des fichiers CSV contenant plutôt majoritairement des
cellules texte, et dont la première ligne du fichier fournit les noms des colonnes. Les lignes suivantes contiennent
les valeurs.

Nom,Naissance,Ville
Toto,1977,Ajaccio [{'Nom':'Toto','Naissance':'1977','Ville':'Ajaccio'},
Alice,2000,Montpellier ==> {'Nom':'Alice','Naissance':'2000','Ville':'Montpellier'}
Bob,1998,Grenoble {'Nom':'Bob','Naissance':'1998','Ville':'Grenoble'}]

Écrire une fonction dicoCSV qui prend en argument un nom de fichier CSV et un qui crée à partir de ce
fichier une liste de dictionnaires, chaque dictionnaire représentant une ligne de valeurs (type str) du fichier,
dont les clés sont les noms présents sur la première ligne.
Il est conseillé d’écrire une fonction auxiliaire listeNettoyee qui prend en argument une chaîne de carac-
tère correspondant à une ligne de fichier (terminant par \n), et une chaîne de caractère correspondant au
séparateur CSV, et qui renvoie une liste de chaînes de caractères "nettoyées" correspondant au contenu des
cellules non-vides, sans caractères blancs au début ni à la fin.

UCA - Licence N1 / LAS / PASS - UE Info. - Python 2


3. Écrire une fonction conversion qui prend en argument une liste de chaîne de caractères l, et une autre liste
de même taille liste_type dont les valeurs valent str, int ou float, et qui modifie l de façon à convertir
en int ou en float comme sur l’exemple suivant : si l vaut ["Alice", "2000", "1.67"] et liste_type
vaut ["str", "int", "float"], alors il faut convertir le deuxième élément en int et le troisième en float
donc l doit valoir ensuite ["Alice", 2000, 1.67]
4. Améliorer la fonction dicoCSV pour qu’elle prenne également une liste de type et qu’elle fasse appel à la
fonction conversion de telle sorte que les valeurs enregistrées dans les dictionnaires correspondent à la liste
des types.
Dans l’exemple précédent, si l’on donne ["str", "int", "str"] comme liste de types, alors les années de
naissances doivent être enregistrées comme des entiers.
5. On souhaite maintenant faire l’opération contraire de dicoCSV. Écrire une fonction ecritListeDico qui
reçoit une liste de dictionnaires, au même format que la valeur de retour de dicoCSV, ainsi qu’une chaîne de
caractères nomFichier, et un séparateur CSV (valant par défaut un point-virgule) et qui crée le fichier CSV
correspondant à la liste de dictionnaires passée en argument. Pour simplifier, on écrira le séparateur CSV en
fin de ligne (ce qui revient à créer une colonne vide en fin de tableau). N’oubliez pas les conversions.

Exercice 3 : Histogramme
On s’intéresse à des données mesurant le nombres de visiteurs à un stand pendant un salon d’exposition.
L’intervalle entre deux mesures n’étant pas régulier, chaque relevé est du type minute:nombreDeVisiteurs où
minute est un entier indiquant le nombre de minutes écoulées depuis l’ouverture du stand. Le but est de construire
un histogramme de ces relevés, minute par minute, en extrapolant pour les minutes sans relevé le nombre de visiteurs
au point de relevé précédent (avec un symbole différent pour distinguer les véritables relevés des extrapolations).

1:2 ====> 00|


3:5 01|**
4:4 02|--
6:10 03|*****
8:3 04|****
05|----
06|**********
07|----------
08|***
09|---
10|---

1. Écrire une fonction getDonnees qui prend en argument un nom de fichier supposé formaté comme présenté
précédemment et qui renvoie un dictionnaire contenant les relevés. Pour l’exemple ci-dessus, on doit obtenir
{1: 2, 3: 5, 4: 4, 6: 10, 8: 3}
2. Écrire une fonction strAvecZero qui prend en argument deux entiers n et borne et qui renvoie la chaîne de
caractères correspondant à n, précédé d’un ou plusieurs zéros de telle sorte qu’elle ait la même longueur que
l’écriture décimale de l’entier borne. Exemple : strAvecZero(14, 3512) vaut "0014" car on rajoute deux
zéros pour avoir 4 chiffres au total, comme 3512.
3. Écrire une fonction histogramme qui prend en argument un dictionnaire d contenant les relevés, et une
borne entière donnant la dernière minute voulue dans l’histogramme, et qui renvoie la chaîne de caractère
correspondant à l’histogramme, comme illustré sur l’exemple ci-dessus. Les véritables relevés de visiteurs
doivent être représentés par des barres avec des *, et les barres issues d’extrapolation (reproduction du
dernier relevé) doivent être affichées avec des -. L’exemple représenté ci-dessus est la chaîne correspondant à
l’histogramme pour le dictionnaire {1: 2, 3: 5, 4: 4, 6: 10, 8: 3} et borne valant 10.
4. Écrire une fonction ecritHistogramme qui prend en argument un nom de fichier source contenant les relevés,
un nom de fichier destination dans lequel il faut écrire l’histogramme, un entier borne, et un argument
optionnel affiche valant False par défaut. Si affiche est vrai, il faut afficher l’histogramme dans la console
en plus de l’écrire dans le fichier destination.

Exercice 4 : Analyse de texte


On veut connaître les lettres de l’alphabet qui sont les plus utilisées dans la langue française. Pour ce faire,
on regroupe dans un fichier texte un grand nombre de romans écrits en français (en majuscule ou en minuscule
mais sans accents, sans "ç", "œ", ...) et on souhaite écrire un programme qui permet de compter la fréquence
d’apparition de chaque lettre, en ignorant la ponctuation et les caractères spéciaux.
1. Écrire une fonction lire_fichier(nom_fichier), qui prend le nom du fichier contenant le texte en argument,
et retourne une chaîne de caractères contenant l’intégralité du texte.

UCA - Licence N1 / LAS / PASS - UE Info. - Python 3


2. Écrire une fonction liste_spec qui reçoit un texte et renvoie la liste de ses caractères non alphabétiques
(pour simplifier on considère qu’il n’y a pas de lettres accentuées dans le texte). Pour information, on peut
utiliser lower sur une chaîne de caractère qui n’est pas une lettre, cela la renverra à l’identique sans provoquer
d’erreur.
3. Écrire une fonction compter_lettres(texte, exceptions) qui prend un texte en argument et retourne
un dictionnaire qui associe à chaque lettre sa fréquence d’apparition dans le texte (le nombre de fois où elle
apparaît). L’argument exceptions est une liste contenant les caractères spéciaux à ignorer. On prendra soin de
n’avoir comme clés dans le dictionnaire que les lettres en minuscule (les occurrences des lettres en majuscules
devront être comptées dans le même compteur que leur version minuscule).
4. Écrire une fonction lettre_rare(frequences) qui prend le dictionnaire construit dans la question précédente
en argument, et retourne la lettre de l’alphabet la plus rare (celle qui apparaît, mais le moins souvent).
5. Écrire une fonction plus_rare qui prend en argument le nom de fichier contenant l’ensemble des romans et
qui renvoie la lettre la plus rare y apparaissant, ainsi que son nombre d’occurrences (indépendamment de la
casse).

Exercice 5 : Résultats des étudiants


Dans cet exercice, nous allons lire et traiter des données qui sont stockées dans des fichiers, et qui concernent
des notes d’étudiants aux examens. Il y a deux types de fichiers :
1. un fichier contenant la liste des étudiants inscrits, comme dans le fichier Inscrits.txt qui vous est fourni comme
modèle. Il y a une ligne pour chaque étudiant, contenant son numéro étudiant, son nom et son prénom, séparés
par des points-virgules
2. des fichiers contenant les résultats d’une épreuve, comme les exemples Info.txt et Maths.txt qui vous sont
fournis : il y a une ligne pour chaque copie rendue, contenant le numéro étudiant de celui qui a rendu la
copie, et la note attribuée à la copie, séparés par un point-virgule.
Le but global de cet exercice est de :
— lire les données dans les fichiers,
— les combiner,
— écrire dans un fichier les résultats : comme dans le fichier resultats.txt qui vous est fourni, il doit y avoir une
ligne par étudiant, contenant : son nom et son prénom (séparés par un espace), puis pour chaque matière
dont l’étudiant a passé l’examen : un tiret, le nom de la matière, deux-points ( : ), la note de cet étudiant
pour cette matière.
Inscrits.txt Info.txt Maths.txt resultats.txt

304304;DURAND;Alexis 304304;14.5 233345;7.6 DURAND Alexis-Info:14.5


202356;TOULI;Maria 202356;4.67 202356;12.1 TOULI Maria-Info:4.67-Maths:12.1
758843;POTIN;Maxime 758843;9.8 100100;5.6 POTIN Maxime-Info:9.8
233345;TRUPAT;Lise 233345;12.3 349999;10.01 TRUPAT Lise-Info:12.3-Maths:7.6
100100;MANOT;Lucas MANOT Lucas-Maths:5.6
349999;RISING;James RISING James-Maths:10.01

1. Écrire une fonction get_lines qui prend en argument un nom de fichier et qui renvoie la liste des lignes
"simplifiées" du fichier, c’est-à-dire une liste de chaînes de caractères, où chaque élément de la liste correspond
à une ligne du fichier à laquelle on a supprimé les caractères blancs (espaces, retours à la ligne, ...).
2. Écrire une fonction dico_resultats qui prend en argument un nom de fichier, supposé contenir les résultats
des étudiants à une épreuve (au format décrit plus haut, comme Info.txt ou Maths.txt) et qui renvoie un
dictionnaire qui contient une entrée pour chaque étudiant : la clé du dictionnaire est son numéro étudiant,
et la valeur associée est la note de l’étudiant à cette épreuve. La clé (numéro étudiant) devra être une chaîne
de caractères (pour garder les éventuels 0 en début de numéro), et la note devra être un nombre à virgule.
Exemple avec Info.txt : vous devez obtenir {"304304": 14.5, "202356": 4.67, "758843": 9.8, "233345":
12.3}
3. Écrire une fonction dico_noms qui prend en argument un nom de fichier, supposé contenir la liste des étudiants
inscrits (au format décrit plus haut, comme Inscrits.txt) et qui renvoie un dictionnaire de dictionnaires au
format suivant : si l’on appelle etudiants le dictionnaire qui est renvoyé, alors etudiants contient une entrée
pour chaque étudiant : la clé est son numéro étudiant (sous forme de chaîne de caractères) et la valeur associée
est un dictionnaire à deux clés : "nom" et "prenom" (les valeurs associées étant respectivement le nom et le
prénom de l’étudiant).
Exemples : sur un fichier contenant :

304304;DURAND;Alexis
202356;TOULI;Maria

UCA - Licence N1 / LAS / PASS - UE Info. - Python 4


votre fonction doit renvoyer {"304304": {"nom": "DURAND", "prenom": "Alexis"}, "202356": {"nom":
"TOULI", "prenom": "Maria"}}
4. Écrire une fonction combine qui prend en argument :
— d, un dictionnaire de dictionnaires au même format que celui renvoyé par dico_noms (pour chaque
étudiant, le dictionnaire contient une entrée, dont la clé est le numéro étudiant et la valeur associée est
un dictionnaire à deux clés "nom" et "prenom" contenant les informations de l’étudiant)
— un dictionnaire au même format que celui renvoyé par dico_resultats (pour chaque étudiant, le dic-
tionnaire contient une entrée dont la clé est le numéro étudiant et la valeur associée est la note à un
examen)
— une chaîne de caractères donnant le nom de la matière, par exemple "Info"
et qui modifie d de telle sorte que le dictionnaire associé à chaque étudiant qui a passé l’épreuve contienne
une entrée de plus, dont la clé doit être le nom de la matière, et la valeur associée doit être la note. Cette
fonction ne renvoie rien.
Exemple : si d vaut
{'304304': {'nom': 'DURAND', 'prenom': 'Alexis'}, '202356': {'nom': 'TOULI', 'prenom': 'Maria'}},
alors l’appel combine(d, {'304304': 12.5}, "Info") doit mettre à jour d de telle sorte que d contienne à
l’issue de l’appel :

{'304304': {'nom': 'DURAND', 'prenom': 'Alexis', 'Info': 12.5},


'202356': {'nom': 'TOULI', 'prenom': 'Maria'}}

Attention : un étudiant peut être inscrit mais ne pas avoir passé l’épreuve. En revanche, on suppose que tous
les étudiants qui ont passé l’épreuve sont bien inscrits.
5. Écrire une fonction cree_ligne qui prend en argument un dictionnaire contenant les données d’un étudiant
(une clé "nom" associée à son nom, une clé "prenom" associée à son prénom, et pour chaque épreuve que
l’étudiant a passée, une clé égale à la matière concernée, associée à sa note dans cette matière) et une liste de
matières, et qui renvoie une chaîne de caractères composée (comme dans resultats.txt) : du nom et prénom
de l’étudiant, séparés par un espace ; puis pour chaque matière qui est dans la liste des matières et qui est
égale à une clé du dictionnaire : un tiret, le nom de la matière, deux-points ( : ), la note de cet étudiant pour
cette matière. Il faut respecter l’ordre de matières telles qu’elles apparaissent dans la liste.
Exemple : si d vaut
{'nom': 'DURAND', 'prenom': 'Alexis', 'Info': 12.5, 'Maths':17.2, 'Physique':13.1}, alors
cree_ligne(d, ["Info", "Maths", "Anglais"]) vaut : "DURAND Alexis-Info:12.5-Maths:17.2"

6. Écrire une fonction ecrit_resultats qui prend en argument :


— d, un dictionnaire de dictionnaires, dans lequel chaque clé est un numéro étudiant, et la valeur associée
est un dictionnaire contenant les informations de l’étudiant : une clé "nom" associée à son nom, une
clé "prenom" associée à son prénom, et pour chaque épreuve que l’étudiant a passée, une clé égale à la
matière concernée, associée à sa note dans cette matière.
— une liste de matière, par exemple ["Info", "Maths"]
— un nom de fichier dans lequel il faut écrire
et qui écrit dans le fichier : une ligne pour chaque étudiant, au format décrit dans l’énoncé de cree_ligne.
L’ordre des lignes des étudiants n’importe pas.
7. Écrire une fonction traitement_complet qui prend en arguments :
— la liste des matières,
— le nom du fichier de destination,
— et le nom du fichier contenant la liste des inscrits,
qui ne renvoie rien, et qui va écrire dans le fichier de destination une ligne pour chaque étudiant inscrit, au
format décrit dans l’énoncé des questions précédentes. Pour cela, on supposera que, pour chaque matière,
on dispose d’un fichier de résultats, nommé comme le nom de la matière suivi de .txt (exemple : les résul-
tats pour la matière "Info" sont dans "Info.txt"). Vous pouvez voir dans le fichier resultats.txt le résultat
attendu après l’appel traitement_complet(["Info", "Maths"], "resultats.txt", "Inscrits.txt").
L’ordre des lignes des étudiants n’importe pas.

UCA - Licence N1 / LAS / PASS - UE Info. - Python 5

Vous aimerez peut-être aussi