Séance 09 · Partie A · Python pas à pas
Modules et
bibliothèques.
Personne ne réécrit la racine carrée ou le générateur aléatoire. Python livre des centaines de modules prêts à l’emploi, et vous allez apprendre à créer les vôtres.
Durée : 90 min · Objectifs : import sous toutes ses formes, tour d’horizon de math, random, time, statistics, collections, itertools ; écrire et importer son propre module ; installer une bibliothèque externe.
Ce que vous saurez faire à la fin
- Trouver et utiliser la fonction qu’il vous faut dans la bibliothèque standard.
- Découper un projet en plusieurs fichiers.
- Comprendre
if __name__ == "__main__":. - Installer un paquet avec
pipsur votre PC.
01 / import
Quatre façons d’importer
Laquelle choisir ?
La forme 1 est la plus claire : en lisant math.sqrt, on sait d’où vient la fonction. La forme 2 est bien pour deux ou trois noms très utilisés. L’alias (3) est la convention pour certaines bibliothèques (import numpy as np). La forme 4 déverse des dizaines de noms dans votre programme et peut en écraser d’autres silencieusement : on ne l’utilise pas. dir(module) liste ce qu’il contient ; help(module.fonction) explique.
02 / La bibliothèque standard
math : ce que la calculatrice sait faire, et plus
Radians
Toutes les fonctions trigonométriques travaillent en radians : 360° = 2π rad. Oublier la conversion est l’erreur n°1 des programmes de robots qui tournent dans le mauvais sens. atan2(y, x) donne l’angle du vecteur (x, y) dans le bon quadrant, contrairement à atan(y/x). La séance 14 y consacre une heure entière.
02 / La bibliothèque standard
random : simuler le hasard
Pseudo-aléatoire
Un ordinateur ne sait pas tirer au hasard : il calcule une suite déterministe qui en a l’air, à partir d’une graine. Fixer la graine avec seed permet de reproduire exactement une simulation (indispensable pour déboguer). gauss(moyenne, écart-type) modélise le bruit réel d’un capteur. Pour de la cryptographie, on utilise le module secrets, pas random.
02 / La bibliothèque standard
time et datetime : mesurer et dater
Trois horloges
perf_counter() : pour mesurer des durées (le plus précis). time.time() : secondes écoulées depuis le 1er janvier 1970, pour horodater. datetime.now() : date et heure lisibles. sleep() bloque le programme : sur un robot, on préfère souvent comparer l’heure à chaque tour de boucle plutôt que dormir (séance 20).
02 / La bibliothèque standard
statistics, collections, itertools : les outils malins
Médiane contre moyenne
Un capteur qui renvoie parfois une valeur aberrante fausse complètement la moyenne (90 tire tout vers le haut) mais pas la médiane. Les filtres médians sont partout en robotique. Counter remplace le comptage manuel de la séance 06 ; deque(maxlen=n) est une fenêtre glissante gratuite ; itertools.product énumère tous les cas d’un problème combinatoire — utile pour vérifier une table de vérité par force brute.
03 / Vos modules
Un fichier .py est un module
Le mystère de __name__
Quand on lance python outils.py, la variable __name__ vaut "__main__" et le bloc de tests s’exécute. Quand on fait import outils depuis un autre fichier, __name__ vaut "outils" et le bloc est ignoré : on récupère les fonctions sans lancer les tests. C’est la convention pour qu’un même fichier soit à la fois une bibliothèque et un programme. Vous verrez cette ligne dans presque tout code Python sérieux.
03 / Vos modules
Organiser un projet
mon_robot/
├── main.py # point d'entrée : python main.py
├── capteurs.py # lire_distance(), lire_batterie()
├── decision.py # decider(etat)
├── moteurs.py # avancer(), tourner()
├── outils.py # maths, conversions
├── test_decision.py # tests (pytest)
└── donnees/
└── journal.csv# main.py
import capteurs
import decision
import moteurs
def cycle():
etat = capteurs.lire_tout()
action = decision.decider(etat)
moteurs.executer(action)
if __name__ == "__main__":
while True:
cycle()Principes
Un fichier par responsabilité, comme une fonction par tâche. main.py ne contient presque rien : il assemble. Les tests sont à côté, avec le préfixe test_. Les données ne sont jamais mélangées au code. Python trouve les modules dans le dossier du script lancé, puis dans la bibliothèque standard, puis dans les paquets installés : c’est sys.path. Un dossier contenant plusieurs modules s’appelle un paquet et s’importe avec des points : from mon_robot.capteurs import lire_distance.
04 / Bibliothèques externes
pip : installer ce que Python ne fournit pas
# Dans un terminal, sur votre PC
python -m pip install numpy
python -m pip install matplotlib pyserial
python -m pip list # ce qui est installé
python -m pip show numpy # détails d'un paquet# Puis dans un programme
import numpy as np
import matplotlib.pyplot as plt
import serial # pyserial : parler à l'Arduino| Bibliothèque | Usage dans ce cours |
|---|---|
numpy | Calcul sur tableaux de mesures (séance 19) |
matplotlib | Graphiques (séance 19) |
pyserial | Port série ↔ Arduino / Pico (séance 20, 26) |
pytest | Lancer les tests |
pygame | Simulateur de robot 2D |
Environnements virtuels
Le dépôt PyPI contient plus de 500 000 paquets. Pour éviter que les projets se marchent dessus, on crée un environnement virtuel par projet : python -m venv .venv, puis l’activer (.venv\Scripts\activate sous Windows, source .venv/bin/activate ailleurs) avant de pip install. On liste les dépendances dans requirements.txt. Dans cette page, numpy est disponible sans installation ; la plupart des autres paquets ne le sont pas.
05 / Défis
Défi ★ — Le dé truqué et le chronomètre
Consigne
1. Simuler 10 000 lancers d’un dé à 6 faces et afficher la fréquence de chaque face avec Counter. Sont-elles proches de 1/6 ?
2. Mesurer avec perf_counter le temps pris par ces 10 000 lancers, puis par 1 000 000. Le rapport est-il de 100 ?
Correction
import random, time
from collections import Counter
for n in (10_000, 1_000_000):
t0 = time.perf_counter()
lancers = [random.randint(1, 6) for _ in range(n)]
duree = time.perf_counter() - t0
c = Counter(lancers)
print(f"{n} lancers en {duree:.3f} s")
for face in sorted(c):
print(f" face {face} : {c[face] / n:.4f}")Le rapport des temps est proche de 100 : le temps est proportionnel au nombre de lancers. On dit que l’algorithme est linéaire. Séance 11.
05 / Défis
Défi ★★ — Estimer π par la méthode de Monte-Carlo
Consigne
On tire N points au hasard dans le carré [0,1]×[0,1]. La proportion de points à distance ≤ 1 de l’origine (dans le quart de disque) vaut π/4. Écrire estimer_pi(n) et comparer avec math.pi pour n = 1 000, 100 000, 1 000 000. Comment l’erreur évolue-t-elle ?
Correction
def estimer_pi(n):
dedans = 0
for _ in range(n):
x, y = random.random(), random.random()
if x * x + y * y <= 1:
dedans += 1
return 4 * dedans / n
for n in (1_000, 100_000, 1_000_000):
p = estimer_pi(n)
print(f"n={n:>9} π≈{p:.5f} erreur={abs(p - math.pi):.5f}")L’erreur décroît environ comme 1/√n : pour gagner une décimale, il faut 100 fois plus de points. C’est lent mais ça marche pour des problèmes où aucune formule n’existe : les méthodes de Monte-Carlo ont été inventées pour le projet Manhattan et servent aujourd’hui en finance, en physique et en robotique (localisation d’un robot par « filtre à particules »).
05 / Défis
Défi ★★★ — Esprit prépa : un module de géométrie testé
Consigne
Écrire un fichier geometrie.py contenant : distance(p, q), angle(p, q) (angle en degrés du vecteur p→q, dans ]−180, 180]), rotation(p, theta_deg) (rotation du point p autour de l’origine), aire_polygone(points) (formule du lacet : ½ |Σ (xᵢ·yᵢ₊₁ − xᵢ₊₁·yᵢ)|). Avec un bloc __main__ de tests. L’importer et l’utiliser pour calculer l’aire d’un carré de côté 2 tourné de 45°.
Correction et ouverture
import math
def distance(p, q):
return math.hypot(q[0] - p[0], q[1] - p[1])
def angle(p, q):
return math.degrees(math.atan2(q[1] - p[1], q[0] - p[0]))
def rotation(p, theta_deg):
t = math.radians(theta_deg)
x, y = p
return (x * math.cos(t) - y * math.sin(t), x * math.sin(t) + y * math.cos(t))
def aire_polygone(points):
s = 0
n = len(points)
for i in range(n):
x1, y1 = points[i]
x2, y2 = points[(i + 1) % n] # le dernier rejoint le premier
s += x1 * y2 - x2 * y1
return abs(s) / 2
if __name__ == "__main__":
assert distance((0, 0), (3, 4)) == 5
assert angle((0, 0), (0, 1)) == 90 and angle((0, 0), (-1, 0)) == 180
r = rotation((1, 0), 90)
assert math.isclose(r[0], 0, abs_tol=1e-12) and math.isclose(r[1], 1)
assert aire_polygone([(0, 0), (2, 0), (2, 2), (0, 2)]) == 4
print("geometrie : OK")Le carré tourné : [geometrie.rotation(p, 45) for p in carre] puis aire_polygone → 4.0 (à 1e-15 près) : une rotation conserve l’aire, et votre code le vérifie numériquement. La formule du lacet est un cas particulier du théorème de Green, que vous verrez en prépa ; (i + 1) % n pour « boucler » sur le premier point est un idiome à retenir. Ces quatre fonctions sont exactement celles dont un robot a besoin pour naviguer (séance 14).
06 / Vérification
Après import math, que donne sqrt(4) ?
Deux questions supplémentaires
1. À quoi sert if __name__ == "__main__": ? À n’exécuter un bloc que lorsque le fichier est lancé directement, pas quand il est importé.
2. Pourquoi random.seed(0) ? Pour rendre une simulation reproductible : même graine, mêmes tirages.
Référence
Les mots à retenir
| Mot | Définition |
|---|---|
| Module | Fichier .py importable. |
| Paquet | Dossier de modules. |
| Bibliothèque standard | Modules livrés avec Python (math, random…). |
pip | Installateur de paquets externes (PyPI). |
__name__ | Vaut "__main__" dans le fichier lancé. |
| Environnement virtuel | Installation Python isolée pour un projet. |
| Graine (seed) | Valeur initiale du générateur pseudo-aléatoire. |
Pour continuer
Vous avez toute la boîte à outils
Variables, conditions, boucles, fonctions, structures de données, fichiers, erreurs, modules. Il est temps de tout assembler : séance suivante, un projet complet.
À faire chez soi
- Sur votre PC : créer un dossier de projet, un environnement virtuel, installer
pytest, y placeroutils.pyet un fichier de tests, lancerpytest. - Explorer
help(random)ethelp(itertools). Choisir une fonction inconnue et l’essayer. - Simuler un capteur bruité avec
random.gausset le filtrer avec une médiane glissante (deque+statistics.median).
Documentation
Tutoriel officiel : modules · Index de la bibliothèque standard · PyPI