03 - Python (1)

Les exercices se font dans Thonny, dans le fichier 03_python_1.py.

Cours associés : 01 - Syntaxe , 02 - Types de base , 03 - Opérateurs , 04 - Conditions .

Exercice 0 : QCM – vérification des prérequis

Pour chaque question, une seule réponse est correcte.

1. Après l’exécution de x = 3, que contient la variable x ?

  • A. La chaîne "3"
  • B. L’entier 3
  • C. Le flottant 3.0
  • D. Rien, car x n’a pas été déclarée
Correction

Réponse : B. En Python, x = 3 affecte l’entier 3 à la variable x. Python crée automatiquement la variable lors de la première affectation, sans déclaration préalable.

  • A est faux : pour obtenir la chaîne "3", il faudrait écrire x = "3" (avec des guillemets).
  • C est faux : 3 est un int, pas un float. Pour obtenir 3.0, il faudrait écrire x = 3.0.
  • D est faux : en Python, il n’y a pas de déclaration séparée ; l’affectation crée la variable.

2. Quelle est la valeur de y après l’exécution du code suivant ?

x = 5
y = x + 1
x = 10
  • A. 11
  • B. 6
  • C. 10
  • D. 5
Correction

Réponse : B. Au moment de l’affectation y = x + 1, la variable x vaut 5, donc y reçoit 6. La modification ultérieure de x (ligne 3) ne change pas y : l’expression x + 1 est calculée une seule fois, au moment de l’affectation, puis x = 10 colle l’étiquette x sur 10 sans toucher à y.

  • A est faux : c’est l’erreur qui consiste à croire que y est « liée » à x et se recalcule automatiquement (confusion avec un tableur).
  • C est faux : y n’a jamais reçu la valeur de x après sa modification.
  • D est faux : y vaut x + 1, pas x.

3. Que produit print(type(3 / 1)) ?

  • A. <class 'int'>
  • B. <class 'float'>
  • C. <class 'str'>
  • D. Une erreur
Correction

Réponse : B. En Python, l’opérateur / (division) renvoie toujours un float, même si le résultat est entier. Ainsi 3 / 1 vaut 3.0.

  • A est faux : pour obtenir un int, il faudrait utiliser la division entière 3 // 1.
  • C est faux : le résultat d’une division n’est pas une chaîne.
  • D est faux : la division par 1 est tout à fait valide.

4. Quel est l’affichage produit par le code suivant ?

a = 2
b = 3
a = b
b = a
print(f"{a} {b}")
  • A. 2 3
  • B. 3 2
  • C. 3 3
  • D. 2 2
Correction

Réponse : C. Après a = b, la variable a vaut 3. Ensuite, b = a affecte à b la valeur actuelle de a, qui est 3. Les deux variables valent donc 3.

  • B est faux : c’est l’erreur classique de croire que ces deux lignes échangent les valeurs (il faudrait une variable temporaire ou l’écriture simultanée a, b = b, a).
  • A est faux : a a été modifié à la ligne 3.
  • D est faux : b a été modifié à la ligne 4.

Exercice 1

On exécute le programme suivant :

prix = 12
quantite = 3
total = prix * quantite
prix = 15
quantite = quantite + 1
print(f"{total} {quantite}")
  1. Recopier et compléter un tableau qui donne, après chaque ligne, la valeur de prix, de quantite et de total.
  2. Qu’affiche le programme ? La valeur de total tient-elle compte du nouveau prix ?
Indice

Une affectation calcule la valeur de droite au moment où elle s’exécute, puis la range dans la variable de gauche. Les lignes suivantes ne refont pas ce calcul.

Correction
LigneInstructionprixquantitetotal
1prix = 1212——
2quantite = 3123—
3total = prix * quantite12336
4prix = 1515336
5quantite = quantite + 115436

Le programme affiche 36 4. Le total a été calculé à la ligne 3, avec le prix de 12 : changer prix ensuite ne modifie pas total. À la ligne 5, quantite + 1 est calculé avec l’ancienne valeur 3, puis le résultat 4 remplace cette valeur.

Exercice 2

Après les deux affectations ci-dessous, donner la valeur et le type de chacune des expressions qui suivent, sans exécuter le code, puis vérifier.

a = 7
b = 2
a + b
a * b - 1
a // b
a % b
a / b
a > b
a % 2 == 1
a > 10 or b < 5
a > 10 and b < 5
not a == b
Indice

// donne le quotient de la division entière et % son reste ; / donne toujours un flottant. Une comparaison vaut True ou False ; and n’est vrai que si les deux conditions le sont, or dès que l’une l’est, et not inverse une condition.

Correction
ExpressionValeurTypeExplication
a + b9int
a * b - 113intla multiplication est faite avant la soustraction
a // b3int\(7 = 2 \times 3 + 1\) : le quotient vaut 3
a % b1int… et le reste vaut 1
a / b3.5float/ donne toujours un flottant
a > bTruebool
a % 2 == 1Trueboolle reste de 7 par 2 vaut 1 : 7 est impair
a > 10 or b < 5Trueboolla seconde condition est vraie
a > 10 and b < 5Falseboolla première condition est fausse
not a == bTrueboola == b est faux, not l’inverse

Exercice 3

Pour chaque ligne, dire s’il s’agit d’une instruction ou d’une expression, et justifier.

n
n = 4
n = n * 2
n * 2
print(n)
n > 3
n > 3 and n < 10
"bon" + "jour"
Indice

Une expression se calcule et donne une valeur, que l’on pourrait afficher ou ranger dans une variable. Une instruction demande à Python d’agir : ranger une valeur dans une variable, afficher un message.

Correction
CodeNatureJustification
nexpressionsa valeur est le contenu de n
n = 4instructionaffectation : range 4 dans n
n = n * 2instructionaffectation ; la partie droite, n * 2, est une expression
n * 2expressiondonne une valeur, sans rien modifier
print(n)instructionaffiche la valeur de n
n > 3expressiondonne un booléen
n > 3 and n < 10expressiondonne un booléen
"bon" + "jour"expressiondonne la chaîne "bonjour"

Exercice 4

Un cinéma fait payer 6 € aux moins de 18 ans et 10 € aux autres ; les adultes reçoivent en plus un bon de réduction de 2 € pour leur prochaine séance. Voici deux programmes qui ne diffèrent que par l’indentation d’une ligne.

Script 1

age = 15
tarif = 10
reduction = 0
if age < 18:
    tarif = 6
else:
    tarif = 10
    reduction = 2
print(f"{tarif} {reduction}")

Script 2

age = 15
tarif = 10
reduction = 0
if age < 18:
    tarif = 6
else:
    tarif = 10
reduction = 2
print(f"{tarif} {reduction}")
  1. Qu’affiche chaque script ?
  2. Mêmes questions en remplaçant age = 15 par age = 20.
  3. Lequel des deux scripts respecte la règle du cinéma ?
Indice

En Python, c’est l’indentation qui indique les lignes qui font partie d’un bloc. Dans quel script la ligne reduction = 2 appartient-elle au bloc else ?

Correction
  1. Avec age = 15, la condition age < 18 est vraie. Le script 1 affiche 6 0 : le bloc else, qui contient reduction = 2, n’est pas exécuté. Le script 2 affiche 6 2 : la ligne reduction = 2 n’est pas indentée, elle est donc exécutée dans tous les cas.
  2. Avec age = 20, le bloc else est exécuté : les deux scripts affichent 10 2.
  3. Seul le script 1 respecte la règle : dans le script 2, un mineur reçoit aussi le bon de réduction. Ce genre d’erreur ne se voit qu’en testant plusieurs cas, ici un mineur et un adulte.

Exercice 5

Un professeur veut répartir sa classe en groupes de même taille. Écrire un programme qui demande le nombre d’élèves de la classe, puis le nombre d’élèves par groupe, et qui affiche :

  • soit que tous les groupes sont complets, avec le nombre de groupes ;
  • soit le nombre de groupes complets et le nombre d’élèves qui restent.

Par exemple, 30 élèves par groupes de 4 donnent 7 groupes complets et 2 élèves restants.

Indice

Le nombre de groupes complets est le quotient de la division entière (//), le nombre d’élèves restants est son reste (%). Tous les groupes sont complets quand ce reste est nul.

Code à copier puis compléter
eleves = int(input("Nombre d'élèves : "))
taille = int(input("Nombre d'élèves par groupe : "))
groupes = ...
reste = ...
if ...:
    print(f"{groupes} groupes complets")
else:
    ...
Correction
eleves = int(input("Nombre d'élèves : "))
taille = int(input("Nombre d'élèves par groupe : "))
groupes = eleves // taille
reste = eleves % taille
if reste == 0:
    print(f"{groupes} groupes complets")
else:
    print(f"{groupes} groupes complets et {reste} élève(s) restant(s)")

Tests : 30 et 4 donnent 7 groupes et 2 élèves restants ; 30 et 5 donnent 6 groupes complets ; 3 et 4 donnent 0 groupe et 3 élèves restants.

Exercice 6

  1. Que calcule le programme suivant ? Les noms des variables aident-ils à le comprendre ?

    p = float(input())
    q = int(input())
    r = p * q
    if q >= 10:
        r = r * 0.9
    print(r)
    
    Indice

    Imaginer que p est un prix et q une quantité achetée. Que représente alors la multiplication par 0,9 ?

  2. Réécrire ce programme avec des noms de variables explicites, en indiquant à l’utilisateur ce qu’il doit saisir et en affichant un message clair.

  3. Ajouter un commentaire (ligne commençant par #) qui explique le rôle de la condition.

Correction
  1. Le programme calcule le prix à payer pour q articles au prix unitaire p, avec une remise de 10 % dès 10 articles : multiplier par 0,9, c’est retirer 10 %. Les noms p, q et r ne disent rien de leur rôle, et l’utilisateur ne sait pas quoi saisir.
  2. et 3. Version améliorée :
prix_unitaire = float(input("Prix d'un article (en euros) : "))
quantite = int(input("Nombre d'articles : "))
montant = prix_unitaire * quantite
# Remise de 10 % à partir de 10 articles achetés
if quantite >= 10:
    montant = montant * 0.9
print(f"Montant à payer : {montant} euros")

Exercice 7

  1. Une élève note dans un programme ce qu’elle met de côté chaque semaine :

    epargne = epargne + 20
    epargne = epargne + 35
    epargne = epargne + 15
    print(epargne)
    

    Exécuter ce programme. Quelle erreur Python signale-t-il ? La corriger, puis donner le montant affiché.

    Indice

    À la première ligne, Python doit calculer epargne + 20. Quelle est la valeur de epargne à ce moment-là ?

  2. On veut maintenant calculer \(2^5\), c’est-à-dire \(2 \times 2 \times 2 \times 2 \times 2\), en multipliant cinq fois une variable puissance par 2. Par quelle valeur faut-il initialiser puissance ? Écrire le programme.

Correction
  1. Python signale NameError: name 'epargne' is not defined : la variable est utilisée avant d’avoir reçu une valeur. Il faut l’initialiser au début avec epargne = 0, la valeur de départ d’une somme. Le programme affiche alors 70.
  2. Pour un produit, la valeur de départ est 1, qui ne change pas le résultat d’une multiplication ; avec 0, le résultat resterait 0.
puissance = 1
puissance = puissance * 2
puissance = puissance * 2
puissance = puissance * 2
puissance = puissance * 2
puissance = puissance * 2
print(puissance)

Le programme affiche 32. Le chapitre sur les boucles permettra d’écrire cette répétition une seule fois.

Exercice 8

Le module random fournit des nombres tirés au hasard. Après import random :

  • random.randint(1, 6) renvoie un entier au hasard entre 1 et 6, bornes comprises ;
  • random.random() renvoie un flottant au hasard entre 0 (compris) et 1 (exclu).
  1. Écrire un programme qui simule le lancer d’un dé à six faces, affiche la valeur obtenue, puis affiche Gagné ! si c’est un 6 et Perdu sinon.
  2. Avec random.random(), écrire un programme qui affiche Bonus avec une chance sur quatre, et rien sinon.
Indice

Pour la question 2, un flottant tiré au hasard entre 0 et 1 tombe dans l’intervalle \([0 ; 0{,}25[\) une fois sur quatre en moyenne.

Correction
  1. Lancer de dé :
import random

de = random.randint(1, 6)
print(f"Le dé affiche {de}")
if de == 6:
    print("Gagné !")
else:
    print("Perdu")
  1. Événement de probabilité \(\frac{1}{4}\) :
import random

if random.random() < 0.25:
    print("Bonus")

Il n’y a pas de else, puisque le programme n’affiche rien dans l’autre cas. En relançant le programme une vingtaine de fois, on obtient Bonus environ une fois sur quatre.

Exercice 9

Écrire un programme qui demande une température en degrés Celsius (elle peut être décimale) et affiche :

  • gel si elle est strictement inférieure à 0 ;
  • froid si elle est comprise entre 0 (inclus) et 15 (exclu) ;
  • doux si elle est comprise entre 15 (inclus) et 25 (exclu) ;
  • chaud si elle vaut 25 ou plus.
Indice

Utiliser if, puis deux elif, puis else. Les conditions sont testées dans l’ordre : quand on arrive au premier elif, on sait déjà que la température n’est pas inférieure à 0.

Correction
temperature = float(input("Température (en °C) : "))
if temperature < 0:
    print("gel")
elif temperature < 15:
    print("froid")
elif temperature < 25:
    print("doux")
else:
    print("chaud")

Il est inutile d’écrire temperature >= 0 and temperature < 15 : le premier elif n’est examiné que si la condition temperature < 0 est fausse.

Tests, en essayant aussi les valeurs frontières : -3 donne gel, 0 froid, 14.9 froid, 15 doux, 25 chaud, 31.5 chaud.

Exercice 10

Une boulangerie est ouverte de 7 h à 19 h : elle ouvre à 7 h et ferme à 19 h. Écrire un programme qui demande une heure, éventuellement décimale (13.5 pour 13 h 30), et affiche si la boulangerie est ouverte à cette heure-là.

Écrire trois versions du programme :

  • avec deux if imbriqués ;
  • avec le mot-clé and dans la condition ;
  • avec le mot-clé or dans la condition.
Indice

La boulangerie est ouverte quand heure >= 7 et heure < 19. Pour la version avec or, écrire plutôt la condition « la boulangerie est fermée ».

Correction

Avec deux if imbriqués

heure = float(input("Heure : "))
if heure >= 7:
    if heure < 19:
        print("Ouvert")
    else:
        print("Fermé")
else:
    print("Fermé")

Avec and

heure = float(input("Heure : "))
if heure >= 7 and heure < 19:
    print("Ouvert")
else:
    print("Fermé")

Avec or

heure = float(input("Heure : "))
if heure < 7 or heure >= 19:
    print("Fermé")
else:
    print("Ouvert")

La condition de la troisième version est la négation de la deuxième : « non (A et B) » équivaut à « (non A) ou (non B) ».

Tests : 6.5 donne fermé, 7 ouvert, 13.5 ouvert, 19 fermé, 22 fermé.

Exercice 11

On veut résoudre une équation de la forme \(ax^2 + bx + c = 0\), où \(a\), \(b\) et \(c\) sont des nombres saisis par l’utilisateur. On rappelle que, lorsque \(a \neq 0\), on calcule le discriminant \(\Delta = b^2 - 4ac\) :

  • si \(\Delta > 0\), l’équation a deux solutions, \(x_1 = \dfrac{-b - \sqrt{\Delta}}{2a}\) et \(x_2 = \dfrac{-b + \sqrt{\Delta}}{2a}\) ;
  • si \(\Delta = 0\), elle a une seule solution, \(x_0 = \dfrac{-b}{2a}\) ;
  • si \(\Delta < 0\), elle n’a pas de solution réelle.
  1. Écrire un programme qui demande \(a\), \(b\) et \(c\), affiche la valeur du discriminant, puis le nombre de solutions et leurs valeurs. La racine carrée s’obtient avec math.sqrt, après import math.
  2. Que se passe-t-il si l’utilisateur saisit \(a = 0\) ? Modifier le programme pour traiter ce cas : l’équation devient alors \(bx + c = 0\).
  3. Proposer un jeu de tests qui passe par tous les cas du programme.
Indice

Pour la question 2, essayer \(a = 0\), \(b = 2\), \(c = -6\) : quelle division le programme tente-t-il ? Placer le test if a == 0: avant le calcul du discriminant.

Code à copier puis compléter
import math

a = float(input("a : "))
b = float(input("b : "))
c = float(input("c : "))
delta = ...
print(f"Discriminant : {delta}")
if delta > 0:
    x1 = (-b - math.sqrt(delta)) / (2 * a)
    x2 = ...
    print(f"Deux solutions : {x1} et {x2}")
elif ...:
    ...
else:
    print("Pas de solution réelle")
Correction

Avec \(a = 0\), le programme de la question 1 divise par \(2a = 0\) et s’arrête sur l’erreur ZeroDivisionError. On traite donc ce cas en premier :

import math

a = float(input("a : "))
b = float(input("b : "))
c = float(input("c : "))
if a == 0:
    if b != 0:
        print(f"Équation du premier degré, une solution : {-c / b}")
    else:
        print("Ce n'est pas une équation en x")
else:
    delta = b**2 - 4 * a * c
    print(f"Discriminant : {delta}")
    if delta > 0:
        x1 = (-b - math.sqrt(delta)) / (2 * a)
        x2 = (-b + math.sqrt(delta)) / (2 * a)
        print(f"Deux solutions : {x1} et {x2}")
    elif delta == 0:
        print(f"Une solution : {-b / (2 * a)}")
    else:
        print("Pas de solution réelle")

Jeu de tests :

\(a\)\(b\)\(c\)\(\Delta\)Résultat attendu
1-561deux solutions, 2 et 3
1690une solution, -3
213-23pas de solution réelle
02-6premier degré, une solution, 3
004pas une équation en \(x\)

Chaque ligne du tableau fait passer le programme par une branche différente.

Exercice 12 (pour aller plus loin)

Une année est bissextile (février a alors 29 jours) si elle est divisible par 4 sans être divisible par 100, ou si elle est divisible par 400. Ainsi 2024 et 2000 sont bissextiles, mais 1900 et 2026 ne le sont pas.

  1. Écrire un programme qui demande une année et affiche si elle est bissextile.
  2. Écrire un programme, à partir de celui de la question 1, qui demande aussi un numéro de mois (de 1 à 12) et affiche le nombre de jours de ce mois. Avril, juin, septembre et novembre ont 30 jours ; février en a 28 ou 29 ; les autres mois en ont 31.
  3. Écrire un programme qui demande une date (jour, mois, année) et affiche la date du lendemain. Par exemple, le lendemain du 28/2/2024 est le 29/2/2024, et celui du 31/12/2026 est le 1/1/2027.
Indice

Pour la question 3, calculer d’abord le nombre de jours du mois, avec la question 2. Trois cas se présentent ensuite : on reste dans le même mois, on passe au mois suivant, ou on passe à l’année suivante.

Correction

Le programme complet répond aux trois questions :

jour = int(input("Jour : "))
mois = int(input("Mois : "))
annee = int(input("Année : "))

# Questions 1 et 2 : année bissextile et nombre de jours du mois
if (annee % 4 == 0 and annee % 100 != 0) or annee % 400 == 0:
    print(f"{annee} est bissextile")
    jours_fevrier = 29
else:
    print(f"{annee} n'est pas bissextile")
    jours_fevrier = 28

if mois == 2:
    nb_jours = jours_fevrier
elif mois == 4 or mois == 6 or mois == 9 or mois == 11:
    nb_jours = 30
else:
    nb_jours = 31
print(f"Ce mois compte {nb_jours} jours")

# Question 3 : date du lendemain
if jour < nb_jours:
    jour = jour + 1
elif mois < 12:
    jour = 1
    mois = mois + 1
else:
    jour = 1
    mois = 1
    annee = annee + 1
print(f"Lendemain : {jour}/{mois}/{annee}")

Tests : 14/7/2026 donne 15/7/2026 ; 30/4/2026 donne 1/5/2026 ; 28/2/2026 donne 1/3/2026 ; 28/2/2024 donne 29/2/2024 ; 28/2/1900 donne 1/3/1900 ; 31/12/2026 donne 1/1/2027.