Skip to content

Les variables et le type entier

Prédire la valeur

Écris la valeur de l'expression demandée comme Python l'écrirait ('abc', True, 2.0), puis valide. Quand le champ est marqué « affiche », écris plutôt ce que le programme affiche. Si le programme s'arrête sur une erreur, écris erreur. Les valeurs changent à chaque essai.

Rappel d'ouverture (5 minutes, cours fermé)

Réponds sans rouvrir les chapitres sur la représentation de l'information et l'architecture, en écrivant tes réponses. Se tester est ce qui fixe les acquis, relire ne le fait pas.

  1. Combien de valeurs différentes peut-on coder sur un octet ? Quelle est la plus grande, en écriture binaire ?
  2. Dans le Little Man Computer, à quoi servent les instructions STA et LDA ?
  3. Convertis 1011 (binaire) en décimal.
Correction
  1. 256 valeurs, de 0 à 255. La plus grande s'écrit 11111111 : huit bits, donc \(2^8\) combinaisons.
  2. STA (store) range une valeur à une adresse mémoire. LDA (load) lit la valeur qui s'y trouve. Ce sont les deux seules opérations de la mémoire : écrire et lire.
  3. 1011 vaut \(8 + 0 + 2 + 1 = 11\).

Ces trois questions ne sont pas là par hasard : cette page montre que ce que Python appelle une variable est exactement la case mémoire du Little Man Computer, avec un nom à la place d'une adresse.

Se souvenir d'une information

Le plus important

Une variable est le seul moyen de se souvenir d'une information entre les instructions d'un programme.

  • Toute information qui n'est pas stockée dans une variable est perdue.
  • Toute nouvelle information stockée dans une variable efface la précédente.
  • Les variables sont stockées sous forme binaire dans la mémoire de l'ordinateur : la RAM.

Barrette de RAM de 128 Go

Exercice

a = 4
a + 3
Que vaut a après ces deux lignes ? Et où est passé le résultat de a + 3 ?

Correction

a vaut toujours 4. La deuxième ligne calcule bien 7, mais aucune variable ne le reçoit : la valeur est produite puis immédiatement perdue, et plus rien dans le programme ne permet de la retrouver.

Exercice

cote = 6
cote * cote
Ce programme devait calculer l'aire d'un carré pour pouvoir s'en servir plus loin. Il ne le fait pas. Qu'est-ce qui manque ?

Correction

Il manque une affectation pour conserver le résultat :

cote = 6
aire = cote * cote

aire vaut alors 36, et la suite du programme peut l'utiliser. Sans cette ligne, le 36 est calculé puis jeté.

Exercice

mesure = 7
mesure = 9
Après ces deux lignes, on voudrait pouvoir se servir à la fois de 7 et de 9. Est-ce possible en l'état ? Si non, que faut-il changer ?

Correction

Ce n'est pas possible : mesure ne contient qu'une valeur à la fois, et c'est 9. Le 7 a été effacé par la deuxième ligne.

Pour garder les deux, il faut deux cases, donc deux variables :

mesure1 = 7
mesure2 = 9

Exercice

jour = 12
mois = 3
jour = mois
Combien de cases mémoire sont utilisées, et que vaut chacune à la fin ? Quelle valeur n'existe plus nulle part dans le programme ?

Correction

Deux cases. jour vaut 3 et mois vaut 3.

La valeur 12 n'existe plus : la troisième ligne a écrit 3 par-dessus. Noter que les deux cases contiennent maintenant la même valeur, mais elles restent deux cases distinctes : changer mois ensuite ne changerait pas jour.

Exercice

n = 200
Sur combien de bits au minimum la valeur de n tient-elle dans la mémoire ? Justifie.

Correction

8 bits, soit un octet.

Sur 7 bits, on code \(2^7\) = 128 valeurs, de 0 à 127, et 200 dépasse. Sur 8 bits, on code \(2^8\) = 256 valeurs, de 0 à 255, ce qui suffit.

Exercice

Un programme range une valeur dans une variable, puis l'ordinateur est éteint. Que devient cette valeur ? Dans quel composant était-elle pendant l'exécution ?

Correction

Elle est perdue. Les variables vivent dans la RAM, qui est une mémoire volatile : son contenu disparaît à l'extinction.

Pour conserver une information après l'extinction, il faut l'écrire ailleurs, sur un disque par exemple. Une variable ne sert à se souvenir que pendant l'exécution du programme.

Une variable est une case mémoire nommée

Souviens-toi du modèle de von Neumann et du Little Man Computer : la mémoire est une suite de cases, chacune repérée par une adresse, et le processeur y range ou y lit des valeurs.

Une variable, c'est exactement cela : une case mémoire à laquelle on a donné un nom. Plutôt que de retenir « la case d'adresse 17 », on écrit age, et l'ordinateur sait de quelle case on parle.

Exercice

a = 5
b = a
Pour chacune de ces deux lignes, dis si la machine lit une case, si elle écrit dans une case, ou les deux, et nomme la ou les cases concernées.

Correction
  • a = 5 : la machine écrit seulement. Elle range 5 dans la case a.
  • b = a : la machine lit la case a pour en obtenir 5, puis écrit ce 5 dans la case b. Deux cases, deux opérations.

Exercice

x = 1
y = 2
x = 3
z = x + y
Combien de cases mémoire ce programme utilise-t-il ?

Correction

Trois : x, y et z. La ligne x = 3 ne crée pas une quatrième case, elle écrit dans celle de x, qui existe déjà, et sa valeur 1 est effacée. À la fin, x vaut 3, y vaut 2 et z vaut 5.

Écrire dans une variable : l'affectation

Pour ranger une valeur dans une variable, on utilise l'opérateur =, appelé affectation.

a = 4

= n'est pas l'égalité

= ne signifie pas « est égal à ». C'est une opération mécanique : « calcule ce qui est à droite, et range le résultat dans la variable de gauche ».

Si la variable n'existe pas encore, elle est créée. Sinon, son contenu est remplacé.

Ce que fait vraiment la machine

Cette opération correspond très exactement à une instruction du processeur. Dans le Little Man Computer, affecter une valeur, c'est l'instruction STA (store) : « écris cette valeur à telle adresse mémoire ». Ainsi a = 4 revient à ranger 4 dans la case étiquetée a.

Exercice

truc = 4
truc = 3
Que vaut truc à la fin ? Pourquoi ?

Correction

3. La deuxième affectation a remplacé le contenu de la case : 4 est perdu.

Exercice

score = 12
score = 20
score = 15
Que vaut score à la fin ? Combien de valeurs différentes cette case a-t-elle contenues au cours du programme, et combien en contient-elle à la fin ?

Correction

score vaut 15. La case a contenu trois valeurs successives, mais elle n'en contient qu'une seule à la fois : 12 puis 20 ont été effacés. Rien dans le programme ne permet de les retrouver.

Lire une variable

On utilise le contenu d'une variable simplement en écrivant son nom dans une expression.

Ce que fait vraiment la machine

Lire une variable correspond à l'instruction LDA (load) du Little Man Computer : « va chercher la valeur à telle adresse ». On en obtient une copie : lire une variable ne la vide pas, on peut la relire autant qu'on veut.

bidule = truc + 5    # on lit truc, on calcule, on range le résultat dans bidule

Exercice

n = 5
m = n + n
n = n + m
Que valent n et m à la fin ?

Indice

Dans n + n, on lit n deux fois. Combien vaut-il à la deuxième lecture ?

Correction

m vaut 10 et n vaut 15.

À la deuxième ligne, on lit n deux fois de suite, et il vaut 5 les deux fois : la première lecture ne l'a pas vidé. On range donc 10 dans m. À la troisième ligne, on lit n (5) et m (10), on calcule 15, et on le range dans n, dont l'ancienne valeur est effacée.

Exercice

k = 3
a = k + k
b = k * k
c = k
Que valent a, b, c et k à la fin ?

Correction

a vaut 6, b vaut 9, c vaut 3, et k vaut toujours 3.

k a été lu cinq fois et n'a jamais changé. Seule une affectation vers k pourrait le modifier, et il n'y en a aucune après la première ligne.

Afficher : sortir de la machine

Une variable sert à se souvenir à l'intérieur de la machine. Pour qu'une information en sorte, il faut une instruction de plus : print.

Appelée sans rien d'autre que la valeur à écrire, elle l'envoie sur la sortie standard, c'est-à-dire le terminal, donc l'écran. C'est son comportement par défaut, et on peut lui demander autre chose, mais ce ne sera pas utile ici.

truc = 2
print(truc)

Ce que fait vraiment la machine

C'est l'instruction OUT (output) du Little Man Computer : « envoie la valeur de l'accumulateur sur la sortie ». print(truc) enchaîne donc les deux instructions que tu connais déjà : LDA pour lire la case truc, puis OUT pour envoyer la valeur dehors.

C'est par là que la machine communique avec ses périphériques. OUT parle à l'écran, comme INP écoutait le clavier.

Exercice

n = 42
print(n)
Quelles instructions du Little Man Computer la deuxième ligne demande-t-elle ? Combien d'opérations la machine fait-elle ?

Correction

Deux : LDA n puis OUT.

print ne va pas chercher la valeur directement sur la sortie. Il faut d'abord lire la case, ce qui en donne une copie, puis envoyer cette copie dehors. La case n n'est pas modifiée, et elle vaut toujours 42.

Exercice

a = 3
b = 5
print(a + b)
Qu'affiche ce programme ? Que valent a et b à la fin ? Une variable contient-elle 8 ?

Correction

Il affiche 8. a vaut 3 et b vaut 5, inchangés : ils ont seulement été lus.

Et aucune variable ne contient 8. La valeur a été calculée, envoyée sur la sortie, puis perdue, comme toute valeur qu'aucune affectation ne range. Afficher une information n'est pas la mémoriser : ce sont deux opérations différentes, OUT et STA.

Exercice

truc = 2
print(truc)
bidule = truc + 5
print(bidule + truc)
print(truc)
Qu'affichent les trois print, dans l'ordre ?

Correction

2, puis 9, puis 2.

Le deuxième lit bidule (7) et truc (2), et affiche leur somme sans la ranger nulle part. Le troisième montre que truc vaut toujours 2 : il a été lu trois fois et n'a jamais changé.

Le membre de droite est calculé, puis rangé

Parce que = n'est pas l'égalité, une ligne comme celle-ci a un sens parfaitement clair :

a = a + 1

En tant qu'égalité mathématique, ce serait absurde. En tant qu'affectation, c'est mécanique : on calcule d'abord la droite (a + 1, avec la valeur actuelle de a), puis on range le résultat dans a. Si a valait 4, il vaut maintenant 5.

Exercice

c = 0
c = c + 3
c = c * 2
c = c - 1
Que vaut c après chaque ligne ?

Correction

0, puis 3, puis 6, puis 5.

Chaque ligne lit la valeur actuelle de c, calcule, et range le résultat dans c par-dessus l'ancienne valeur.

Exercice

u = 2
w = 5
u = u + w
w = w + u
Que valent u et w à la fin ?

Indice

À la quatrième ligne, u ne vaut plus 2.

Correction

u vaut 7 et w vaut 12.

La troisième ligne range 2 + 5 dans u, qui vaut donc 7. La quatrième lit w (5) et u (7, sa nouvelle valeur), ce qui donne 12.

Dérouler un programme pas à pas

Suivons l'état des cases mémoire, instruction après instruction :

x = 10
y = x + 2
x = 0
print(x, y)
Instruction x y
x = 10 10
y = x + 2 10 12
x = 0 0 12

L'affichage est donc 0 12. Remarque que y garde 12 : sa valeur a été calculée au moment du y = x + 2, et changer x ensuite n'y touche pas.

Exercice

À ton tour de dérouler. Recopie le tableau et remplis-le ligne par ligne, puis donne l'affichage.

p = 2
q = p + 3
p = q
q = p - 1
print(p, q)
Instruction p q
p = 2
q = p + 3
p = q
q = p - 1
Correction
Instruction p q
p = 2 2
q = p + 3 2 5
p = q 5 5
q = p - 1 5 4

L'affichage est 5 4. À la troisième ligne, p et q valent tous les deux 5 : p = q a recopié la valeur de q, il n'a pas lié les deux variables. C'est pourquoi changer q juste après ne touche pas p.

Exercice

Même travail avec trois cases.

r = 1
s = r + 1
t = r + s
r = t
print(r, s, t)
Instruction r s t
r = 1
s = r + 1
t = r + s
r = t
Correction
Instruction r s t
r = 1 1
s = r + 1 1 2
t = r + s 1 2 3
r = t 3 2 3

L'affichage est 3 2 3. La dernière ligne change r, mais t avait été calculé avant : il garde 3.

Trace toi-même avec Python Tutor

Ne te contente pas de lire les traces : produis-les. Copie un programme dans Python Tutor, avance pas à pas et observe, à chaque instruction, ce que contiennent les cases mémoire. C'est le meilleur moyen de construire une image juste de ce que fait la machine, et c'est un réflexe à garder pour tout le cours.

Échanger le contenu de deux variables

Tu as déjà traité ce problème en langage machine, sur les cases n°10 et n°11. Rien ne change ici, sauf que les cases ont un nom au lieu d'un numéro.

Exercice

a = 4
b = 7
Écris la suite du programme pour que a vaille 7 et b vaille 4.

Indice

Écris la solution qui vient spontanément, a = b puis b = a, et déroule-la ligne par ligne. Quelle valeur n'existe déjà plus après la première ligne ?

Correction

La solution spontanée échoue :

a = b   # a devient 7, et le 4 est perdu
b = a   # b devient 7 aussi. Raté.

En rangeant b dans a, on a écrasé le 4, et plus rien ne permet de le retrouver. Il faut le mettre de côté avant :

temp = a    # on sauvegarde 4
a = b       # a devient 7
b = temp    # b récupère 4

C'est exactement la case de passage du langage machine.

La variable de passage

Trois affectations, et une variable de plus : c'est le prix d'un échange, et il n'y a pas moins cher. La raison est la même que dans la machine : une case ne contient qu'une valeur à la fois, donc celle qu'on va écraser doit être copiée ailleurs avant de l'être.

Exercice

Trois variables valent a = 1, b = 2, c = 3. On veut les faire tourner : à la fin, a doit valoir 3, b doit valoir 1 et c doit valoir 2. Chaque variable reçoit la valeur de la précédente.

Écris les instructions, sans utiliser le raccourci de Python.

Indice

Une seule valeur est menacée dès la première affectation que tu écris : celle de la variable que tu écrases en premier. Mets-la de côté avant.

Correction
t = c    # on sauvegarde 3, la valeur qu'on va écraser
c = b    # c devient 2
b = a    # b devient 1
a = t    # a récupère 3

L'ordre compte : chaque ligne écrase une valeur, donc on part de celle qu'on a sauvegardée et on remonte. Si tu avais commencé par a = t avant d'avoir servi b, tu aurais perdu le 1.

Exercice

a = 1
b = 2
c = 3

t = a
a = b
b = c
c = t
Que valent a, b et c à la fin ? Que fait ce programme, comparé à celui de l'exercice précédent ?

Correction

a vaut 2, b vaut 3, c vaut 1.

Il fait tourner les trois valeurs dans l'autre sens : chaque variable reçoit la valeur de la suivante, et non de la précédente. La méthode est la même, seule la valeur mise de côté change : ici c'est celle de a, puisque c'est a qu'on écrase en premier.

Le type d'une variable

Toute variable a un type, qui indique le genre d'information qu'elle contient :

Type Exemple Signification
int age = 16 un entier relatif, de l'anglais integer
float taille = 1.75 un nombre à virgule
str nom = "Alice" une chaîne de caractères
bool majeur = True un booléen

Python devine le type d'après la valeur rangée, et cela s'appelle l'inférence de type. On peut aussi l'écrire explicitement :

age: int = 16

Rien n'y oblige, mais quand un programme s'allonge on finit par ne plus savoir ce que contient quoi. Prends l'habitude de noter le type à la création d'une variable.

Et pour savoir ce qu'une variable contient réellement, type le dit :

age = 16
print(type(age))   # affiche <class 'int'>

Exercice

Donne le type de chacune de ces quatre variables.

a = 7
b = 7.0
c = "7"
d = True
Correction

a est un int, b un float, c un str, d un bool.

7, 7.0 et "7" sont trois valeurs de types différents, alors qu'on y lit le même chiffre. Les guillemets de c en font une chaîne de caractères, c'est-à-dire du texte, et non un nombre : on ne peut pas calculer avec. La fin de cette page traite les entiers, et la page suivante les chaînes de caractères.

Exercice

Même question sur quatre autres variables.

a = 0
b = "16"
c = False
d = 3.0
Correction

a est un int, b un str, c un bool, d un float.

Deux remarques. 3.0 est un float bien qu'il n'ait aucune décimale après la virgule : c'est la présence du point qui le décide, pas la valeur. Et "16" est du texte, pas le nombre seize, à cause de ses guillemets.

Calculer avec des entiers

Le type int vient avec ses opérateurs. Les voici tous, et il n'y en a pas d'autres au programme de cette année.

Opération Symbole Exemple
addition + 17 + 5 donne 22
soustraction - 17 - 5 donne 12
multiplication * 17 * 5 donne 85
quotient entier // 17 // 5 donne 3
reste % 17 % 5 donne 2
puissance ** 17 ** 2 donne 289
division / 17 / 5 donne 3.4

Les priorités sont celles des mathématiques : la puissance d'abord, puis la multiplication et les divisions, puis l'addition et la soustraction. Les parenthèses passent avant tout.

/ ne rend jamais un entier

C'est le seul opérateur de cette table qui change de type : 10 / 2 donne 5.0, un float, et non 5. Même quand la division est exacte, même quand le résultat est un nombre rond.

Pour obtenir un entier, c'est // qu'il faut écrire : 10 // 2 donne 5.

Exercice

a = 17
b = 5
Que valent a + b, a * b, a // b, a % b et a ** 2 ?

Correction

22, 85, 3, 2 et 289.

Exercice

Que valent ces quatre expressions ?

2 + 3 * 4
(2 + 3) * 4
10 - 2 * 3
2 ** 3 * 2
Correction

14, 20, 4 et 16.

Dans la première, la multiplication passe avant l'addition. Dans la deuxième, les parenthèses renversent l'ordre. Dans la quatrième, la puissance se calcule d'abord, ce qui donne 8 * 2.

Exercice

x = 10 / 2
y = 10 // 2
Que valent x et y ? De quel type est chacune des deux variables ?

Correction

x vaut 5.0 et c'est un float. y vaut 5 et c'est un int.

Les deux valeurs se lisent « cinq », mais elles ne sont pas du même type et Python ne les écrit pas pareil.

Exercice

a = 7 / 7
b = 6 / 3
c = 9 // 2
Que vaut chaque variable, et de quel type est-elle ?

Correction

a vaut 1.0, b vaut 2.0, tous deux des float : / rend un float même quand la division tombe juste. c vaut 4, un int : 9 // 2 donne le quotient entier, la moitié de 9 étant 4 et des restes.

Écrire plus court : +=

Ajouter quelque chose à une variable est si fréquent que Python offre une écriture abrégée pour le faire.

a = a + 3    # l'écriture longue
a += 3       # exactement la même chose

On appelle cela une affectation combinée. Il en existe pour les autres opérateurs, -=, *= et les suivantes, mais += est de loin la plus utilisée, parce qu'ajouter à un total ou à un compteur est ce qu'on fait le plus souvent.

Ce que fait vraiment la machine

Rien de nouveau : a += 3 lit a, calcule, et range le résultat dans a. C'est le LDA, le calcul, puis le STA que tu connais déjà. Seule l'écriture raccourcit, pas le travail de la machine.

Conséquence à retenir : la variable doit exister avant. a += 3 commence par lire a, donc si a n'a jamais reçu de valeur, le programme s'arrête sur une erreur.

Exercice

a = 5
a += 3
a += 3
a += 10
Que vaut a après chaque ligne ?

Correction

5, puis 8, puis 11, puis 21.

Chaque ligne repart de la valeur courante de a et lui ajoute quelque chose. C'est ainsi qu'on accumule dans une variable.

Exercice

c = 10
c += 7
Réécris la deuxième ligne en écriture longue, et donne la valeur de c. Que se passerait-il si la première ligne n'existait pas ?

Correction

c += 7 s'écrit c = c + 7, et c vaut 17.

Sans la première ligne, le programme s'arrête sur une erreur : c += 7 commence par lire c, et il n'y a rien à lire dans une case qui n'a jamais été créée.

La division euclidienne

// et % sont les deux moitiés d'une même opération, celle que tu as apprise à l'école primaire.

Le vocabulaire, d'abord. On divise le dividende par le diviseur, ce qui donne un quotient et un reste.

Les quatre noms de la division posée : dividende, diviseur, quotient et reste

Voici la division de 163 par 5, posée en entier.

Division posée de 163 par 5 : le quotient est 32 et le reste est 3

Le quotient est 32, et on l'obtient par 163 // 5. Le reste est 3, et on l'obtient par 163 % 5.

Les deux propriétés à retenir

Pour une division de n par d :

  • d * (n // d) + (n % d) redonne toujours n ;
  • le reste est toujours plus petit que le diviseur. Un reste de 5 ou plus dans une division par 5 voudrait dire qu'il reste de quoi faire un paquet de plus, donc que le quotient était faux.

Ce que cela veut dire

J'ai 163 chocolats et je veux les ranger dans des boîtes de 5. Je remplis 32 boîtes, et il me reste 3 chocolats.

\(163 = 5 \times 32 + 3\)

Exercice

On veut ranger 47 bonbons dans des sachets de 6.

Combien de sachets pleins, et combien de bonbons en trop ? Écris les deux calculs Python qui donnent ces deux nombres, puis vérifie ton résultat avec la première propriété.

Correction

47 // 6 donne 7 sachets pleins, et 47 % 6 donne 5 bonbons en trop.

Vérification : 6 * 7 + 5 redonne bien 47. Et 5 est plus petit que 6, donc on ne peut pas faire un sachet de plus.

Exercice

n = 100
d = 7
q = n // d
r = n % d
Que valent q et r ? Que vaut d * q + r ?

Correction

q vaut 14 et r vaut 2. d * q + r vaut 7 * 14 + 2, donc 100, c'est-à-dire n.

Exercice

Peut-on écrire un programme où n % 5 vaut 7 ? Quelles valeurs cette expression peut-elle prendre ?

Correction

Non, c'est impossible pour un n positif. Le reste d'une division par 5 est toujours plus petit que 5, donc l'expression ne peut valoir que 0, 1, 2, 3 ou 4.

Exercice

Que valent 14 % 2 et 15 % 2 ? Et plus généralement, que t'apprend n % 2 sur n ?

Correction

14 % 2 vaut 0 et 15 % 2 vaut 1.

n % 2 vaut 0 quand n est pair et 1 quand il est impair, puisque ce sont les deux seuls restes possibles d'une division par 2. C'est la façon habituelle de tester la parité en programmation.

Comment un entier est écrit en mémoire

Comme toute information, un entier est stocké sous forme d'une suite de bits groupés en octets. Deux fonctions donnent cette écriture.

print(bin(157))   # affiche 0b10011101
print(hex(157))   # affiche 0x9d

bin donne l'écriture binaire, hex l'écriture hexadécimale. Les préfixes 0b et 0x ne font pas partie du nombre : ils sont là pour dire dans quelle base lire ce qui suit, puisque 10011101 tout seul serait ambigu.

Exercice

n = 200
print(bin(n))
Qu'affiche ce programme ? Combien de bits occupe cette écriture, et tient-elle sur un octet ?

Correction

Il affiche 0b11001000.

Huit bits après le préfixe, donc exactement un octet. C'est cohérent avec ce qu'on a vu plus haut : 200 dépasse 127, donc 7 bits ne suffisent pas, et il reste sous 255, donc 8 bits suffisent.

Exercice

n = 157
print(hex(n))
Qu'affiche ce programme ? Retrouve ce résultat à la main depuis l'écriture binaire 10011101.

Correction

Il affiche 0x9d.

On groupe les bits par quatre en partant de la droite : 1001 et 1101. Le premier groupe vaut \(8 + 1\), soit 9, et le second \(8 + 4 + 1\), soit 13, qui s'écrit d en hexadécimal. D'où 9d.

Faire entrer une information : input

Jusqu'ici, toutes les valeurs étaient écrites dans le programme. Pour qu'une information entre dans la machine pendant qu'elle tourne, il faut input.

Ce que fait vraiment la machine

C'est l'instruction INP (input) du Little Man Computer : « attends une valeur et mets-la dans l'accumulateur ». saisie = input() enchaîne donc INP puis STA, exactement comme print(truc) enchaînait LDA puis OUT.

Le texte entre parenthèses est la question posée à l'écran avant d'attendre.

saisie = input("Un nombre : ")

input rend toujours du texte

Et c'est là que input cesse de ressembler à INP. Le INP du simulateur mettait un nombre dans l'accumulateur. input, lui, rend du texte, toujours, même quand tu as tapé 7. Tu peux le vérifier avec type.

saisie = input("Un nombre : ")
print(type(saisie))

Si on tape 7, ce programme affiche <class 'str'>, et pas <class 'int'>.

La conséquence est immédiate : on ne peut pas calculer avec.

n = input("Un nombre : ")
print(n + 1)

Ce programme s'arrête sur une erreur, TypeError: can only concatenate str (not "int") to str. La machine refuse d'ajouter le nombre 1 à du texte, et elle a raison de refuser : ce sont deux informations de natures différentes.

La méthode, et elle ne change jamais

On convertit le texte en entier avec int.

saisie = input("Un nombre : ")
n = int(saisie)
print(n + 1)

Si on tape 7, ce programme affiche 8.

Garde toujours les deux lignes, l'une pour la saisie, l'autre pour la conversion. Elles font deux choses différentes, et les voir séparément est ce qui permet de savoir laquelle a échoué quand quelque chose ne marche pas.

La règle à retenir

input rend du texte. Si tu veux un nombre, tu le convertis à la ligne suivante, avec int.

Fais-le systématiquement, dès la saisie. Une saisie non convertie ne se voit pas tout de suite : elle se voit plus loin, au premier calcul, sous la forme d'une erreur dont la cause est quelques lignes plus haut.

Et ce « texte », qu'est-ce que c'est au juste ?

Il a un nom, un type (str), et des opérations qui lui sont propres. C'est l'objet du cours suivant, Les chaînes de caractère. Pour l'instant, retiens seulement la conversion.

Exercice

saisie = input("Un nombre : ")
n = int(saisie)
print(n + 1)
print(n)
On tape 41. Qu'affiche ce programme, dans l'ordre ? Et que vaut n à la fin ?

Correction

Il affiche 42, puis 41.

n vaut toujours 41. Le premier print a calculé n + 1, l'a envoyé sur la sortie et l'a perdu, sans rien ranger : c'est le même constat que pour print(a + b) plus haut.

Exercice

saisie = input("a : ")
a = int(saisie)
saisie = input("b : ")
b = int(saisie)
print(a + b)
On tape 3 puis 8. Qu'affiche ce programme ? Et si on tape 8 puis 3 ?

Correction

11 dans les deux cas. L'ordre de saisie change ce que contiennent a et b, mais pas leur somme.

Attention : il n'en irait pas de même avec a - b, qui donnerait -5 dans un cas et 5 dans l'autre.

Exercice

n = input("Un nombre : ")
m = int(n)
print(type(n))
print(type(m))
On tape 12. Qu'affichent les deux print ?

Correction

<class 'str'> puis <class 'int'>.

int(n) ne modifie pas n : il en fabrique une nouvelle valeur, rangée dans m. La case n contient toujours du texte. C'est le même mécanisme que b = a + 1, qui laisse a intact.

Exercices

Comment faire ces exercices

Tout se passe dans un seul fichier, python/exos_variables.py, et chaque exercice commence par une ligne qui le repère :

print("Exercice 1")

Écris chaque nouvel exercice tout en haut du fichier, au-dessus des précédents. Celui sur lequel tu travailles s'exécute alors en premier, et tu n'as pas à retaper les saisies de tous les autres avant d'arriver à lui. Ton fichier se lit donc à l'envers, du plus récent au plus ancien, et les lignes Exercice 1, Exercice 2... te disent quel résultat appartient à quel exercice.

Chaque énoncé donne un exemple de saisie et le résultat attendu : c'est avec lui que tu vérifies ton programme.

Les exercices 1 à 8 sont à faire, les 9 à 12 sont de l'entraînement, et les 13 et 14 sont des bonus.

Arrêter un programme en cours : Ctrl+C

Quand tu as vu le résultat qui t'intéresse, inutile de répondre aux saisies des exercices suivants. Clique dans le terminal et appuie sur Ctrl+C.

Cette combinaison envoie au programme un signal qui lui demande de s'arrêter immédiatement, où qu'il en soit. Python affiche alors quelques lignes qui se terminent par KeyboardInterrupt : c'est normal, cela veut seulement dire « arrêté au clavier ». Tu n'as rien cassé.

Exercice 1 (à faire)

Demande un nombre, puis affiche son double.

Avec 7, le programme affiche 14.

Correction
print("Exercice 1")
saisie = input("Un nombre : ")
n = int(saisie)
print(n * 2)

Exercice 2 (à faire)

Demande deux nombres, puis affiche leur somme, et en dessous leur produit.

Avec 3 puis 5, le programme affiche 8 puis 15.

Correction
print("Exercice 2")
saisie = input("Premier nombre : ")
a = int(saisie)
saisie = input("Deuxième nombre : ")
b = int(saisie)
print(a + b)
print(a * b)

Exercice 3 (à faire)

Demande un nombre de secondes, puis affiche combien cela fait de minutes entières, et en dessous combien il reste de secondes.

Avec 163, le programme affiche 2 puis 43.

Correction
print("Exercice 3")
saisie = input("Un nombre de secondes : ")
s = int(saisie)
print(s // 60)
print(s % 60)

Exercice 4 (à faire)

Demande un prix en centimes, puis affiche le nombre d'euros, et en dessous les centimes restants.

Avec 1250, le programme affiche 12 puis 50.

Correction
print("Exercice 4")
saisie = input("Un prix en centimes : ")
centimes = int(saisie)
print(centimes // 100)
print(centimes % 100)

Exercice 5 (à faire)

Demande deux nombres x et y, échange leurs contenus, puis affiche x et en dessous y.

Avec 3 puis 8, le programme affiche 8 puis 3.

Correction
print("Exercice 5")
saisie = input("x : ")
x = int(saisie)
saisie = input("y : ")
y = int(saisie)
temp = x
x = y
y = temp
print(x)
print(y)

Sans la variable temp, la première affectation écraserait la valeur qu'il faut garder.

Exercice 6 (à faire)

Demande un nombre, puis affiche son écriture binaire, et en dessous son écriture hexadécimale.

Avec 157, le programme affiche 0b10011101 puis 0x9d.

Correction
print("Exercice 6")
saisie = input("Un nombre : ")
n = int(saisie)
print(bin(n))
print(hex(n))

Exercice 7 (à faire)

Demande un nombre de bonbons, puis la taille d'un sachet. Affiche le nombre de sachets pleins, et en dessous le nombre de bonbons en trop.

Avec 47 puis 6, le programme affiche 7 puis 5.

Correction
print("Exercice 7")
saisie = input("Nombre de bonbons : ")
bonbons = int(saisie)
saisie = input("Taille d'un sachet : ")
taille = int(saisie)
print(bonbons // taille)
print(bonbons % taille)

Exercice 8 (à faire)

Demande un nombre et affiche son reste dans la division par 2.

Avec 15, le programme affiche 1. Avec 14, il affiche 0.

Correction
print("Exercice 8")
saisie = input("Un nombre : ")
n = int(saisie)
print(n % 2)

Ce reste ne peut valoir que 0 ou 1 : il dit si le nombre est pair ou impair.

Exercice 9 (entraînement)

Demande un nombre, augmente-le de 10 en réutilisant la même variable, puis affiche-le.

Avec 32, le programme affiche 42.

Correction
print("Exercice 9")
saisie = input("Un nombre : ")
n = int(saisie)
n += 10
print(n)

n = n + 10 fait exactement la même chose.

Exercice 10 (entraînement)

Demande un âge, puis affiche cet âge dans dix ans, et en dessous cet âge il y a dix ans.

Avec 17, le programme affiche 27 puis 7.

Correction
print("Exercice 10")
saisie = input("Ton âge : ")
age = int(saisie)
print(age + 10)
print(age - 10)

Exercice 11 (entraînement)

Demande trois notes entières. Affiche leur moyenne entière, et en dessous le reste de la division de leur total par 3.

Avec 12, 15 puis 20, le programme affiche 15 puis 2.

Correction
print("Exercice 11")
saisie = input("Note 1 : ")
a = int(saisie)
saisie = input("Note 2 : ")
b = int(saisie)
saisie = input("Note 3 : ")
c = int(saisie)
total = a + b + c
print(total // 3)
print(total % 3)

Le total vaut 47, et \(3 \times 15 + 2 = 47\). La moyenne entière perd le reste : ce n'est pas la même chose que la moyenne exacte, qui vaudrait 15.666....

Exercice 12 (entraînement)

Demande un nombre. Affiche le type de ce que input a rendu, puis convertis-le et affiche le type du résultat.

Avec 7, le programme affiche <class 'str'> puis <class 'int'>.

Correction
print("Exercice 12")
saisie = input("Un nombre : ")
print(type(saisie))
nombre = int(saisie)
print(type(nombre))

Exercice 13 (bonus)

Demande un prix en centimes. Affiche le nombre de pièces de 2 euros, puis le nombre de pièces de 1 euro, puis les centimes restants, en utilisant le moins de pièces possible.

Avec 1370, le programme affiche 6, puis 1, puis 70.

Correction
print("Exercice 13")
saisie = input("Un prix en centimes : ")
centimes = int(saisie)
pieces2 = centimes // 200
reste = centimes % 200
pieces1 = reste // 100
restant = reste % 100
print(pieces2)
print(pieces1)
print(restant)

La méthode se répète : on prend le quotient par la valeur de la pièce, puis on continue sur le reste. Une pièce de 2 euros vaut 200 centimes, d'où le 200.

Exercice 14 (bonus)

Demande un nombre, puis affiche son chiffre des unités, et en dessous son chiffre des dizaines.

Avec 482, le programme affiche 2 puis 8.

Correction
print("Exercice 14")
saisie = input("Un nombre : ")
n = int(saisie)
print(n % 10)
print(n // 10 % 10)

Le chiffre des unités est le reste de la division par 10. Pour les dizaines, on enlève d'abord les unités avec n // 10, ce qui décale le nombre d'un rang, et on reprend le reste par 10.