Vous pouvez me contacter via Facebook pour questions & suggestions :
Page Facebook relative à mon site
Dès que vous fermez un programme les données produites sont perdues.
Pour stocker de façon permanente des données on pense aux bases de données.
Mais pour de nombreuses applications, utiliser une BD alors qu'il n'y a que quelques données à stocker, c'est "tuer
une mouche avec un canon".
Dans ce chapitre je n'évoque que le traitement en Python des fichiers TXT.
Pour le traitement des fichiers CSV & JSON via la bibliothèque pandas : Chapitre 16
Mais revenons aux fichiers TXT (données non formatées).
Ces fichiers sont enregistrés dans le dossier c:/python_prog ; donc dans le même dossier que les scripts Python.
éponges Cnidaires Cténaires Vers Crustacés Echinodernes Bryozaires Urocordés Poissons osseux Poissons cartilagineux Gastéropodes Bivalves Cephalopodes Cirripèdes Décapodes Cétacés Pinnipèdes échinodermes Anémones Amphipodes Méduses
Notez qu'il n'y aucun formatage des données, uniquement des sauts de ligne.
Encodage en ANSI afin que les lettres accentuées soient affichées proprement.
Seiche Calmar Moule commune Huitre creuse Huitre plate Balane Crevette grise Bouquet Sole Bar Crabe vert étrille Tourteau Arénicole
Avant de passer à la programmation nous allons manipuler ces fichiers via la console Python. Vous verrez qu'on peut déjà faire pas mal de choses ...
>>> import os
>>> os.getcwd()
'C:\\Users\\darch'
>>> os.chdir("c:\\Users\\darch")
J'ai importé le module os ( OS comme Operating System).
Ce module propose des méthodes qui permettent de manipuler fichiers et dossiers.
La fonction os.getcwd() précise le répertoire courant. Notez qu'il s'agit du dossier C:\Python39
Dès que vous êtes sous l'interpréteur le répertoire par défaut est celui qui contient l'exécutable de l'interpréteur :
'C:\\Users\\darch'.
Mes fichiers texte sont dans un autre dossier ; ils sont dans : c:\python_prog. Il faut donc changer de "directory" (répertoire).
>>> os.chdir("c:/python_prog")
>>> fichier = open("especes.txt", "r")
>>> fichier.readlines()
['seiche\n', 'calmar\n', 'pouple\n', 'moule commune\n', 'huitre creuse\n',
'huitre plate\n', 'balane\n',
'crevette grise\n', 'bouquet\n', '\n']
>>>fichier.close()
Cet affichage du contenu du fichier n'est pas très satisfaisant.
On suppose bien sûr qu'on est toujours dans le bon répertoire.
>>> with open('taxons.txt','r') as fichier :
... fichier.readlines()
...
['éponges\n', 'Cnidaires\n', 'Cténaires\n', 'Vers\n', 'Crustacés\n',
'Echinodernes\n', 'Bryozaires\n', 'Urocordés\n', 'Poissons osseux\n',
'Poissons cartilagineux\n', 'Gastéropodes\n', 'Bivalves\n',
'Céphalopodes\n', 'Cirripèdes\n',
'Décapodes\n', 'Cétacés\n', 'Pinnipèdes\n', 'échinodermes\n',
'Anémones\n', 'Amphipodes\n', 'Méduses\n', 'Coraux\n']
>>>
Notez la nouvelle syntaxe pour ouvrir le fichier : with open(nom_fichier, "r") as fichier :
Cette commande permet d'ouvrir et de fermer un fichier de manière efficace.
En effet, si pour diverses raisons, l'ouverture ou la lecture du fichier conduit à une erreur, l'utilisation de la syntaxe
"with open ... as objectFile" garantit une fermeture effective du fichier.
L'instruction "with open ..." crée un bloc d'instructions. Les commandes de manipulation du fichier doivent être
dans ce bloc.
À la sortie du bloc il y a fermeture automatique du fichier.
>>> with open('especes.txt','r') as fichier :
... contenu = fichier.read()
...
>>> print(contenu)
Seiche
Calmar
Moule commune
Huitre creuse
Huitre plate
Balane
Crevette grise
Bouquet
Sole
Bar
...
La méthode read() lit la totalité du fichier et retourne le contenu sous forme d'une chaine de caractères
unique ici récupérée dans la variable "contenu".
print(contenu) : la chaine est affichée sur plusieurs lignes grâce aux (\n) à la fin de chaque ligne du fichier.
On obtient donc un affichage plus satisfaisant qu'avec readlines()
La méthode readline() (sans s à la fin) lit seulement une ligne du fichier et la retourne sous forme d'une chaine.
Donc le premier appel de cette méthode lit la première ligne, le deuxième appel lit la seconde, etc.
>>> with open('taxons.txt','r') as fichier :
... ligne = fichier.readline()
... while ligne !="" :
... print(ligne)
... ligne =fichier.readline()
...
éponges
Cnidaires
Cténaires
...
Pour lire successivement les lignes du fichier il faut une commande "readline()" avant la boucle et
une deuxième dans la boucle.
L'itération s'effectue tant que la fin de fichier n'est pas détectée.
Notez les lignes vierges ... Il y a en effet le saut de ligne de la commande print() et le saut de ligne provoqué par le
caractère "\n".
Ces trois méthodes sont surtout utiles en mode console : elles permettent de lire un fichier (ou une ligne)
sans recourir à une boucle et à la commmande print().
Sachez qu'un "objectFile" peut être parcouru par une boucle.
>>> with open('taxons.txt','r') as fichier :
... for ligne in fichier :
... print(ligne,end =" ")
...
éponges
Cnidaires
Cténaires
Vers
Crustacés
Echinodernes
Bryozaires
...
En mode programmé on préférera cette solution.
Remarquez que cette fois les lignes vierges ont disparu gràce au deuxième argument de la commande print() qui supprime
le saut de ligne par defaut de cette fonction.
Vous savez désormais lire le contenu d'un fichier TXT. Bien évidemment il est possible d'écrire dans ce type de fichier.
Créez avec NotePad un fichier TXT vierge de tout contenu dans le dossier "c:/python_prog" et nommez le "vierge.txt".
>>> os.getcwd()
'c:\\python_prog'
>>> with open('vierge.txt','a') as fichier :
... fichier.write("sole")
... fichier.write("bar")
... fichier.write("morue")
...
4
3
5
>>> with open('vierge.txt','r') as fichier :
... fichier.readlines()
...
['barsolebarmorue']
>>>
On ouvre ensuite le même fichier en lecture et on constate qu'il y a un gros problème : les textes ont bien été ajoutés mais sans saut de ligne ; ils sont collés !
Le fichier "vierge.txt" n'est plus vide mais contient des données qui ne nous satisfont pas.
Nous allons l'ouvrir en mode "w" afin que l'ajout écrase l'ancien contenu.
>>>with open('vierge.txt','w') as fichier :
... fichier.write("sole \n")
... fichier.write("bar \n")
... fichier.write("morue \n")
...
6
5
7
>>>with open('vierge.txt','r') as fichier :
... lignes = fichier.read()
>>>print(lignes)
sole
bar
morue
Cette fois le fichier contient bien 3 lignes de texte.
Si vous doutez, ouvrez ce fichier avec NotePad !
>>> import os
>>> os.chdir("c:/python_prog")
>>> fichier =open("especes.txt","r")
>>> fichier.read()
'Seiche\nCalmar\nMoule commune\nHuitre creuse\nHuitre plate\nBalane\nCrevette grise\n
Bouquet\nSole\nBar\nCrabe vert\nétrille\nTourteau\nArénicole\n\nRoussette\n
Hareng\nMerlan\nRoussette\nHareng\nMerlan\nRoussette\nHareng\nMerlan\n'
>>> fichier.readable()
True
>>> fichier.writable()
False
>>> fichier.tell()
229
>>> fichier.seek(1)
1
>>> fichier.tell()
1
J'ai ouvert le fichier en lecture ; aussi la méthode readable() retourne True et la méthode writable() retourne
False.
La méthode tell() indique la position du curseur. Après une lecture du fichier le curseur pointe la fin de fichier.
La méthode seek() déplace le curseur.
Le programme qui manipule un fichier TXT et ce dernier doivent de préférence être dans le même répertoire ; ainsi le problème parfois délicat du chemin relatif sera résolu.
Le programme lit un fichier qui contient le dernier score.
Le jeu se déroule et le score de la session est produit.
Le fichier est de nouveau ouvert pour enregistrez le nouveau score ; le contenu précédent est écrasé !
Il lit l'ancien contenu du fichier texte puis écrit dans ce fichier le nouveau score et la date.
#nom du fichier : structure_jeu.py
# coding: utf-8
import random
import os
import datetime as dt
courant = os.getcwd()
print(f"Répertoire courant : {courant}")
with open("score.txt","r") as fichier:
contenu = fichier.read()
print(f"Votre ancien score : {contenu}")
score_session = 0
pseudo = input ("tapez votre pseudo : " )
for i in range(10):
"""ici il y aurait appel de la fonction
correspondant à une partie
fonction retourant le score d'une partie
"""
score_partie = random.randint(1,11)
score_session +=score_partie
# conservation du scrore de la dernière session
print(f"votre nouveau score : {score_session} ")
cejour = dt.datetime.today()
datecourante = cejour.strftime("%H:%M:%d:%m:%Y")
contenu = " pseudo, date et score : " + pseudo + " "
+ datecourante + " " + str(score_session)
with open("score.txt", "w") as fichier:
fichier.write(contenu)
Attention le code correspondant à une partie est remplacée
par la génération aléatoire d'un entier compris entre 1 et 10.
Une session de jeu c'est 10 parties d'où la boucle.
Répertoire courant : C:\python_prog Votre ancien score : pseudo, date et score : darche 15:34:10:08:2024 59 tapez votre pseudo : darche votre nouveau score : 60
À la différence du mode console, le répertoire courant en mode programme est celui qui contient le script et donc le fichier TXT.
La méthode writelines() permet d'ajouter plusieurs lignes en une seule instruction.
Voyons cette méthode au travers d'un programme.
L'utilisateur lit l'ancien contenu du fichier ; fait des ajouts puis lit le contenu actualisé par les ajouts.
# nom du programme : writelines.py
# coding: utf-8
# ajout de plusieurs lignes à un fichier txt
print("Ancien contenu : ")
with open ("especes.txt", "r") as fichier:
ancien_contenu = fichier.read()
print(ancien_contenu, end =" ")
print("-----------------------------------")
with open ("especes.txt", "a") as fichier:
ajouts = ["Roussette\n","Hareng\n","Merlan\n"]
fichier.writelines(ajouts)
print("Nouveau contenu : ")
with open ("especes.txt", "r") as fichier:
nouveau_contenu = fichier.read()
print(nouveau_contenu, end =" ")
Il faut ouvrir trois fois le même fichier texte avec à chaque fois un mode différent.
C'est un peu lourd ...
Ancien contenu : Seiche Calmar Moule commune Huitre creuse ... Tourteau Arénicole ----------------------------------- Nouveau contenu : Seiche Calmar Moule commune Huitre creuse ... Tourteau Arénicole Roussette Hareng Merlan
On a bien rajouté trois lignes dans le fichier.
Je vous propose maintenant une variante qui n'exige qu'une ouverture du fichier (et non pas trois).
# nom du programme : writelines_bis.py
# coding: utf-8
with open ("especes.txt", "r+") as fichier:
print("Ancien contenu :")
for ligne in fichier :
print(ligne,end =" ")
print("--------------------------")
ajouts = ["Roussette\n","Hareng\n","Merlan\n"]
fichier.writelines(ajouts)
fichier.seek(0) # repointer le début du ficher
print("Nouveau contenu :")
for ligne in fichier :
print(ligne,end =" ")
Avant de lancer la nouvelle version, ouvrez le fichier "especes.txt" avec NotePad, supprimez les trois dernières lignes ajoutées via la première version ("Roussette\n","Hareng\n","Merlan\n") puis fermez le fichier. Vous pouvez alors exécuter le nouveau script.
Ancien contenu : Seiche Calmar ... Tourteau Arénicole -------------------------- Nouveau contenu : Seiche Calmar ... Tourteau Arénicole Roussette Hareng Merlan
Trois lignes ajoutées !
Vous pouvez aussi ouvrir le fichier texte avec NotePad pour constater les ajouts.
Quand vous aborderez la programmation de jeux vidéos en Python vous verrez qu'il peut être utile de lire un fichier tXT qui sert de modèle pour créer le décor du jeu : afficher tel ou tel sprite en fonction du caractère lu.
MMMMMMMMMMMMMMMMMMMMMMMMM M M MMMMMMM MMMMM MMMM MMMM M M M MMMMMMMMMM MMMMMMMMMMMMMM M MMM MM M MMMM M MM MMM M MM M M MMMMMMMMMMM MMM M M M M M MMM M M M MMMMM MMMMMMM MMM MMMM M M M MMMMMMMMM MMMMMM MMMMMM M MM MM MMMMMM MMMMMMMMMMM MMMMMM MM MMM M M MM MMM M MMMMMMMMMMMMM MM MM MMM MMMMM MM MM MMMMMMMMMMMM MMMMMM MM MM MM MMMMMM MMMMMMMM MMMMM MMMMMM MMMMMM MMMMM M MMM MMMMM M MMMMMMMMM MMM MMMMMM M M MMMMMM MMMMMMMMMMMMMMMMMMMMMMMMM
Chaque caractère est "M" ou " " (espace).
Il y a 25 lignes et chaque ligne comprend 25 caractères.
#nom du fichier : lire_modele.py
# script qui lit le fichier modele.txt
with open("modele.txt", "r") as fichier:
for ligne in fichier:
for car in ligne:
if car == 'M':
print(car, end =' ')
else :
print(' ',end=' ')
print() # saut de ligne
Il faut donc deux boucles imbriquées : la boucle externe lit une ligne du fichier et la boucle interne lit
chaque caractère de la ligne.
Notez que je n'utilise aucune méthode pour lire le fichier.
Puisque l'objet "file" (nommé ici "fichier") est itérable j'utilise deux boucles pour lire chaque ligne et
à l'intérieur de chaque ligne, chaque caractère.
M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M
On affiche un beau labyrinthe !
La fonction with open() ...as ... crée un "objectFile" et exige deux arguments : le chemin du fichier texte, le mode d'ouverture du fichier.
Le chemin du fichier se résume à son nom si le répertoire courant est celui qui contient le fichier texte.
Le dossier "c:/python_prog" contient aussi des fichiers CSV (présentation tabulaire) et JSON (séquences de paires de clé:valeur).
>>> fichier = open("data3.csv")
>>> fichier.read()
"Durée,Date,Pouls,Pouls_max,Calories\n
60,'2020/12/01',110,130,409.1\n
60,'2020/12/02',117,145,479.0\n
60,'2020/12/03',103,135,340.0\n
45,'2020/12/04',109,175,282.4\n
45,'2020/12/05',117,148,406.0\n
60,'2020/12/06',102,127,300.0\n
60,'2020/12/07',110,136,374.0\n
450,'2020/12/08',104,134,253.3\n
30,'2020/12/09',109,133,195.1\n
60,'2020/12/10',98,124,269.0\n
60,'2020/12/11',103,147,329.3\n
60,'2020/12/12',100,120,250.7\n
60,'2020/12/12',100,120,250.7\n
60,'2020/12/13',106,128,345.3\n
60,'2020/12/14',104,132,379.3\n
60,'2020/12/15',98,123,275.0\n
60,'2020/12/16',98,120,215.2\n
60,'2020/12/17',100,120,300.0\n
45,'2020/12/18',90,112,\n
60,'2020/12/19',103,123,323.0\n
45,'2020/12/20',97,125,243.0\n
60,'2020/12/21',108,131,364.2\n
45,,100,119,282.0\n
60,'2020/12/23',130,101,300.0\n
45,'2020/12/24',105,132,246.0\n
60,'2020/12/25',102,126,334.5\n
60,20201226,100,120,250.0\n
...
"
>>> fichier.close()
La méthode read() retourne une chaine unique ; difficile d'envisager un analyse des données.
Pour traiter des fichiers structurés au format CSV ou JSON il faut mieux utiliser respectivement les modules csv ou json ou
mieux encore la bibliothèque pandas.
Je vous invite à lire le chapitre 16. Bibliothèque pandas pour fichiers CSV & JSON