Aller au contenu

Exercices#

Les bases de la programmation Python

Mode d’emploi

  • Niveau : ★ échauffement, ★★ classique (niveau bac), ★★★ défi ; les coups de pouce et les corrigés se déplient sous chaque exercice.

  • Sauf mention sur papier , les exercices se font sur machine (Spyder ou Basthon) : on écrit dans l’éditeur, on exécute, on vérifie dans la console.

  • ▶ signale les exercices où l’on écrit un vrai programme à tester.

  • Avancez dans l’ordre : chaque section suit la progression du cours.

  • Usage de l’IA, indiqué sur chaque exercice : aucune ; en appui (déboguer, reformuler, vérifier ; la réponse finale est écrite et comprise par vous) ; l’exercice s’appuie sur une réponse d’IA. Voir la charte d’usage de l’IA.

Premiers pas : afficher#

★ Exercice 1 — Bonjour #

• essentiel

▶ Écrire un programme qui affiche : Bonjour, je m’appelle … (en y mettant son prénom).

Coup de pouce

Relisez le tout premier programme du cours (« Hello World ») : il suffit d’en changer le texte.

Corrigé

Remarque

Plusieurs écritures sont souvent possibles ; on en donne une simple. Les exercices marqués « sur papier » indiquent le résultat attendu. Rappel utile : input renvoie toujours du texte, on convertit avec int(...) pour calculer.

print("Bonjour, je m'appelle Marie")

★ Exercice 2 — Le menu de la cantine #

▶ Écrire un programme qui affiche le menu du jour sur trois lignes : l’entrée, le plat, puis le dessert (par exemple Entrée : salade niçoise).

Coup de pouce

Une instruction print affiche une ligne : combien en faut-il pour trois lignes ?

Corrigé

Une instruction print par ligne à afficher.

print("Entree : salade nicoise")
print("Plat : lasagnes")
print("Dessert : tarte aux pommes")

Variables#

★ Exercice 3 — Deux variables #

• essentiel

▶ Créer une variable sport contenant son sport préféré (du texte) et une variable heures contenant le nombre d’heures qu’on y consacre par semaine (un nombre), puis les afficher.

Coup de pouce

Du texte s’écrit entre guillemets, un nombre sans guillemets. Pour afficher la valeur d’une variable, on écrit son nom sans guillemets dans print.

Corrigé

Le texte va entre guillemets, le nombre non.

sport = "natation"
heures = 4
print(sport)
print(heures)

★ Exercice 4 — Valeur finale #

• essentiel

sur papier Sans machine, donner la valeur finale de a et de b, puis vérifier.

Coup de pouce

Lisez les lignes une par une, dans l’ordre : au moment où l’on calcule b, combien vaut a ? La troisième ligne revient-elle en arrière ?

a = 5
b = a + 1
a = 10
Corrigé

Sur papier. a \(= \mathbf{10}\) et b \(= \mathbf{6}\). La valeur de b a été calculée une fois pour toutes quand a valait \(5\) : modifier a ensuite ne change pas b.

▷ Erreur fréquente. Répondre que b vaut \(11\). La ligne b = a + 1 n’est pas une formule qui se met à jour toute seule : c’est un calcul fait une seule fois, avec la valeur que a avait à ce moment-là.

★ Exercice 5 — Des noms parlants #

sur papier Ce programme calcule le prix de \(3\) places de cinéma à \(12\) €, mais ses noms de variables ne veulent rien dire :

x = 12
y = 3
z = x * y
  1. Proposer des noms parlants (et valides) pour x, y et z.

  2. Un camarade propose prix place, 3places et total€. Pourquoi Python les refuse-t-il ?

    Coup de pouce

    Relisez dans le cours les règles pour nommer une variable : espaces, chiffre au début, caractères spéciaux.

Corrigé

Sur papier.

  1. Par exemple prix_place, nb_places et total.

  2. prix place contient une espace ; 3places commence par un chiffre ; total€ contient un symbole (€) interdit dans un nom.

★★ Exercice 6 — L’échange #

• essentiel

▶ On a a = 1 et b = 2. Écrire les instructions qui échangent leurs valeurs (à la fin, a vaut \(2\) et b vaut \(1\)).

Coup de pouce

Si l’on écrit directement a = b, l’ancienne valeur de a est perdue : rangez-la d’abord dans une troisième variable temporaire.

Corrigé

On garde l’une des valeurs de côté dans une variable temporaire, sinon on l’écrase.

a = 1
b = 2
temporaire = a
a = b
b = temporaire

▷ Erreur fréquente. Écrire a = b puis b = a : après la première ligne, a vaut déjà \(2\), et l’ancienne valeur (\(1\)) est perdue. Les deux variables finissent à \(2\).

Calculs#

★ Exercice 7 — Somme et produit #

▶ Ranger deux nombres dans a et b, puis afficher leur somme et leur produit.

Coup de pouce

Deux lignes pour ranger les nombres (a = ...), puis un print par résultat. La multiplication s’écrit avec le symbole *.

Corrigé
a = 6
b = 4
print(a + b)   # 10
print(a * b)   # 24

★ Exercice 8 — Le trajet #

• essentiel

▶ À partir de deux variables vitesse (en km/h) et duree (en heures), calculer et afficher la distance parcourue. Test : \(90\) km/h pendant \(2{,}5\) h donnent \(225\) km.

Coup de pouce

Distance \(=\) vitesse \(\times\) durée. Attention : en Python, \(2{,}5\) s’écrit avec un point.

Corrigé

Distance \(=\) vitesse \(\times\) durée. En Python, la virgule décimale s’écrit avec un point.

vitesse = 90
duree = 2.5
print(vitesse * duree)   # 225.0

★★ Exercice 9 — La tirelire #

• essentiel

▶ La variable tirelire de Léa vaut \(20\). Sa grand-mère double son contenu, puis Léa dépense \(15\) € au cinéma, puis elle ajoute \(8\) € d’argent de poche. En modifiant tirelire à chaque étape, afficher le contenu final (attendu : \(33\)).

Coup de pouce

Chaque étape s’écrit tirelire = ... en partant de l’ancienne valeur de tirelire.

Corrigé

On met à jour tirelire à partir de sa propre valeur, étape par étape.

tirelire = 20
tirelire = tirelire * 2    # 40
tirelire = tirelire - 15   # 25
tirelire = tirelire + 8    # 33
print(tirelire)

★★ Exercice 10 — Priorités de calcul #

sur papier Python respecte les priorités opératoires des maths. Sans machine, donner la valeur et le type de chaque résultat, puis vérifier.

2 + 3 * 4
(2 + 3) * 4
10 - 6 / 2
2 * 3 ** 2
20 // 3 % 2
Coup de pouce

Comme en maths : d’abord les parenthèses, puis **, puis *, /, //, % (de gauche à droite), enfin + et -. Pensez aussi au type : / donne toujours un float.

Corrigé

Sur papier.

  • 2 + 3 * 4 \(= 14\) (int) : la multiplication passe avant ;

  • (2 + 3) * 4 \(= 20\) (int) : les parenthèses d’abord ;

  • 10 - 6 / 2 \(= 7.0\) (float) : 6 / 2 vaut 3.0 ;

  • 2 * 3 ** 2 \(= 18\) (int) : la puissance passe avant la multiplication ;

  • 20 // 3 % 2 \(= 0\) (int) : même priorité, on calcule de gauche à droite, 20 // 3 \(= 6\) puis 6 % 2 \(= 0\).

★★ Exercice 11 — La note d’une application #

▶ Sur une boutique d’applications, un jeu a reçu \(12\) avis à \(5\) étoiles, \(5\) avis à \(4\) étoiles et \(3\) avis à \(1\) étoile. Ranger ces nombres d’avis dans des variables, puis calculer et afficher la note moyenne du jeu (attendu : \(4{,}15\)).

Coup de pouce

Note moyenne = (nombre total d’étoiles données) divisé par (nombre total d’avis). Les \(12\) avis à \(5\) étoiles rapportent à eux seuls \(12 \times 5\) étoiles. Attention aux parenthèses.

Corrigé

On compte toutes les étoiles données (chaque nombre d’avis multiplié par sa note), puis on divise par le nombre total d’avis (\(20\)), et non par \(3\) (le nombre de notes différentes).

avis_5 = 12
avis_4 = 5
avis_1 = 3
etoiles = avis_5 * 5 + avis_4 * 4 + avis_1 * 1
moyenne = etoiles / (avis_5 + avis_4 + avis_1)
print(moyenne)   # 4.15

▷ Erreur fréquente. Oublier les parenthèses : etoiles / avis_5 + avis_4 + avis_1 divise seulement par \(12\) puis ajoute \(5\) et \(3\) (la division passe avant l’addition), ce qui donne environ \(14{,}9\) : une note impossible sur \(5\) étoiles, qui aurait dû alerter.

★★ Exercice 12 — Le forfait de données #

▶ Un forfait mobile comprend \(80\) Go de données par mois (Go : gigaoctet). Vous en avez déjà utilisé \(25\,\%\). Écrire un programme qui calcule et affiche le nombre de gigaoctets qu’il vous reste.

Coup de pouce

Calculez d’abord la quantité déjà utilisée, puis retirez-la du forfait de départ. Rappel : prendre \(25\,\%\) d’un nombre, c’est le multiplier par \(25/100\).

Corrigé

On calcule d’abord la quantité utilisée (\(25\,\%\) de \(80\) Go, soit \(20\) Go), puis on la retire du forfait. (Autre écriture : il reste \(75\,\%\) du forfait, forfait * 75 / 100.)

forfait = 80
utilise = forfait * 25 / 100
print(forfait - utilise)   # 60.0

Il reste \(60\) Go.

★★ Exercice 13 — Quel jour serons-nous ? #

• essentiel

▶ On numérote les jours de la semaine : lundi \(= 0\), mardi \(= 1\), …, dimanche \(= 6\). Aujourd’hui, c’est mercredi (jour \(2\)). Écrire un programme qui calcule et affiche :

  1. le nombre de semaines complètes contenues dans \(100\) jours ;

  2. le numéro du jour de la semaine qu’il sera dans \(100\) jours.

Coup de pouce

Les jours reviennent tous les \(7\) jours : // donne le nombre de semaines complètes, % le nombre de jours qui restent. N’oubliez pas qu’on part du jour \(2\).

Corrigé

// compte les semaines complètes ; % donne le reste, ce qui « fait le tour » de la semaine.

aujourd_hui = 2                     # mercredi
print(100 // 7)                     # 14 semaines completes
print((aujourd_hui + 100) % 7)      # 4, c'est-a-dire vendredi

★★★ Exercice 14 — Le rendu de monnaie #

≈ 15 min

▶ Écrire un programme qui, à partir d’une somme en euros entiers (variable montant), affiche comment la payer avec le moins de coupures possible en billets de \(10\), pièces de \(2\) et pièces de \(1\). Par exemple pour \(27\) € : \(2\) billets de \(10\), \(3\) pièces de \(2\), \(1\) pièce de \(1\) (\(20 + 6 + 1 = 27\)).

Coup de pouce

Commencez par la plus grosse coupure : // donne combien on en utilise, % donne ce qui reste à payer avec les coupures plus petites.

Coup de pouce 2 (début de solution)

billets10 = montant // 10
reste = montant % 10
puis la même chose avec les pièces de \(2\), en partant de reste.

Corrigé

On traite les coupures de la plus grande à la plus petite : // donne le nombre, % garde le reste à traiter ensuite.

montant = 27
billets10 = montant // 10     # 2
reste = montant % 10          # 7
pieces2 = reste // 2          # 3
pieces1 = reste % 2           # 1
print(f"{billets10} billet(s) de 10")
print(f"{pieces2} piece(s) de 2")
print(f"{pieces1} piece(s) de 1")

Vérification : \(2 \times 10 + 3 \times 2 + 1 \times 1 = 27\).

Chaînes de caractères et dialogue#

★ Exercice 15 — Texte ou calcul ? #

• essentiel

▶ Écrire un programme qui affiche exactement les trois lignes ci-dessous. La deuxième doit être calculée par Python (interdit d’écrire 17 soi-même !).

12 + 5
17
Bonjour Monaco
Coup de pouce

Pour la troisième ligne, collez deux morceaux de texte avec + (sans oublier l’espace entre les deux mots).

Corrigé

Entre guillemets, Python affiche le texte tel quel ; sans guillemets, il calcule. Le + entre deux textes les colle (attention à l’espace après Bonjour).

print("12 + 5")
print(12 + 5)
print("Bonjour " + "Monaco")

★ Exercice 16 — Nom de code #

• essentiel

▶ Demander à l’utilisateur son prénom, puis sa ville, et afficher à l’aide d’une f-string : « Agent prénom, votre mission vous attend à ville. »

Coup de pouce

Deux input, chacun rangé dans sa variable. Dans une f-string (un f juste avant le guillemet), chaque variable s’écrit entre accolades.

Corrigé
prenom = input("Ton prenom ? ")
ville = input("Ta ville ? ")
print(f"Agent {prenom}, votre mission vous attend a {ville}.")

★★ Exercice 17 — Le type d’un résultat #

sur papier Sans machine, donner la valeur et le type (int, float ou str) du résultat de chaque expression, puis vérifier avec type(...) : 7 + 2 ; 7 / 7 ; "7" + "2" ; 3 * 1.0 ; int("5") + 1 ; str(4) + "0".

Coup de pouce

Pour chaque expression, demandez-vous si les valeurs sont des nombres ou du texte (entre guillemets). Relisez dans le cours ce que donne toujours la division /.

Corrigé

Sur papier.

  • 7 + 2 \(\to\) 9 (int) ; 7 / 7 \(\to\) 1.0 (float : la division / donne toujours un flottant) ;

  • "7" + "2" \(\to\) "72" (str : on colle deux textes) ; 3 * 1.0 \(\to\) 3.0 (float) ;

  • int("5") + 1 \(\to\) 6 (int) ; str(4) + "0" \(\to\) "40" (str).

★★ Exercice 18 — Le temps d’écran #

• essentiel

▶ Demander à l’utilisateur combien d’heures par jour il passe devant un écran, puis afficher combien d’heures cela représente sur une année (\(365\) jours), et combien de jours entiers cela fait. (Attention : input renvoie du texte, il faut le convertir avec int !)

Coup de pouce

Sur une année : multipliez par \(365\). Pour les jours entiers, une journée dure \(24\) heures : quel opérateur donne le quotient entier ?

Corrigé

Pour \(3\) h par jour : \(1095\) h, soit \(45\) jours entiers.

par_jour = int(input("Heures d'ecran par jour ? "))
par_an = par_jour * 365
print(f"{par_an} heures par an")
print(f"soit {par_an // 24} jours entiers")

▷ Erreur fréquente. Oublier int(...) autour de input. La réponse tapée reste du texte : "3" * 365 ne multiplie pas, il répète le texte \(365\) fois, puis par_an // 24 provoque une erreur (TypeError).

★★ Exercice 19 — Le temps de téléchargement #

▶ Demander la taille d’un fichier en mégaoctets (Mo), puis le débit de la connexion en mégaoctets par seconde (Mo/s : chaque seconde, on reçoit ce nombre de mégaoctets). Ce sont des nombres à virgule, à taper avec un point : convertir avec float. Afficher ensuite en une seule f-string : « Un fichier de T Mo se télécharge en D secondes. » Test : \(45\) Mo à \(2{,}5\) Mo/s donnent \(18\) secondes.

Coup de pouce

Combien de secondes faut-il pour recevoir \(45\) Mo si l’on en reçoit \(2{,}5\) chaque seconde ? Posez le calcul avec les nombres, puis remplacez-les par les variables. Convertissez chaque input avec float(...) avant de calculer.

Corrigé

Chaque seconde, on reçoit debit mégaoctets : la durée est donc la taille divisée par le débit. float convertit le texte saisi en nombre à virgule (int planterait sur 2.5).

taille = float(input("Taille du fichier (Mo) : "))
debit = float(input("Debit (Mo/s) : "))
print(f"Un fichier de {taille} Mo se telecharge en {taille / debit} secondes.")

Avec \(45\) et \(2.5\), le programme affiche : Un fichier de 45.0 Mo se telecharge en 18.0 secondes.

★★ Exercice 20 — L’écho #

▶ Demander un mot puis un nombre entier n à l’utilisateur, et afficher le mot répété n fois collé (par exemple "go" et \(3\) donnent gogogo).

Coup de pouce

Avec les chaînes, * répète : "ha" * 2 donne "haha". Le nombre saisi doit d’abord être converti avec int.

Corrigé

Avec les chaînes, * répète.

mot = input("Un mot : ")
n = int(input("Combien de fois ? "))
print(mot * n)

★★ Exercice 21 — Le ticket de caisse #

▶ Demander le nom d’un article, son prix unitaire (nombre à virgule) et la quantité achetée (entier), puis afficher un ticket encadré par des lignes de tirets, par exemple :

Coup de pouce

Commencez par les trois input (avec les bonnes conversions), calculez le total, puis enchaînez les print. Une ligne de tirets peut s’écrire "-" * 20.

--------------------
3 x croissant
Prix unitaire : 1.5
TOTAL : 4.5 euros
--------------------
Corrigé

On convertit chaque saisie dans le bon type, on calcule le total, puis on affiche une ligne de tirets avant et après ("-" * 20 répète le tiret \(20\) fois).

article = input("Article : ")
prix = float(input("Prix unitaire : "))
quantite = int(input("Quantite : "))
print("-" * 20)
print(f"{quantite} x {article}")
print(f"Prix unitaire : {prix}")
print(f"TOTAL : {prix * quantite} euros")
print("-" * 20)

Les fonctions#

★ Exercice 22 — Les codes PIN #

• essentiel

▶ Un code PIN est formé de chiffres (chacun de \(0\) à \(9\)). Avec \(1\) chiffre, il y a \(10\) codes possibles ; avec \(2\) chiffres, \(10 \times 10 = 100\) ; chaque chiffre de plus multiplie le nombre de codes par \(10\). Écrire une fonction nb_codes(n) qui renvoie le nombre de codes possibles à n chiffres. Tester avec nb_codes(4) (attendu : \(10\,000\)).

Coup de pouce

Avec \(3\) chiffres, on a \(10 \times 10 \times 10\) codes. Quel opérateur de Python calcule une puissance ?

Corrigé

Avec n chiffres, on multiplie n fois par \(10\) : c’est \(10^n\), qui s’écrit 10 ** n en Python.

def nb_codes(n):
    return 10 ** n

print(nb_codes(4))   # 10000

Seulement \(10\,000\) codes à \(4\) chiffres : c’est pour cela qu’un téléphone se bloque après quelques essais ratés.

▷ Erreur fréquente. Écrire print(10 ** n) au lieu de return 10 ** n dans la fonction. L’écran montre bien \(10000\), mais nb_codes(4) ne renvoie rien (None) : impossible de réutiliser le résultat dans un calcul.

★ Exercice 23 — L’aire du triangle #

▶ Écrire une fonction aire_triangle(base, hauteur) qui renvoie l’aire d’un triangle (rappel : \(\dfrac{\text{base} \times \text{hauteur}}{2}\)).

Coup de pouce

Le corps de la fonction tient en une ligne : return suivi du calcul, écrit avec les noms des paramètres.

Corrigé
def aire_triangle(base, hauteur):
    return base * hauteur / 2

print(aire_triangle(6, 4))   # 12.0

★★ Exercice 24 — Une note sur 20 #

▶ Un contrôle est noté sur un total qui n’est pas toujours \(20\). Écrire une fonction note_sur_20(points, total) qui renvoie la note ramenée sur \(20\). Vérifier que note_sur_20(12, 15) vaut \(16\).

Coup de pouce

Règle de trois : \(12\) points sur \(15\), combien cela fait-il sur \(20\) ? Écrivez le calcul avec les nombres, puis remplacez-les par points et total.

Corrigé

C’est une proportionnalité : \(\dfrac{\text{points}}{\text{total}} \times 20\).

def note_sur_20(points, total):
    return points * 20 / total

print(note_sur_20(12, 15))   # 16.0

★★ Exercice 25 — Retrouver le poids d’origine #

▶ Une messagerie compresse les photos avant de les envoyer : la photo envoyée pèse \(75\,\%\) du poids de la photo d’origine. Écrire une fonction poids_origine(poids_envoye) qui renvoie le poids de la photo d’origine. Vérifier que poids_origine(3) vaut \(4\) (en Mo). (Attention : ajouter \(25\,\%\) au poids envoyé ne donne pas le bon résultat !)

Coup de pouce

Compresser revient à multiplier le poids d’origine par \(0{,}75\). Pour revenir en arrière, quelle opération faut-il faire ?

Corrigé

Le poids envoyé vaut \(0{,}75\) fois le poids d’origine, donc on divise par \(0{,}75\). (Ajouter \(25\,\%\) à \(3\) donnerait \(3{,}75\), et \(3{,}75 \times 0{,}75 = 2{,}8125 \neq 3\).)

def poids_origine(poids_envoye):
    return poids_envoye / 0.75

print(poids_origine(3))   # 4.0

★★ Exercice 26 — Le poids d’une photo #

• essentiel

▶ Une photo numérique non compressée utilise \(3\) octets par pixel (un pour le rouge, un pour le vert, un pour le bleu). Écrire une fonction poids_photo(largeur, hauteur) qui renvoie le poids de l’image en octets, puis calculer celui d’une photo de \(4000 \times 3000\) pixels. Combien de mégaoctets cela fait-il (\(1\) Mo \(= 1\,000\,000\) octets) ?

Coup de pouce

Nombre de pixels \(=\) largeur \(\times\) hauteur, et chaque pixel occupe \(3\) octets. Pour obtenir des mégaoctets, divisez par \(1\,000\,000\).

Corrigé

Nombre de pixels \(\times 3\) octets.

def poids_photo(largeur, hauteur):
    return largeur * hauteur * 3

print(poids_photo(4000, 3000))   # 36000000

Soit \(36\) Mo : c’est pour cela que les appareils compressent les photos (JPEG).

★★ Exercice 27 — Tout en secondes #

▶ Écrire une fonction en_secondes(h, m, s) qui prend une durée en heures, minutes et secondes et renvoie cette durée convertie en secondes. Tester avec en_secondes(1, 30, 15) (on doit obtenir \(5415\)).

Coup de pouce

Une heure contient \(3600\) secondes et une minute \(60\) secondes : convertissez chaque morceau, puis additionnez.

Corrigé

Une heure vaut \(3600\) s et une minute \(60\) s.

def en_secondes(h, m, s):
    return h * 3600 + m * 60 + s

print(en_secondes(1, 30, 15))   # 5415

★★ Exercice 28 — Deviner l’affichage (fonctions) #

• essentiel

sur papier Sans machine, écrire ce qu’affiche ce programme, puis vérifier sur machine.

def f(x):
    return 2 * x + 1

def g(x):
    return x * x

print(f(3))
print(g(f(1)))
print(f(g(2)) + 1)
Coup de pouce

Calculez de l’intérieur vers l’extérieur : pour g(f(1)), calculez d’abord f(1), puis donnez ce résultat à g.

Corrigé

On calcule de l’intérieur vers l’extérieur.

  • f(3) \(= 2 \times 3 + 1 = 7\) : affiche 7 ;

  • f(1) \(= 3\), puis g(3) \(= 9\) : affiche 9 ;

  • g(2) \(= 4\), puis f(4) \(= 9\), et \(9 + 1 = 10\) : affiche 10.

★★★ Exercice 29 — Le coût d’un trajet #

≈ 15 min

▶ Une voiture consomme conso litres d’essence aux \(100\) km.

  1. Écrire une fonction litres(distance, conso) qui renvoie le nombre de litres consommés pour parcourir distance kilomètres.

  2. Écrire une fonction cout_trajet(distance, conso, prix_litre) qui renvoie le coût du trajet en euros en appelant litres.

  3. Combien coûte un trajet de \(800\) km avec une voiture qui consomme \(6\) L aux \(100\) km, si l’essence coûte \(2\) € le litre ?

Coup de pouce

Pour \(100\) km, la voiture consomme conso litres : pour \(1\) km, elle consomme donc conso / 100 litres.

Coup de pouce 2 (début de solution)

def cout_trajet(distance, conso, prix_litre):
nb_litres = litres(distance, conso)
puis on multiplie par le prix d’un litre.

Corrigé

cout_trajet réutilise litres au lieu de réécrire le calcul.

def litres(distance, conso):
    return distance * conso / 100

def cout_trajet(distance, conso, prix_litre):
    return litres(distance, conso) * prix_litre

print(cout_trajet(800, 6, 2))   # 96.0

Le trajet consomme \(48\) L et coûte \(96\) €.

Les conditions#

★ Exercice 30 — Le code secret #

• essentiel

▶ Écrire une fonction verifier(code) qui renvoie "Acces autorise" si le code reçu vaut \(2468\), et "Acces refuse" sinon.

Coup de pouce

Un if pour le bon code, un else pour tous les autres. Relisez dans le cours quel signe sert à comparer deux valeurs.

Corrigé

Un if pour le bon code, un else pour tous les autres.

def verifier(code):
    if code == 2468:
        return "Acces autorise"
    else:
        return "Acces refuse"

▷ Erreur fréquente. Écrire if code = 2468: avec un seul signe égal : Python refuse le programme (SyntaxError). Le = simple range une valeur ; pour comparer, il faut ==.

★★ Exercice 31 — Pair ? #

▶ Écrire une fonction est_pair(n) qui renvoie True si n est pair et False sinon.

Coup de pouce

La comparaison n % 2 == 0 vaut déjà True ou False : on peut la renvoyer directement.

Corrigé

La comparaison n % 2 == 0 est déjà un booléen : on le renvoie directement.

def est_pair(n):
    return n % 2 == 0

★★ Exercice 32 — Le signe #

▶ Écrire une fonction signe(x) qui renvoie "negatif", "nul" ou "positif" selon le nombre reçu (utiliser elif).

Coup de pouce

Trois cas, donc : if pour le premier, elif pour le deuxième, else pour le dernier.

Corrigé

Trois cas, donc if / elif / else.

def signe(x):
    if x < 0:
        return "negatif"
    elif x == 0:
        return "nul"
    else:
        return "positif"

★★ Exercice 33 — Le découpage en paquets #

▶ Sur un réseau, un fichier voyage découpé en paquets de \(1500\) octets au plus : tous les paquets sont pleins, sauf peut-être le dernier. Écrire un programme qui demande la taille d’un fichier (en octets, un entier), puis affiche « Il faut n paquets. » (avec la vraie valeur, à l’aide d’une f-string). Tester avec \(3000\) (\(2\) paquets) et \(3001\) (\(3\) paquets).

Coup de pouce

Avec \(3001\) octets : combien de paquets pleins de \(1500\) octets ? Reste-t-il des octets à envoyer ? Pensez à // et à %.

Corrigé

taille // 1500 donne le nombre de paquets pleins ; s’il reste des octets (taille % 1500 différent de \(0\)), il faut un paquet de plus pour eux.

taille = int(input("Taille du fichier (octets) : "))
paquets = taille // 1500
if taille % 1500 != 0:
    paquets = paquets + 1
print(f"Il faut {paquets} paquets.")

Pour \(3000\) octets : \(2\) paquets (reste \(0\)) ; pour \(3001\) octets : \(2\) paquets pleins et un dernier paquet d’un seul octet, soit \(3\) paquets.

★★ Exercice 34 — Valeur absolue maison #

▶ Écrire une fonction valeur_absolue(x) qui renvoie la valeur absolue de x sans utiliser la fonction abs de Python (se servir d’un if).

Coup de pouce

Quels sont les deux cas possibles selon le signe de x ? Que vaut la valeur absolue dans chacun d’eux ?

Corrigé

Si le nombre est négatif, on renvoie son opposé.

def valeur_absolue(x):
    if x < 0:
        return -x
    else:
        return x

★★ Exercice 35 — L’icône de batterie #

• essentiel

▶ Un téléphone affiche une icône selon le niveau de batterie (en %). Écrire une fonction icone(niveau) qui renvoie "critique" si le niveau est inférieur à \(10\), "faible" s’il est inférieur à \(30\), "moyenne" s’il est inférieur à \(70\), et "pleine" sinon. Tester avec \(5\), \(50\) et \(100\).

Coup de pouce

Testez les seuils dans l’ordre croissant avec if / elif : dès qu’une condition est vraie, les suivantes ne sont plus regardées.

Corrigé

On teste les seuils du plus bas au plus haut : le premier qui est vrai l’emporte.

def icone(niveau):
    if niveau < 10:
        return "critique"
    elif niveau < 30:
        return "faible"
    elif niveau < 70:
        return "moyenne"
    else:
        return "pleine"

print(icone(5))     # critique
print(icone(50))    # moyenne
print(icone(100))   # pleine

★★★ Exercice 36 — La meilleure antenne #

≈ 15 min

▶ Un téléphone capte trois antennes-relais et se connecte à celle dont le signal est le plus fort. Écrire une fonction meilleur_signal(a, b, c) qui renvoie le plus grand des trois niveaux de signal reçus (sans utiliser la fonction max de Python). Tester avec meilleur_signal(40, 75, 62) (attendu : \(75\)).

Coup de pouce

Gardez le plus grand niveau « vu jusqu’ici » dans une variable grand, puis comparez-la aux autres niveaux un par un.

Coup de pouce 2 (début de solution)

grand = a
if b > grand:
grand = b
puis la même chose avec c, et enfin return grand.

Corrigé

On garde le plus grand niveau vu jusqu’ici dans une variable grand.

def meilleur_signal(a, b, c):
    grand = a
    if b > grand:
        grand = b
    if c > grand:
        grand = c
    return grand

print(meilleur_signal(40, 75, 62))   # 75

★★★ Exercice 37 — Année bissextile #

≈ 15 min

▶ Écrire une fonction bissextile(annee) qui renvoie True si l’année est bissextile. Règle : une année est bissextile si elle est divisible par \(4\), sauf les années de siècle (divisibles par \(100\)) qui doivent en plus être divisibles par \(400\). Tester avec \(2024\) (oui), \(1900\) (non) et \(2000\) (oui).

Coup de pouce

« Divisible par \(4\) » s’écrit annee % 4 == 0. Traitez les cas du plus particulier au plus général : d’abord \(400\), puis \(100\), puis \(4\).

Coup de pouce 2 (début de solution)

if annee % 400 == 0:
return True
elif annee % 100 == 0:
return False

Corrigé

On traite les cas du plus particulier au plus général : d’abord \(400\), puis \(100\), puis \(4\) (le premier test vrai l’emporte).

def bissextile(annee):
    if annee % 400 == 0:
        return True
    elif annee % 100 == 0:
        return False
    elif annee % 4 == 0:
        return True
    else:
        return False

print(bissextile(2024))   # True
print(bissextile(1900))   # False
print(bissextile(2000))   # True

Autre écriture, en une seule condition : divisible par \(4\) et pas par \(100\), ou divisible par \(400\).

def bissextile(annee):
    return (annee % 4 == 0 and annee % 100 != 0) or (annee % 400 == 0)

★★ Exercice 38 — Une couleur valide ? #

▶ Sur un écran, une couleur est codée par trois nombres : sa part de rouge, de vert et de bleu. Chacun doit être compris entre \(0\) et \(255\) (bornes incluses). Écrire une fonction couleur_valide(rouge, vert, bleu) qui renvoie True si les trois nombres sont valides, et False sinon. Tester avec couleur_valide(255, 128, 0) (True) et couleur_valide(300, 0, 0) (False).

Coup de pouce

Chaque nombre doit être à la fois supérieur ou égal à \(0\) et inférieur ou égal à \(255\), et cela pour les trois nombres : toutes ces conditions doivent être vraies, pensez à and.

Corrigé

Chaque nombre doit être entre \(0\) et \(255\) : deux comparaisons reliées par and pour chacun, puis les trois résultats reliés par and.

def couleur_valide(rouge, vert, bleu):
    rouge_ok = rouge >= 0 and rouge <= 255
    vert_ok = vert >= 0 and vert <= 255
    bleu_ok = bleu >= 0 and bleu <= 255
    return rouge_ok and vert_ok and bleu_ok

print(couleur_valide(255, 128, 0))   # True
print(couleur_valide(300, 0, 0))     # False

(Avec l’écriture raccourcie vue dans le cours : 0 <= rouge <= 255.) On retrouvera ces nombres de \(0\) à \(255\) au chapitre sur la photographie numérique.

▷ Erreur fréquente. Relier les conditions par or : couleur_valide(300, 0, 0) renverrait alors True, puisqu’il suffirait qu’une condition soit vraie. Ici, toutes doivent l’être.

Les boucles#

★ Exercice 39 — De 1 à 10 #

• essentiel

▶ Écrire un programme qui affiche tous les entiers de \(1\) à \(10\) (boucle for).

Coup de pouce

range(1, 6) donne \(1, 2, 3, 4, 5\) : la borne de droite est exclue. Que faut-il écrire pour aller jusqu’à \(10\) ?

Corrigé

range(1, 11) va de \(1\) inclus à \(11\) exclu.

for i in range(1, 11):
    print(i)

▷ Erreur fréquente. Écrire range(10) (qui affiche \(0\) à \(9\)) ou range(1, 10) (qui s’arrête à \(9\)) : la borne de droite n’est jamais atteinte.

★ Exercice 40 — Trace de boucle #

• essentiel

sur papier Sans machine, écrire ce qu’affiche ce programme, puis vérifier.

for i in range(4):
    print(i * i)
Coup de pouce

Notez d’abord la liste des valeurs que prend i avec range(4) (on part de \(0\)), puis calculez i * i pour chacune.

Corrigé

Sur papier. i prend les valeurs \(0, 1, 2, 3\) ; on affiche \(i \times i\) :

0
1
4
9

★★ Exercice 41 — Un message qui se propage #

• essentiel

▶ Une personne publie un message (étape \(0\)). À l’étape \(1\), ses \(3\) amis le reçoivent ; à l’étape \(2\), chacun d’eux le relaie à \(3\) nouveaux amis, soit \(9\) personnes ; et ainsi de suite (on suppose que personne ne le reçoit deux fois) : à l’étape i, \(3^i\) nouvelles personnes reçoivent le message. Écrire une fonction diffusion(n) qui renvoie le nombre total de personnes touchées de l’étape \(0\) à l’étape n (l’auteur compris). Vérifier que diffusion(3) vaut \(40\), puis calculer diffusion(10).

Coup de pouce

À l’étape i, 3 ** i personnes reçoivent le message. Additionnez-les dans une variable total qui commence à \(0\), en parcourant range(n + 1).

Corrigé

On accumule dans total le nombre de personnes touchées à chaque étape, de \(0\) à n inclus.

def diffusion(n):
    total = 0
    for i in range(n + 1):
        total = total + 3 ** i
    return total

print(diffusion(3))    # 40
print(diffusion(10))   # 88573

\(1 + 3 + 9 + 27 = 40\). En \(10\) étapes seulement, près de \(90\,000\) personnes : c’est ainsi qu’un message devient « viral ».

▷ Erreur fréquente. Écrire total = 0 à l’intérieur de la boucle : le total repart de \(0\) à chaque tour et la fonction ne renvoie que le dernier terme (\(27\) pour diffusion(3)). Autre piège : range(n) oublie la dernière étape.

★★ Exercice 42 — Les puissances de 2 #

▶ Écrire une fonction puissances_de_2(n) qui affiche \(2^0, 2^1, 2^2, \ldots, 2^n\), une valeur par ligne. Que vaut \(2^{10}\) ? (Ce nombre est partout en informatique !)

Coup de pouce

La boucle for i in range(n + 1) parcourt \(0, 1, \ldots, n\) ; à chaque tour, on affiche 2 ** i.

Corrigé

range(n + 1) va de \(0\) à \(n\) inclus. On trouve \(2^{10} = 1024\).

def puissances_de_2(n):
    for i in range(n + 1):
        print(2 ** i)

puissances_de_2(10)   # 1, 2, 4, ..., 1024

★★ Exercice 43 — Les écouteurs #

• essentiel

▶ Léa part de \(0\) € et économise \(15\) € par semaine. Avec une boucle while, calculer et afficher au bout de combien de semaines elle aura au moins \(200\) € pour s’offrir des écouteurs.

Coup de pouce

Deux variables : economies et semaines. Tant que les économies sont inférieures à \(200\), on ajoute \(15\) et on compte une semaine de plus.

Corrigé

On ne sait pas à l’avance combien de semaines il faudra : c’est un while.

economies = 0
semaines = 0
while economies < 200:
    economies = economies + 15
    semaines = semaines + 1
print(semaines)   # 14 (210 euros)

★★ Exercice 44 — Les multiples de 7 #

▶ Écrire un programme qui compte (sans les afficher) combien il y a de multiples de \(7\) entre \(1\) et \(1000\), puis affiche ce nombre.

Coup de pouce

Un compteur commence à \(0\) ; on parcourt les nombres de \(1\) à \(1000\) et on ajoute \(1\) au compteur lorsque le nombre est multiple de \(7\) (avec %).

Corrigé

Un compteur qu’on augmente à chaque multiple rencontré (le test % dans la boucle).

compteur = 0
for n in range(1, 1001):
    if n % 7 == 0:
        compteur = compteur + 1
print(compteur)   # 142

Autre méthode, sans boucle : tout simplement 1000 // 7.

★★★ Exercice 45 — Les abonnés #

≈ 15 min

▶ Le compte d’une créatrice de vidéos gagne \(3\,\%\) d’abonnés par mois : chaque mois, son nombre d’abonnés est multiplié par \(1{,}03\). Écrire une fonction abonnes(depart, n) qui renvoie le nombre d’abonnés au bout de n mois, à l’aide d’une boucle for (sans utiliser **). Vérifier que abonnes(1000, 10) vaut environ \(1343{,}92\) (soit environ \(1344\) abonnés).

Coup de pouce

Une variable a part de depart ; chaque mois (un tour de boucle), elle est multipliée par \(1{,}03\).

Coup de pouce 2 (début de solution)

def abonnes(depart, n):
a = depart
for mois in range(n):

Corrigé

On multiplie le nombre d’abonnés par \(1{,}03\) autant de fois qu’il y a de mois.

def abonnes(depart, n):
    a = depart
    for mois in range(n):
        a = a * 1.03
    return a

print(abonnes(1000, 10))   # 1343.916...

Le calcul donne un nombre à virgule ; on l’arrondit : environ \(1344\) abonnés. Remarquer que le compte gagne \(344\) abonnés en \(10\) mois, et non \(10 \times 30 = 300\) : chaque mois, les \(3\,\%\) portent sur un nombre d’abonnés plus grand.

★★★ Exercice 46 — Combien de chiffres ? #

≈ 15 min

▶ Écrire une fonction nb_chiffres(n) qui renvoie le nombre de chiffres d’un entier positif. Par exemple nb_chiffres(2048) vaut \(4\).

Coup de pouce

Diviser par \(10\) avec // enlève le dernier chiffre (2048 // 10 vaut 204). Comptez combien de fois on peut le faire, dans une boucle while, avant d’arriver à \(0\).

Coup de pouce 2 (début de solution)

compteur = 0
while n > 0:
n = n // 10
(il reste à augmenter le compteur et à le renvoyer.)

Corrigé

Chaque division entière par \(10\) retire le dernier chiffre ; on compte les étapes.

def nb_chiffres(n):
    compteur = 0
    while n > 0:
        n = n // 10
        compteur = compteur + 1
    return compteur

print(nb_chiffres(2048))   # 4

★★★ Exercice 47 — Nombre premier #

≈ 20 min

▶ Écrire une fonction est_premier(n) qui renvoie True si n est un nombre premier (divisible seulement par \(1\) et par lui-même), et False sinon.

Coup de pouce

n est premier s’il vaut au moins \(2\) et si aucun nombre d compris entre \(2\) et n - 1 ne le divise. Dès qu’on trouve un diviseur, on peut répondre.

Coup de pouce 2 (début de solution)

if n < 2:
return False
for d in range(2, n):
if n % d == 0:

Corrigé

On cherche un diviseur entre \(2\) et \(n - 1\) ; s’il en existe un, n n’est pas premier.

def est_premier(n):
    if n < 2:
        return False
    for d in range(2, n):
        if n % d == 0:
            return False
    return True

return arrête immédiatement la fonction, même au milieu d’une boucle : dès qu’un diviseur est trouvé, on renvoie False sans tester les suivants. Si la boucle va jusqu’au bout sans trouver de diviseur, on arrive à la dernière ligne, return True.

Petits défis de synthèse#

★★ Exercice 48 — Fizz #

≈ 10 min

▶ Afficher les entiers de \(1\) à \(30\), mais remplacer par le mot « Fizz » ceux qui sont des multiples de \(3\).

Coup de pouce

Une boucle for de \(1\) à \(30\) ; à chaque tour, un if teste si le nombre est multiple de \(3\) (avec %) ; sinon (else), on affiche le nombre.

Corrigé
for i in range(1, 31):
    if i % 3 == 0:
        print("Fizz")
    else:
        print(i)

★★★ Exercice 49 — L’ordinateur devine #

≈ 30 min

▶ Cette fois, c’est l’utilisateur qui pense à un nombre entre \(1\) et \(100\), et l’ordinateur qui cherche. Il propose toujours le milieu de l’intervalle encore possible (variables bas et haut) ; l’utilisateur répond + (c’est plus grand), - (c’est plus petit) ou = (trouvé), et il resserre l’intervalle. Afficher à la fin le nombre d’essais. Combien lui en faut-il au maximum ?

Coup de pouce

Le nombre proposé est (bas + haut) // 2. Si l’utilisateur répond +, le nombre cherché est au-dessus de la proposition : que devient alors bas ?

Coup de pouce 2 (début de solution)

bas = 1
haut = 100
essais = 0
reponse = ""
while reponse != "=":

Corrigé

À chaque réponse, l’intervalle est coupé en deux : c’est la recherche par dichotomie.

bas = 1
haut = 100
essais = 0
reponse = ""
while reponse != "=":
    proposition = (bas + haut) // 2
    essais = essais + 1
    reponse = input(f"Je propose {proposition} (+, - ou =) : ")
    if reponse == "+":
        bas = proposition + 1
    elif reponse == "-":
        haut = proposition - 1
print(f"Trouve en {essais} essais !")

Au maximum \(7\) essais : chaque essai divise l’intervalle par deux, et \(2^7 = 128 \geq 100\).

★★★ Exercice 50 — Moyenne d’une série de notes #

≈ 20 min

▶ L’utilisateur saisit des notes une par une ; il tape \(-1\) pour terminer. Afficher alors la moyenne des notes saisies.

Coup de pouce

Boucle while : on ne sait pas combien de notes il y aura. Gardez la somme et le nombre de notes ; la valeur \(-1\) ne doit pas être comptée.

Coup de pouce 2 (début de solution)

somme = 0
nombre = 0
note = float(input("Note : "))
while note != -1:

Corrigé

On lit une première note, puis on continue tant que ce n’est pas \(-1\).

somme = 0
nombre = 0
note = float(input("Note (-1 pour finir) : "))
while note != -1:
    somme = somme + note
    nombre = nombre + 1
    note = float(input("Note (-1 pour finir) : "))
if nombre > 0:
    print(f"Moyenne : {somme / nombre}")
else:
    print("Aucune note saisie.")

★★★ Exercice 51 — Le PGCD #

≈ 15 min

▶ Écrire une fonction pgcd(a, b) qui renvoie le plus grand diviseur commun de deux entiers, par la méthode des soustractions successives : tant que les deux nombres sont différents, on remplace le plus grand par sa différence avec le plus petit. Tester avec pgcd(24, 36) (attendu : \(12\)).

Coup de pouce

Boucle while a != b ; à chaque tour, un if décide lequel des deux nombres est le plus grand.

Coup de pouce 2 (début de solution)

while a != b:
if a > b:
a = a - b

Corrigé

Tant que les deux nombres diffèrent, on remplace le plus grand par sa différence avec le plus petit.

def pgcd(a, b):
    while a != b:
        if a > b:
            a = a - b
        else:
            b = b - a
    return a

print(pgcd(24, 36))   # 12

Critiquer une réponse d’IA#

★★ Exercice 52 — Une puissance calculée par un assistant #

• essentiel

▶ Un élève a demandé à un assistant d’IA : « Écris une fonction puissance(x, n) qui renvoie x multiplié n fois par lui-même, avec une boucle for et sans utiliser l’opérateur **. » Voici la réponse obtenue :

def puissance(x, n):
    resultat = 1
    for i in range(n + 1):
        resultat = resultat * x
    return resultat

print(puissance(2, 3))   # affiche 8
  1. La réponse est-elle correcte ? Recopier la fonction, l’exécuter et comparer ce qui s’affiche avec le commentaire de l’assistant. Tester aussi puissance(5, 2) et puissance(3, 0).

  2. Localiser l’erreur et corriger la fonction (une seule ligne à modifier).

    Coup de pouce

    Comptez combien de tours fait range(n + 1) quand n vaut \(3\). Combien de fois faut-il multiplier par x ?

  3. Quelle vérification simple, faite avant de faire confiance à cette réponse, aurait suffi à détecter l’erreur ?

Corrigé

1. Non. L’exécution affiche 16 et non 8 comme l’annonce le commentaire ; de même puissance(5, 2) donne 125 au lieu de 25, et puissance(3, 0) donne 3 au lieu de 1.
2. L’erreur est dans range(n + 1) : cette suite contient \(n + 1\) nombres (\(0, 1, \ldots, n\)), donc la boucle multiplie une fois de trop. Il faut écrire range(n) (rappel du cours : range(5) fabrique cinq nombres, de \(0\) à \(4\)).

def puissance(x, n):
    resultat = 1
    for i in range(n):
        resultat = resultat * x
    return resultat

print(puissance(2, 3))   # affiche bien 8

3. Exécuter la fonction sur un petit exemple dont on connaît le résultat (\(2 \times 2 \times 2 = 8\)) : le commentaire # affiche 8 n’est qu’une affirmation de l’assistant ; seule la console fait foi.