Projet : Création d'un répertoire téléphonique

Cette dernière séquence vous permettra de réinvestir tout ce que vous avez appris au cours des premiers modules. Vous allez essayer d'écrire un programme un peu plus complexe que ceux que vous avez déjà réalisés : un répertoire téléphonique.

Écrire et lire dans un fichier externe

Jusqu’à présent, les programmes que nous avons réalisés ne traitaient qu’un très petit nombre de données. Nous pouvions donc à chaque fois inclure ces données dans le corps du programme lui-même (par exemple dans une liste). Cette façon de procéder devient cependant tout à fait inadéquate lorsque l’on souhaite traiter une quantité d’informations plus importante.Pour cela nous allons donc apprendre à séparer les données et le programme qui les traitent dans des fichiers différents.

Pour que cela devienne possible, nous devrons doter nos programmes de divers mécanismes permettant de créer des fichiers, d’y envoyer des données et de les récupérer par la suite.

Sous Python, l’accès aux fichiers est assuré par l’intermédiaire d’un objet-interface particulier, que l’on appelle objet-fichier. On crée cet objet à l’aide de la fonction intégrée open(). Celle-ci renvoie un objet doté de méthodes spécifiques, qui vous permettront de lire et écrire dans le fichier. L’exemple ci-après vous montre comment ouvrir un fichier en écriture, y enregistrer deux chaînes de caractères, puis le refermer. Notez bien que si le fichier n’existe pas encore, il sera créé automatiquement. Par contre, si le nom utilisé concerne un fichier préexistant qui contient déjà des données, les caractères que vous y enregistrerez viendront s’ajouter à la suite de ceux qui s’y trouvent déjà. Vous pouvez faire tout cet exercice directement à la ligne de commande :

In [ ]:
objetFichier = open('monfichier', 'a')
objetfichier.write("Bonjour !")
objetfichier.write("Quel beau temps aujourd'hui !")
objetfichier.close()

La fonction open() reçoit deux arguments, le premier est le nom du fichier et le second le mode d'ouverture.

Il existe 3 modes d'ouverture :

  • 'r ' : ouverture en lecture
  • 'w' : ouverture en écriture. Le contenu du fichier est écrasé. Si le fichier n'existe pas, il est créé.
  • 'a' : ouverture en écriture en mode ajout. On écrit à la fin du fichier sans écraser l'ancien contenu du fichier. Si le fichier n'existe pas, il est créé.

Toujours dans la console, vous allez maintenant ouvrir le fichier précédent mais cette fois-ci en mode lecture pour en extraire le contenu :

In [ ]:
obfi = open('monfichier', 'r')
contenu = obfi.read()
print(contenu)
obfi.close()

Remarques

  • Les deux chaînes de caractères que nous avions entrées dans le fichier sont à présent accolées en une seule. C’est normal, puisque nous n’avons fourni aucun caractère de séparation lorsque nous les avons enregistrées. Pour remédier à ce problème, il nous faudra utiliser le caractère '\n' de fin de ligne.
  • La méthode read() peut également être utilisée avec un argument. Celui-ci indiquera combien de caractères doivent être lus, à partir de la position déjà atteinte dans le fichier:
In [ ]:
obfi = open('monfichier', 'r')
t = obfi.read(3)
print(t)
t = obfi.read(6)
print(t)
obfi.close()

Les méthodes readline() et readlines()

Taper le code suivant et vérifier ensuite le contenu du fichier monfichier :

In [ ]:
f = open('monfichier', 'w')
f.write("la première ligne.\n")  # équivalent à print("la première ligne.", file=f) qui introduit automatiquement un saut de ligne
f.write("La seconde ligne\n")
f.write("la troisième ligne\nEt enfin la quatrième ligne\n")
f.close()

Lors des opérations de lecture, les lignes d’un fichier texte peuvent être extraites séparément les unes des autres. La méthode readline(), par exemple, ne lit qu’une seule ligne à la fois (en incluant le caractère de fin de ligne):

In [ ]:
f = open('monfichier', 'r')
ligne = f.readline()
print(ligne)
print(f.readline())

La méthode readlines() transfère toutes les lignes restantes dans une liste de chaînes :

In [ ]:
t = f.readlines()
print(t)
print(type(t))
f.close()

Remarques

  • La liste apparaît en format brut, avec des apostrophes pour délimiter les chaînes, et les caractères spéciaux sous leur forme conventionnelle. Vous pourrez bien évidemment parcourir cette liste (à l’aide d’une boucle while, par exemple) pour en extraire les chaînes individuelles.

  • La méthode readlines() permet donc de lire l’intégralité d’un fichier en une instruction seulement. Cela n’est possible toutefois que si le fichier à lire n’est pas trop gros : puisqu’il est copié intégralement dans une variable, c’est-à-dire dans la mémoire vive de l’ordinateur, il faut que la taille de celle-ci soit suffisante. Si vous devez traiter de gros fichiers, utilisez plutôt la méthode readline() dans une boucle.

  • Notez bien que readline() est une méthode qui renvoie une chaîne de caractères, alors que la méthode readlines() renvoie une liste. À la fin du fichier, readline() renvoie une chaîne vide, tandis que readlines() renvoie une liste vide.

  • Quand on travaille avec des fichiers texte, il est important de savoir manipuler les chaînes de caractères grâce à quelques méthodes. En voici trois qui pourront être utiles dans la suite...
In [ ]:
#  La méthode split permet de découper une chaîne de caractères et renvoie une liste :
"1,2,3".split(',')
"1<>2<>3".split("<>")
"1,2,3,".split(",")  # remarquer la présence de la dernière chaîne vide dans la liste....

#  la méthode splitlines() se comporte comme split(). La découpe se fait au niveau des lignes...

"1\n2\n3".splitlines()
"première ligne \n deuxième...\n".splitlines()  # liste de deux termes seulement contrairement à split(\n)....

#  méthode strip() qui supprime des caractères initiaux et finaux

"wwwabcw".strip("w")
"une ligne \n".strip("\n")

Essayez également les méthodes lower() upper() capitalize() title() swapcase().

Projet : Répertoire téléphonique

En utilisant les connaissances acquises jusqu'à présent, vous allez écrire un programme de gestion de répertoire téléphonique. Pour réaliser ce projet, vous pourrez utiliser un environnement de développement (IDE) comme IDLE ou Spyder.

Cahier des charges

Ce programme devra proposer le menu suivant à l'utilisateur :

0-quitter
1-écrire dans le répertoire
2-rechercher dans le répertoire
Votre choix ?

Si le choix est 0 :

Le programme sera stoppé.

Si le choix est 1 :

L'utilisateur devra saisir un nom ou 0 s'il veut terminer la saisie (« Nom (0 pour terminer) : ») :

  • L'utilisateur entre 0 => le programme devra le renvoyer vers le menu
  • L'utilisateur entre un nom => le programme devra lui demander de saisir le numéro de téléphone correspondant au nom. Une fois le numéro saisi, le programme devra lui proposer d'entrer un nouveau nom (ou 0 pour terminer)...

title

exemple de saisie d'un utilisateur (toto)

Si le choix est 2 :

L'utilisateur devra saisir le nom recherché (« Entrer un nom : »).

  • Si le nom recherché est présent dans le répertoire, le programme devra afficher « Le numéro recherché est : » suivi du numéro de téléphone correspondant au nom saisi.

  • Si le nom recherché est absent du répertoire, le programme devra afficher « Inconnu ».

L'utilisateur est ensuite redirigé vers le menu principal.

title

recherche des utilisateurs (toto et titi)

Les noms et numéros de téléphone devront être stockés dans un fichier texte.

Votre programme devra être composé de 3 fonctions : une fonction « menu », une fonction « lecture » et une fonction « ecriture ».

Pour les plus téméraires, vous pouvez essayer de munir le programme d'une interface graphique.... Pour cela je vous invite à découvrir ce livre qui aborde au chapitre 8 la notion d'interface graphique.