Aller au contenu principal

Les bases de Python

On sait afficher, calculer et retenir une valeur. Ce chapitre reprend ces trois gestes sérieusement, et nous fait rencontrer le piège qui bloque tous les débutants à leur première saisie.

Chaque exemple est exécutable. Les lancer, les modifier, les casser : c'est comme ça qu'on apprend, et rien ici ne peut casser autre chose que le bloc lui-même.

Ce qu'on va apprendre

  • Comprendre ce qu'est vraiment une variable, et ce qu'elle n'est pas.
  • Calculer avec les sept opérateurs de Python.
  • Afficher proprement, et demander une valeur à l'utilisateur.
  • Reconnaître les types de données, et convertir quand il le faut.

Une variable est une étiquette

Définition

Une variable est un nom collé sur une valeur rangée en mémoire. Le signe = est un ordre : calcule ce qui est à droite, puis colle sur le résultat l'étiquette écrite à gauche.

Ce n'est pas une boîte
On lit souvent qu'une variable est « une boîte qui contient une valeur ». L'image est commode et elle finira par nous gêner : elle laisse croire que la valeur est dans la variable, et qu'elle a une taille, une forme, un emplacement fixe.
En Python, c'est l'inverse. La valeur existe d'abord, en mémoire, et le nom vient s'y coller comme un Post-it. Réaffecter une variable ne vide aucune boîte : cela décolle l'étiquette pour la coller ailleurs. Cette image-là restera juste jusqu'au bout du cours, y compris le jour où on partagera une liste entre deux noms.
main.py
Sortie
>_ Prêt à exécuter…

L'affectation se lit toujours de droite à gauche. Ce qui est à gauche du = doit donc être un nom, jamais un calcul ni une valeur. Le bloc suivant est faux exprès : l'exécuter pour voir comment Python le dit.

main.py
Sortie
>_ Prêt à exécuter…

SyntaxError: cannot assign to literal : on ne peut pas coller une étiquette sur le côté gauche quand ce côté est déjà une valeur. Inverse les deux et l'erreur disparaît.

Mettre une variable à jour

En mathématiques, x = x + 1 n'a aucune solution. En programmation, c'est l'opération la plus courante qui soit, parce que = n'est pas une égalité mais une action, exécutée dans le temps.

main.py
Sortie
>_ Prêt à exécuter…
Deux étiquettes, une seule valeur
Que vaut b à la fin de a = 5, b = a, a = 10 ?
b vaut 5. La ligne b = a a collé l'étiquette b sur la valeur 5, celle qui portait déjà a. Changer a ensuite décolle a et la pose sur 10 : cela ne touche pas à b, qui est restée où elle était.
L'essayer dans un bloc : c'est la question de prédiction la plus posée en début de cours.

Nommer correctement

  • Pas d'espaces ni d'accents, on commence par une lettre ou un _, jamais par un chiffre.
  • Par convention : minuscules et tirets bas pour séparer les mots, prix_ht, nombre_total, nom_utilisateur.
  • Python distingue les majuscules : Nom, nom et NOM sont trois étiquettes différentes.
  • Certains mots lui appartiennent (if, for, while, def, class) et ne peuvent pas servir de nom.

Un bon nom dit ce que la valeur représente, pas ce qu'elle vaut. prix_ht vaut mieux que p, et bien mieux que cent.

Une variable qui change de valeur est ce qui distingue un programme d'une formule mathématique. En maths, x = x + 1 n'a pas de solution ; en programmation, c'est l'instruction la plus courante qui soit. La trace montre pourquoi il n'y a là aucune contradiction.

pas 1 / 5
1prix = 100
2remise = 20
3final = prix - remise
4prix = 80
5final = prix - remise

Variables

prix100
Le programme, exécuté pas à pas. La ligne surlignée est celle qui vient de s'exécuter, et le tableau de droite donne l'état des variables juste après.

Le signe = ne pose pas une égalité, il range : il évalue la droite, puis colle l'étiquette de gauche sur le résultat. Réexécuter la même ligne avec un prix différent donne donc un final différent, et l'ancien est perdu. Aucune ligne ne se met à jour toute seule : final ne suit pas prix, il ne garde que ce qu'il valait au moment du calcul.

Calculer

Python calcule comme en mathématiques, avec les mêmes priorités : puissances d'abord, puis multiplications et divisions, puis additions et soustractions, et les parenthèses au-dessus de tout.

OpérateurCe qu'il faitExempleRésultat
+addition5 + 38
-soustraction10 - 46
*multiplication2 * 612
/division, toujours décimale10 / 33.333…
//quotient entier10 // 33
%reste de la division10 % 31
**puissance2 ** 38
Les trois divisions, sur un cas concret
Dix pièces à répartir sur trois machines.
10 / 3 = 3.33… : la part théorique de chaque machine. Utile pour un ratio, pas pour distribuer des pièces.
10 // 3 = 3 : ce que chaque machine reçoit vraiment, en pièces entières.
10 % 3 = 1 : ce qui reste sur la table et qu'on ne peut pas répartir.
Et l'on retrouve toujours le compte de départ : 3 × 3 + 1 = 10.
main.py
Sortie
>_ Prêt à exécuter…
0.1 + 0.2 ne fait pas 0.3
Exécuter print(0.1 + 0.2) : on obtient 0.30000000000000004. Ce n'est pas un défaut de Python, c'est vrai dans tous les langages.
Un ordinateur calcule en binaire, et 0,1 ne s'écrit pas exactement en binaire, pas plus que 1/3 ne s'écrit exactement en décimal. Il arrondit, et les arrondis s'accumulent.
La conséquence pratique tient en une règle : ne compare jamais deux nombres décimaux avec ==. On teste que leur écart est petit, par exemple abs(a - b) < 0.0001.

Afficher

print() accepte plusieurs valeurs, séparées par des virgules, et insère une espace entre chacune.

main.py
Sortie
>_ Prêt à exécuter…

Mais la façon claire d'écrire une phrase avec des valeurs dedans, c'est la f-string : un f devant les guillemets, et les noms entre accolades.

main.py
Sortie
>_ Prêt à exécuter…

Demander une valeur, et le mur qui vient avec

input() affiche une question et attend la réponse de l'utilisateur.

main.py
Sortie
>_ Prêt à exécuter…

Jusqu'ici tout va bien. Maintenant, essaie de calculer avec une valeur saisie. Le bloc ci-dessous est faux exprès : l'exécuter en écrivant 2000 dans la zone Entrées.

main.py
Sortie
>_ Prêt à exécuter…

TypeError: unsupported operand type(s) for -: 'int' and 'str'. Traduction : Python refuse de soustraire du texte à un nombre.

input() renvoie toujours du texte
Toujours. Même si l'utilisateur tape 2000, ce que input() rend est la chaîne "2000", une suite de deux caractères zéro entourée d'un deux et d'un zéro, pas le nombre deux mille.
C'est l'erreur numéro un des débutants, et elle explique la moitié des TypeError des premiers programmes.

Pour nous en convaincre, regarde ce que Python fait de deux textes qui ressemblent à des nombres.

main.py
Sortie
>_ Prêt à exécuter…

"20" + "20" donne 2020 : sur du texte, + colle au lieu d'additionner. C'est cohérent, et c'est bien le problème : Python ne signale rien, il fait autre chose que ce qu'on voulait.

Les types, et la conversion

Cette histoire de texte et de nombres porte un nom : le type. Chaque valeur en a un, et c'est lui qui décide de ce que les opérateurs font.

TypeCe que c'estExemple
intnombre entier42, -7
floatnombre décimal3.14, 4.0
strtexte, entre guillemets"Bonjour", "20"
boolvrai ou fauxTrue, False

La fonction type() répond directement.

main.py
Sortie
>_ Prêt à exécuter…
Une variable n'a pas de type, sa valeur en a un
On dit souvent « la variable x est un entier ». C'est un raccourci trompeur : l'étiquette x n'a aucun type, elle est simplement collée, en ce moment, sur une valeur qui, elle, est un entier. La coller ailleurs et le type change.
C'est ce qu'on appelle le typage dynamique. Commode, et exigeant : rien ne nous empêche d'écrire du texte là où on attendait un nombre, et personne ne nous préviendra avant l'exécution.

Convertir, c'est fabriquer une nouvelle valeur d'un autre type à partir d'une valeur existante.

FonctionExempleRésultat
int()int("20")20
int()int(3.9)3, la partie entière, sans arrondi
float()float("3.5")3.5
str()str(42)"42"
bool()bool(0), bool("")False
bool()bool(1), bool("texte")True

Reprenons le programme qui plantait, avec la conversion au bon endroit.

main.py
Sortie
>_ Prêt à exécuter…
bool("False") vaut True
Pour une chaîne, la règle est brutale : tout ce qui n'est pas vide est vrai. Donc bool("False"), bool("0") et bool("non") valent tous True, puisque ces textes contiennent des caractères.
Seule la chaîne vide "" est fausse. Même logique pour les nombres : seul 0 est faux.
Conséquence : ne teste jamais une réponse utilisateur avec if bool(reponse). La comparer à ce qu'on attend, par exemple if reponse == "oui".
main.py
Sortie
>_ Prêt à exécuter…

À mettre en pratique

Le prix TTC. On a un prix hors taxes et un taux de TVA. Calculons le prix TTC et l'afficher avec deux décimales, en f-string.

main.py
Sortie
>_ Prêt à exécuter…
Afficher la solution
main.py
Sortie
>_ Prêt à exécuter…

Le .2f dans les accolades demande deux décimales. Sans lui, un calcul flottant afficherait parfois 120.00000000000001.

Vérification rapideon peut se reprendre

1.Que vaut b à la fin de : a = 5, puis b = a, puis a = 10 ?

2.Que fait print("7" + "2") ?

3.Après reponse = input("Continuer ? "), l'utilisateur tape 12. Que vaut reponse ?

4.Que vaut int(3.9) ?

5.Que vaut bool("False") ?

Synthèse

  • Une variable est une étiquette collée sur une valeur, pas une boîte qui la contient.
  • = se lit de droite à gauche : on calcule, puis on colle l'étiquette.
  • x = x + 1 est une mise à jour, pas une équation.
  • / divise, // donne le quotient entier, % donne le reste.
  • Les décimaux sont approchés : jamais de == entre deux flottants.
  • Les f-strings sont la façon claire d'afficher, avec {valeur:.2f} pour arrondir.
  • input() renvoie toujours du texte : convertis avec int() ou float() avant de calculer.
  • Ce n'est pas la variable qui a un type, c'est sa valeur.
  • Pour une chaîne, tout ce qui n'est pas vide est True.

Mettre en pratique