La discipline de programmation
Cours · informatique (tronc commun des prépas scientifiques), chapitre 1 · prépas scientifiques, tronc commun · le début du chapitre, la suite sur Adloun
1.1 Introduction et motivation
Au lycée, on apprend à faire marcher un programme. En classes préparatoires, on apprend à savoir pourquoi il marche — et à le dire. La différence n'est pas un raffinement d'esthète : un programme qui semble fonctionner sur deux exemples peut échouer sur le troisième, et l'histoire de l'informatique est jalonnée de catastrophes nées d'un code non spécifié, non testé, non relu. Ce premier chapitre met en place les habitudes qui serviront pendant deux ans (et toute une vie professionnelle) : un environnement de travail maîtrisé, des fonctions spécifiées avec précision, des programmes annotés et commentés à bon escient, et des jeux de tests construits méthodiquement. Il s'achève sur une première rencontre avec les deux outils de validation qui structureront tout le cours : le variant, qui garantit qu'une boucle s'arrête, et l'invariant, qui garantit qu'elle calcule la bonne chose.
Le mot d'ordre du programme officiel est limpide : faire bien plutôt que beaucoup. Une fonction de cinq lignes, spécifiée, testée et justifiée, vaut mieux que cinquante lignes dont personne — pas même leur auteur — ne sait exactement ce qu'elles font.
1.2 L'environnement de travail
1.2.1 L'interpréteur et les scripts
L'interpréteur Python est le programme qui lit du code Python et l'exécute. On l'utilise de deux façons complémentaires :
- en mode interactif (la console, reconnaissable à son invite
>{>{}>}) : chaque expression saisie est immédiatement évaluée et son résultat affiché — idéal pour expérimenter ; - en mode script : les instructions sont enregistrées dans un fichier
.py, exécuté d'un bloc — c'est la forme de tout programme durable.
>>> 2 + 3
5
>>> [k ** 2 for k in range(6)]
[0, 1, 4, 9, 16, 25]
La console n'affiche spontanément que les résultats du mode interactif. Dans un script, rien ne s'affiche sans print : un calcul dont le résultat n'est ni affiché, ni renvoyé, ni enregistré est tout simplement perdu.
1.2.2 Le cycle de travail et les trois familles d'erreurs
Programmer, c'est itérer le cycle écrire → exécuter → observer → corriger. Les incidents rencontrés en chemin se classent en trois familles, qu'il faut apprendre à distinguer car elles ne se traitent pas du tout de la même façon.
- Erreur de syntaxe (
SyntaxError) : le texte n'est pas du Python valide — deux-points oublié, parenthèse non fermée. L'interpréteur refuse même de commencer l'exécution et désigne la ligne fautive. - Erreur d'exécution (exception) : le programme démarre puis s'interrompt sur une opération impossible — division par zéro (
ZeroDivisionError), indice hors borne (IndexError), types incompatibles (TypeError), nom inconnu (NameError). - Erreur de logique : le programme s'exécute sans broncher… et rend un résultat faux. C'est la plus dangereuse, car rien ne la signale : seuls la spécification et les tests peuvent la débusquer.
On veut calculer la moyenne d'une liste non vide de nombres.
def moyenne(t):
s = 0
for x in t
s = s + x # SyntaxError : il manque « : » après « for x in t »
return s / len(t)
Une fois la syntaxe corrigée, moyenne([]) lève ZeroDivisionError : erreur d'exécution. Et la variante suivante, syntaxiquement correcte et qui ne plante jamais sur une liste non vide, est pourtant fausse :
def moyenne(t):
s = 0
for x in t:
s = s + x
return s / len(t) # erreur de LOGIQUE : le return est DANS la boucle
moyenne([2, 4, 6]) renvoie au lieu de : la fonction s'arrête dès le premier passage. Aucun message d'erreur — seule la confrontation à un résultat attendu révèle le problème.
Lire un message d'erreur de bas en haut : la dernière ligne donne la nature de l'erreur, les lignes au-dessus (la traceback) localisent l'endroit exact, fichier et numéro de ligne. Un message d'erreur n'est pas une sanction : c'est l'information de débogage la plus précieuse qui soit.
1.2.3 Le bagage du lycée
Le présent cours suppose acquis le noyau du langage vu au lycée. Le tableau suivant le récapitule — chacune de ces constructions sera réutilisée dès ce chapitre.
| Construction | Exemple | Rôle |
|---|---|---|
| Affectation | x = 3 | lier un nom à une valeur |
| Types de base | int, float, bool, str | entiers, flottants, booléens, chaînes |
| Conditionnelle | if ... elif ... else | exécution selon un test |
| Boucle bornée | for k in range(n) | répéter un nombre connu de fois |
| Boucle conditionnelle | while c | répéter tant qu'une condition tient |
| Fonction | def f(x): ... return y | nommer et réutiliser un calcul |
| Liste | t = [1, 2, 3] ; t[i] ; len(t) | tableau d'éléments indexés de à |
| Parcours | for x in t | visiter les éléments un à un |
Exercices du chapitre
- Le contrat ambigu corrigé
- Variant non trivial — l'algorithme d'Euclide corrigé
- Invariant du maximum corrigé
- Le test de propriété corrigé
- La boucle qui ne termine pas toujours corrigé
- Spécification, tests et preuve d'un algorithme corrigé