Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 320 minDébutant

Les bases de Python : variables, types, conditions et boucles

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • manipuler les types de base et les convertir ;
  • afficher des résultats lisibles avec les f-strings ;
  • écrire des conditions avec if, elif, else et match ;
  • choisir entre for et while, et sortir d'une boucle avec break.

3 exercices corrigés

Les bases de Python tiennent en quatre notions : les variables qui retiennent des valeurs, les types qui disent ce que sont ces valeurs, les conditions qui choisissent quoi faire, les boucles qui répètent. Ce chapitre les présente avec la syntaxe propre à Python : l'affichage avec les f-strings, la saisie au clavier, if, match, for, while et l'indentation. Si tu découvres la programmation, le cours Algorithmique explique les mêmes notions pas à pas, en pseudo-code puis en Python.

Variables et affectation

Une variable est un nom qui désigne une valeur. On la crée en lui affectant une valeur avec = ; pas de déclaration, pas de type à écrire.

python
serveur = "srv-ad"
disques = 2
serveur = "srv-ad2"        # la variable désigne maintenant une autre valeur
a, b = 3, 8                # deux affectations d'un coup
a, b = b, a                # échange : a vaut 8, b vaut 3
TAUX_ALERTE = 80           # en majuscules : une constante, par convention

Les noms suivent la convention snake_case : minuscules et tirets bas (espace_libre, nb_postes). Ils peuvent contenir des lettres accentuées, mais évite-le : un collègue au clavier QWERTY te maudirait. Les majuscules comptent : Serveur et serveur sont deux variables différentes.

Les types de base

TypeCe qu'il contientExemples
intEntier, sans limite de taille42, -7, 2 ** 100
floatNombre à virgule (flottant), avec un point3.5, 0.1, 1e6
strChaîne de caractères, entre " ou '"srv-ad", 'Chloé'
boolBooléenTrue, False
NoneTypeL'absence de valeurNone

La fonction type() donne le type d'une valeur ; int(), float(), str() et bool() convertissent :

python
>>> type(42)
<class 'int'>
>>> type(3.5)
<class 'float'>
>>> type("Sorbier")
<class 'str'>
>>> type(True)
<class 'bool'>
>>> type(None)
<class 'NoneType'>
>>> 2 ** 100
1267650600228229401496703205376
>>> 0.1 + 0.2
0.30000000000000004
>>> round(0.1 + 0.2, 2)
0.3
>>> int("42") + 1
43
>>> float("3.5")
3.5
>>> int(3.9)
3
>>> str(500) + " Go"
'500 Go'
>>> bool(0), bool(""), bool("non")
(False, False, True)

Trois remarques. Les entiers de Python n'ont pas de limite : 2 ** 100 s'affiche en entier, sans dépassement. Les flottants, eux, sont approchés : 0.1 + 0.2 ne vaut pas tout à fait 0.3, car 0,1 n'a pas d'écriture exacte en binaire (nombres à virgule en binaire) ; pour comparer deux flottants, arrondis ou compare leur écart. Enfin, int(3.9) tronque (3) au lieu d'arrondir : pour arrondir, c'est round().

Opérateurs

OpérateurSensExempleRésultat
+ - *Addition, soustraction, multiplication7 * 321
/Division, toujours flottante7 / 23.5
//Quotient de la division entière7 // 23
%Reste de la division entière (modulo)7 % 21
**Puissance2 ** 8256
== !=Égal, différent3 == 3.0True
< <= > >=Comparaisons"abc" < "abd"True
and or notEt, ou, non logiquesnot (1 > 2)True
inAppartenance"ad" in "srv-ad"True

Python accepte les comparaisons enchaînées comme en maths : 0 <= note <= 20. Et and s'arrête dès que le résultat est connu : dans x != 0 and 10 / x > 2, la division n'est jamais faite si x vaut 0.

Afficher avec print et les f-strings

print() affiche ses arguments séparés par une espace. Pour composer un message avec des valeurs, utilise une f-string : une chaîne précédée de f, où chaque {expression} est remplacée par sa valeur. Après deux-points, un format règle l'affichage.

python
# disque.py : taux d'occupation d'un volume, affiché avec des f-strings
serveur = "srv-fichiers"
total_go = 500
utilise_go = 437.5

taux = utilise_go / total_go * 100
print(f"{serveur} : {utilise_go} Go utilisés sur {total_go} Go")
print(f"Occupation : {taux:.1f} %")
print(f"Libre : {total_go - utilise_go:.2f} Go")
print(f"|{serveur:<15}|{taux:>8.1f}|")
print(f"{taux=}")
text
srv-fichiers : 437.5 Go utilisés sur 500 Go
Occupation : 87.5 %
Libre : 62.50 Go
|srv-fichiers   |    87.5|
taux=87.5
FormatEffetExemple avec 87.5
:.1f1 chiffre après la virgule87.5
:.2f2 chiffres après la virgule87.50
:>8Aligné à droite sur 8 caractères 87.5
:<15Aligné à gauche sur 15 caractères87.5
:,Séparateur des milliers1,234,567 pour 1234567
= après le nomAffiche le nom et la valeur, pour déboguertaux=87.5

Lire une saisie avec input

input() affiche un message, attend la saisie de l'utilisateur et renvoie toujours une chaîne. Pour un nombre, convertis aussitôt :

python
# saisie.py : lire deux nombres au clavier
total = int(input("Taille du volume (Go) ? "))
utilise = float(input("Espace utilisé (Go) ? "))
print(f"Occupation : {utilise / total * 100:.1f} %")
text
Taille du volume (Go) ? 500
Espace utilisé (Go) ? 437.5
Occupation : 87.5 %

Si l'utilisateur tape autre chose qu'un nombre, la conversion échoue et le script s'arrête :

text
Taille du volume (Go) ? 500 Go
Traceback (most recent call last):
  File "/home/etudiant/cours-python/saisie.py", line 2, in <module>
    total = int(input("Taille du volume (Go) ? "))
ValueError: invalid literal for int() with base 10: '500 Go'

Le chapitre 8 montre comment intercepter cette erreur et redemander. Dans un script d'administration, on évite d'ailleurs input() : un script planifié n'a personne pour répondre. Les valeurs arrivent par la ligne de commande (chapitre 10) ou par un fichier.

Conditions : if, elif, else

python
# alerte.py : niveau d'alerte selon le taux d'occupation d'un disque
taux = 87.5

if taux >= 90:
    niveau = "CRITIQUE"
elif taux >= 80:
    niveau = "ALERTE"
else:
    niveau = "OK"

print(f"Occupation {taux} % : {niveau}")
text
Occupation 87.5 % : ALERTE

Les conditions sont testées dans l'ordre et seule la première vraie s'exécute : 87,5 n'atteint pas 90, mais atteint 80, donc ALERTE. Écris toujours les seuils du plus exigeant au moins exigeant ; dans l'ordre inverse, taux >= 80 attraperait aussi les disques à 95 %. Les deux-points en fin de ligne et l'indentation du bloc sont obligatoires.

Pour une affectation simple selon une condition, l'expression conditionnelle tient sur une ligne : etat = "en ligne" if repond else "hors ligne".

match : choisir selon une valeur

Depuis Python 3.10, match compare une valeur à une série de motifs, comme le switch d'autres langages, en plus puissant. | sépare plusieurs valeurs possibles, _ attrape tout le reste et if ajoute une condition à un motif :

python
# http_codes.py : classer des codes de statut HTTP avec match
for code in [200, 201, 301, 404, 500, 418]:
    match code:
        case 200 | 201 | 204:
            sens = "succès"
        case 301 | 302 | 308:
            sens = "redirection"
        case 401 | 403:
            sens = "accès refusé"
        case 404:
            sens = "ressource introuvable"
        case _ if 500 <= code <= 599:
            sens = "erreur du serveur"
        case _:
            sens = "autre code"
    print(code, sens)
text
200 succès
201 succès
301 redirection
404 ressource introuvable
500 erreur du serveur
418 autre code

Pas besoin de break : seul le premier motif qui correspond s'exécute. Les codes HTTP sont détaillés dans le cours API REST.

Boucles for et while

La boucle for parcourt les éléments d'une séquence : une liste, une chaîne, ou les nombres produits par range(). La boucle while répète tant qu'une condition est vraie.

python
# boucles.py : for, range et while
for serveur in ["srv-ad", "srv-ad2", "srv-fichiers"]:
    print("Contrôle de", serveur)

print(list(range(5)))
print(list(range(1, 11, 3)))

# Nombre d'adresses utilisables selon la longueur du préfixe
for prefixe in range(24, 31):
    print(f"/{prefixe} : {2 ** (32 - prefixe) - 2} hôtes")

# while : en combien d'années 100 Go de données, +20 % par an, dépassent 500 Go ?
volume = 100
annees = 0
while volume <= 500:
    volume = volume * 1.2
    annees = annees + 1
print(f"{annees} ans ({volume:.1f} Go)")
text
Contrôle de srv-ad
Contrôle de srv-ad2
Contrôle de srv-fichiers
[0, 1, 2, 3, 4]
[1, 4, 7, 10]
/24 : 254 hôtes
/25 : 126 hôtes
/26 : 62 hôtes
/27 : 30 hôtes
/28 : 14 hôtes
/29 : 6 hôtes
/30 : 2 hôtes
9 ans (516.0 Go)

range(fin) produit les entiers de 0 à fin - 1 ; range(debut, fin, pas) commence à debut et avance de pas. La borne de fin est toujours exclue : range(24, 31) s'arrête à 30. La boucle des préfixes retrouve le nombre d'hôtes d'un sous-réseau, 2 puissance le nombre de bits d'hôte, moins les adresses de réseau et de diffusion (masque de sous-réseau).

Utilise for quand tu sais sur quoi tu boucles, while quand tu boucles jusqu'à ce qu'un événement arrive. Dans un while, vérifie que le corps fait avancer la condition vers faux : sinon, la boucle ne s'arrête jamais (Ctrl+C interrompt le script).

break et continue

break quitte la boucle immédiatement ; continue passe directement au tour suivant. enumerate() numérote les éléments au passage :

python
# break_continue.py : sortir d'une boucle, sauter un tour
codes = [200, 200, 304, 200, 500, 200]

for numero, code in enumerate(codes, start=1):
    if code == 304:
        continue            # rien à signaler : tour suivant
    if code >= 500:
        print(f"Requête {numero} : erreur {code}, on arrête")
        break               # sortie immédiate de la boucle
    print(f"Requête {numero} : {code}")
text
Requête 1 : 200
Requête 2 : 200
Requête 4 : 200
Requête 5 : erreur 500, on arrête

La requête 3 (code 304) est sautée par continue ; la 5 (code 500) déclenche break, et la 6 n'est jamais examinée.

L'indentation

En Python, l'indentation est la syntaxe : un bloc commence après les deux-points et regroupe les lignes indentées de la même façon. La convention (PEP 8) est de 4 espaces par niveau ; les éditeurs les insèrent quand tu appuies sur Tab. Un bloc oublié :

python
taux = 95
if taux >= 90:
print("Disque presque plein")
text
  File "/home/etudiant/cours-python/indentation.py", line 3
    print("Disque presque plein")
    ^^^^^
IndentationError: expected an indented block after 'if' statement on line 2

Python indique la ligne fautive et la cause : il attendait un bloc indenté après le if de la ligne 2. Les autres erreurs classiques : IndentationError: unexpected indent (une ligne indentée sans raison) et TabError (tabulations et espaces mélangés dans un même bloc, souvent après un copier-coller).

Exercices

Exercice 1 sur 3 Prévoir l'affichage Réussi À revoir

Sans exécuter, écris ce qu'affiche ce programme :

python
prix_ht = 249.9
quantite = 3
remise = quantite >= 3
total = prix_ht * quantite
if remise:
    total = total * 0.9
print(f"{quantite} × {prix_ht} € HT, remise : {remise}")
print(f"Total HT : {total:.2f} €")
print(f"Total TTC : {total * 1.2:.2f} €")
Voir la réponseMasquer la réponse de l'exercice 1
text
3 × 249.9 € HT, remise : True
Total HT : 674.73 €
Total TTC : 809.68 €

quantite >= 3 est une comparaison : elle vaut True, rangé dans remise. 249,9 × 3 = 749,7, et 749,7 × 0,9 = 674,73. Le TTC vaut 674,73 × 1,2 = 809,676, arrondi à l'affichage à 809,68 par le format .2f.

Tu avais trouvé ?

Exercice 2 sur 3 Un mot de passe conforme Réussi À revoir

La politique de Sorbier exige au moins 12 caractères dont au moins un chiffre. Écris un script qui demande un mot de passe et affiche Conforme, Trop court : n caractères sur 12 ou Il manque un chiffre. La méthode caractere.isdigit() dit si un caractère est un chiffre. Teste avec Sorbier2026!, Entrepot71 et MotDePasseSansChiffre.

Voir la réponseMasquer la réponse de l'exercice 2
python
# ex_mdp.py : vérifier qu'un mot de passe fait au moins 12 caractères et contient un chiffre
mot_de_passe = input("Mot de passe à tester ? ")

contient_chiffre = False
for caractere in mot_de_passe:
    if caractere.isdigit():
        contient_chiffre = True
        break

if len(mot_de_passe) >= 12 and contient_chiffre:
    print("Conforme")
elif len(mot_de_passe) < 12:
    print(f"Trop court : {len(mot_de_passe)} caractères sur 12")
else:
    print("Il manque un chiffre")
text
Mot de passe à tester ? Sorbier2026!
Conforme
Mot de passe à tester ? Entrepot71
Trop court : 10 caractères sur 12
Mot de passe à tester ? MotDePasseSansChiffre
Il manque un chiffre

Le break arrête la recherche au premier chiffre trouvé. La longueur se teste avant le chiffre dans le elif : un mot de passe court et sans chiffre est signalé comme trop court. Une politique de mots de passe réelle se décide avec les recommandations de l'ANSSI (cours Authentification) ; ce script ne fait que la contrôler.

Tu avais trouvé ?

Exercice 3 sur 3 Combien de bits ? Réussi À revoir

Écris un script qui demande un nombre de postes et affiche le plus petit nombre de bits n tel que 2ⁿ est au moins égal à ce nombre. Teste avec 300 et avec 256. Quelle boucle choisis-tu, et pourquoi ?

Voir la réponseMasquer la réponse de l'exercice 3

On ne sait pas d'avance combien de tours faire : c'est un while.

python
# ex_bits.py : le plus petit nombre de bits n tel que 2**n >= postes
postes = int(input("Nombre de postes à numéroter ? "))
n = 0
while 2 ** n < postes:
    n = n + 1
print(f"{n} bits suffisent : 2**{n} = {2 ** n} valeurs")
text
Nombre de postes à numéroter ? 300
9 bits suffisent : 2**9 = 512 valeurs
Nombre de postes à numéroter ? 256
8 bits suffisent : 2**8 = 256 valeurs

2⁸ = 256 < 300 ≤ 512 = 2⁹ : il faut 9 bits. Pour 256 postes, 8 bits suffisent tout juste : la condition 2 ** n < postes devient fausse dès que 2ⁿ égale le nombre de postes. Écrire <= au lieu de < donnerait 9 bits, un de trop : vérifie toujours le cas limite.

Tu avais trouvé ?

Chapitre terminé !

Fais les 3 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Fonctions, modules et import en PythonRevoir le sommaire du cours