Quelques bonnes pratiques pour les documents exécutables#
Introduction#
Lors de la création d’un document exécutable – tel que le rapport d’analyse de données que nous allons explorer aujourd’hui – le but est de rendre le document aussi lisible que possible, en mettant en évidence ce qui est calculé et en faisant abstraction des détails techniques de comment il est calculé.
Avec les feuilles Jupyter, cela est généralement réalisé en
développant une collection d’utilitaires dans des fichiers de code
séparés. De la sorte, les détails techniques de ces utilitaires ne
polluent pas la lecture du document. Ils n’en restent pas moins
immédiatement accessibles pour étude plus approfondie: le lecteur peut
à tout moment utiliser l”introspection (en utilisant ?
après la
fonction, voir les exemples ci-dessous) pour consulter rapidement la
documentation et le code des utilitaires.
Des utilitaires pour l’ensemble du cours sont fournis dans le module
Python intro_science_donnees
préinstallé sur le système. En outre, des
utilitaires dédiés au devoir en cours sont fournis dans le module
utilities.py présent dans le dossier du devoir.
Certains de ces utilitaires sont incomplets : vous serez invité à les compléter au fur et à mesure de votre progression. Nous ne nous attendons pas à ce que vous soyez dès maintenant en capacité de tous les réécrire vous-même; cependant, vous devriez certainement les consulter et essayer de les comprendre.
Rendre les données disponibles pour l’analyse peut également nécessiter un certain soin. En général, c’est un sujet à part entière; voir par exemple les principes FAIR (Findable, Accessible, Interoperable, Reproducible) de la Science Ouverte. À l’échelle de l’analyse que nous allons mener dans ce cours, la principale préoccupation est de rendre les données facilement accessibles depuis les feuilles Jupyter sans les dupliquer partout - et en particulier dans vos espaces en salle de TP, sur JupyterHub et sur GitLab – pour économiser de l’espace de stockage. Aussi, les jeux de données sont ils préinstallés avec la pile logicielle du cours.
En pratique#
Les commandes suivantes configurent Jupyter pour recharger
automatiquement les modules comme utilities.py
chaque fois qu’ils
sont modifiés; ainsi il ne sera pas nécessaire de redémarrer le noyau
à tout bout de champ.
%load_ext autoreload
%autoreload 2
Importons toutes les fonctions du module intro_science_donnees
et du module utilities.py :
# Import des utilitaires
from intro_science_donnees import *
from utilities import *
# Configuration intégration dans Jupyter
%matplotlib widget
Nous pouvons maintenant utiliser l’introspection pour consulter, par
exemple, la documentation de la fonction load_images
:
load_images?
voire pour étudier son code:
load_images??
Les jeux de données pour ce TP (et le projet 1) sont disponibles dans le dossier suivant :
from intro_science_donnees import data
data.dir
La liste des jeux de données disponibles peut s’obtenir ainsi :
!ls {data.dir}
Quelques explications: vous aurez reconnu la commande ls
du shell,
et ce n’est pas un accident: lorsqu’une cellule commence par un !
,
la commande est interprétée avec le shell au lieu de Python. Qui plus
est, un nom de variable Python apparaissant entre accolade dans la
commande shell, comme {data.dir}
ci-dessus, est substitué par sa
valeur.
Aujourd’hui nous nous intéressons au jeu de données
ApplesAndBananasSimple
:
import os.path
dataset_dir = os.path.join(data.dir, 'ApplesAndBananasSimple')
dataset_dir
Il consiste en une collection d’images :
! ls {dataset_dir}
Exercice
Chargez toutes ces images dans une variable images
et affichez les.
Indication : consultez la documentation des fonctions load_images
et de
image_grid
.
### BEGIN SOLUTION
images = load_images(dataset_dir, '*.png')
image_grid(images, titles=images.index)
### END SOLUTION
assert isinstance(images, pd.Series)
assert len(images) == 20
assert images.index[0] == "a01.png"
Rappelez-vous de la documentation : images
est une série Pandas
indexé par les noms des images :
images.index
Ainsi, vous pouvez récupérer une image individuelle soit par son nom, soit par son numéro :
images['a03.png']
images.iloc[2]
Chargez maintenant dans la variable bimages
les images dont le nom
commence par b
. Affichez-les en utilisant leur nom de fichier comme
titre.
Indication : si besoin, relisez les documentations !
### BEGIN SOLUTION
bimages = load_images(dataset_dir, 'b*.png')
image_grid(bimages, titles=bimages.index)
### END SOLUTION
assert isinstance(bimages, pd.Series)
assert len(bimages) == 10
assert bimages.index[0] == "b01.png"
Sections repliables#
Lors de la manipulation d’un long document comme un rapport, il devient vite fastidieux de naviguer dans le document en faisant défiler d’avant en arrière. L’extension Jupyter «Collapsible Headings» permet de replier à volonté sections et sous-sections. Cette extension est activée par défaut dans l’environnement du cours : cherchez le triangle gris «» ou «» à gauche des titres de section et essayez de cliquer dessus.
Toutes les cellules ci-dessous (code ou texte) sont contenues dans une section repliable.
print("Hello")
Conclusion#
Dans cette feuille, nous avons exploré quelques bonnes pratiques pour la rédaction de documents exécutables. C’est un premier pas vers la reproductibilité et la Science Ouverte!
Mettez à jour votre rapport dans la feuille index.md et déposez
votre travail sur GitLab (submit
). Passez ensuite à la feuille
analyse de données.