De la rigueur dans le carnet
- Leçon 16
- 40 min
- Module 6 : Du carnet Jupyter au projet facile à maintenir
Leçon 16 sur 18 · Python pour l'ingénierie de l'IA en pratiqueDe la rigueur dans le carnet
1. Bases de l'ordinateur et de l'environnement
2. Valeurs et flux de contrôle
3. Fonctions et structure du programme
4. Fichiers, données et services externes
5. Débogage et fiabilité
6. Du carnet Jupyter au projet facile à maintenir
Ce que vous saurez faire
Utilisez un carnet (notebook) Jupyter pour ce qu’il fait bien : essayer des idées rapidement. Mais ne vous fiez pas à un résultat qui dépend seulement de l’ordre d’exécution des cellules. Déplacez ensuite le code à conserver dans le projet, où il a des tests.
Carnet JupyterFaites cette leçon dans un carnet
Le carnet de laboratoire crée volontairement chaque type d’état caché pour que vous puissiez l’observer. Il télécharge les 15 billets de soutien du cours et les vérifie d’abord. Il ne nécessite aucune installation ni aucun projet local. Environ 30 minutes. Vous l’utilisez dans la pratique guidée ci-dessous.
Le carnet est en anglais. Colab et Kaggle ouvrent votre propre copie. Il faut un compte Google ou Kaggle gratuit. Vous êtes bloqué ? Consultez le carnet de solution.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Les modules et les importations, et le fait qu’une importation exécute un module une seule fois, dans Modules et importations.
- Le contrat d’une fonction, dans Le contrat d’une fonction : le contrat, et les tests, dans Des tests ciblés. Vous utilisez les deux pour déplacer du code d’un carnet vers le projet.
Ce qu’il vous faut sur votre ordinateur
- Pour le carnet de laboratoire : un compte Google gratuit (pour Colab) ou un compte Kaggle. Vous pouvez aussi utiliser VS Code avec l’extension Jupyter, comme dans l’encadré sous la pratique guidée. Le carnet ne nécessite aucun paquet autre que Python.
- Pour À vous de jouer, ticket-cleaner avec ses tests, sur votre ordinateur. Vous les avez créés dans Des tests ciblés : pratique guidée et À vous de jouer. Vous avez téléchargé
data/tickets.csvdans Lire et écrire des fichiers. Si les tests échouent, refaites ces sections. - L’environnement
.venvdu projet, actif dans votre terminal (l’invite commence par(.venv)). Vous l’avez créé dans Isoler les dépendances : pratique guidée. S’il manque ou ne fonctionne plus, supprimez-le et recréez-le à partir du fichier de verrouillage. Suivez Recréer l’environnement à partir de zéro. VS Code y installeipykernelquand vous le sélectionnez comme noyau. N’ajoutez pasipykernelàrequirements.txt.
Testé avec Python 3.12 et 3.14 dans JupyterLab 4.6. Le carnet a été testé dans Jupyter.
Ce qu’est un carnet
Section intitulée « Ce qu’est un carnet »Un carnet (un fichier .ipynb) est une page de cellules. Une cellule de code contient du code Python, et sa sortie apparaît en dessous. Une cellule de texte contient des explications. Vous exécutez une cellule à la fois, regardez le résultat et ajustez l’étape suivante. Pour explorer des données, c’est plus rapide que de relancer un script complet à répétition. Les scientifiques des données et les ingénieurs en IA utilisent des carnets chaque jour, notamment dans Google Colab, Kaggle ou JupyterLab.
Le code s’exécute dans un noyau : un programme Python qui démarre avec le carnet. Il garde toutes les variables en mémoire jusqu’à son redémarrage. C’est la cause des problèmes de cette leçon. La page et le noyau sont deux choses différentes :
| La page montre | Le noyau contient |
|---|---|
| Les cellules dans leur ordre, de haut en bas. | Les variables de toutes les cellules exécutées, dans l’ordre où vous les avez exécutées. |
| Le texte actuel de chaque cellule. | Le résultat du texte que la cellule contenait au moment de son exécution. |
| Seulement les cellules qui existent. | Des variables de cellules que vous avez supprimées. |
Le nombre entre [ ] à côté d’une cellule, le compteur d’exécution, indique l’ordre. Un [7] au-dessus d’un [3] sur la page signifie que la cellule du haut a été exécutée plus tard.
L’état caché
Section intitulée « L’état caché »Quand le noyau contient des valeurs que la page n’explique pas, le carnet a un état caché. Voici trois façons de le créer :
- Une cellule modifiée sans réexécuter les suivantes. Vous remplacez
wanted_status = "open"par"closed"et exécutez cette cellule, mais pas celle qui filtre les lignes. La page indique « closed » (fermé), mais le résultat correspond encore à « open » (ouvert). - Une cellule supprimée. Vous supprimez la cellule qui définit
priority_limit. Toutes les cellules suivantes fonctionnent encore, jusqu’au redémarrage du noyau. - Un module modifié. Vous modifiez un fichier
.pyque le carnet a importé. Python importe un module une seule fois par noyau. Le carnet utilise donc encore l’ancienne version.
Dans chaque cas, le carnet fonctionne pour vous aujourd’hui. Il échoue pour un collègue qui l’ouvre, et pour vous après un redémarrage. Pire encore, il peut afficher un nombre erroné sans aucune erreur.
Redémarrer et tout exécuter
Section intitulée « Redémarrer et tout exécuter »Le test est simple : redémarrez le noyau et exécutez toutes les cellules depuis le haut. Le noyau contient alors seulement ce que la page indique, dans l’ordre indiqué. Si le carnet s’exécute sans erreur et donne les mêmes résultats, il n’a pas d’état caché. Faites-le avant de vous fier à un résultat, et chaque fois avant de partager un carnet.
| Outil | Menu |
|---|---|
| JupyterLab | Kernel › Restart Kernel and Run All Cells (noyau › redémarrer le noyau et exécuter toutes les cellules) |
| VS Code | Restart (redémarrer), puis Run All (tout exécuter), dans la barre au-dessus du carnet |
| Colab | Runtime › Restart session and run all (exécution › redémarrer la session et tout exécuter) |
| Kaggle | Run › Restart & clear cell outputs (exécuter › redémarrer et effacer les sorties), puis Run › Run all (tout exécuter) |
Pratique guidée : le carnet de laboratoire
Section intitulée « Pratique guidée : le carnet de laboratoire »Le carnet de laboratoire crée volontairement chaque type d’état caché pour que vous puissiez l’observer. Il télécharge les 15 billets du cours et les vérifie d’abord. Environ 30 minutes. Chaque cellule de code est précédée d’une cellule de texte qui indique quoi faire et quel résultat attendre.
- Ouvrez le carnet dans Colab ou Kaggle depuis l’encadré Faites cette leçon dans un carnet, en haut de cette page. Si vous préférez travailler sur votre ordinateur, consultez l’encadré sous les étapes.
- Exécutez les cellules une à la fois, depuis le haut. Lisez la cellule de texte avant chaque cellule de code.
- Dans Predict, then run (prédire, puis exécuter), écrivez votre prédiction avant d’exécuter la cellule. Vous voyez
closed 9(9 fermés), même si seulement 3 billets sont fermés. - Dans A deleted cell that still counts (une cellule supprimée qui compte encore), supprimez la cellule et exécutez la suivante. Elle fonctionne encore.
- Redémarrez et exécutez tout. L’exécution s’arrête avec
NameError: name 'priority_limit' is not defined(le nom « priority_limit » n’est pas défini). Remettez la valeur au-dessus de la cellule qui l’utilise. Redémarrez et exécutez tout de nouveau, jusqu’à la fin sans erreur. - Dans Change one thing (modifier une chose), prédisez le numéro de version, puis exécutez. L’importation affiche
1 False, etimportlib.reloadaffiche2 True. - Faites les deux exercices. Chacun se termine par une cellule de vérification qui affiche
Check passed.(vérification réussie) quand votre réponse est correcte. - Redémarrez et exécutez tout une dernière fois. Toutes les cellules s’exécutent, et les deux cellules de vérification affichent
Check passed.
Explorer dans le carnet, conserver dans le projet
Section intitulée « Explorer dans le carnet, conserver dans le projet »Un carnet est un bon endroit pour découvrir quoi faire. C’est un mauvais endroit pour conserver du code dont le projet dépend. Vous ne pouvez pas importer une fonction depuis une cellule, et les cellules n’ont pas de tests. L’état caché peut changer un résultat sans avertissement.
Quand une idée fonctionne dans le carnet et que vous voulez la conserver, déplacez-la :
Description textuelle du diagramme
Dans le carnet, vous chargez et examinez les données, essayez une règle de nettoyage, puis comptez et comparez les résultats. Une règle à conserver devient une fonction dans ticket_cleaner/parsing.py. Un calcul à conserver passe dans ticket_cleaner/report.py. Chacun reçoit un test dans tests/. L’interface en ligne de commande dans ticket_cleaner/cli.py utilise les deux. Le fichier README.md explique comment préparer et exécuter le programme. Ensuite, le carnet importe les fonctions du paquet au lieu de garder sa propre copie.
Les règles pour ce déplacement :
- Créez une fonction avec un contrat. Une cellule qui modifie des variables globales devient une fonction avec des paramètres et une valeur de retour. Consultez Le contrat d’une fonction.
- Ajoutez un test, à partir de l’exemple que vous avez essayé dans le carnet.
- Importez la fonction dans le carnet, ne la copiez pas. Le carnet et le programme utilisent alors toujours la même version.
ticket-cleaner suit déjà ce modèle. Dans ce module, vous ajoutez les dernières parties. La prochaine leçon ajoute une commande pour l’exécuter. La dernière ajoute les outils et le README qui permettent à une autre personne de l’utiliser.
À vous de jouer : une exploration à conserver
Section intitulée « À vous de jouer : une exploration à conserver »Ouvrez un carnet sur votre ordinateur, dans votre dossier ticket-cleaner, avec le .venv du projet comme noyau. (Dans VS Code : Select Kernel › Python Environments › .venv. Acceptez l’installation de ipykernel. C’est un outil pour vous, pas une dépendance du projet. Ne l’ajoutez donc pas à requirements.txt.)
-
Dans la première cellule, importez depuis le paquet et lisez les données :
from pathlib import Pathfrom ticket_cleaner.files import read_rowsfrom ticket_cleaner.parsing import split_recordstickets, rejected = split_records(read_rows(Path("data/tickets.csv")))len(tickets), len(rejected)La sortie est
(9, 6). -
Explorez une question dans les cellules suivantes : combien de billets urgents (priorité 1) y a-t-il dans chaque catégorie?
-
Redémarrez et exécutez tout.
-
Décidez : le rapport devrait-il toujours inclure cette réponse? Si oui, déplacez le calcul dans
report.pycomme fonction, avec un test danstests/test_report.py. Importez ensuite la fonction dans le carnet.
Afficher une réponse
Exploration dans le carnet :
urgent = [ticket for ticket in tickets if ticket.is_urgent()][(ticket.id, ticket.category) for ticket in urgent]La sortie est [('T-1003', 'login'), ('T-1006', 'shipping'), ('T-1010', 'login')]. La réponse est donc login: 2, shipping: 1 (connexion : 2, livraison : 1), et count_by_category(urgent) la calcule déjà. Aucune nouvelle fonction n’est nécessaire : le carnet a révélé qu’une fonction existante répond à la question. Si le service de soutien la veut dans chaque rapport, ajoutez une ligne à build_summary, "urgent_by_category": count_by_category([t for t in selected if t.is_urgent()]), et un test correspondant.
Erreur courante
Ça fonctionnait hier
Symptôme : vous ouvrez un carnet qui fonctionnait hier, et il s’arrête avec NameError (erreur de nom) ou ModuleNotFoundError (module introuvable). Ou un collègue obtient un nombre différent avec le même carnet.
Cause : l’état caché. Hier, le noyau contenait une variable d’une cellule maintenant supprimée ou modifiée, ou une version de module absente du disque. La réouverture du carnet a démarré un nouveau noyau, qui contient seulement ce qui figure sur la page.
Solution :
- Redémarrez et exécutez tout. Notez la première cellule qui échoue.
- Trouvez d’où venait sa valeur manquante. Remettez ce code dans une cellule au-dessus de celle qui échoue.
- Redémarrez et exécutez tout de nouveau, jusqu’à ce que le carnet s’exécute de haut en bas.
- Si la cellule utilise votre propre module, redémarrez le noyau après chaque modification du module, ou utilisez
importlib.reload.
Vérifiez votre compréhension
Un carnet affiche les compteurs d'exécution [1], [2], [9], [4], [5], de haut en bas. Qu'est-ce que cela indique? Que faites-vous avant de vous fier à sa dernière sortie?
Afficher la réponse
La troisième cellule a été exécutée en dernier, après la quatrième et la cinquième. Ces deux cellules ont donc utilisé les valeurs d’avant la dernière exécution de la troisième. Leur sortie ne reflète pas la modification de la troisième cellule. Redémarrez et exécutez tout, puis relisez les résultats. Les compteurs vont alors de [1] à [5], dans l’ordre.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Pourquoi importer clean_text depuis ticket_cleaner dans un carnet, plutôt que de copier la fonction dans une cellule?
Afficher la réponse
Avec une copie, il existe deux versions. La fonction du paquet change, par exemple après la correction d’un bogue accompagnée d’un test de régression. La copie dans le carnet garde l’ancien comportement. Le carnet donne donc des résultats différents du programme. Une importation utilise toujours la version qui a les tests.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Le noyau garde toutes les variables jusqu’à son redémarrage. C’est l’ordre d’exécution des cellules qui compte, pas leur ordre sur la page.
- L’état caché vient de cellules modifiées sans nouvelle exécution, de cellules supprimées et de modules modifiés.
- Redémarrez et exécutez tout avant de vous fier à un résultat ou de partager un carnet.
- Explorez dans le carnet. Conservez dans le projet : une fonction avec un contrat, un test et une importation dans le carnet.
Ensuite, vous donnez à ticket-cleaner une interface en ligne de commande. Tout le monde pourra l’exécuter avec des options, plutôt qu’avec des variables d’environnement et des modifications du code.
Leçon suivante : L'interface en ligne de commande