Leçon 01-2 — Types, nombres, input() et conversions
1. Objectif
À la fin de cette leçon tu sauras : reconnaître le type d'une valeur (int, float, str, bool) et le vérifier avec type(), calculer avec les opérateurs arithmétiques (y compris //, %, **), demander une donnée à l'utilisateur avec input(), et convertir entre types avec int(), float() et str() — en sachant exactement quand une conversion échoue et pourquoi.
2. Pourquoi c'est important
Le bug le plus fréquent des débutants — de très loin — est un mélange de types : additionner un texte et un nombre, calculer avec le résultat brut d'un input(), comparer des centimes en float. Tous les programmes réels manipulent des données qui arrivent sous forme de texte (saisie clavier, fichier, réponse web ⏩ niveau 9) et doivent les convertir en nombres avant de calculer. Cette leçon t'installe le réflexe qui t'évitera des heures de débogage : quel est le type de cette valeur, là, maintenant ?
3. Explication simple
En Python, chaque valeur a un type : sa nature, ce qu'on a le droit de faire avec.
42 # int : nombre entier
3.14 # float : nombre à virgule (le POINT, pas la virgule !)
"42" # str : texte — même s'il ressemble à un nombre
True # bool : vrai ou faux (majuscule obligatoire)
La fonction type() te dit la nature d'une valeur :
print(type(42)) # <class 'int'>
print(type("42")) # <class 'str'>
Retiens l'image : le type, c'est l'uniforme de la valeur. "42" porte l'uniforme « texte » : tu peux le coller à un autre texte, mais pas faire de maths avec. 42 porte l'uniforme « nombre » : l'inverse. Pour changer d'uniforme, il faut une conversion explicite : int("42") donne 42, str(42) donne "42". Python ne convertit jamais à ta place dans une addition — il préfère planter que deviner.
Dernière brique : input("question ") affiche la question, attend que l'utilisateur tape quelque chose, et retourne ce qu'il a tapé — toujours sous forme de str, même si l'utilisateur a tapé 42.
4. Explication approfondie
a) Les quatre types simples, précisément.
int: entiers, positifs ou négatifs, sans limite de taille en Python (tu peux calculer2 ** 1000sans problème).float: nombres à virgule flottante, stockés en binaire sur 64 bits. Précision limitée — voir le point (c), c'est important.str: texte, entre guillemets"..."ou apostrophes'...'(équivalents).bool: exactement deux valeurs,TrueetFalse. Unboolest le résultat naturel d'une comparaison :
print(5 > 3) # True
print(type(5 > 3)) # <class 'bool'>
print(0.1 + 0.2 == 0.3) # False (!) — « == » teste l'égalité
⏩ Les comparaisons (==, <, >=…) et les décisions if sont le cœur du niveau 2. Ici tu dois seulement savoir que True/False existent, que c'est un type, et surtout que == (teste l'égalité) n'est pas = (assigne). Cette confusion produira des bugs au niveau 2 ; grave la différence maintenant.
b) Les opérateurs arithmétiques.
| Opérateur | Nom | Exemple | Résultat |
|---|---|---|---|
+ - * | addition, soustraction, multiplication | 7 * 2 | 14 |
/ | division vraie | 7 / 2 | 3.5 |
// | division entière (quotient) | 7 // 2 | 3 |
% | modulo (reste de la division) | 7 % 2 | 1 |
** | puissance | 2 ** 10 | 1024 |
Deux subtilités que tout le monde rate :
/retourne TOUJOURS unfloat, même quand la division tombe juste :8 / 2vaut4.0, pas4. Si tu veux un entier, c'est//.//arrondit vers le bas, pas vers zéro :-7 // 2vaut-4(pas-3). Rare au début, mais autant le savoir tout de suite.
Le couple // + % est l'outil de décomposition : 130 // 60 donne 2 (heures) et 130 % 60 donne 10 (minutes restantes). Tu t'en serviras sans arrêt.
c) Les flottants ne sont pas exacts — honnêtement.
print(0.1 + 0.2) # 0.30000000000000004
Ce n'est pas un bug de Python : c'est vrai dans quasiment tous les langages. Un float est stocké en binaire, et 0.1 en binaire est un nombre infini périodique (comme 1/3 = 0.3333… en décimal). L'ordinateur le tronque, donc il stocke une valeur très proche de 0.1, pas 0.1. Additionne deux approximations, tu obtiens une approximation.
Conséquences pratiques :
- Pour afficher proprement :
round(x, 2)arrondit à 2 décimales, ou le format f-stringf"{x:.2f}"(vu en section 5). - Ne jamais tester l'égalité exacte de deux
float(⏩ niveau 2, on verra comment comparer « à peu près »). - Pour de l'argent en vrai logiciel, on compte en centimes entiers ou avec un type spécialisé (⏩ module
decimal, niveau 5). Pour nos exercices,round()suffit.
Note honnête sur round() : sur le cas pile-poil .5, il arrondit vers le chiffre pair (round(2.5) vaut 2, round(3.5) vaut 4). C'est voulu (norme de calcul scientifique) et sans importance pour nous — mais si tu le croises, ce n'est pas un bug.
d) input() retourne TOUJOURS une str.
Toujours. Même si l'utilisateur tape 42. Même s'il tape 3.14. La règle mécanique à t'installer dans les doigts :
age = int(input("Ton âge ? ")) # saisie d'un entier
height = float(input("Ta taille ? ")) # saisie d'un nombre à virgule
name = input("Ton prénom ? ") # saisie de texte : pas de conversion
e) Les conversions et leurs limites.
int("42")→42;int(" 42 ")→42(les espaces autour sont tolérés).int("abc")→ValueError: la valeur ne ressemble pas à un entier.int("3.5")→ValueErroraussi !int()depuis une chaîne n'accepte que des entiers. Pour passer par la virgule :int(float("3.5"))→3.int(3.9)→3: depuis unfloat,int()tronque (coupe la partie décimale), il n'arrondit pas. Pour arrondir :round(3.9)→4.float("3.5")→3.5;float("42")→42.0.str(42)→"42": marche toujours, aucune valeur ne refuse de devenir texte.
Difficulté honnête : cette leçon contient plus de pièges que la 01-1 (/ qui donne un float, int("3.5") qui plante, 0.1 + 0.2, l'input jamais converti). Prévois deux sessions : une pour les sections 1–7 en tapant tous les exemples, une pour les exercices. Le point (c) n'a pas besoin d'être maîtrisé en profondeur — retiens le symptôme et les deux remèdes (round, :.2f).
5. Exemples commentés
Exemple 1 — type() sur des littéraux
print(type(42)) # <class 'int'>
print(type(3.14)) # <class 'float'>
print(type("3.14")) # <class 'str'> ← guillemets = texte, point final
print(type(True)) # <class 'bool'>
print(type(7 / 7)) # <class 'float'> ← / donne TOUJOURS un float
Exemple 2 — le tableau des divisions, vérifié
print(7 / 2) # 3.5
print(8 / 2) # 4.0 ← float même quand ça tombe juste
print(7 // 2) # 3 ← quotient entier
print(7 % 2) # 1 ← reste
print(2 ** 10) # 1024
Exemple 3 — décomposer avec // et %
total_minutes = 130
hours = total_minutes // 60 # 2 : combien d'heures complètes
minutes = total_minutes % 60 # 10 : ce qui reste
print(f"{total_minutes} min = {hours} h {minutes} min")
Sortie : 130 min = 2 h 10 min
Exemple 4 — les flottants approximatifs, et les deux remèdes
result = 0.1 + 0.2
print(result) # 0.30000000000000004 ← brut : moche mais honnête
print(round(result, 2)) # 0.3 ← remède 1 : round()
print(f"{result:.2f}") # 0.30 ← remède 2 : format .2f
Le :.2f dans une f-string signifie « affiche ce nombre avec exactement 2 chiffres après le point ». C'est un format d'affichage : la valeur stockée reste approximative, seul l'affichage est propre.
Exemple 5 — input() et la conversion obligatoire
raw = input("Année de naissance ? ") # l'utilisateur tape : 1984
print(type(raw)) # <class 'str'> ← toujours !
birth_year = int(raw) # conversion explicite
age = 2026 - birth_year
print(f"Tu as environ {age} ans.") # Tu as environ 42 ans.
En pratique on écrit directement birth_year = int(input("Année ? ")) — mais quand tu débogues, séparer les deux lignes te permet de print(type(raw)).
Exemple 6 — concaténer, c'est du texte ; additionner, c'est des nombres
a = "5"
b = "3"
print(a + b) # 53 ← + entre deux str : COLLE les textes
print(int(a) + int(b)) # 8 ← + entre deux int : ADDITIONNE
print(str(4) + "2") # 42 ← le texte "42", pas le nombre !
Même symbole +, deux métiers différents selon les uniformes en présence.
6. Erreurs fréquentes
1) Additionner un texte et un nombre
price = "5"
total = price + 3
# TypeError: can only concatenate str (not "int") to str
Python voit un str à gauche, comprend « concaténation », puis refuse de coller un int à un texte. Correction : int(price) + 3 → 8. (Et si tu voulais du texte : price + str(3) → "53".) Pourquoi Python ne devine pas ? Parce que les deux réponses (8 et "53") sont légitimes — il préfère t'obliger à choisir.
2) Oublier de convertir un input()
age = input("Ton âge ? ") # l'utilisateur tape 42... mais age vaut "42"
print(age + 1)
# TypeError: can only concatenate str (not "int") to str
C'est l'erreur n°1, la même que ci-dessus, mais camouflée : le programme marche jusqu'à la saisie, puis plante au calcul. Correction : age = int(input("Ton âge ? ")).
3) int() sur une valeur non convertible
count = int("abc")
# ValueError: invalid literal for int() with base 10: 'abc'
ValueError ≠ TypeError : ici le type de l'argument est acceptable (une str), c'est la valeur qui ne ressemble pas à un entier. Le message te montre la valeur coupable entre apostrophes — regarde-la toujours : c'est souvent une chaîne vide '' (l'utilisateur a juste appuyé sur Entrée).
4) int("3.5") plante aussi
size = int("3.5")
# ValueError: invalid literal for int() with base 10: '3.5'
Piège vicieux : int(3.5) (depuis un float) marche et donne 3, mais int("3.5") (depuis une str) plante. Une chaîne doit ressembler à un entier, point. Correction en deux étapes : int(float("3.5")) → 3.
5) S'attendre à un int après une division /
half = 8 / 2
print(half) # 4.0 ← pas d'erreur, mais ce n'est PAS 4 (c'est un float)
Bug silencieux : aucun traceback, mais half est un float, et ton affichage montre 4.0 là où tu attendais 4. Si tu veux un entier : 8 // 2.
6) Écrire = en croyant tester une égalité
age = 18 # ceci ASSIGNE 18 à age — ça ne « vérifie » rien du tout
Tu n'as pas encore l'outil pour tester (==, ⏩ niveau 2), donc le piège est encore invisible — mais installe le vocabulaire dès maintenant : = assigne, == compare. Au niveau 2, if age = 18: te donnera une SyntaxError ; tu sauras immédiatement pourquoi.
7. Lire les messages d'erreur
Les deux exceptions emblématiques de cette leçon. Toujours de bas en haut.
TypeError — le mélange de types
Traceback (most recent call last):
File "C:\Users\jtron\Claude\learnpython\age.py", line 2, in <module>
print(age + 1)
~~~~^~~
TypeError: can only concatenate str (not "int") to str
- Dernière ligne :
TypeError= opération interdite entre ces types. Le message dit exactement lesquels : unstrà gauche, unintrefusé. - Au-dessus : fichier
age.py, ligne 2, et le code fautif avec les~~~~^~~qui soulignent l'opération coupable (age + 1, le^sous le+). - Réflexe : remonte à la création de la variable. D'où vient
age? D'uninput()ligne 1 → c'est unestr→ conversion manquante. Le bug se déclare ligne 2 mais se corrige ligne 1. C'est très courant : la ligne du traceback est la ligne du symptôme, pas toujours celle de la cause.
ValueError — la conversion impossible
Traceback (most recent call last):
File "C:\Users\jtron\Claude\learnpython\convert.py", line 1, in <module>
age = int(input("Ton âge ? "))
ValueError: invalid literal for int() with base 10: 'quarante'
- Dernière ligne :
ValueError= bon type d'argument, mauvaise valeur.invalid literal for int()= « ce texte ne ressemble pas à un entier », et la valeur coupable est affichée :'quarante'. - Au-dessus : ligne 1 de
convert.py, c'est leint(...)qui a levé l'erreur — pas l'input(), qui lui a très bien marché. (Remarque : pas de soulignement~~^~~ici — Python ne le montre que lorsqu'il peut isoler une sous-partie de la ligne ; quand toute l'instruction est en cause, il n'y a rien à souligner.) - Réflexe : cette erreur dépend de ce que l'utilisateur tape. Ton programme peut tourner dix fois puis planter à la onzième. On apprendra à s'en protéger avec
try/except(⏩ niveau 5) ; pour l'instant, contente-toi de savoir la lire.
Distinction à mémoriser : TypeError = mauvais uniforme (opération interdite entre ces types). ValueError = bon uniforme, mauvaise valeur.
8. Exercices — faciles
Règles : nouveau fichier par exercice dans
lessons/level-01-bases/exercices/mes-reponses/, nomméex-01-2-a.py, etc. Tape tout à la main. Prédis la sortie AVANT d'exécuter.
a) Sans exécuter, écris sur papier le type ET la valeur affichés par chaque ligne, puis vérifie :
print(type(7))
print(type(7.0))
print(type("7"))
print(type(7 / 7))
print(type(7 // 7))
print(type(7 > 7))
b) Prédis les six sorties, puis vérifie :
print(9 / 2)
print(9 // 2)
print(9 % 2)
print(2 ** 4)
print(10 / 5)
print(10 % 5)
c) Demande à l'utilisateur son prénom puis son année de naissance (input() × 2). Calcule son âge approximatif en 2026 et affiche, en f-string : Bonjour Ada, tu as environ 42 ans. Contrainte : le calcul de l'âge doit être fait sur des int, pas des textes.
d) Crée budget = 100 et spent = 37.5. Affiche Reste : 62.50 € en utilisant le format :.2f. Puis affiche le type de budget - spent — explique en commentaire pourquoi ce n'est pas un int.
9. Exercices — moyens
a) Ce programme est censé afficher Dans 10 ans tu auras 52 ans. mais il plante. Trouve les DEUX bugs sans l'exécuter (ils ne sont pas sur la même ligne), puis corrige :
age = input("Ton âge ? ")
future_age = age + 10
print(f"Dans 10 ans tu auras {future-age} ans.")
b) Prédis la sortie EXACTE des quatre lignes (attention, c'est piégé), puis vérifie et note dans ton journal ce qui t'a surpris :
print(0.1 + 0.2)
print(round(0.1 + 0.2, 2))
print(1.1 + 2.2)
print(f"{1.1 + 2.2:.1f}")
c) Demande une durée en minutes (ex. 200) et affiche-la en heures + minutes : 200 min = 3 h 20 min. Contraintes : // et % obligatoires ; le programme doit afficher des entiers (pas 3.0 h).
10. Exercices — difficiles
a) Demande à l'utilisateur un nombre à TROIS chiffres (ex. 472) et affiche la somme de ses chiffres : 4 + 7 + 2 = 13. Contraintes : traiter le nombre comme un int — interdiction de découper le texte (⏩ le slicing de chaînes arrive en 01-3, on refera cet exercice autrement). Uniquement //, % et les notions de cette leçon.
- Indice 1 : comment obtenir le dernier chiffre d'un nombre entier avec une seule opération ? (
472→2) - Indice 2 : comment « enlever » le dernier chiffre d'un nombre ? (
472→47) Regarde l'exemple 3. - Indice 3 :
units = n % 10, puisn = n // 10, puis recommence la même paire d'opérations sur ce qui reste. Trois chiffres = trois extractions.
11. Mini-projet lié — « convertisseur de devises »
Écris converter.py : un convertisseur euros → dollars à taux fixe.
Comportement attendu (exemple de session) :
=== Convertisseur EUR -> USD ===
Taux : 1 EUR = 1.08 USD
Montant en euros ? 250
250.00 EUR = 270.00 USD
Soit environ 270 dollars tout rond.
Contraintes :
- Le taux est stocké dans une variable
rate = 1.08définie EN HAUT du fichier (une seule ligne à changer si le taux bouge). - Le montant vient d'un
input()converti enfloat(l'utilisateur doit pouvoir taper99.50). - Les deux montants sont affichés avec
:.2f; la dernière ligne utiliseround()pour donner un entier. - f-strings obligatoires. Durée cible : 20–30 min.
Extension (facultative) : ajoute une deuxième conversion dans le même programme — le montant en dollars reconverti en euros — et vérifie que tu retombes (presque !) sur le montant de départ. Si l'affichage brut montre un truc comme 249.99999999999997, tu sais maintenant exactement pourquoi.
12. Correction / méthode de correction
Les solutions détaillées sont dans solutions/serie-01-2-solutions.md.
Méthode : (1) finis TOUS les exercices avant d'ouvrir les solutions ; (2) compare le raisonnement, pas seulement le code — une solution différente qui marche est souvent valable ; (3) pour chaque écart, écris une ligne dans ton journal : « je pensais X, en fait Y » ; (4) refais de tête l'exercice raté, le lendemain.
13. À retenir
- Quatre types simples :
int,float,str,bool—type()pour vérifier. /retourne toujours unfloat; pour un quotient entier c'est//, pour le reste c'est%.- Les
floatsont approximatifs (0.1 + 0.2≠0.3) :round()ou:.2fpour afficher proprement. input()retourne toujours unestr— conversion obligatoire avant calcul.int("abc")etint("3.5")→ValueError;int(3.9)→3(tronque)."5" + 3→TypeError: Python ne convertit jamais à ta place.TypeError= mauvais type pour l'opération ;ValueError= bon type, mauvaise valeur.=assigne,==compare (⏩ niveau 2) — ne les confonds jamais.
14. Questions de révision
- Quel est le type de
8 / 2? Et de8 // 2? Pourquoi la différence ? - Pourquoi
print(0.1 + 0.2)n'affiche-t-il pas0.3? Cite les deux façons d'afficher proprement. - Que retourne
input()si l'utilisateur tape3.14? Quel type ? - Pourquoi
int("3.5")plante-t-il alors queint(3.5)marche ? Que valent-ils ? - Quelle est la différence entre un
TypeErroret unValueError? Donne un exemple de chaque. - La ligne indiquée par un traceback est-elle toujours celle qu'il faut corriger ? Illustre avec l'erreur de l'
input()non converti. - Que valent
130 // 60et130 % 60? À quoi sert ce couple d'opérateurs ? - Quelle est la différence entre
=et==?
15. Checklist de compréhension
- Je donne le type de n'importe quel littéral sans exécuter
type(). - Je connais par cœur les résultats de
9 / 2,9 // 2,9 % 2,2 ** 4. - Je peux expliquer à voix haute pourquoi
0.1 + 0.2n'affiche pas0.3. - J'écris
int(input(...))sans réfléchir quand j'attends un entier. - Je peux provoquer volontairement un
TypeErroret unValueError, et dire lequel est lequel avant de lire le traceback. - Je sais convertir
"3.5"en3(en deux étapes) et expliquer pourquoi il en faut deux. - J'ai fait le mini-projet et il tourne sans erreur, y compris avec
99.50.
Si une case reste vide : refais les exercices de la section correspondante demain, AVANT d'ouvrir la leçon suivante.
16. Commit conseillé
git add lessons/level-01-bases/exercices/mes-reponses/
git commit -m "exercises: complete lesson 01-2 types numbers input conversions"
Puis, si c'est ta fin de session : entrée de journal + git push.