⌂  Menu général
Ce support réunit les trois séances de révision utilisées en tout début d'année, avant d'attaquer le chapitre sur la programmation orientée objet. Il sert à la fois de support de projection en classe et de support de révision à la maison : cliquez sur « Voir la réponse » sous chaque exercice pour afficher le corrigé.

Séance 1 — Héron d'Alexandrie

Décomposition fonctionnelle et tests unitaires (assert)

Durée : 2hFonctions & assertBoucle while
Un peu d'histoire. Héron d'Alexandrie, ingénieur et mathématicien du 1er siècle après J.-C., a laissé son nom à une méthode simple pour approcher une racine carrée sans calculatrice.
  1. Choisir une première valeur d'essai.
  2. Améliorer l'essai : il devient la moyenne entre l'essai précédent et x / essai.
  3. Vérifier si l'approximation est suffisamment précise.
  4. Recommencer tant que ce n'est pas le cas.

Q1 moyenne

Écrire une fonction moyenne(a, b) qui calcule la moyenne de deux nombres.

Voir la réponse
def moyenne(a: float, b: float) -> float:
    """Calcule et retourne la moyenne des deux nombres a et b."""
    return (a + b) / 2

assert moyenne(12, 16) == 14
assert moyenne(0, 8) == 4

Q2 valeur_absolue

Écrire une fonction valeur_absolue(x) qui retourne |x| sans utiliser abs.

Voir la réponse
def valeur_absolue(x: float) -> float:
    """Calcule et retourne la valeur absolue du nombre x."""
    if x >= 0:
        return x
    else:
        return -x

assert valeur_absolue(3) == 3
assert valeur_absolue(-3) == 3

Q3 puissance

Écrire une fonction puissance(x, n) qui calcule x^n sans utiliser ** ni pow.

assert puissance(2, 8) == 256

Voir la réponse
def puissance(x: float, n: int) -> float:
    """Calcule et retourne x^n = x . x . ... . x (n fois)."""
    res = 1
    for _ in range(1, n + 1):
        res *= x
    return res

assert puissance(2, 8) == 256
assert puissance(0, 2) == 0
assert puissance(3, 0) == 1

Q4 amelioration_essai

Améliorer un essai : moyenne entre essai et x/essai.

Voir la réponse
def amelioration_essai(essai: float, x: float) -> float:
    """Moyenne entre essai (strictement positif) et x/essai."""
    return moyenne(essai, x / essai)

assert amelioration_essai(1, 2) == 1.5
assert amelioration_essai(2, 1) == 1.25

Q5 est_suffisamment_bon

Un essai est « suffisamment bon » si |essai² − x| < 0.001.

Voir la réponse
def est_suffisamment_bon(essai: float, x: float) -> bool:
    """Retourne True si |essai^2 - x| < 0.001."""
    tolerance = 0.001
    return valeur_absolue(puissance(essai, 2) - x) < tolerance

assert est_suffisamment_bon(1.9, 4) == False
assert est_suffisamment_bon(1.9999, 4) == True

Q6 test — algorithme complet

Assembler les briques précédentes dans une boucle while.

Voir la réponse
def test(essai: float, x: float) -> float:
    """Retourne la racine carrée de x en partant d'une valeur d'essai."""
    while not est_suffisamment_bon(essai, x):
        essai = amelioration_essai(essai, x)
    return essai

assert test(2, 4) == 2
assert test(1, 4) == 2.0000000929222947
Piège classique : le not mal placé, ou une fonction d'amélioration qui ne fait plus varier l'essai (boucle infinie).

Q7 racine_carree

Simplifier l'appel précédent avec un essai de départ toujours égal à 1.

Voir la réponse
def racine_carree(x: float) -> float:
    """Retourne la racine carrée de x (essai initial = 1)."""
    return test(1, x)

assert racine_carree(4) == 2.0000000929222947
assert racine_carree(9) == 3.00009155413138

Q8 main — liste en compréhension

Afficher la liste des racines carrées de tous les nombres pairs entre 1 et 100.

Voir la réponse
def main():
    return [racine_carree(i) for i in range(1, 101) if i % 2 == 0]

print(main())

🎯 Défis bonus

Pour les élèves qui terminent en avance.

Bonus 1 — Tolérance paramétrable

Faire en sorte que le seuil de précision (0.001) soit passé en argument.

Voir la réponse
def racine_carree_tolerance(x: float, tolerance: float) -> float:
    essai = 1
    while valeur_absolue(puissance(essai, 2) - x) >= tolerance:
        essai = amelioration_essai(essai, x)
    return essai
Bonus 2 — Racine cubique

Généraliser la méthode (Newton) : essai ← (2×essai + x/essai²) / 3.

Voir la réponse
def racine_cubique(x: float) -> float:
    essai = 1
    tolerance = 0.001
    while valeur_absolue(puissance(essai, 3) - x) >= tolerance:
        essai = (2 * essai + x / puissance(essai, 2)) / 3
    return essai

Séance 2 — Structures de boucle

Révisions : for, while, boucles imbriquées

Durée : 2hfor / whileBoucles imbriquéesSaisie utilisateur

Bloc A — Boucles simples et accumulateur

Ex 1 multiplication

Retourne les 10 premiers termes de la table de a.
multiplication(7) → '7 14 21 28 35 42 49 56 63 70 '

Voir la réponse
def multiplication(a: int) -> str:
    chaine_retour = ""
    nbre_tours_boucle = 10
    i = 1
    while i <= nbre_tours_boucle:
        chaine_retour += str(a * i) + " "
        i += 1
    return chaine_retour

Ex 2 multiplication_multiple_trois

Idem, en signalant les multiples de 3 par un astérisque.

Voir la réponse
def multiplication_multiple_trois(a: int) -> str:
    chaine_retour = ""
    for i in range(1, 11):
        resultat = a * i
        chaine_retour += str(resultat)
        if resultat % 3 == 0:
            chaine_retour += "*"
        chaine_retour += " "
    return chaine_retour

Ex 3 multiplication_multiple_sept

50 premiers termes de la table de a, on ne garde que les multiples de 7.

Voir la réponse
def multiplication_multiple_sept(a: int) -> str:
    chaine_retour = ""
    for i in range(1, 51):
        resultat = a * i
        if resultat % 7 == 0:
            chaine_retour += str(resultat) + " "
    return chaine_retour

Ex 4 diviseurs

Liste des diviseurs de a, du plus grand au plus petit.
diviseurs(18) → '18 9 6 3 2 1 '

Voir la réponse
def diviseurs(a: int) -> str:
    chaine_retour = ""
    for i in range(a, 0, -1):
        if a % i == 0:
            chaine_retour += str(i) + " "
    return chaine_retour

Bloc B — Boucles imbriquées

Ex 5 table_multiplication

Table de multiplication de 1 à 10, une ligne par table (séparateur \n). Deux boucles imbriquées.

Voir la réponse
def table_multiplication() -> str:
    chaine_retour = ""
    for i in range(1, 11):
        for j in range(1, 11):
            chaine_retour += str(i * j) + " "
        chaine_retour += "\n"
    return chaine_retour
# print(table_multiplication())
Le "\n" doit être ajouté après la boucle interne, pas dedans, sinon les lignes se mélangent.

Ex 13 alphabet

Alphabet à l'endroit ("croissant") ou à l'envers, via ord/chr (codes ASCII [97 ; 122]).

Voir la réponse
def alphabet(sens: str) -> str:
    if sens == "croissant":
        debut, fin, inc, pas = 97, 122, 1, 1
    else:
        debut, fin, inc, pas = 122, 97, -1, -1
    rep = ""
    for i in range(debut, fin + inc, pas):
        rep += chr(i)
    return rep

Ex 14 fibo

n premiers termes de la suite de Fibonacci (u1=1, u2=1, un=u(n-1)+u(n-2)).

Voir la réponse
def fibo(n: int) -> str:
    rep = "0 1 "
    u, v = 0, 1
    for i in range(2, n):
        z = u + v
        rep += str(z) + " "
        u, v = v, z
    return rep

Bloc C — Boucles et saisie utilisateur

Ex 6-7 plus_grand_plus_petit

Demander 10 valeurs (puis un nombre passé en argument) et retourner min et max.

Voir la réponse
def plus_grand_plus_petit(nbre_tours: int) -> str:
    valeur_max = float('-inf')
    valeur_min = float('inf')
    for i in range(1, nbre_tours + 1):
        valeur = float(input(f"Entrez la valeur {i} : "))
        if valeur > valeur_max: valeur_max = valeur
        if valeur < valeur_min: valeur_min = valeur
    return f"Min : {valeur_min}, Max : {valeur_max}"

Ex 8-9 moyenne

Demander des notes (10, puis un nombre passé en argument) et retourner la moyenne.

Voir la réponse
def moyenne(nbre_notes: int) -> float:
    total_notes = 0
    for i in range(nbre_notes):
        note = float(input(f"Entrez la note {i + 1} : "))
        total_notes += note
    return total_notes / nbre_notes

Ex 10 moyenne_auto

Sans nombre de notes fixé : une note négative arrête la saisie (valeur sentinelle).

Voir la réponse
def moyenne_auto() -> tuple[int, float]:
    nbre_notes = 0
    total_notes = 0
    stop = False
    while not stop:
        note = float(input(f"Entrez la note {nbre_notes + 1} : "))
        if note < 0:
            stop = True
        else:
            total_notes += note
            nbre_notes += 1
    return (nbre_notes, total_notes / nbre_notes)
Cas limite non géré : si la 1re note saisie est négative, division par zéro (nbre_notes = 0).

Bloc D — Boucles et hasard (module random)

Ex 11 loto_naif

6 entiers aléatoires entre 1 et 49 (répétitions possibles à ce stade).

Voir la réponse
from random import randint

def loto_naif() -> str:
    rep = ""
    for i in range(6):
        rep += str(randint(1, 49)) + " "
    return rep

Ex 12 devine

Jeu du nombre mystère entre 1 et 50, avec indices "trop grand"/"trop petit".

Voir la réponse
def devine() -> None:
    nbre_a_deviner = randint(1, 50)
    nbre_tentatives = 0
    trouve = False
    while not trouve:
        proposition = int(input("Entrez votre proposition : "))
        nbre_tentatives += 1
        if proposition == nbre_a_deviner:
            trouve = True
        elif proposition > nbre_a_deviner:
            print("Trop grand !")
        else:
            print("Trop petit !")
    print(f"Nombre de tentatives : {nbre_tentatives}")

🎯 Défis bonus

Pour les élèves qui terminent en avance.

Bonus 1 — Pierre-feuille-ciseaux

Jeu contre l'ordinateur (random.choice), boucle tant que le joueur veut continuer.

Voir la réponse
from random import choice

def pierre_feuille_ciseaux() -> None:
    choix = ["pierre", "feuille", "ciseaux"]
    v = d = e = 0
    continuer = True
    while continuer:
        joueur = input("pierre, feuille ou ciseaux ? ")
        ordi = choice(choix)
        if joueur == ordi:
            e += 1
        elif (joueur, ordi) in [("pierre","ciseaux"),("feuille","pierre"),("ciseaux","feuille")]:
            v += 1
        else:
            d += 1
        continuer = (input("Encore ? (o/n) ") == "o")
    print(f"V:{v} D:{d} E:{e}")
Bonus 2 — Nombres premiers

Liste des nombres premiers inférieurs à n (boucles imbriquées).

Voir la réponse
def nombres_premiers(n: int) -> str:
    rep = ""
    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:
            rep += str(candidat) + " "
    return rep

Séance 3 — Structure de liste

Révisions : parcours, construction et manipulation de listes

Durée : 2hListesTuplesListes de listes
⚠️ Deux corrigés « historiques » de cette page contiennent chacun un bug d'un cran (« off-by-one »). Avant de regarder la réponse, testez votre fonction sur les bornes (premier / dernier élément) !

Ex 1 minmax

Retourne un tuple (min, max) d'une liste de nombres.

Voir la réponse
def minmax(liste: list[float]) -> tuple[float, float]:
    val_min = liste[0]
    val_max = liste[0]
    for i in range(1, len(liste)):
        if liste[i] > val_max: val_max = liste[i]
        if liste[i] < val_min: val_min = liste[i]
    return val_min, val_max
Bug fréquent : range(1, len(liste) - 1) ignore le dernier élément de la liste.

Ex 2 longueur

Nombre d'éléments d'une liste, sans utiliser len().

Voir la réponse
def longueur(liste: list) -> int:
    longueur = 0
    for element in liste:
        longueur += 1
    return longueur

Ex 3 loto

6 entiers distincts tirés entre 1 et 49 (utiliser l'opérateur in pour éviter les doublons).

Voir la réponse
from random import randint

def loto() -> list[int]:
    tirages = []
    while len(tirages) < 6:
        tirage = randint(1, 49)
        if tirage not in tirages:
            tirages.append(tirage)
    return tirages
Bug fréquent : while len(tirages) <= 6 boucle une fois de trop et retourne 7 numéros.

Ex 4 statistiques

Moyenne d'une liste de notes + % de notes dans [0, moy-3[, [moy-3, moy+3[, [moy+3, 20], via deux fonctions auxiliaires.

Voir la réponse
def nombre_dans_intervalle(liste, valeur_min, valeur_max) -> int:
    compteur = 0
    for valeur in liste:
        if valeur_min <= valeur < valeur_max:
            compteur += 1
    return compteur

def statistiques(notes: list[float]) -> tuple[float, float, float, float]:
    moy = moyenne(notes)
    n = longueur(notes)
    nb_faibles  = nombre_dans_intervalle(notes, 0, moy - 3)
    nb_moyennes = nombre_dans_intervalle(notes, moy - 3, moy + 3)
    nb_fortes   = nombre_dans_intervalle(notes, moy + 3, 20.0001)
    return (moy, nb_faibles/n*100, nb_moyennes/n*100, nb_fortes/n*100)

Ex 5-6 distance / distanceN

Distance euclidienne entre deux points (tuples), en dimension 3 puis en dimension N.

Voir la réponse
from math import sqrt

def distanceN(pt1: tuple, pt2: tuple) -> float:
    if len(pt1) != len(pt2):
        raise Exception("Les dimensions ne correspondent pas !")
    carre_distance = 0
    for i in range(len(pt1)):
        carre_distance += (pt2[i] - pt1[i]) ** 2
    return sqrt(carre_distance)
# distance (dim 3) est un cas particulier de distanceN

Ex 7 table_multiplication (liste de listes)

table_multiplication(4) → [[1,2,3,4],[2,4,6,8],[3,6,9,12],[4,8,12,16]]

Voir la réponse
def table_multiplication(n: int) -> list[list[int]]:
    table = []
    for i in range(1, n + 1):
        ligne = []
        for j in range(1, n + 1):
            ligne.append(i * j)
        table.append(ligne)
    return table

🎯 Défis bonus

Pour les élèves qui terminent en avance.

Bonus 1 — Tri à bulles

Trier une liste de nombres croissants en comparant les voisins.

Voir la réponse
def tri_a_bulles(liste: list[float]) -> list[float]:
    resultat = liste.copy()
    n = longueur(resultat)
    for i in range(n):
        for j in range(0, n - i - 1):
            if resultat[j] > resultat[j + 1]:
                resultat[j], resultat[j + 1] = resultat[j + 1], resultat[j]
    return resultat
Bonus 2 — Recherche séquentielle

Retrouver l'indice d'un élément sans utiliser .index().

Voir la réponse
def recherche(liste: list, element) -> int:
    for i in range(longueur(liste)):
        if liste[i] == element:
            return i
    return -1