Exercices - Langages et programmation
Constructions élémentaires
Section intitulée « Constructions élémentaires »Exercice 1 - Identifier les constructions
Section intitulée « Exercice 1 - Identifier les constructions »Pour chacun des extraits Python suivants, identifier les constructions élémentaires utilisées (affectation, séquence, conditionnelle, boucle bornée, boucle non bornée, appel de fonction).
a.
x = 10y = x * 2print(y)b.
for i in range(5): if i % 2 == 0: print(i, "est pair")c.
n = int(input("Nombre : "))while n != 1: if n % 2 == 0: n = n // 2 else: n = 3 * n + 1Solution
a. Affectation (x = 10, y = x * 2), séquence (les 3 instructions dans l'ordre), appel de fonction (print(y)).
b. Boucle bornée (for i in range(5)), conditionnelle (if i % 2 == 0), appel de fonction (print(...)).
c. Appel de fonction (int(input(...))), affectation (n = ...), boucle non bornée (while n != 1), conditionnelle (if n % 2 == 0), affectation dans les branches.
Exercice 2 - Portée des variables
Section intitulée « Exercice 2 - Portée des variables »Prédire la sortie de chaque programme sans l'exécuter.
a.
x = 5
def modifier(): x = 10 print("Dans la fonction :", x)
modifier()print("Après la fonction :", x)b.
def f(a, b): a = a + b return a
x = 3y = 7z = f(x, y)print(x, y, z)Solution
a.
Dans la fonction : 10Après la fonction : 5Le x = 10 dans la fonction crée une variable locale x, distincte de la variable globale x. La variable globale x reste à 5.
b.
3 7 10Le paramètre a reçoit une copie de x (3). a = a + b modifie la copie locale (a vaut 10), mais x reste à 3. La fonction renvoie 10, stocké dans z.
Exercice 3 - Comparer Python et JavaScript
Section intitulée « Exercice 3 - Comparer Python et JavaScript »Traduire le programme Python suivant en JavaScript :
def compter_voyelles(texte): voyelles = "aeiouyAEIOUY" compteur = 0 for lettre in texte: if lettre in voyelles: compteur = compteur + 1 return compteur
resultat = compter_voyelles("Bonjour le monde")print(resultat)Solution
function compterVoyelles(texte) { let voyelles = "aeiouyAEIOUY"; let compteur = 0; for (let i = 0; i < texte.length; i++) { if (voyelles.includes(texte[i])) { compteur = compteur + 1; } } return compteur;}
let resultat = compterVoyelles("Bonjour le monde");console.log(resultat);Points de comparaison :
def→function,print()→console.log()- Indentation → accolades
{ } for lettre in texte:→for (let i = 0; i < texte.length; i++)in(appartenance) →.includes()
Spécification et tests
Section intitulée « Spécification et tests »Exercice 4 - Spécifier une fonction
Section intitulée « Exercice 4 - Spécifier une fonction »a. Écrire la spécification complète (prototype, docstring, préconditions, postconditions) de la fonction est_premier(n) qui teste si un entier est premier.
b. Implémenter la fonction.
c. Écrire un jeu d'au moins 6 tests couvrant des cas normaux, limites et particuliers.
def est_premier(n):
pass
Solution
a. et b.
def est_premier(n: int) -> bool: """Détermine si n est un nombre premier.
Preconditions: n est un entier strictement positif. Postconditions: Renvoie True si n est premier (divisible uniquement par 1 et lui-même). Renvoie False sinon. """ assert isinstance(n, int), "n doit être un entier" assert n > 0, "n doit être strictement positif"
if n <= 1: return False if n <= 3: return True if n % 2 == 0: return False d = 3 while d * d <= n: if n % d == 0: return False d += 2 return Truec.
# Cas limitesassert est_premier(1) == False, "1 n'est pas premier"assert est_premier(2) == True, "2 est premier"assert est_premier(3) == True, "3 est premier"
# Cas normauxassert est_premier(7) == True, "7 est premier"assert est_premier(10) == False, "10 n'est pas premier"assert est_premier(13) == True, "13 est premier"
# Cas particuliersassert est_premier(4) == False, "4 n'est pas premier"assert est_premier(97) == True, "97 est premier"assert est_premier(100) == False, "100 n'est pas premier"print("Tous les tests passent !")Exercice 5 - Trouver les erreurs
Section intitulée « Exercice 5 - Trouver les erreurs »La fonction suivante est censée renvoyer le nombre d'occurrences d'un élément dans un tableau. Elle contient des erreurs. Les trouver et les corriger.
def compter(tableau, element) compteur = 0 for i in range(len(tableau)): if tableau[i] = element: compteur + 1 return compteurSolution
Trois erreurs :
- Ligne 1 : il manque les
:après la parenthèse →def compter(tableau, element): - Ligne 4 :
=est une affectation, il faut==pour la comparaison →if tableau[i] == element: - Ligne 5 :
compteur + 1calcule mais ne stocke pas le résultat →compteur = compteur + 1(oucompteur += 1)
Version corrigée :
def compter(tableau, element): compteur = 0 for i in range(len(tableau)): if tableau[i] == element: compteur += 1 return compteurExercice 6 - Tests avec doctest
Section intitulée « Exercice 6 - Tests avec doctest »Écrire la fonction pgcd(a, b) qui calcule le PGCD de deux entiers positifs par l'algorithme d'Euclide, avec des tests intégrés dans la docstring au format doctest.
Solution
def pgcd(a, b): """Calcule le PGCD de a et b par l'algorithme d'Euclide.
Preconditions: a et b entiers >= 0, pas tous les deux nuls.
>>> pgcd(12, 8) 4 >>> pgcd(7, 3) 1 >>> pgcd(100, 25) 25 >>> pgcd(17, 0) 17 >>> pgcd(0, 5) 5 >>> pgcd(48, 18) 6 """ assert isinstance(a, int) and isinstance(b, int) assert a >= 0 and b >= 0 assert not (a == 0 and b == 0)
while b != 0: a, b = b, a % b return a
if __name__ == "__main__": import doctest doctest.testmod()Modules et mise au point
Section intitulée « Modules et mise au point »Exercice 7 - Utiliser des modules
Section intitulée « Exercice 7 - Utiliser des modules »a. En utilisant le module math, calculer : , (plafond), (plancher), .
b. En utilisant le module random, écrire une fonction lancer_des(n) qui simule le lancer de n dés à 6 faces et renvoie la somme.
c. Écrire une fonction mot_de_passe(longueur) qui génère un mot de passe aléatoire de la longueur donnée, composé de lettres minuscules et de chiffres.
Solution
a.
import math
print(math.sqrt(2)) # 1.4142135623730951print(math.ceil(7.3)) # 8print(math.floor(7.8)) # 7print(math.log2(256)) # 8.0b.
import random
def lancer_des(n): """Simule n lancers de dé et renvoie la somme.""" somme = 0 for _ in range(n): somme += random.randint(1, 6) return somme
print(lancer_des(3)) # un nombre entre 3 et 18c.
import random
def mot_de_passe(longueur): """Génère un mot de passe aléatoire.""" caracteres = "abcdefghijklmnopqrstuvwxyz0123456789" mdp = "" for _ in range(longueur): mdp += random.choice(caracteres) return mdp
print(mot_de_passe(12)) # ex: "k7m2pq9xf4a1"Exercice 8 - Créer un module
Section intitulée « Exercice 8 - Créer un module »a. Créer un module geometrie.py contenant les fonctions :
aire_cercle(rayon)→ renvoie l'aire du cercle ()perimetre_cercle(rayon)→ renvoie le périmètre ()aire_triangle(base, hauteur)→ renvoie l'aire ()
b. Ajouter des assertions de précondition (rayon, base et hauteur > 0).
c. Ajouter un bloc if __name__ == "__main__" avec des tests.
d. Utiliser ce module depuis un fichier programme.py.
Solution
geometrie.py :
import math
def aire_cercle(rayon): """Renvoie l'aire d'un cercle de rayon donné.""" assert rayon > 0, "Le rayon doit être strictement positif" return math.pi * rayon ** 2
def perimetre_cercle(rayon): """Renvoie le périmètre d'un cercle de rayon donné.""" assert rayon > 0, "Le rayon doit être strictement positif" return 2 * math.pi * rayon
def aire_triangle(base, hauteur): """Renvoie l'aire d'un triangle.""" assert base > 0 and hauteur > 0, "Base et hauteur doivent être positives" return base * hauteur / 2
if __name__ == "__main__": assert abs(aire_cercle(1) - math.pi) < 0.001 assert abs(perimetre_cercle(1) - 2 * math.pi) < 0.001 assert aire_triangle(6, 4) == 12.0 print("Tests OK !")programme.py :
from geometrie import aire_cercle, aire_triangle
print(f"Aire d'un cercle de rayon 5 : {aire_cercle(5):.2f}")print(f"Aire d'un triangle 10x6 : {aire_triangle(10, 6):.2f}")Exercice 9 - Déboguer un programme
Section intitulée « Exercice 9 - Déboguer un programme »Le programme suivant est censé renvoyer la liste des nombres premiers inférieurs à n. Il contient une erreur de logique. La trouver en utilisant des affichages intermédiaires.
def premiers_jusqu_a(n): resultat = [] for candidat in range(2, n): est_premier = True for diviseur in range(2, candidat): if candidat % diviseur == 0: est_premier = False if est_premier: resultat.append(candidat) return resultat
print(premiers_jusqu_a(20))a. Exécuter le programme. Le résultat est-il correct ?
b. Si non, ajouter des print() pour identifier le problème et corriger.
Solution
a. Le programme fonctionne correctement et renvoie [2, 3, 5, 7, 11, 13, 17, 19].
Cependant, il est inefficace : même après avoir trouvé un diviseur, la boucle interne continue. On peut l'optimiser avec un break :
b.
def premiers_jusqu_a(n): resultat = [] for candidat in range(2, n): est_premier = True for diviseur in range(2, candidat): if candidat % diviseur == 0: est_premier = False break # inutile de continuer, on sait que c'est pas premier if est_premier: resultat.append(candidat) return resultatOn peut aussi optimiser en ne testant que jusqu'à :
import math
def premiers_jusqu_a(n): resultat = [] for candidat in range(2, n): est_premier = True for diviseur in range(2, int(math.sqrt(candidat)) + 1): if candidat % diviseur == 0: est_premier = False break if est_premier: resultat.append(candidat) return resultatExercice 10 - Messages d'erreur
Section intitulée « Exercice 10 - Messages d'erreur »Pour chaque extrait de code, prédire le type d'erreur Python qui sera levée et expliquer pourquoi.
a. print(10 / 0)
b. int("abc")
c. [1, 2, 3][5]
d. "3" + 5
e. {"a": 1}["b"]
Solution
a. ZeroDivisionError : division par zéro, opération mathématiquement interdite.
b. ValueError : la chaîne "abc" ne peut pas être convertie en entier.
c. IndexError: list index out of range : l'indice 5 n'existe pas dans une liste de 3 éléments (indices 0, 1, 2).
d. TypeError: can only concatenate str to str : on ne peut pas additionner une chaîne et un entier. Il faudrait écrire "3" + str(5) ou int("3") + 5.
e. KeyError: 'b' : la clé "b" n'existe pas dans le dictionnaire. On peut utiliser .get("b", valeur_defaut) pour éviter l'erreur.
Activités
Section intitulée « Activités »Activité 1 - Le même algorithme en plusieurs langages
Section intitulée « Activité 1 - Le même algorithme en plusieurs langages »a. Écrire une fonction qui calcule le maximum d'un tableau en Python, JavaScript et pseudo-code.
b. Pour chaque version, identifier : la déclaration de fonction, la boucle, la condition, le retour de valeur.
c. Quels sont les traits communs entre ces langages ? Quels sont les traits particuliers à chaque langage ?
Correction
Python :
def maximum(tableau): maxi = tableau[0] for element in tableau: if element > maxi: maxi = element return maxiJavaScript :
function maximum(tableau) { let maxi = tableau[0]; for (let i = 0; i < tableau.length; i++) { if (tableau[i] > maxi) { maxi = tableau[i]; } } return maxi;}Traits communs : mot-clé return, variable maxi, comparaison >, structure if.
Différences : Python utilise for element in tableau (itération directe) et l'indentation, JavaScript utilise for (let i=0; ...) (itération par indice) et les accolades.
Activité 2 - Atelier TDD
Section intitulée « Activité 2 - Atelier TDD »On souhaite écrire une fonction cesar(texte, decalage) qui chiffre un texte par le chiffre de César (décalage de chaque lettre dans l'alphabet).
a. Écrire d'abord les tests :
assert cesar("ABC", 3) == "DEF"assert cesar("XYZ", 3) == "ABC"assert cesar("HELLO", 0) == "HELLO"assert cesar("NSI", 13) == "AFV"assert cesar("abc", 1) == "bcd"b. Implémenter la fonction pour que tous les tests passent. Les caractères non alphabétiques restent inchangés.
c. Écrire la fonction de déchiffrement decesar(texte, decalage) et vérifier que decesar(cesar(texte, d), d) == texte.
Correction
def cesar(texte, decalage): """Chiffre un texte par le chiffre de César.""" resultat = "" for c in texte: if "A" <= c <= "Z": resultat += chr((ord(c) - ord("A") + decalage) % 26 + ord("A")) elif "a" <= c <= "z": resultat += chr((ord(c) - ord("a") + decalage) % 26 + ord("a")) else: resultat += c return resultat
def decesar(texte, decalage): """Déchiffre un texte chiffré par César.""" return cesar(texte, -decalage)
# Testsassert cesar("ABC", 3) == "DEF"assert cesar("XYZ", 3) == "ABC"assert cesar("HELLO", 0) == "HELLO"assert cesar("NSI", 13) == "AFV"assert cesar("abc", 1) == "bcd"
# Test aller-retourassert decesar(cesar("Bonjour le monde", 7), 7) == "Bonjour le monde"print("Tous les tests passent !")Projet final - Bibliothèque de fonctions utilitaires
Section intitulée « Projet final - Bibliothèque de fonctions utilitaires »Partie A - Créer le module
Section intitulée « Partie A - Créer le module »a. Créer un fichier utilitaires.py contenant les fonctions suivantes, chacune avec docstring, préconditions et postconditions :
inverser(texte): renvoie le texte inverséest_palindrome(texte): vérifie si un texte est un palindrome (ignore la casse)compter_mots(texte): renvoie le nombre de mots dans un textefrequence_lettres(texte): renvoie un dictionnaire des fréquences de chaque lettre
Partie B - Tester
Section intitulée « Partie B - Tester »b. Écrire un jeu de tests complet pour chaque fonction (au moins 4 tests par fonction, incluant les cas limites).
c. Ajouter les tests dans la docstring au format doctest.
Partie C - Utiliser
Section intitulée « Partie C - Utiliser »d. Créer un fichier analyse.py qui importe le module et analyse un texte saisi par l'utilisateur : affiche le texte inversé, teste s'il est palindrome, compte les mots et affiche les 5 lettres les plus fréquentes.
Correction
utilitaires.py :
def inverser(texte): """Renvoie le texte inversé.
>>> inverser("Bonjour") 'ruojnoB' >>> inverser("") '' >>> inverser("a") 'a' >>> inverser("abba") 'abba' """ return texte[::-1]
def est_palindrome(texte): """Vérifie si texte est un palindrome (insensible à la casse).
>>> est_palindrome("kayak") True >>> est_palindrome("Kayak") True >>> est_palindrome("python") False >>> est_palindrome("") True >>> est_palindrome("a") True """ texte_min = texte.lower() return texte_min == texte_min[::-1]
def compter_mots(texte): """Renvoie le nombre de mots dans le texte.
>>> compter_mots("Bonjour le monde") 3 >>> compter_mots("") 0 >>> compter_mots("mot") 1 >>> compter_mots(" espaces multiples ") 2 """ if texte.strip() == "": return 0 return len(texte.split())
def frequence_lettres(texte): """Renvoie un dictionnaire des fréquences de chaque lettre (en minuscule).
>>> frequence_lettres("aab") {'a': 2, 'b': 1} >>> frequence_lettres("") {} >>> frequence_lettres("123") {} """ freq = {} for c in texte.lower(): if c.isalpha(): if c in freq: freq[c] += 1 else: freq[c] = 1 return freq
if __name__ == "__main__": import doctest doctest.testmod() print("Tous les tests passent !")analyse.py :
from utilitaires import inverser, est_palindrome, compter_mots, frequence_lettres
texte = input("Entrez un texte : ")
print(f"\nTexte inversé : {inverser(texte)}")print(f"Palindrome : {'Oui' if est_palindrome(texte) else 'Non'}")print(f"Nombre de mots : {compter_mots(texte)}")
freq = frequence_lettres(texte)top5 = sorted(freq.items(), key=lambda x: x[1], reverse=True)[:5]print("Top 5 des lettres :")for lettre, nombre in top5: print(f" '{lettre}' : {nombre} fois")© 2026 Corentin Dupont - LyCode
Créé avec Astro Starlight