08 — Quiz interactif
Niveau requis : 4 (fonctions) + début du 5 (lecture de fichier) / Difficulté : 3/5 / Durée estimée : 2–3 h
Objectif
Un quiz à choix multiples dans le terminal : les questions vivent dans un fichier séparé (pas dans le code), le programme les pose une par une, accepte la réponse, dit juste/faux avec la bonne réponse, et affiche le score final avec un commentaire.
Question 2/5 — Que retourne len("abc") ?
a) "abc"
b) 3
c) 2
Ta reponse : b
Correct !
...
Score : 4/5 — Solide. Une revision sur la question 3 et c'est bon.
Le point clé : séparer les données du code. Ajouter une question ne doit pas demander de toucher au programme.
Notions utilisées
- Fonctions avec paramètres et retours — niveau 4
- Lecture d'un fichier avec
with open(...)— niveau 5 json.load()(recommandé) — niveau 5- Listes de dictionnaires, parcours avec
enumerate()— niveau 3 - Validation d'entrée en boucle
while— niveau 2 - f-strings et compteurs — niveaux 1–2
Cahier des charges
- Deux fichiers :
quiz.pyetquestions.json. questions.json: une liste d'objets{"question": str, "choices": ["...", "...", "..."], "answer": "b"}— au moins 5 questions (idéalement sur… Python : le quiz devient un outil de révision).- Le programme fonctionne avec N'IMPORTE quel nombre de questions : rien n'est codé en dur sur 5.
- La réponse acceptée est
a,bouc(insensible à la casse, espaces tolérés) ; toute autre entrée est redemandée sans consommer la question. - Mauvaise réponse → afficher la bonne réponse (lettre + texte).
- Score final :
X/N, plus un commentaire par palier (par ex. < 50 %, 50–80 %, > 80 %). - Structure imposée :
load_questions(path),ask_question(item, number, total)(retourneTrue/False),main(). Chaque fonction fait UNE chose.
Étapes de construction
- Code en dur UNE question dans
quiz.py(un dict) et écris la boucle d'affichage question/choix + saisie + verdict. Programme complet pour une question. Lance-le. - Extrais
ask_question(item, number, total): elle affiche, valide la saisie, dit juste/faux, retourne un booléen. Appelle-la sur ta question en dur. Même comportement qu'avant = extraction réussie. - Passe à une LISTE de 3 dicts en dur et boucle dessus avec
enumerate; accumule le score avec les retours deask_question. AfficheX/N. - Crée
questions.jsonavec ces 3 mêmes questions. Écrisload_questions(path)avecwith open(path, encoding="utf-8")etjson.load. Remplace la liste en dur. Le comportement ne change pas — mais maintenant les données vivent hors du code. - Ajoute la validation de saisie en boucle (
a/b/c, casse et espaces tolérés :answer.strip().lower()). Teste en tapantZ,B, une ligne vide. - Ajoute les commentaires par palier de score, puis enrichis
questions.jsonà 5+ questions SANS toucher àquiz.py. Si tu dois modifier le code pour ajouter une question, le contrat est cassé — corrige.
Extensions possibles
- Mélanger l'ordre des questions à chaque partie (
random.shuffle). - Mélanger aussi l'ordre des CHOIX — attention : la bonne lettre change, il faut suivre la bonne réponse à travers le mélange (bon petit casse-tête).
- À la fin, reproposer uniquement les questions ratées (les collecter dans une liste pendant la partie).
- Plusieurs fichiers de questions (thèmes) et un menu de sélection du thème.
Erreurs fréquentes sur ce projet
- Écrire le JSON à la main avec une virgule finale ou des apostrophes simples :
json.JSONDecodeError. Le message donne ligne et colonne — apprends à le lire, il est précis. FileNotFoundError: questions.jsonalors que le fichier existe : tu as lancé le programme depuis un autre dossier. Le chemin est relatif au RÉPERTOIRE COURANT, pas au fichier .py (⏩ solution propre avecpathlibau projet 10).- Comparer sans normaliser :
"B" == "b"est faux. D'où le.strip().lower()AVANT toute comparaison — une fois, au bon endroit. - Accents cassés à l'affichage :
open()sansencoding="utf-8"sur Windows. Prends le réflexe : TOUJOURSencoding="utf-8". ask_questionqui modifie le score global directement (variable globale) au lieu de retourner un booléen : ça marche ici, ça devient ingérable dès que le programme grossit. Le retour de fonction EST le canal de communication.
Critères de réussite
- Ajouter une 6e question dans le JSON fonctionne sans toucher au code.
- Une saisie invalide est redemandée et ne compte ni juste ni faux.
- Le score final et le palier de commentaire sont corrects (testé en jouant tout juste, tout faux, moitié).
- Les accents s'affichent correctement.
-
ask_questionest appelable seule dans le REPL avec un dict de test.
Commit conseillé
git add projects/mini-projects/08-quiz-interactif/
git commit -m "project: add interactive quiz"
Puis entrée de journal + git push.