52  Corrigés de l’examen blanc

Ce chapitre reprend chaque question de l’examen blanc avec :

Comment exploiter ce chapitre

Ne vous contentez pas de compter vos bonnes réponses. Pour chaque erreur, lisez attentivement l’explication et retournez au chapitre indiqué. Cette étape est cruciale pour progresser.


52.1 Q1 — Quotient et reste de division

Réponse : b) 3 1

print(10 // 3, 10 % 3)
3 1

// est la division entière (quotient), % le modulo (reste). Renvoient des int quand les opérandes sont entiers.

📚 Révisions : Partie 1 — Calculs et variables.


52.2 Q2 — Multiplication de chaînes

Réponse : a) "abcabcabc"

print("abc" * 3)
abcabcabc

L’opérateur * sur une chaîne et un entier répète la chaîne. Même chose pour les listes : [0] * 5 = [0, 0, 0, 0, 0].

📚 Révisions : Partie 1 — Chaînes de caractères.


52.3 Q3 — Valeur booléenne d’une liste vide

Réponse : b) False

print(bool([]))
False

Une collection vide ([], (), {}, set(), "") est falsy. De même pour 0, None, False. Tout le reste est truthy.

📚 Révisions : Partie 2 — Logique booléenne approfondie.


52.4 Q4 — Indexation négative

Réponse : a) "o"

print("Python"[-2])
o

Les indices négatifs comptent à partir de la fin : -1 = dernier, -2 = avant-dernier. Ici “Python” a 6 caractères, -2 = ‘o’.

📚 Révisions : Partie 1 — Chaînes de caractères.


52.5 Q5 — range avec pas négatif

Réponse : b) [5, 4, 3, 2, 1]

print(list(range(5, 0, -1)))
[5, 4, 3, 2, 1]

range(start, stop, step) : stop est exclu. Ici on va de 5 à 1 inclus.

📚 Révisions : Partie 2 — Itération avancée et range.


52.6 Q6 — Ensemble et doublons

Réponse : a) 3

print(len({1, 2, 2, 3, 3, 3}))
3

Les ensembles n’autorisent pas les doublons. L’écriture littérale avec répétitions est valide, mais les doublons sont éliminés.

📚 Révisions : Partie 1 — Ensembles.


52.7 Q7 — Ajout dans un dict

Réponse : b) 3

d = {"a": 1, "b": 2}
d["c"] = 3
print(len(d))
3

d["c"] = 3 ajoute une nouvelle clé. Après, le dict contient 3 paires.

📚 Révisions : Partie 1 — Dictionnaires.


52.8 Q8 — if/elif/else

Réponse : c) 10

x = 5
if x > 0:
    x = x * 2
elif x < 0:
    x = -x
else:
    x = 0
print(x)
10

Le premier if est vrai (5 > 0), donc x = 5 * 2 = 10. Les autres branches ne sont pas exécutées (c’est elif/else, mutuellement exclusif).

📚 Révisions : Partie 1 — Conditions.


52.9 Q9 — Fonction récursive (Fibonacci)

Réponse : a) 5

def f(n):
    if n <= 1:
        return n
    return f(n - 1) + f(n - 2)

print(f(5))
5

C’est la suite de Fibonacci : 0, 1, 1, 2, 3, 5, 8, 13… f(5) = 5.

Piège : on peut confondre avec f(5) = 8 (le 5e terme en partant de 1). Avec f(0) = 0 et f(1) = 1, on a f(5) = 5.

📚 Révisions : Partie 2 — Fonctions récursives (notion abordée).


52.10 Q10 — Méthode inexistante sur une liste

Réponse : c) .add()

L = [1, 2, 3]
# L.add(4)   # ❌ AttributeError
L.append(4)   # ✅
print(L)
[1, 2, 3, 4]

.add() existe sur les ensembles, pas les listes. Les listes utilisent .append().

📚 Révisions : Partie 1 — Listes.


52.11 Q11 — Slice inversé

Réponse : b) [3, 2, 1]

L = [1, 2, 3]
print(L[::-1])
[3, 2, 1]

Le slicing [::-1] inverse la liste. Syntaxe générique : [début:fin:pas]. Avec pas = -1, on parcourt à l’envers.

📚 Révisions : Partie 1 — Listes.


52.12 Q12 — is vs ==

Réponse : b) is

is teste l’identité (même objet en mémoire). == teste l’égalité (même valeur).

a = [1, 2, 3]
b = [1, 2, 3]
print(a == b, a is b)     # True False
True False

📚 Révisions : Partie 2 — Références et mutabilité.


52.13 Q13 — Default mutable (PIÈGE TOSA CLASSIQUE)

Réponse : b) [1] puis [1, 2]

def f(x, L=[]):
    L.append(x)
    return L

print(f(1))
print(f(2))
[1]
[1, 2]

Le L=[] est évalué une seule fois à la définition de la fonction. Toutes les instances partagent cette liste.

Correction : utiliser L=None puis if L is None: L = [].

📚 Révisions : Partie 2 — Fonctions (argument par défaut mutable).


52.14 Q14 — Tri décroissant

Réponse : b) [3, 2, 1]

print(sorted([3, 1, 2], reverse=True))
[3, 2, 1]

reverse=True inverse l’ordre. sorted renvoie une nouvelle liste, ne modifie pas l’originale.

📚 Révisions : Partie 2 — Algorithmes : tri, recherche, graphes.


52.15 Q15 — Longueur de .keys()

Réponse : a) 3

print(len({"a": 1, "b": 2, "c": 3}.keys()))
3

.keys() renvoie une vue sur les clés. len compte les éléments : 3 clés.

📚 Révisions : Partie 1 — Dictionnaires.


52.16 Q16 — join

Réponse : a) "a, b, c"

print(", ".join(["a", "b", "c"]))
a, b, c

separateur.join(iterable_de_chaînes) : assemble avec le séparateur entre chaque élément.

📚 Révisions : Partie 1 — Chaînes de caractères.


52.17 Q17 — .copy()

Réponse : a) [1, 2, 3] [1, 2, 3, 4]

a = [1, 2, 3]
b = a.copy()
b.append(4)
print(a, b)
[1, 2, 3] [1, 2, 3, 4]

.copy() crée une nouvelle liste indépendante. Modifier b n’affecte pas a — à la différence d’un simple b = a (alias).

📚 Révisions : Partie 2 — Références et mutabilité.


52.18 Q18 — filter avec lambda

Réponse : b) [2, 4]

print(list(filter(lambda x: x > 0, [-1, 2, -3, 4])))
[2, 4]

filter(fonction, iterable) garde les éléments pour lesquels la fonction renvoie True.

Équivalent en compréhension : [x for x in [-1, 2, -3, 4] if x > 0].

📚 Révisions : Partie 3 — Lambdas.


52.19 Q19 — Lecture efficace de fichier

Réponse : c) for ligne in f:

Les options a) et b) chargent tout le fichier en mémoire. for ligne in f: utilise le streaming — mémoire constante, fonctionne même sur plusieurs Go.

📚 Révisions : Partie 3 — Fichiers.


52.20 Q20 — Compréhension avec filtre

Réponse : a) [0, 4]

print([x ** 2 for x in range(4) if x % 2 == 0])
[0, 4]

range(4) = 0, 1, 2, 3. Filtrer les pairs : 0, 2. Carrés : 0, 4.

📚 Révisions : Partie 3 — Compréhensions.


52.21 Q21 — *args

Réponse : c) 6

def f(*args):
    return sum(args)

print(f(1, 2, 3))
6

args est un tuple (1, 2, 3). sum(args) = 6.

📚 Révisions : Partie 3 — *args et **kwargs.


52.22 Q22 — *args + **kwargs combinés

Réponse : c) 5

def f(*args, **kwargs):
    return len(args) + len(kwargs)

print(f(1, 2, a=3, b=4, c=5))
5

args = (1, 2) → len 2. kwargs = {"a": 3, "b": 4, "c": 5} → len 3. Total : 5.

📚 Révisions : Partie 3 — *args et **kwargs.


52.23 Q23 — __str__

Réponse : b) A(5)

class A:
    def __init__(self, x):
        self.x = x
    def __str__(self):
        return f"A({self.x})"

print(A(5))
A(5)

print(obj) appelle __str__. Si __str__ n’est pas définie, Python utilise __repr__, puis la forme <A object at 0x...>.

📚 Révisions : Partie 3 — POO (2/2).


52.24 Q24 — Syntaxe d’héritage

Réponse : a) class B(A):

Python utilise les parenthèses pour indiquer la classe mère.

class B(A):
    pass

📚 Révisions : Partie 3 — POO (2/2).


52.25 Q25 — try / except / finally

Réponse : b) 99

try:
    x = 10 / 0
except ZeroDivisionError:
    x = -1
finally:
    x += 100
print(x)
99
  1. 10 / 0 lève ZeroDivisionError.
  2. Le except attrape : x = -1.
  3. finally s’exécute toujours : x = -1 + 100 = 99.

📚 Révisions : Partie 3 — Gestion des exceptions.


52.26 Q26 — json.dumps

Réponse : b) '{"a": 1}' (chaîne)

import json
r = json.dumps({"a": 1})
print(r, type(r))
{"a": 1} <class 'str'>

dumps avec le s final = string (chaîne). dump (sans s) écrit dans un fichier.

Mnémo :

  • dump / load → fichier
  • dumps / loads → string (s = string)

📚 Révisions : Partie 3 — Fichiers.


52.27 Q27 — Complexité de in sur une liste

Réponse : c) O(n)

Python doit parcourir la liste dans le pire cas. Pour des tests fréquents, convertir en set donne O(1).

📚 Révisions : Partie 3 — Complexité algorithmique.


52.28 Q28 — Structure à recherche rapide

Réponse : c) set

Les sets (et dicts) utilisent une table de hachage : lookup en O(1) amorti. Les listes, tuples et chaînes sont en O(n) pour in.

📚 Révisions : Partie 3 — Complexité algorithmique.


52.29 Q29 — match / case avec alternative

Réponse : b) moyen

x = 5
match x:
    case 1 | 2:
        print("petit")
    case 3 | 4 | 5:
        print("moyen")
    case _:
        print("autre")
moyen

| est l’alternative dans un case. 5 matche 3 | 4 | 5.

📚 Révisions : Partie 3 — Pattern matching.


52.30 Q30 — Regex \d+

Réponse : b) Un ou plusieurs chiffres

  • \d : un chiffre.
  • + : une ou plus occurrences.
  • ? : zéro ou une.
  • * : zéro ou plus.
import re
print(re.findall(r"\d+", "abc 123 def 4567"))
['123', '4567']

📚 Révisions : Partie 4 — Regex.


52.31 Q31 — Générateur

Réponse : a) [0, 2, 4]

def g():
    for i in range(3):
        yield i * 2

print(list(g()))
[0, 2, 4]

yield transforme la fonction en générateur. Ici on produit 0*2, 1*2, 2*2.

📚 Révisions : Partie 4 — Itérateurs et générateurs.


52.32 Q32 — @functools.wraps

Réponse : b) Préserve les métadonnées de la fonction décorée

Sans @wraps, toutes les fonctions décorées apparaissent comme wrapper dans les introspections (débogage catastrophique). @wraps copie __name__, __doc__, etc.

📚 Révisions : Partie 4 — Décorateurs.


52.33 Q33 — nonlocal et scopes

Réponse : a) 30 10

x = 10
def f():
    x = 20
    def g():
        nonlocal x
        x = 30
    g()
    return x

print(f(), x)
30 10
  • g utilise nonlocal x → modifie le x de f (le plus proche englobant), pas le global.
  • Après g(), dans f : x = 30.
  • f() renvoie 30.
  • x global reste à 10.

Sortie : 30 10.

📚 Révisions : Partie 4 — Scopes et closures (LEGB).


52.34 Q34 — pathlib.Path.suffix

Réponse : b) .txt

from pathlib import Path
p = Path("rapport.txt")
print(p.suffix)
.txt
  • p.suffix.txt (avec le point).
  • p.stemrapport (sans extension).
  • p.namerapport.txt.

📚 Révisions : Partie 4 — sys, os, pathlib.


52.35 Q35 — Type hints modernes

Réponse : d) b) et c) sont équivalents

  • list[int] | None (Python 3.10+) — syntaxe moderne.
  • Optional[list[int]] (avec from typing import Optional) — équivalent exact.
  • List[int] | None : correct aussi, mais List de typing est déprécié depuis 3.9 au profit de list.

Donc b et c sont strictement équivalents : Optional[X] est X | None.

📚 Révisions : Partie 4 — Type hints.


52.36 📊 Calcul du score

Comptez vos bonnes réponses

Score Niveau TOSA estimé Certification
0-10 Initial (1-350) Non
11-17 Basique (351-550) Juste en-dessous
18-24 Opérationnel (551-725) ✅ Oui
25-30 Avancé (726-875) ✅ Oui
31-35 Expert (876-1000) ✅ Oui

Analyse par section

Regroupez vos résultats pour identifier vos points forts et faibles.

Questions Domaine
Q1-8 Fondamentaux (types, opérateurs, conditions)
Q9-11 Structures (récursion, méthodes, slicing)
Q12-17 Opérationnel (références, fonctions, copie, tri)
Q18-21 Avancé (lambda, fichiers, compréhensions, args)
Q22-26 POO et erreurs (classes, exceptions, JSON)
Q27-30 Complexité et match
Q31-35 Expert (générateurs, décorateurs, scopes, pathlib, types)

Un score < 4/8 sur une section indique une zone à reprendre prioritairement.

52.37 Prochaines étapes

  • Score ≥ 20 avec répartition équilibrée : vous êtes prêt pour l’examen réel. Lisez le chapitre 4 (Conseils jour J) pour optimiser votre passage.
  • Score < 20 ou déséquilibré : retournez travailler les chapitres pointés ci-dessus, puis refaites un examen blanc (pensez à changer les réponses si vous vous souvenez des bonnes).
Un cerveau, un crayon

Pour consolider : prenez 5 questions que vous avez ratées, et réécrivez le code à la main dans un vrai éditeur Python. Exécutez, observez, modifiez. C’est la seule façon de vraiment ancrer.

← Chapitre précédent : Examen blancChapitre suivant : Conseils jour J →