• 4 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 02/05/2018

Organisez un projet en modules

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Dans ce chapitre vous apprendrez à lire un fichier avec Python. Mais ce n'est pas tout ! Afin de bien commencer votre projet, vous apprendrez également à passer le nom de ce fichier en argument et à organiser votre projet de manière professionnelle.

Mais commençons par lire le CSV des membres !

Créez un dossier data dans le dossier courant. Déplacez-y les fichiers que vous avez téléchargés au premier chapitre de ce cours.

Organisation du projet

Les deux fichiers ont des fomats différents : CSV et XML. Afin de différencier les analyses, je vous propose de créer un script d'analyse par fichier :

  • csv_analysis.py : analyse du fichier current_mps.csv

  • xml_analysis.py : analyse du fichier SyceronBrut.xml

Le fichier parite.py, qui existe déjà, servira à lancer les analyses.

En récapitulant, voici l'organisation actuelle :

  • csv_analysis.py

  • parite.py

  • xml_analysis.py

  • data

    •  current_mps.csv

    • SyceronBrut.xml

Parfait ! Ouvrez csv_analysis.py et commençons à analyser le fichier CSV.

Analyse d'un fichier CSV

Nous allons utiliser la librairie standard  os  afin d'interagir avec le système. Elle vous permet d'utiliser des fonctionnalités qui dépendent du système d'exploitation, par exemple écrire ou retrouver le chemin d'un fichier.

Importez-la en haut de votre fichier :

import os

Puis créez une fonction main() , comme précédemment :

def main():
    pass

if __name__ == "__main__":
    main()

Lire un fichier

C'est très simple ! Utilisez la méthode open() qui prend deux paramètres :

  • le chemin vers le fichier à lire

  • le mode d'ouverture (optionnel) : r ouvre un fichier en lecture, w  vous donne également le droit de le modifier, etc. En savoir plus

Comment indiquer le chemin vers un fichier à l'intérieur d'un script ? Encore une fois, Python vient à notre rescousse ! Vous pouvez utiliser la variable __file__ dont la valeur correspond au chemin vers un fichier. Puis nous pourrons retrouver très facilement le chemin du fichier que nous souhaitons utiliser. Voici comment faire :

csv_analysis.py

import os

def launch_analysis(data_file):
    directory = os.path.dirname(__file__) # we get the right path.
    path_to_file = os.path.join(directory, "data", data_file) # with this path, we go inside the folder `data` and get the file.

    with open(path_to_file,"r") as f:
       pass # read first line

if __name__ == "__main__":
    launch_analysis('current_mps.csv')

Vous pouvez ensuite utiliser la méthode readline() pour lire la première ligne du fichier. Démonstration :

def launch_analysis(data_file):
    directory = os.path.dirname(__file__) # we get the right path.
    path_to_file = os.path.join(directory, "data", data_file) # with this path, we go inside the folder `data` and get the file.

    with open(path_to_file,"r") as f:
        preview = f.readline()

    print("Yeah! We managed to read the file. Here is a preview: {}".format(preview))


if __name__ == "__main__":
    launch_analysis('current_mps.csv')

Voici ce qui apparait au lancement du fichier :

$ python csv_analysis.py
id;nom;nom_de_famille;prenom;sexe;date_naissance;lieu_naissance;num_deptmt;nom_circo;num_circo;mandat_debut;groupe_sigle;parti_ratt_financier;sites_web;emails;adresses;anciens_mandats;autres_mandats;anciens_autres_mandats;profession;place_en_hemicycle;url_an;id_an;slug;url_nosdeputes;url_nosdeputes_api;nb_mandats;twitter;

Bravo ! Une première étape de franchie !

Vous pouvez à présent lire le fichier. Mais il serait plus intéressant de lancer l'analyse non pas à partir de ce fichier mais à partir de parite.py afin de pouvoir choisir, plus tard, le format de fichier adéquat.

"Transformons" le fichier csv_analysis.py en module.

Créer un module

Nous avons parlé des modules dans les quelques chapitres précédents mais nous ne les avons pas encore définis. Qu'est-ce qu'un module ?

Importer un module

Un module peut ensuite être importé de plusieurs manières. Celle que je préconise, et que j'utilise, est la suivante :

# Import du module
import csv_analysis as c_an

# Exécution de la fonction main() du module csv_analysis
c_an.main()

Modifiez donc les fichiers :

parite.py

import csv_analysis as c_an

if __name__ == '__main__':
    c_an.launch_analysis('current_mps.csv')

csv_analysis.py

import os

def launch_analysis(data_file):
    directory = os.path.dirname(__file__) # we get the right path.
    path_to_file = os.path.join(directory, "data", data_file) # with this path, we go inside the folder `data` and get the file.

    with open(path_to_file,"r") as f:
        preview = f.readline()

    print("Yeah! We managed to read the file. Here is a preview: {}".format(preview))


if __name__ == "__main__":
    launch_analysis('current_mps.csv')

Vous avez réussi à lire le fichier csv. Bien joué !

Procédez de la même manière pour le fichier xml_analysis.py même si nous le modifierons plus tard dans ce cours :

xml_analysis.py.

import os

def launch_analysis(data_file):
    directory = os.path.dirname(__file__) # we get the right path.
    path_to_file = os.path.join(directory, "data", data_file) # with this path, we go inside the folder `data` and get the file.

    with open(path_to_file,"r") as f:
        preview = f.readline()

    print("Yeah! We managed to read the file. Here is a preview: {}".format(preview))


if __name__ == "__main__":
    launch_analysis('SyceronBrut.xml')

parite.py

#! /usr/bin/env python3
# coding: utf-8

import csv_analysis as c_an
import xml_analysis as x_an

def main():
    c_an.launch_analysis('current_mps.csv')
    x_an.launch_analysis('SyceronBrut.xml')

if __name__ == "__main__":
    main()

Importer une partie d'un module

Selon la taille d'un module, son import peut s'avérer très consommateur en mémoire. Lorsque vous travaillez avec des librairies conséquentes, telles que Pandas ou Numpy, il est d'usage de ne pas importer toute la librairie mais uniquement les objets dont vous aurez besoin.

Les imports personnalisés ont deux avantages majeurs :

  • Optimisation de la mémoire vive nécessaire à l'exécution du script.

  • Amélioration de la sécurité : plus vous importez de code, plus vous augmentez le risque que ce dernier soit frauduleux ou mal conçu. 

csv_analysis.py

# remplace import os
from os import path

Pour importer plusieurs objets, séparez-les par des virgules :

from os import path, name

Créer une librairie

Simplifions notre projet en le transformant en librairie.

Qu'est-ce qu'une librairie ?

Une librairie, également appelée paquet (package en anglais), est un ensemble de modules. Cette organisation vous permet de les importer en utilisant une autre syntaxe en "point nomdumodule". Par exemple, un module qui s'appelle A.B désigne un sous-module appelé B dans un paquet s'appelant A.

Un paquet contient impérativement un fichier __init__.py par module. Un dossier sans ce fichier ne sera pas reconnu comme étant un module du paquet.

Afin d'illustrer ce propos, voici ce que vous pourriez écrire dans le projet si vous le transformez en librairie :

import analysis.xml as x_an
import analysis.csv as c_an

Comment faire ?

Une librairie minimale est organisée de la façon suivante :

  • nom_librairie

    • setup.py

    • nom_sous_module

      • sous_module.py

      • __init__.py

Créez simplement un nouveau dossier, à la racine du projet, qui s'appelle analysis. A l'intérieur, déplacez les fichiers xml_analysis.py et csv_analysis.py. Renommez-les xml.py et csv.py. Ajoutez également un fichier vide nommé __init__.py dans analysis .

rappel de l'organisation :

  • analysis

    • __init__.py

    • csv.py

    • xml.py

  • data

    • current_mps.csv

    • SyceronGlobal.xml

  • parite.py

  • setup.py

Mettez à jour parite.py et relancez le programme. Vous devriez voir apparaître une erreur. C'est normal car les chemins d'accès aux fichiers ont changé ! Modifiez le fichier csv.py :

def launch_analysis(data_file):
    directory = os.path.dirname(os.path.dirname(__file__)) # we get the right path.
    ...

if __name__ == "__main__":
    launch_analysis('SyceronBrut.xml')

Tout fonctionne comme prévu ! Faites-en de même pour xml.py.

Lancer les fichiers en ligne de commande

A présent, concentrons-nous sur la résolution d'un souci : l'exécution de parite.py lance deux analyses (xml et csv). Ce serait plutôt intéressant de choisir le type d'analyse.

Je vous propose de fournir cette indication en tant qu'argument lorsque vous lancez le script en ligne de commande. Ainsi :

$ python parite.py --extension xml

Utilisez pour cela la librairie standard Argparse. Elle contient de nombreuses méthodes très utiles pour récupérer des arguments.

Importez la librairie : import argparse.

Nous allons l'utiliser en trois temps :

  • Création d'un objet ArgumentParser()

  • Lecture des arguments

  • Renvoi des arguments

parite.py

import argparse
import analysis.csv as c_an
import analysis.xml as x_an

def parse_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--extension", help="""Type of file to analyse. Is it a CSV or an XML?""")
    return parser.parse_args()

if __name__ == '__main__':
    args = parse_arguments()
    if args.extension == 'xml':
        x_an.launch_analysis('SyceronBrut.xml')
    elif args.extension == 'csv':
        c_an.launch_analysis('current_mps.csv')

Exécutez la commande :

$ python parite.py -e csv
Opening data file current_mps.csv from directory 'data'
Yeah! We managed to read the file. Here is a preview: id;nom;nom_de_famille;prenom;sexe;date_naissance;lieu_naissance;num_deptmt;nom_circo;num_circo;mandat_debut;groupe_sigle;parti_ratt_financier;sites_web;emails;adresses;anciens_mandats;autres_mandats;anciens_autres_mandats;profession;place_en_hemicycle;url_an;id_an;slug;url_nosdeputes;url_nosdeputes_api;nb_mandats;twitter;

#! /usr/bin/env python3
# coding: utf-8
import argparse

import analysis.csv as c_an
import analysis.xml as x_an

def parse_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--extension", help="""Type of file to analyse. Is it a CSV or an XML?""")
    parser.add_argument("-d","--datafile",help="""CSV file containing pieces of information about the members of parliament""")
    return parser.parse_args()

def main():
    args = parse_arguments()
    datafile = args.datafile
    if args.extension == 'xml':
        x_an.launch_analysis(datafile)
    elif args.extension == 'csv':
        c_an.launch_analysis(datafile)

if __name__ == "__main__":
    main()

A quoi sert le paramètre   help   de la méthode   add_argument()  ?

Argparse  vous donne la possibilité d'afficher un message expliquant les différents arguments en ajoutant  -h  ou  --help

Par exemple : 

$ python parite.py --help
usage: parite.py [-h] [-d DATAFILE] [-e EXTENSION]

optional arguments:
  -h, --help            show this help message and exit
  -d DATAFILE, --datafile DATAFILE
                        CSV file containing pieces of information about the
                        members of parliament
  -e EXTENSION, --extension EXTENSION
                        Kind of file to analyse. Is it a CSV or an XML?

 

Découvrez toutes les fonctionnalités de la librairie dans la documentation.  

Vous pouvez désormais lancer le programme en utilisant la commande suivante :  python parite.py -d current_mps.csv -e csv . 

$ python parite.py -d current_mps.csv -e csv
Yeah! We managed to read the file. Here is a preview: id;nom;nom_de_famille;prenom;sexe;date_naissance;lieu_naissance;num_deptmt;nom_circo;num_circo;mandat_debut;groupe_sigle;parti_ratt_financier;sites_web;emails;adresses;anciens_mandats;autres_mandats;anciens_autres_mandats;profession;place_en_hemicycle;url_an;id_an;slug;url_nosdeputes;url_nosdeputes_api;nb_mandats;twitter;

Bravo ! Vous connaissez désormais la différence entre un module et une librairie. Vous savez également utiliser la librairie ArgParse pour ajouter des arguments. Mais que se passe-t-il si vous indiquez un fichier qui n'existe pas ? Le programme renverra une erreur. Voyons dans le chapitre suivant comment les gérer.

A vous de jouer !

Cliquez sur ce lien

Code du chapitre

Retrouvez le code de ce chapitre en cliquant ici. 

Exemple de certificat de réussite
Exemple de certificat de réussite