Cours#
Les bases de la programmation Python
| Programme (BO) | « Mettre en évidence un corpus de constructions élémentaires. » Ces constructions sont : « séquences, affectation, conditionnelles, boucles bornées, boucles non bornées, appels de fonction ». On y ajoute la spécification d’une fonction (prototype, préconditions, postconditions) et l’usage de jeux de tests. |
| Prérequis | aucun. Il suffit de savoir ouvrir une console ou un éditeur Python en ligne. |
| Objectifs | lire, écrire et exécuter un programme simple ; maîtriser les six constructions élémentaires ; spécifier et tester une fonction. C’est le socle de toute l’année (et de toute la suite). |
Situation de départ
-
Comment faire échanger leurs contenus à deux « boîtes » d’un programme sans perdre aucune des deux valeurs ?
-
Comment faire calculer \(1 + 2 + \dots + 100\) à un ordinateur sans écrire soi-même les cent nombres ?
-
Un programme qui répète une action peut-il ne jamais s’arrêter ? Comment être sûr qu’il s’arrêtera ?
Programmer, c’est quoi ?#
Un programme est une suite d’instructions, écrites dans un langage de programmation, qu’un ordinateur exécute pour accomplir une tâche. L’idée est plus ancienne que les ordinateurs eux-mêmes : dès 1843, la mathématicienne Ada Lovelace rédige ce que l’on considère comme le premier programme de l’histoire, destiné à une machine qui ne sera jamais construite. Le mot algorithme, lui, vient du nom du savant persan al-Khwârizmî (IXe siècle).
Pour les curieux (facultatif) — Un peu d’histoire
Ada Lovelace (1815–1852), fille du poète Byron, se passionne pour la machine analytique imaginée par l’Anglais Charles Babbage : une calculatrice mécanique programmable par cartes perforées. En 1843, elle traduit un article sur cette machine et l’enrichit de notes trois fois plus longues que le texte. La dernière, la note G, détaille pas à pas comment la machine calculerait les nombres de Bernoulli, avec des opérations répétées : c’est le premier programme publié. Mille ans plus tôt, vers 820, al-Khwârizmî, savant de la « Maison de la sagesse » de Bagdad, écrit un traité de calcul dont le titre a donné le mot algèbre (al-jabr), et un autre sur les chiffres indiens dont la traduction latine, Algoritmi de numero Indorum, a donné le mot algorithme.

Ada Lovelace (portrait par A. E. Chalon, v. 1840)

Le tableau de la note G (1843)

L’Algèbre d’al-Khwârizmî (copie de 1342, Oxford)
Définition 1 — Algorithme et programme
Un algorithme est une méthode : une suite finie et non ambiguë d’étapes qui, à partir de données, produit un résultat. Un programme est la traduction d’un algorithme dans un langage que la machine peut exécuter.
Nous utiliserons le langage Python, créé en 1991 par le Néerlandais Guido van Rossum. Il est aujourd’hui l’un des langages les plus enseignés et les plus utilisés au monde, pour sa lisibilité.
Pour les curieux (facultatif) — Pourquoi « Python » ?
Rien à voir avec le serpent ! Guido van Rossum était fan de la troupe comique britannique Monty Python. C’est pourquoi la documentation officielle fourmille encore de références à leurs sketchs (et de spam, eggs et autres ham en guise d’exemples).
La première construction : la séquence#
Quand on écrit plusieurs instructions les unes sous les autres, Python les exécute dans l’ordre, de haut en bas, une à la fois. C’est la construction la plus simple : la séquence.
Exemple — Testez ce programme dans une console ou un éditeur en ligne
print("Bonjour")
print("et")
print("au revoir")
Correction
Les trois lignes s’affichent dans l’ordre où elles sont écrites :
Bonjour
et
au revoir
Règle 1 — L’ordre compte
Dans une séquence, l’ordre des instructions détermine le résultat. Échanger deux lignes peut tout changer : la machine ne « devine » pas votre intention, elle applique vos instructions à la lettre.
Remarque
print(...) est un appel de fonction : on demande à une fonction déjà écrite (print) d’afficher ce qu’on lui donne entre parenthèses. Nous reviendrons longuement sur les fonctions.
Variables et affectation#
À quoi sert une variable ?#
Un programme manipule des données : un âge, un prix, un nom, une note… Pour les conserver et les réutiliser, on leur donne un nom. Ce nom, associé à une valeur, s’appelle une variable.
age = 15
prix = 12.5
prenom = "Ada"
Définition 2 — Variable
Une variable est un nom qui désigne un emplacement de la mémoire où est rangée une valeur. On peut lire cette valeur (l’utiliser) et l’écrire (la modifier).
L’image classique est celle du casier étiqueté : le nom de la variable est l’étiquette collée sur le casier, la valeur est ce qui se trouve à l’intérieur. On ne s’intéresse jamais à l’adresse exacte du casier dans la mémoire ; l’étiquette suffit.
Trois casiers en mémoire : l’étiquette (le nom) désigne le contenu (la valeur).
Ce modèle du casier est provisoire : il suffit pour tout ce chapitre. Le chapitre Les types construits le précisera : on y verra qu’une variable est plutôt une étiquette attachée à une valeur rangée ailleurs en mémoire.
L’affectation : une histoire en deux temps#
L’instruction age = 15 s’appelle une affectation. Le symbole = ne veut pas dire « égal » au sens mathématique : il veut dire « prend pour valeur », ou « reçoit ». On lit age = 15 comme « age reçoit 15 ».
Règle 2 — Le mécanisme de l’affectation
Une affectation nom = expression se déroule toujours en deux temps :
-
Python évalue d’abord la partie droite (il calcule la valeur de l’expression) ;
-
puis il range cette valeur dans la variable nommée à gauche.
On lit et on calcule à droite, on range à gauche.
↺ Retour sur l'activité. Dans le programme 2 de l’activité « L’ordinateur humain », vous avez déjà commencé par la droite : calculer n + 1 avec l’ancienne valeur 5, puis gommer la boîte n pour y écrire 6.
Ce mécanisme éclaire une ligne qui, sinon, semble absurde en mathématiques :
n = 5
n = n + 1
La valeur de n passe donc de 5 à 6. Cette écriture, très fréquente, s’appelle un incrément.
Exemple — Le grand classique : échanger le contenu de deux variables. Prévoyez l’affichage
a = 1
b = 2
a = b
b = a
print(a, b)
Correction
Beaucoup attendent 2 1… mais le programme affiche 2 2 ! À la ligne a = b, a vaut désormais 2 ; la valeur 1 est perdue. La ligne suivante range donc 2 (la valeur actuelle de a) dans b.
Règle 3 — Échanger deux variables
Pour ne pas perdre une valeur, on utilise une variable temporaire :
a = 1
b = 2
temp = a # on met a l'abri la valeur de a
a = b
b = temp
print(a, b) # affiche : 2 1
↺ Retour sur l'activité. Le programme 3 de l’activité affichait 2 2 pour cette raison ; la troisième boîte c que vous avez proposée pour le corriger joue exactement le rôle de temp.
Remarque
La variable temporaire est indispensable : sans elle, la première affectation a = b écraserait la valeur de a, alors définitivement perdue. C’est l’image des deux verres, l’un d’eau, l’autre de jus : pour intervertir leurs contenus, il faut un troisième verre vide.
▶ Exercices d'application : exercices 1 et 2 (lire une trace, échanger deux variables)
Les types de données de base#
Chaque valeur a un type, qui décrit sa nature et les opérations permises. En classe de première, quatre types de base suffisent :
| Type | Nature | Exemples |
|---|---|---|
int |
entier | 15, -3, 0 |
float |
nombre à virgule (« flottant ») | 12.5, -0.1, 3.0 |
str |
chaîne de caractères (texte) | "Ada", ’bonjour’ |
bool |
booléen (vrai/faux) | True, False |
La fonction type(...) renvoie le type d’une valeur :
type(15) # <class 'int'>
type(12.5) # <class 'float'>
type("Ada") # <class 'str'>
type(3 == 3) # <class 'bool'>
Sur les nombres, Python dispose des opérations usuelles, et de deux opérations propres à la division entière :
+ |
- |
* |
/ |
// |
% |
** |
|---|---|---|---|---|---|---|
| addition | soustraction | multiplication | division | quotient entier | reste | puissance |
7 + 2 \(\to\) 9 |
7 - 2 \(\to\) 5 |
7 * 2 \(\to\) 14 |
7 / 2 \(\to\) 3.5 |
7 // 2 \(\to\) 3 |
7 % 2 \(\to\) 1 |
7 ** 2 \(\to\) 49 |
Pour les curieux (facultatif) — Typage dynamique
Python est à typage dynamique : on ne déclare pas le type d’une variable, il est déduit de la valeur rangée, et il peut changer au fil du programme. Pratique, mais il faut rester vigilant : additionner un int et un str provoque une erreur.
Remarque — Deux pièges célèbres à connaître
-
Les entiers de Python sont de taille arbitraire. Contrairement à beaucoup de langages, Python calcule
2 ** 1000sans broncher : la seule limite est la mémoire de la machine. -
Les flottants sont approximatifs. Testez
0.1 + 0.2: Python répond0.30000000000000004! Un nombre à virgule est stocké en binaire de manière approchée. On n’écrit donc jamaisif x == 0.3sur des flottants ; on teste plutôt si l’écart est très petit.
Lire une entrée au clavier et convertir#
La fonction input(...) affiche un message, attend que l’utilisateur tape quelque chose au clavier puis valide, et renvoie ce qui a été tapé, toujours sous forme de chaîne (str), même si l’on a tapé des chiffres. Pour calculer avec, il faut donc convertir la valeur dans le bon type :
| Conversion | Rôle | Exemple |
|---|---|---|
int(...) |
vers un entier | int("17") \(\to\) 17 |
float(...) |
vers un flottant | float("12.5") \(\to\) 12.5 |
str(...) |
vers une chaîne | str(17) \(\to\) "17" |
age = int(input("Votre age ? ")) # on tape 16 : age vaut 16
print("Dans un an, vous aurez", age + 1, "ans")
Remarque
Sans int, age vaudrait la chaîne "16", et age + 1 provoquerait une erreur : on ne peut pas additionner un str et un int. De même, int("deux") provoque une erreur : la chaîne doit représenter un nombre.
Premier contact avec les chaînes de caractères#
Une chaîne est une suite de caractères, numérotés à partir de 0. Voici les opérations dont on se sert dès ce chapitre ; le chapitre Les types construits les reprendra en détail.
>>> mot = "radar"
>>> len(mot) # nombre de caracteres
5
>>> mot[0] # caractere en position 0 : le premier
'r'
>>> mot[-1] # le dernier caractere
'r'
>>> "d" in mot # ce caractere est-il dans la chaine ?
True
>>> "Ada" + " Lovelace" # concatenation : on met bout a bout
'Ada Lovelace'
>>> "*" * 3 # repetition
'***'
Si mot a n caractères, les positions vont de 0 à n - 1 : mot[n] provoque une erreur.
Remarque — Compter depuis la fin : les positions négatives
Python accepte aussi des positions négatives, qui se comptent à partir de la fin : mot[-1] est le dernier caractère, mot[-2] l’avant-dernier, etc. Ainsi mot[-1] est un raccourci pour mot[len(mot) - 1].
| caractère | r |
a |
d |
a |
r |
|---|---|---|---|---|---|
| position | 0 |
1 |
2 |
3 |
4 |
| position négative | -5 |
-4 |
-3 |
-2 |
-1 |
Sur un mot vide (""), mot[-1] provoque une erreur, comme mot[0] : il n’y a pas de dernier caractère.
On verra avec la boucle for comment parcourir une chaîne caractère par caractère.
Bien nommer ses variables#
Un programme se lit bien plus souvent qu’il ne s’écrit. Le choix des noms est donc essentiel.
Règle 4 — Règles et conventions de nommage
-
un nom commence par une lettre ou
_, puis lettres, chiffres,_; pas d’espace, pas d’accent conseillé ; -
Python distingue les majuscules :
noteetNotesont deux variables différentes ; -
par convention, on écrit en
minuscules_avec_underscores(style snake_case) ; -
on choisit des noms parlants :
prix_totalplutôt quexoutruc; -
on ne peut pas utiliser un mot réservé du langage (
if,for,while,def,return…).
Écrire une fonction : le gabarit
Dès les premiers exercices, on vous demande d’« écrire une fonction ». Pour l’instant, utilisez-la comme une boîte noire : on lui donne des valeurs (les paramètres), elle renvoie un résultat. Il suffit de recopier ce gabarit ; la section Les fonctions l’approfondira.
def nom_de_la_fonction(parametre1, parametre2):
resultat = ... # le calcul, avec les parametres
return resultat # la valeur renvoyee
-
la ligne
defse termine par un deux-points:; les lignes suivantes sont décalées de 4 espaces ; -
returnindique la valeur que la fonction renvoie ; -
certaines fonctions des exercices affichent (avec
print) au lieu de renvoyer : on les appelle de la même façon.
Exemple — Le prix d’un achat
Écrire une fonction prix_total(prix, quantite) qui renvoie le prix à payer pour quantite articles à prix euros pièce.
Correction
On suit le gabarit :
def prix_total(prix, quantite):
total = prix * quantite
return total
On exécute d’abord le fichier : la définition seule n’affiche rien. Puis on appelle la fonction dans la console, avec des valeurs dont on connaît le résultat, pour la tester :
>>> prix_total(2.5, 4)
10.0
>>> prix_total(3, 0)
0
▶ Exercices d'application : exercices 3 à 5 (// et % ; les fonctions s’écrivent avec le gabarit ci-dessus) et 40, 41 (entraînement : int(input(...)), longueur et indices d’une chaîne)
Les conditionnelles : if, elif, else#
Jusqu’ici, tout s’exécutait ligne après ligne. Or un programme doit souvent choisir entre plusieurs comportements selon les données. C’est le rôle de la construction conditionnelle.
Booléens et conditions#
Une condition est une expression dont la valeur est un booléen : True ou False. On la construit avec des opérateurs de comparaison :
== |
!= |
< |
<= |
> |
>= |
|---|---|---|---|---|---|
| égal | différent | inférieur | inf. ou égal | supérieur | sup. ou égal |
Règle 5 — = n’est pas ==
= affecte une valeur (« reçoit ») ; == teste l’égalité (« est-il égal à ? ») et renvoie un booléen. Les confondre est l’une des erreurs les plus fréquentes du débutant.
On combine plusieurs conditions avec les opérateurs booléens and, or, not :
age = 16
age >= 13 and age <= 17 # True : un adolescent
not (age == 18) # True
À retenir — Évaluation « paresseuse » de and et or
Les opérateurs and et or sont séquentiels : Python évalue les conditions de gauche à droite et s’arrête dès que le résultat est connu. Dans a and b, si a est déjà False, b n’est même pas évalué (le résultat est forcément False). On exploite cela pour se protéger, par exemple dans n != 0 and total / n > 1.
La syntaxe : le rôle capital de l’indentation#
temperature = 12
if temperature < 0:
print("Il gele !")
print("Couvre-toi.")
else:
print("Pas de gel.")
print("Bonne journee.") # toujours execute
Deux points de syntaxe sont obligatoires en Python : le deux-points : en fin de ligne if/else, et l’indentation (le décalage vers la droite) des lignes qui dépendent du test.
Règle 6 — L’indentation est la structure
Là où d’autres langages utilisent des accolades, Python utilise le décalage pour délimiter un bloc d’instructions. Toutes les lignes indentées d’un même cran après le : forment le bloc exécuté si la condition est vraie. Une indentation fautive change le sens du programme, ou provoque une IndentationError. Une seule règle d’or : on ne mélange jamais espaces et tabulations (le standard : 4 espaces).
Pour les curieux (facultatif) — Une histoire de goût… devenu règle
Dans la plupart des langages, l’indentation n’est qu’une politesse pour le lecteur humain. Python a fait un choix radical : la rendre obligatoire et signifiante. Résultat, un code Python mal rangé ne s’exécute pas — ce qui force chacun à écrire proprement. Certains détestent, beaucoup adorent.
Les cas multiples : elif#
Pour enchaîner plusieurs tests, on intercale des elif (contraction de else if). Python teste les conditions dans l’ordre et exécute le premier bloc dont la condition est vraie ; les autres sont ignorés.
Exemple — Attribuer une mention à une note sur 20
Écrire une instruction qui range dans mention la mention correspondant à note : « Très bien » à partir de 16, « Bien » à partir de 14, « Assez bien » à partir de 12, « Admis » (sans mention) à partir de 10, « Refusé » en dessous.
Correction
On enchaîne les tests avec elif :
if note >= 16:
mention = "Tres bien"
elif note >= 14:
mention = "Bien"
elif note >= 12:
mention = "Assez bien"
elif note >= 10:
mention = "Admis"
else:
mention = "Refuse"
Remarque
L’ordre est crucial : une note de 17 vérifie aussi note >= 14, mais comme note >= 16 est testée d’abord et acceptée, on obtient bien « Très bien ». On va donc du cas le plus exigeant au moins exigeant.
Un test très utile : la divisibilité#
L’opérateur % (le modulo) donne le reste d’une division entière. Un nombre a est divisible par b exactement lorsque a % b vaut 0.
if n % 2 == 0:
print("n est pair")
else:
print("n est impair")
▶ Exercices d'application : exercices 6 à 13 (les conditionnelles)
Les boucles bornées : for#
Répéter une action est le cœur de la puissance d’un ordinateur. Quand on connaît à l’avance le nombre de répétitions, on utilise une boucle bornée, la boucle for.
Répéter un nombre connu de fois#
for i in range(5):
print("Au travail !")
Ce programme affiche cinq fois la même ligne. range(5) produit la suite des entiers 0, 1, 2, 3, 4 (cinq valeurs, à partir de 0, sans atteindre 5), et la variable i prend successivement chacune de ces valeurs.
Remarque — Bientôt avec la tortue
Le complément Dessiner avec la tortue, qui suit ce chapitre, fera voir cette boucle : un carré, c’est for cote in range(4): suivi de « avancer, tourner ». Il permettra de s’entraîner aux boucles en dessinant.
Définition 3 — range
-
range(n): les entiers de0àn-1; -
range(a, b): les entiers deaàb-1(la bornebest exclue) ; -
range(a, b, pas): deaàb-1en avançant depas(le pas peut être négatif).
Exemple — Prévoyez ce que produit chaque boucle, puis vérifiez
for i in range(1, 6):
print(i)
for i in range(0, 10, 2):
print(i)
for i in range(10, 0, -1):
print(i)
Correction
Chaque print affiche un nombre par ligne :
-
la 1re boucle affiche
1 2 3 4 5(la borne6est exclue) ; -
la 2e affiche
0 2 4 6 8(on avance de 2,10est exclu) ; -
la 3e affiche
10 9 8 7 6 5 4 3 2 1: un compte à rebours (pas de-1,0est exclu).
Exemple — Parcourir une chaîne
La boucle for peut aussi parcourir directement une chaîne : la variable prend successivement chaque caractère.
for lettre in "Ada":
print(lettre)
Correction
Le programme affiche A, puis d, puis a, un par ligne. Avec un test if lettre in "aeiouy": dans la boucle, on peut par exemple repérer les voyelles d’un mot.
Pour les curieux (facultatif) — Pourquoi commencer à 0 ?
Ce choix déroute au début, mais il est partout en informatique : les cases d’un tableau seront elles aussi numérotées à partir de 0. Le grand informaticien Edsger Dijkstra a même écrit une note célèbre pour défendre les intervalles « borne de gauche incluse, borne de droite exclue » : ils rendent les calculs de longueurs plus simples (\(b - a\) valeurs).
Le motif de l’accumulateur#
La boucle for sert rarement à répéter à l’identique : le plus souvent, la variable de boucle intervient dans le calcul. Le motif le plus important est l’accumulateur : une variable que l’on met à jour à chaque tour.
Exemple — Calculer la somme des entiers de 1 à 100
Correction
On utilise un accumulateur total :
total = 0 # on initialise l'accumulateur
for i in range(1, 101): # i prend les valeurs 1, 2, ..., 100
total = total + i # on ajoute i au total courant
print(total) # affiche 5050
| tour | i |
total après le tour |
|---|---|---|
| avant | — | 0 |
| 1 | 1 | 1 |
| 2 | 2 | 3 |
| 3 | 3 | 6 |
| … | … | … |
| 100 | 100 | 5050 |
La trace d’exécution : suivre l’évolution des variables tour après tour est un réflexe essentiel.
↺ Retour sur l'activité. Le tableau rempli pour le programme 4 de l’activité était déjà une trace ; total y était un accumulateur, qui valait 10 après le tour 4, et remplacer 5 par 101 dans range(1, 5) donne exactement le programme ci-dessus.
Pour les curieux (facultatif) — Un peu d’histoire
D’après la légende, le mathématicien Carl Friedrich Gauss, encore écolier, aurait trouvé ce résultat en une poignée de secondes en remarquant que \(1+100 = 2+99 = \dots = 101\), et qu’il y a 50 telles paires : \(50 \times 101 = 5050\). L’ordinateur, lui, additionne bêtement… mais très vite.
Boucler à l’intérieur d’une boucle#
Le corps d’une boucle peut contenir… une autre boucle. On parle de boucles imbriquées. La boucle intérieure effectue un tour complet pour chaque valeur de la boucle extérieure.
Exemple — Prévoyez le nombre d’étoiles affichées
for ligne in range(3):
for colonne in range(4):
print("*", end="") # end="" : reste sur la meme ligne
print() # passe a la ligne suivante
Correction
La boucle intérieure fait 4 tours pour chacun des 3 tours de la boucle extérieure. On obtient un rectangle de \(3 \times 4 = 12\) étoiles :
****
****
****
▶ Exercices d'application : exercices 14 à 24 et 42 (les boucles for)
Les boucles non bornées : while#
Parfois, on ne sait pas à l’avance combien de fois répéter : on veut continuer tant qu’une condition reste vraie. C’est la boucle non bornée, la boucle while.
solde = 100
annees = 0
while solde < 200: # tant que le solde n'a pas double
solde = solde * 1.05 # +5 % par an
annees = annees + 1
print(annees, "annees")
Définition 4 — Boucle while
while condition: répète le bloc indenté tant que la condition est vraie. La condition est testée avant chaque tour : si elle est fausse dès le départ, le bloc n’est jamais exécuté.
Le danger : la boucle infinie#
Règle 7 — Faire évoluer la condition
Le bloc d’un while doit modifier, tôt ou tard, une variable de la condition, faute de quoi la condition reste vraie pour toujours : c’est la boucle infinie. Le programme se fige et ne s’arrête plus.
i = 0
while i < 5:
print(i)
# OUPS : on a oublie d'augmenter i
Ici i vaut toujours 0, donc i < 5 reste éternellement vrai : le programme affiche 0 sans fin. (Pour l’interrompre : Ctrl + C.) L’oubli de l’incrément est le grand classique de la boucle while.
Prouver qu’une boucle s’arrête : le variant#
Le programme demande explicitement de savoir justifier la terminaison d’une boucle non bornée. L’outil s’appelle le variant de boucle.
Définition 5 — Variant de boucle
Un variant est une quantité entière positive qui décroît strictement à chaque tour de boucle. S’il en existe un, la boucle ne peut pas tourner indéfiniment : une suite d’entiers positifs strictement décroissante ne peut pas se prolonger indéfiniment, donc la boucle finit par s’arrêter.
Exemple — Un compte à rebours
n = 10
while n > 0:
print(n)
n = n - 1
La quantité n est un variant : elle est positive tant qu’on entre dans la boucle, et elle diminue de 1 à chaque tour. Elle atteindra donc 0, ce qui rend la condition n > 0 fausse : la boucle se termine.
Règle 8 — for ou while ?
-
on connaît le nombre de tours (parcourir 1 à 100, répéter 10 fois…) \(\rightarrow\)
for; -
on répète selon une condition dont on ignore quand elle deviendra fausse (jusqu’à ce que l’utilisateur tape « stop », jusqu’à ce que le solde double…) \(\rightarrow\)
while.
▶ Exercices d'application : exercices 25 à 30 et 43 (les boucles while)
Les fonctions#
Depuis le début du chapitre, vous écrivez des fonctions en suivant un gabarit ; voyons maintenant ce qu’il contient vraiment. Dès qu’un programme grandit, on a besoin de le découper en morceaux réutilisables, chacun chargé d’une tâche précise. Ces morceaux sont les fonctions. Le programme le dit clairement : la modularisation « permet la réutilisation de programmes et la mise à disposition de bibliothèques ».
Définir et appeler une fonction#
Définition 6 — Fonction
Une fonction est un bloc d’instructions nommé, que l’on définit une fois (mot-clé def) et que l’on appelle ensuite autant de fois qu’on veut. Elle peut recevoir des paramètres (ses entrées) et renvoyer un résultat (mot-clé return).
def aire_rectangle(largeur, hauteur):
return largeur * hauteur
# appels de la fonction :
print(aire_rectangle(3, 4)) # affiche 12
surface = aire_rectangle(10, 2) # surface recoit 20
On voit une fonction comme une boîte noire : on lui fournit des valeurs en entrée (les arguments), elle rend une valeur en sortie. Peu importe comment elle travaille à l’intérieur : pour l’utiliser, il suffit de connaître ses entrées et sa sortie.
Règle 9 — return n’est pas print
print affiche une valeur à l’écran (pour un humain) ; return renvoie une valeur au programme (pour la réutiliser dans un calcul). Une fonction qui print mais ne return rien renvoie en réalité la valeur spéciale None, et son résultat ne peut pas être réutilisé. Confondre les deux est une erreur très fréquente.
À retenir — return termine la fonction
Dès que Python rencontre un return, il sort immédiatement de la fonction : les lignes situées après ne sont pas exécutées.
Portée : variables locales et globales#
Règle 10 — Variables locales
Les paramètres et les variables créées à l’intérieur d’une fonction sont locaux : ils naissent à l’appel, meurent au return, et sont invisibles depuis l’extérieur. Deux fonctions peuvent donc utiliser une variable i sans jamais se gêner.
def double(x):
resultat = 2 * x # resultat est LOCAL a la fonction
return resultat
print(double(5)) # 10
print(resultat) # NameError : resultat n'existe pas ici
Ce cloisonnement est une force : chaque fonction est un petit monde étanche, ce qui rend le programme bien plus facile à comprendre et à corriger.
Spécifier une fonction (au programme)#
Écrire une fonction juste ne suffit pas : il faut dire clairement ce qu’elle fait, ce qu’elle attend et ce qu’elle garantit. C’est la spécification, exigée par le programme.
Définition 7 — Prototype, précondition, postcondition
-
le prototype annonce le nom de la fonction et ses paramètres :
racine(x); -
une précondition est une hypothèse sur les arguments, à la charge de l’appelant (ex. :
x >= 0) ; -
une postcondition décrit une garantie sur le résultat (ex. : « renvoie un nombre positif »).
En pratique, on documente une fonction avec une docstring (un texte entre triples guillemets, juste après le def) et on peut vérifier une précondition avec une assertion. On en donne ici une première idée ; le chapitre Spécifier et mettre au point ses programmes y reviendra en détail.
def racine(x):
"""Renvoie la racine carree de x.
Precondition : x >= 0.
Postcondition : le resultat au carre redonne x."""
assert x >= 0, "x doit etre positif"
return x ** 0.5
Remarque
Une assert qui échoue arrête le programme avec un message clair. C’est un garde-fou précieux : mieux vaut un arrêt net et explicite qu’un résultat faux qui passe inaperçu.
Tester une fonction (au programme)#
Comment être sûr qu’une fonction est correcte ? On la soumet à un jeu de tests : des cas dont on connaît le résultat attendu. En Python, on écrit ces tests avec des assert : si tout se passe bien, le programme ne dit rien ; au premier test faux, il s’arrête.
def maximum(a, b):
if a > b:
return a
return b
assert maximum(3, 5) == 5
assert maximum(5, 3) == 5
assert maximum(4, 4) == 4 # le cas d'egalite : a ne pas oublier
Règle 11 — Un jeu de tests ne prouve rien… mais protège beaucoup
Le programme insiste sur un point subtil : « le succès d’un jeu de tests ne garantit pas la correction d’un programme ». Passer les tests montre seulement que la fonction est juste sur les cas testés. On soigne donc les tests : cas normaux, cas limites (0, valeurs égales, chaîne vide…), cas particuliers.
Trois réflexes à prendre dès aujourd’hui
Pour chaque fonction que vous écrirez cette année, prenez l’habitude de :
-
écrire une docstring (rôle + précondition + postcondition) ;
-
poser un garde-fou
assertsur la précondition ; -
écrire un petit jeu de tests en
assert, sans oublier les cas limites.
Ces gestes seront approfondis dans les chapitres Algorithmique : le parcours séquentiel (invariants de boucle) et Spécifier et mettre au point ses programmes (débogage, oracle) — mais on les met en pratique dès maintenant.
Réutiliser le travail des autres : les bibliothèques#
On ne réécrit pas tout soi-même : une bibliothèque (module) regroupe des fonctions déjà écrites et testées. On y accède avec import.
import random
print(random.randint(1, 6)) # un de : entier au hasard entre 1 et 6
print(random.randint(0, 100)) # un entier au hasard entre 0 et 100
Méthode — Utiliser une bibliothèque
Nul besoin de connaître une bibliothèque par cœur : l’essentiel est de savoir lire sa documentation pour trouver la fonction utile et comprendre ce qu’elle attend.
Pour les curieux (facultatif) — En Terminale
Deux chapitres prolongent les fonctions : La récursivité (une fonction peut s’appeler elle-même) et Programmation objet et paradigmes (créer ses propres types de données, avec leurs fonctions).
▶ Exercices d'application : exercices 31 à 34 et 44 (les fonctions : spécifier, tester)
Trouver et corriger ses erreurs#
Personne n’écrit un programme juste du premier coup. Savoir lire un message d’erreur fait partie du métier.
Les principaux types d’erreur#
| Type d’erreur | Quand ? |
|---|---|
SyntaxError |
le code est mal formé (: ou ) oublié…) |
IndentationError |
indentation incohérente |
NameError |
on utilise un nom qui n’existe pas (ou une faute de frappe) |
TypeError |
opération entre types incompatibles ("a" + 1) |
ZeroDivisionError |
division par zéro |
Pour les curieux (facultatif) — Le premier « bug » était un vrai insecte
En 1947, l’équipe du calculateur Mark II, dont fait partie l’informaticienne Grace Hopper, trouve un papillon de nuit coincé dans un relais. Elle le colle dans son cahier de bord avec la mention « premier cas réel de bug trouvé », et Grace Hopper rendra l’anecdote célèbre. Le mot est resté ; « déboguer » (debug), c’est chasser ces bestioles du code.
Lire un message d’erreur#
Quand Python rencontre une erreur, il s’arrête et affiche un message. Ce message impressionne (il est en anglais), mais il est toujours construit de la même façon. Voici un programme age.py où l’on a oublié de convertir la saisie :
age = input("Votre age ? ")
print("Dans un an :", age + 1)
On l’exécute et on tape 16 :
Votre age ? 16
Traceback (most recent call last):
File "/home/eleve/age.py", line 2, in <module>
print("Dans un an :", age + 1)
~~~~^~~
TypeError: can only concatenate str (not "int") to str
Ce message se lit ainsi :
-
Traceback (most recent call last):: le programme a commencé à s’exécuter, puis s’est arrêté sur une erreur ; -
File "/home/eleve/age.py", line 2: le fichier et le numéro de la ligne où l’erreur s’est produite ; -
vient ensuite la ligne fautive, recopiée ; en dessous, le signe
^(entouré de~) montre l’endroit précis : ici, le+; -
la dernière ligne est la plus importante : le type d’erreur (
TypeError, voir le tableau ci-dessus), puis le message : « on ne peut concaténer à unestrqu’unestr, pas unint».
Le diagnostic suit : age est une chaîne, car input renvoie toujours une chaîne. On corrige avec age = int(input("Votre age ? ")).
Une faute de syntaxe est détectée avant l’exécution : Python refuse le programme sans exécuter la moindre ligne, et le message n’a pas de ligne Traceback, mais il se lit de la même façon. Dans ce programme note.py, il manque le deux-points du if :
note = int(input("Note ? "))
if note >= 10
print("Admis")
La question « Note ? » n’est même pas posée ; Python affiche :
File "/home/eleve/note.py", line 2
if note >= 10
^
SyntaxError: expected ':'
Le ^ pointe juste après 10, là où Python attendait (expected) le :. La présentation varie un peu selon l’éditeur et la version de Python, mais on retrouve toujours le fichier, le numéro de ligne, la ligne fautive et, en dernier, le type d’erreur suivi du message.
Méthode — Quand ça ne marche pas
-
Lire la dernière ligne du message : le type d’erreur et le message.
-
Regarder la ligne indiquée, puis la ligne précédente : une parenthèse ou un guillemet non refermé peut être signalé une ligne trop bas.
-
Vérifier les détails : le
:en fin de ligneif,elif,else,for,while,def; chaque(a sa); chaque"ouvrant a son"fermant ; l’indentation (4 espaces par niveau). -
Si le programme ne s’arrête pas mais donne un mauvais résultat, ajouter un
printde contrôle qui affiche les valeurs des variables, par exempleprint("i =", i, "total =", total)dans une boucle ; le retirer une fois l’erreur trouvée.
▶ Exercices d'application : exercices 45 et 46 (corriger d’après le message d’erreur)
Pour les curieux (facultatif) — Liens avec d’autres chapitres
-
Juste après. Le résultat surprenant de
0.1 + 0.2s’expliquera au chapitre Le binaire et l’écriture des nombres, où//et%serviront à convertir un entier en binaire. -
Plus loin dans l’année. Les chaînes et les
range, numérotés à partir de 0, annoncent les tableaux des Types construits ; l’accumulateur deviendra le patron de tous les parcours ; docstrings,assertet tests seront approfondis dans Spécifier et mettre au point ses programmes. -
En Terminale. Le chapitre Calculabilité montrera qu’aucun programme ne peut décider, pour toute boucle, si elle s’arrête : d’où l’importance de savoir exhiber soi-même un variant.
Bilan — la carte mémoire#
Les six constructions élémentaires du programme, réunies :
| Construction | À retenir |
|---|---|
| Séquence | les instructions s’exécutent dans l’ordre, de haut en bas |
Affectation = |
« reçoit » : on évalue à droite, on range à gauche |
Conditionnelle if/elif/else |
choisir selon une condition (booléen) ; : + indentation |
Boucle bornée for |
répéter un nombre connu de fois (range) |
Boucle non bornée while |
répéter tant qu’une condition est vraie ; gare à l’infini |
| Appel de fonction | def pour définir, return pour renvoyer ; entrées \(\to\) sortie |
| Réflexe | À retenir |
|---|---|
| Types de base | int, float, str, bool ; gare aux flottants |
= contre == |
affecter contre tester l’égalité |
print contre return |
afficher contre renvoyer pour réutiliser |
| Terminaison | un variant (entier \(\geqslant 0\) qui décroît) garantit l’arrêt |
| Spécifier / tester | docstring, préconditions (assert), jeu de tests |
Retour à la situation de départ
-
Avec une variable temporaire :
temp = a, puisa = b, puisb = temp. Sans elle, l’affectationa = bécrase l’ancienne valeur dea, qui est perdue (§ II). -
Avec une boucle bornée
for i in range(1, 101):et un accumulateurtotal, initialisé à0, auquel on ajouteià chaque tour ; le programme affiche5050(§ IV). -
Oui : une boucle
whiledont la condition reste toujours vraie est une boucle infinie. Pour garantir l’arrêt, on exhibe un variant, entier positif qui décroît strictement à chaque tour (§ V).
Erreurs fréquentes#
-
Confondre
=et==.=affecte une valeur,==teste l’égalité. Le réflexe : dans unif, c’est==. -
Confondre
printetreturn.printaffiche ;returnrenvoie une valeur réutilisable. Une fonction sansreturnrenvoieNone. -
Oublier le
:ou mal indenter. En Python, le bloc est défini par l’indentation ; le:termine la ligne d’unif,for,while,def. -
Une boucle
whilequi ne progresse pas. Si la variable de condition n’évolue pas, la boucle est infinie. Le réflexe : un variant qui se rapproche de l’arrêt. -
Oublier que
inputrenvoie une chaîne. Pour calculer, convertir :int(input(…)). -
Confondre
/et//./donne un flottant,//le quotient entier ;%donne le reste.
Savoir-faire à maîtriser#
À la fin du chapitre, je sais…
-
créer (affecter) une variable et reconnaître son type (
int,float,str,bool) ; -
écrire une condition (
if/elif/else) et une expression booléenne ; -
écrire une boucle bornée (
for) et non bornée (while) ; -
définir et appeler une fonction avec paramètres et
return; -
convertir (
int/float/str) et lire une entrée (input) ; -
spécifier (docstring) et tester (
assert) une fonction ; -
justifier qu’une boucle
whilese termine (variant).