<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Terminale/Mise au point et débogage</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Mise au point d'un programme : tests d'intégration,<br/>
profilage (en temps et en mémoire), gestion des<br/>
exceptions avec <code>try</code> et <code>except</code>, analyse des<br/>
journaux d'exécution, débogueur interactif et<br/>
méthodes systématiques de réduction au cas<br/>
minimal et d'explication à voix haute.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q01 : Notion d'exception</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'une <strong>exception</strong> en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les exceptions remontent la pile des appels<br/>
de fonctions jusqu'à un bloc <code>try / except</code><br/>
qui les capture. En l'absence d'un tel<br/>
bloc, le programme s'arrête en affichant<br/>
la trace de l'erreur.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type de variable particulier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une exception est un événement de<br/>
l'exécution, pas un type de donnée que<br/>
l'on déclare comme on déclarerait un<br/>
entier ou une chaîne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un simple avertissement qui n'interrompt pas le programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description correspond à un<br/>
<em>warning</em>. Une exception non capturée,<br/>
au contraire, interrompt l'exécution du<br/>
programme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une erreur signalée durant l'exécution, qui interrompt le flux normal du programme sauf si elle est capturée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Quelques exemples classiques :<br/>
<code>ValueError</code>, <code>TypeError</code>, <code>IndexError</code>,<br/>
<code>KeyError</code>. C'est le mécanisme standard<br/>
pour signaler une condition inattendue<br/>
pendant l'exécution.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un commentaire spécial inséré dans le code</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une exception n'a aucun rapport avec un<br/>
commentaire. Les commentaires en Python<br/>
commencent par le caractère <code>#</code> et n'ont<br/>
aucun effet sur l'exécution.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q02 : Le bloc try / except</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment <strong>gérer</strong> une exception sans que le<br/>
programme ne s'interrompe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Variantes utiles :<br/>
<code>except ValueError:</code> pour capturer un type<br/>
d'exception spécifique ; <code>else:</code> pour le<br/>
cas où aucune exception n'a été levée ;<br/>
<code>finally:</code> pour du code toujours exécuté.<br/>
Bonne pratique : capturer un type<br/>
d'exception précis plutôt qu'utiliser un<br/>
<code>except</code> nu.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun moyen ne permet d'éviter l'arrêt du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Python fournit précisément le bloc<br/>
<code>try / except</code> pour intercepter une<br/>
exception et poursuivre l'exécution.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>try:
    risque()
except Exception as e:
    print("Erreur :", e)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le bloc <code>try</code> tente l'exécution. En<br/>
cas d'exception, le bloc <code>except</code><br/>
prend le relais et permet de gérer<br/>
proprement l'erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>catch risque() {}</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe est utilisée en Java ou<br/>
en C++, mais pas en Python, qui<br/>
emploie <code>try</code> et <code>except</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>if risque() == error: ...</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe n'est pas valide en<br/>
Python. La gestion des erreurs ne<br/>
repose pas sur une comparaison à une<br/>
valeur spéciale, mais sur le mécanisme<br/>
des exceptions.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q03 : Débogueur Python</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel module de la bibliothèque standard de<br/>
Python permet de déboguer interactivement ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les environnements de développement<br/>
modernes (VS Code, PyCharm) intègrent des<br/>
débogueurs graphiques. Un simple clic<br/>
dans la marge pose un point d'arrêt, et<br/>
un panneau dédié affiche la valeur des<br/>
variables. C'est plus ergonomique que la<br/>
ligne de commande de <code>pdb</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>fix</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucun module nommé <code>fix</code> n'existe en<br/>
Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>error</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucun module standard nommé <code>error</code><br/>
n'existe en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>pdb</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On peut écrire <code>import pdb;<br/>
pdb.set_trace()</code>, ou plus simplement<br/>
<code>breakpoint()</code> depuis Python 3.7,<br/>
pour poser un point d'arrêt.<br/>
Quelques commandes utiles : <code>n</code><br/>
(passer à la ligne suivante), <code>s</code><br/>
(entrer dans la fonction), <code>c</code><br/>
(continuer), <code>p variable</code> (afficher<br/>
une variable).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>debug</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucun module nommé <code>debug</code> n'existe<br/>
dans la bibliothèque standard.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q04 : Journalisation</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi préfère-t-on le module <code>logging</code> à<br/>
<code>print</code> pour le débogage en production ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : utiliser le niveau de<br/>
gravité approprié. Le niveau <code>debug</code><br/>
sert pour les détails de développement,<br/>
<code>info</code> pour les événements normaux,<br/>
<code>warning</code> pour les anomalies non<br/>
bloquantes, <code>error</code> pour les erreurs<br/>
récupérables, et <code>critical</code> pour les<br/>
erreurs fatales.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Pour pouvoir activer ou désactiver les messages, choisir leur niveau de gravité (<code>debug</code>, <code>info</code>, <code>warning</code>, <code>error</code>, <code>critical</code>) et les rediriger vers un fichier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le module <code>logging</code> est conçu pour la<br/>
production. Il offre une<br/>
configuration centralisée, plusieurs<br/>
niveaux de gravité, un formatage<br/>
personnalisable et des destinataires<br/>
variés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que la fonction <code>print</code> n'existe pas en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction <code>print</code> existe bel et<br/>
bien et reste utile, notamment pour<br/>
l'apprentissage. Elle est simplement<br/>
insuffisante pour gérer les<br/>
messages de débogage en production.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour économiser de l'espace de stockage</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'économie d'espace n'est pas<br/>
l'objectif principal. L'avantage du<br/>
module <code>logging</code> se situe ailleurs,<br/>
dans la flexibilité et la<br/>
configurabilité des messages.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun avantage particulier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le module <code>logging</code> apporte une<br/>
souplesse importante par rapport à<br/>
un simple <code>print</code>, comme détaillé<br/>
dans la bonne réponse.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q05 : Profilage</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que désigne-t-on par le <strong>profilage</strong> d'un<br/>
programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Avec <code>cProfile</code>, la commande<br/>
<code>python -m cProfile -s time script.py</code><br/>
affiche les fonctions triées par temps<br/>
cumulé d'exécution. Cela permet<br/>
d'identifier les $10\%$ du code qui<br/>
consomment $90\%$ du temps total.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Établir une description de son auteur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le profilage en informatique n'a<br/>
aucun rapport avec une description<br/>
biographique. Il s'agit d'une mesure<br/>
de performances.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Mesurer où le programme passe son temps et consomme la mémoire, afin d'identifier les parties les plus coûteuses</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Avant d'optimiser, il faut mesurer.<br/>
Un adage célèbre rappelle que<br/>
« l'optimisation prématurée est la<br/>
racine de tous les maux ». Quelques<br/>
outils Python : <code>cProfile</code>,<br/>
<code>line_profiler</code>, <code>memory_profiler</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Compresser le code pour gagner de la place</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La compression du code n'a aucun<br/>
rapport avec le profilage, qui<br/>
mesure le temps d'exécution et la<br/>
consommation mémoire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Lancer le programme plusieurs fois pour vérifier sa stabilité</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Lancer un programme plusieurs fois<br/>
relève plutôt du test de robustesse.<br/>
Le profilage cherche à localiser les<br/>
parties coûteuses, et non à mesurer<br/>
la stabilité globale.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q06 : Test d'intégration</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>test d'intégration</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La pyramide classique des tests comporte<br/>
beaucoup de tests unitaires (rapides à<br/>
exécuter), peu de tests d'intégration<br/>
(plus lents mais essentiels), et très<br/>
peu de tests de bout en bout (sur<br/>
l'ensemble du système). C'est une<br/>
stratégie pragmatique de couverture.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un test gratuit, sans contrepartie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation littérale du mot<br/>
« intégration » n'a pas de sens en<br/>
informatique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un test qui vérifie l'intégrité de la pile d'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description ne correspond à<br/>
aucun test classique. Un test<br/>
d'intégration porte sur les<br/>
interactions entre plusieurs modules.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un test qui ne déclenche jamais d'erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Au contraire, un bon test<br/>
d'intégration peut très bien<br/>
détecter des erreurs ; c'est même<br/>
son but principal.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un test qui vérifie que plusieurs modules fonctionnent correctement ensemble, et pas seulement chacun isolément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce type de test se distingue du test<br/>
unitaire, qui ne vérifie qu'un seul<br/>
module pris isolément. Le test<br/>
d'intégration permet de détecter les<br/>
bugs liés aux interactions, comme un<br/>
mauvais format de données échangées<br/>
entre deux modules.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q07 : Trace d'erreur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que représente la <strong>trace d'erreur</strong><br/>
affichée par Python à la suite d'une<br/>
exception non capturée ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour lire une trace d'erreur, on<br/>
commence par la dernière ligne, qui<br/>
indique le type d'erreur, puis on<br/>
remonte pour localiser l'origine de<br/>
l'appel problématique. On ignore<br/>
généralement les blocs internes aux<br/>
bibliothèques pour se concentrer sur<br/>
son propre code.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier journal stocké sur le disque</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une trace d'erreur n'est pas<br/>
stockée par défaut sur le disque ;<br/>
elle est simplement affichée dans<br/>
la sortie d'erreur du programme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le code source complet du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La trace ne contient pas tout le<br/>
code source, mais uniquement la<br/>
séquence d'appels qui a mené à<br/>
l'erreur, avec les numéros de<br/>
lignes correspondants.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La suite des appels de fonctions au moment où l'exception a été levée, chaque ligne indiquant la fonction appelante</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette trace se lit du bas (lieu où<br/>
l'erreur s'est produite) vers le<br/>
haut (point d'entrée du programme).<br/>
Elle aide à comprendre le contexte<br/>
dans lequel l'erreur est apparue.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type de mémoire interne au système</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description évoque la pile<br/>
d'appels en mémoire, qui est une<br/>
notion proche mais distincte. Ici,<br/>
on parle de l'affichage textuel<br/>
obtenu à la sortie du programme.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q08 : Point d'arrêt</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert un <strong>point d'arrêt</strong> dans un<br/>
débogueur ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>En Python, on peut écrire <code>breakpoint()</code><br/>
dans le code, ou cliquer dans la marge<br/>
d'un environnement de développement<br/>
pour poser un point d'arrêt graphique.<br/>
L'exécution s'arrête alors et l'on<br/>
peut explorer l'état du programme<br/>
interactivement.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À empêcher d'écrire du code dans une certaine zone</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucun point d'arrêt ne restreint<br/>
l'écriture du code. Il agit<br/>
uniquement à l'exécution.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À supprimer définitivement le programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un point d'arrêt n'a aucun effet<br/>
destructeur. Il ne fait que<br/>
suspendre temporairement<br/>
l'exécution.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>À suspendre l'exécution à une ligne précise pour inspecter les variables et progresser pas à pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est une technique essentielle<br/>
pour comprendre un programme<br/>
complexe. On peut placer plusieurs<br/>
points d'arrêt, voire des points<br/>
conditionnels (« suspendre<br/>
uniquement si $x &gt; 100$ »).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À enregistrer automatiquement le programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'enregistrement du fichier source<br/>
n'a aucun rapport avec un point<br/>
d'arrêt.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q09 : Reproduction d'un bug</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi est-il <strong>essentiel</strong> de pouvoir<br/>
reproduire un bug avant de le corriger ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'adage classique en débogage est :<br/>
« si l'on ne peut pas reproduire le<br/>
bug, on ne peut pas le corriger ».<br/>
Une fois la reproduction obtenue, on<br/>
écrit un test qui échoue dans cette<br/>
situation, puis on corrige jusqu'à ce<br/>
que ce test passe avec succès.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour pouvoir le montrer à l'utilisateur final</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La présentation du bug à<br/>
l'utilisateur n'est pas la raison<br/>
pour laquelle on cherche à le<br/>
reproduire. L'objectif est de<br/>
pouvoir vérifier qu'il a été<br/>
corrigé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce qu'on ne peut pas vérifier qu'une correction est efficace si l'on n'arrive pas à redéclencher le bug</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un bug intermittent est très<br/>
difficile à corriger. Trouver une<br/>
procédure fiable de reproduction<br/>
représente déjà la moitié du<br/>
travail de correction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour s'amuser à le voir se produire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La reproduction d'un bug est un<br/>
travail technique sérieux, motivé<br/>
par la nécessité de pouvoir<br/>
contrôler la correction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune raison particulière</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La reproduction est au contraire<br/>
l'étape fondatrice de tout<br/>
processus de correction sérieux.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q10 : Réduction au cas minimal</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est l'une des techniques<br/>
systématiques pour <strong>isoler la cause</strong><br/>
d'un bug dans un programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Réduction au cas minimal et<br/>
explication verbale (du code à un<br/>
collègue, ou même à un objet) sont<br/>
les deux méthodes systématiques<br/>
utiles à connaître. Elles<br/>
complètent les outils techniques<br/>
(débogueur, journaux, profilage).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Réduire progressivement l'entrée problématique au cas le plus simple qui reproduit encore le bug, ce qui localise efficacement la zone fautive</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette technique du « cas de test<br/>
minimal » est très efficace : si<br/>
un programme plante sur une liste<br/>
de mille éléments, on essaie avec<br/>
dix, puis cinq, puis deux, en<br/>
gardant à chaque fois la<br/>
propriété qui déclenche le bug.<br/>
Cela localise la cause et fournit<br/>
gratuitement un test de<br/>
régression compact.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Multiplier la taille de l'entrée jusqu'à observer un comportement régulier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est l'inverse. Plus l'entrée est<br/>
grande, plus il est difficile<br/>
d'identifier précisément ce qui<br/>
déclenche le bug.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Demander conseil à un collègue</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cela peut aider à clarifier ses<br/>
idées (technique dite « du canard<br/>
en plastique »), mais n'est pas<br/>
une méthode systématique<br/>
d'isolation de la cause.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Tout réécrire de zéro</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette démarche est risquée : elle<br/>
peut introduire de nouveaux bugs<br/>
et masquer l'origine du problème<br/>
initial.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q11 : Lever une exception explicitement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans une fonction <code>racine_carree(x)</code>, on<br/>
souhaite <strong>signaler une erreur</strong> lorsque<br/>
<code>x</code> est négatif. Quelle est la bonne<br/>
pratique ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les instructions <code>raise ValueError(...)</code><br/>
ou <code>raise TypeError(...)</code> sont les<br/>
moyens standard de signaler une<br/>
mauvaise utilisation d'une fonction.<br/>
Combinées à <code>try / except</code>, elles<br/>
offrent une gestion robuste des<br/>
erreurs sans imposer une convention<br/>
de retour fragile à l'appelant.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Lever explicitement une exception, par<br/>
exemple avec :</p>
<pre><code>if x &lt; 0:
    raise ValueError("x doit être positif")</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'instruction <code>raise</code> interrompt<br/>
immédiatement l'exécution et<br/>
signale un problème de manière<br/>
explicite. L'appelant peut<br/>
capturer cette exception avec<br/>
<code>try / except</code> s'il le souhaite,<br/>
et le message rend le bug facile à<br/>
comprendre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Renvoyer la valeur $-1$ pour signaler l'erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette pratique est dangereuse :<br/>
l'appelant peut oublier de tester<br/>
la valeur de retour, et la valeur<br/>
$-1$ peut aussi être un résultat<br/>
légitime pour une autre fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Afficher un message avec <code>print</code> puis renvoyer la valeur $0$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'appel à <code>print</code> ne peut pas être<br/>
capturé par l'appelant, et la<br/>
valeur $0$ ne se distingue pas<br/>
d'un résultat valide. Cette<br/>
approche dissimule donc le<br/>
problème.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Continuer le calcul comme si de rien n'était</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette pratique conduit à un<br/>
résultat numérique faux (le plus<br/>
souvent <code>nan</code> ou une autre valeur<br/>
aberrante), ce qui rend le bug<br/>
très difficile à diagnostiquer<br/>
ensuite.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q12 : L'instruction raise</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans quelles situations utilise-t-on<br/>
l'instruction <code>raise</code> en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'avantage par rapport à un simple<br/>
<code>if</code> qui renverrait <code>None</code> : l'erreur<br/>
ne peut pas être ignorée<br/>
silencieusement, puisque le<br/>
programme s'arrête sauf si l'on<br/>
capture l'exception explicitement<br/>
avec <code>try / except</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Pour lever explicitement une exception et signaler une erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On l'utilise par exemple pour<br/>
valider un paramètre :<br/>
<code>if x &lt; 0: raise ValueError("x<br/>
doit être positif")</code>. C'est une<br/>
approche défensive de la<br/>
programmation.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour multiplier la valeur d'une variable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La multiplication d'une variable<br/>
s'écrit avec l'opérateur <code><em></code>,<br/>
comme dans <code>x = x </em> 2</code>. Aucun<br/>
rapport avec l'instruction<br/>
<code>raise</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour incrémenter un compteur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'incrémentation d'un compteur<br/>
s'écrit <code>c = c + 1</code> ou <code>c += 1</code>,<br/>
et n'a aucun rapport avec<br/>
l'instruction <code>raise</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour quitter un programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour quitter un programme, on<br/>
utilise plutôt <code>sys.exit()</code>. Une<br/>
exception non capturée arrête<br/>
aussi l'exécution, mais ce n'est<br/>
pas l'usage premier de <code>raise</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q13 : Le bloc except sans type</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi le bloc <code>except:</code> sans<br/>
précision de type est-il <strong>déconseillé</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle d'or : ne jamais ignorer<br/>
silencieusement une erreur. Au<br/>
minimum, il faut journaliser ce qui<br/>
s'est passé, même si l'on choisit<br/>
de poursuivre l'exécution.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce qu'il capture toutes les exceptions, y compris <code>KeyboardInterrupt</code> (interruption clavier) et <code>SystemExit</code>, ce qui peut masquer des bugs et empêcher l'arrêt propre du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Capturer indistinctement toutes<br/>
les exceptions est une mauvaise<br/>
pratique. Mieux vaut écrire<br/>
<code>except Exception:</code> (qui<br/>
n'attrape pas les interruptions<br/>
clavier) ou, idéalement, capturer<br/>
un type d'exception spécifique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'il est plus lent à l'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La performance n'est pas le<br/>
critère ici. Le problème est<br/>
d'ordre fonctionnel : un<br/>
<code>except</code> nu intercepte trop de<br/>
choses.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune raison ne justifie de l'éviter</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Au contraire, plusieurs raisons<br/>
justifient d'éviter le <code>except</code><br/>
nu, comme expliqué dans la bonne<br/>
réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que la syntaxe <code>except:</code> n'existe pas en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La syntaxe existe et est<br/>
syntaxiquement valide. Le<br/>
problème est sémantique : elle<br/>
capture trop largement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q14 : Le bloc finally</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert le bloc <code>finally</code> dans une<br/>
structure <code>try / except</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le motif moderne consiste à utiliser<br/>
<code>with open(f) as fichier:</code>, qui<br/>
ferme automatiquement le fichier,<br/>
même en cas d'erreur. Cette syntaxe<br/>
est plus concise que la construction<br/>
<code>try / finally</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>À exécuter du code dans tous les cas, qu'il y ait eu une exception ou non. Il est utile pour les opérations de nettoyage (fermeture de fichiers, libération de ressources)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Exemple typique :<br/>
<code>try: f = open(...)</code> suivi de<br/>
<code>finally: f.close()</code>. Cette<br/>
construction garantit la<br/>
fermeture du fichier, même en<br/>
cas d'erreur. La construction<br/>
plus moderne <code>with</code> (gestionnaire<br/>
de contexte) automatise ce type<br/>
de gestion.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À ralentir intentionnellement l'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le bloc <code>finally</code> n'a aucun<br/>
objectif de ralentissement. Son<br/>
rôle est purement fonctionnel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À empêcher la levée des exceptions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le bloc <code>finally</code> ne supprime pas<br/>
les exceptions. Il garantit<br/>
simplement l'exécution de<br/>
certaines instructions, quoi<br/>
qu'il advienne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À exécuter du code uniquement en cas d'erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description correspond au<br/>
bloc <code>except</code>. Le bloc <code>finally</code><br/>
a un rôle différent : il<br/>
s'exécute dans tous les cas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q15 : Mesurer le temps d'exécution</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment <strong>mesurer</strong> où un script Python<br/>
passe le plus de temps ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour mesurer la consommation<br/>
mémoire, on utilise <code>memory_profiler</code>.<br/>
Pour analyser ligne par ligne le<br/>
temps passé, on utilise<br/>
<code>line_profiler</code>. Ces deux<br/>
bibliothèques s'installent<br/>
séparément, par exemple avec<br/>
<code>pip install</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec un chronomètre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette mesure est trop manuelle<br/>
et ne permet pas d'identifier<br/>
finement les fonctions les plus<br/>
coûteuses dans le code.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En le lançant plusieurs fois et en chronométrant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette mesure globale du temps<br/>
total ne dit pas <strong>où</strong>, dans le<br/>
code, le programme passe son<br/>
temps. Or c'est précisément<br/>
l'information nécessaire pour<br/>
optimiser.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il est impossible de mesurer cela en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Plusieurs outils existent en<br/>
Python pour mesurer la<br/>
performance d'un script,<br/>
notamment <code>cProfile</code>,<br/>
<code>line_profiler</code> ou <code>timeit</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec la commande <code>python -m cProfile -s time script.py</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette commande standard affiche<br/>
les fonctions triées par temps<br/>
cumulé d'exécution, ce qui<br/>
permet d'identifier rapidement<br/>
les parties les plus coûteuses<br/>
du code.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q16 : Test de régression</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>test de régression</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un cycle classique de correction de<br/>
bug consiste à : écrire d'abord un<br/>
test qui reproduit le bug et échoue,<br/>
puis corriger le code jusqu'à ce<br/>
que ce test passe avec succès, puis<br/>
enfin nettoyer la structure du code.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un test ajouté après avoir corrigé un bug, afin de vérifier que ce bug ne réapparaisse pas lors de modifications ultérieures du code</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette pratique est essentielle<br/>
pour éviter qu'un bug déjà<br/>
corrigé ne réapparaisse à<br/>
l'occasion de modifications<br/>
ultérieures. Une discipline<br/>
courante consiste à ajouter un<br/>
test pour chaque bug corrigé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un test trop simple pour être utile</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La simplicité d'un test n'a rien<br/>
à voir avec sa qualité de test<br/>
de régression. Beaucoup de tests<br/>
de régression sont d'ailleurs<br/>
très simples par construction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un test exécuté sur l'ancienne version du code</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un test de régression s'exécute<br/>
sur la <strong>version courante</strong> du<br/>
code, et non sur une ancienne<br/>
version. Son rôle est de<br/>
vérifier qu'un bug ancien ne<br/>
réapparaît pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un test qui revient en arrière dans le code source</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation littérale du<br/>
mot « régression » est inexacte.<br/>
Le test de régression vise à<br/>
empêcher la réapparition d'un<br/>
bug, pas à revenir en arrière<br/>
dans le code.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q17 : Méthode du canard en plastique</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que désigne la méthode dite <strong>du canard<br/>
en plastique</strong> en débogage ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Plusieurs variantes existent : on<br/>
peut expliquer son code à un<br/>
collègue, ou rédiger un message<br/>
détaillé qu'on n'envoie finalement<br/>
pas. De nombreux bugs se résolvent<br/>
d'ailleurs au cours de la rédaction<br/>
même de l'explication.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une méthode de compression de code</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucun rapport avec la<br/>
compression. Il s'agit d'une<br/>
méthode psychologique de<br/>
débogage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type particulier de test automatique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette méthode n'a rien à voir<br/>
avec un test automatique. Elle<br/>
repose sur l'explication<br/>
verbale du code, généralement<br/>
oralement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La technique consistant à expliquer son code à voix haute, à un objet ou à un interlocuteur, ce qui force à clarifier sa pensée et révèle souvent l'origine du bug</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette technique est réelle et<br/>
remarquablement efficace. Le fait<br/>
d'expliquer le code structure le<br/>
raisonnement et fait apparaître<br/>
les hypothèses cachées qui<br/>
peuvent être à l'origine du<br/>
bug.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'utilisation d'un canard en plastique magique pour résoudre les bugs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation est<br/>
plaisante mais ne reflète qu'une<br/>
moitié de l'idée. Le sens réel<br/>
est plus profond et concerne le<br/>
processus mental d'explication.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q18 : Trace d'exécution</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que produit une <strong>trace d'exécution</strong> d'un<br/>
programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le module <code>trace</code> de Python permet<br/>
d'obtenir une trace très complète,<br/>
avec la commande<br/>
<code>python -m trace --trace script.py</code>.<br/>
Le résultat est verbeux mais utile<br/>
pour analyser des comportements<br/>
complexes.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une optimisation du code</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La trace est un outil<br/>
d'observation du comportement,<br/>
et non une transformation du<br/>
code visant à le rendre plus<br/>
rapide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un journal des étapes effectivement exécutées par le programme, incluant les entrées et sorties de fonctions et les valeurs des variables clés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La trace d'exécution permet de<br/>
comprendre le déroulement réel<br/>
du programme, ce qui est<br/>
particulièrement utile pour des<br/>
bugs complexes ou intermittents.<br/>
Elle peut être réalisée avec<br/>
<code>print</code>, <code>logging</code>, ou des<br/>
décorateurs dédiés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur d'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La trace d'exécution n'est pas<br/>
un message d'erreur, mais le<br/>
journal complet du déroulement<br/>
du programme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une simple copie du code source</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La trace d'exécution n'est pas<br/>
le code source du programme,<br/>
mais un journal de son<br/>
comportement effectif.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q19 : Assertion et exception</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence entre une<br/>
<strong>assertion</strong> et la gestion d'exception ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une assertion est désactivable avec<br/>
l'option <code>python -O</code> (typiquement<br/>
en production). Il faut donc éviter<br/>
d'utiliser <code>assert</code> pour des<br/>
vérifications critiques portant sur<br/>
des entrées utilisateur. Pour<br/>
celles-ci, il vaut mieux utiliser<br/>
<code>raise</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune différence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les deux mécanismes sont<br/>
distincts, à la fois par leur<br/>
fonction et par leur usage,<br/>
comme détaillé dans la bonne<br/>
réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les assertions s'exécutent plus rapidement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La performance n'est pas le<br/>
critère pertinent ici. Les deux<br/>
mécanismes ont des rôles<br/>
différents.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les exceptions n'existent pas en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les exceptions sont au contraire<br/>
un mécanisme central du langage<br/>
Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les assertions vérifient des invariants (des conditions qui ne devraient jamais être fausses) et signalent un bug. Les exceptions, elles, gèrent des conditions exceptionnelles attendues (entrée invalide, fichier manquant) et peuvent être capturées et traitées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On peut résumer ainsi : <code>assert</code><br/>
exprime « cela ne doit jamais<br/>
arriver », tandis que<br/>
<code>raise</code> combiné à <code>try / except</code><br/>
exprime « cela peut arriver, et<br/>
voici comment je le gère ».</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q20 : Outils d'environnement de développement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quels <strong>outils</strong> d'un environnement de<br/>
développement intégré facilitent le<br/>
débogage ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un investissement utile consiste à<br/>
apprendre les raccourcis clavier<br/>
de son environnement de<br/>
développement. Les raccourcis<br/>
classiques sont F5 pour exécuter<br/>
ou déboguer, F10 pour passer à la<br/>
ligne suivante, F11 pour entrer<br/>
dans une fonction, et F9 pour<br/>
poser ou retirer un point d'arrêt.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>L'inspecteur de variables, la navigation pas à pas, les points d'arrêt conditionnels, la console interactive et l'analyseur statique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les environnements modernes<br/>
comme VS Code, PyCharm ou<br/>
Jupyter offrent tous ces<br/>
outils. Un environnement bien<br/>
maîtrisé est un accélérateur<br/>
majeur du travail de débogage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun outil particulier n'aide au débogage</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Au contraire, les environnements<br/>
modernes proposent une riche<br/>
palette d'outils dédiés au<br/>
débogage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Uniquement la coloration syntaxique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La coloration syntaxique est<br/>
utile, mais loin d'être<br/>
suffisante. Les véritables<br/>
outils de débogage vont<br/>
beaucoup plus loin.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le simple choix d'un clavier en disposition QWERTY</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La disposition du clavier n'a<br/>
aucun rapport avec les outils de<br/>
débogage de l'environnement de<br/>
développement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q21 : Bug fantôme</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'appelle-t-on un <strong>bug fantôme</strong> ou<br/>
<em>Heisenbug</em>, en référence au principe<br/>
d'incertitude de Heisenberg ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une stratégie utile consiste à<br/>
ajouter du logging systématique<br/>
plutôt que des modifications<br/>
ponctuelles. Si le bug disparaît<br/>
avec l'ajout du logging, c'est un<br/>
indice fort qu'il est lié à des<br/>
questions de synchronisation<br/>
temporelle.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un bug provenant d'un programme allemand</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La référence à Heisenberg<br/>
concerne le physicien allemand<br/>
du XXe siècle, mais le bug<br/>
lui-même n'a aucune origine<br/>
géographique particulière.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un bug visible uniquement la nuit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation est<br/>
fantaisiste. Le terme<br/>
« fantôme » fait référence à<br/>
l'évanescence du bug, pas à<br/>
un horaire d'apparition.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un bug qui disparaît ou change lorsqu'on tente de l'observer (par exemple, en ajoutant des <code>print</code> ou en lançant le programme dans un débogueur). L'origine est souvent liée à des problèmes de synchronisation ou de mémoire non initialisée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le nom fait référence au<br/>
principe d'incertitude<br/>
d'Heisenberg : observer le<br/>
phénomène le modifie. Ces bugs<br/>
sont particulièrement<br/>
difficiles à diagnostiquer.<br/>
Causes typiques : interactions<br/>
entre fils d'exécution<br/>
concurrents, mémoire partagée,<br/>
dépendances temporelles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un bug que l'on ne parvient pas à reproduire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description est incomplète.<br/>
La caractéristique essentielle<br/>
est plus précise : le bug<br/>
disparaît ou change de<br/>
comportement quand on essaie de<br/>
l'observer.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q22 : Fuite de mémoire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'appelle-t-on une <strong>fuite de mémoire</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Plusieurs outils permettent de<br/>
détecter les fuites de mémoire en<br/>
Python : <code>tracemalloc</code> pour suivre<br/>
les allocations, ou <code>objgraph</code><br/>
pour visualiser les graphes de<br/>
références. Ces outils sont<br/>
particulièrement utiles pour les<br/>
programmes qui s'exécutent sur de<br/>
longues durées, comme les<br/>
serveurs.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>De l'eau qui s'infiltre dans l'ordinateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation littérale<br/>
est plaisante, mais sans rapport<br/>
avec le concept informatique.<br/>
Le terme « fuite de mémoire »<br/>
décrit un comportement<br/>
logiciel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une optimisation du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une fuite de mémoire est au<br/>
contraire un défaut, qui dégrade<br/>
la performance et peut faire<br/>
planter le programme à terme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une situation dans laquelle le programme conserve des références à des données dont il n'a plus besoin, accumulant ainsi la mémoire utilisée jusqu'à un éventuel arrêt brutal</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce phénomène est moins fréquent<br/>
en Python, qui dispose d'un<br/>
ramasse-miettes, qu'en C ou en<br/>
C++. Il peut néanmoins se<br/>
produire, par exemple via des<br/>
caches non bornés ou des<br/>
références cycliques associées<br/>
à des méthodes spéciales comme<br/>
<code>__del__</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La perte d'un fichier sur le disque</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une fuite de mémoire concerne<br/>
la mémoire vive utilisée par<br/>
un programme, et non un fichier<br/>
sur le disque.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q23 : Analyse d'un journal d'exécution</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Face à un programme qui écrit<br/>
régulièrement dans un journal<br/>
d'exécution, quelle stratégie<br/>
d'analyse est la plus efficace<br/>
lorsqu'un bug est signalé en<br/>
production ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : structurer ses<br/>
journaux avec des niveaux<br/>
(<code>debug</code>, <code>info</code>, <code>warning</code>,<br/>
<code>error</code>, <code>critical</code>) et des<br/>
horodatages. En cas d'incident,<br/>
filtrer le journal par niveau<br/>
et par fenêtre temporelle<br/>
permet de reconstituer<br/>
rapidement la chaîne d'événements<br/>
qui a mené au bug.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Lire l'intégralité du journal depuis le début, ligne par ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Démarche peu efficace : un<br/>
journal de production peut<br/>
contenir des millions de lignes.<br/>
Il faut cibler la zone<br/>
temporelle proche du moment<br/>
où le bug s'est produit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Effacer le journal et redémarrer le programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Démarche désastreuse : on<br/>
perd la principale source<br/>
d'information sur le bug. Au<br/>
contraire, il faut conserver<br/>
précieusement les journaux<br/>
des incidents pour pouvoir<br/>
les analyser à froid.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Désactiver le journal et compter sur les utilisateurs pour signaler les erreurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Démarche contre-productive : un<br/>
journal détaillé est l'outil<br/>
principal de diagnostic en<br/>
production. Sans lui, on est<br/>
aveugle quand un bug<br/>
survient.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Localiser dans le journal la fenêtre temporelle proche de l'erreur, puis remonter à rebours en cherchant le premier événement anormal qui a précédé l'erreur observée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est la démarche standard.<br/>
On part de la trace d'erreur<br/>
(qui donne l'horodatage et le<br/>
contexte), on filtre les<br/>
lignes voisines (avec <code>grep</code>,<br/>
<code>tail</code>, ou un outil dédié),<br/>
puis on remonte la chaîne<br/>
de causalité. Le journal<br/>
révèle alors ce qui a<br/>
précédé le plantage : appel<br/>
inattendu, état incohérent,<br/>
ressource manquante, etc.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q24 : Méthodologie face à un bug</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la <strong>bonne méthodologie</strong><br/>
générale lorsqu'on est confronté à un<br/>
bug ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La discipline est essentielle. Il<br/>
faut s'imposer de ne jamais<br/>
corriger un bug sans avoir réussi<br/>
à le reproduire, et de ne jamais<br/>
corriger sans ajouter ensuite un<br/>
test. Sinon, le bug finira par<br/>
réapparaître, et le temps gagné<br/>
au départ sera perdu plus tard.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Réécrire l'intégralité du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Réécrire l'ensemble du<br/>
programme est rarement la<br/>
bonne réponse. Cela demande un<br/>
effort considérable et risque<br/>
d'introduire d'autres bugs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Demander la solution à un collègue</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Solliciter un collègue peut<br/>
être utile dans le diagnostic,<br/>
mais ne constitue pas une<br/>
méthodologie complète face à un<br/>
bug.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Modifier le code au hasard jusqu'à ce que le bug disparaisse</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette démarche est dangereuse :<br/>
elle risque d'introduire de<br/>
nouveaux bugs et masque<br/>
l'origine réelle du problème.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Reproduire le bug, isoler la cause<br/>
(par réduction au cas minimal ou<br/>
avec un débogueur), corriger le<br/>
code, ajouter un test de<br/>
régression, puis documenter si<br/>
pertinent</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette méthodologie est éprouvée.<br/>
Sauter une étape, en particulier<br/>
l'ajout du test de régression,<br/>
garantit que le bug finira par<br/>
réapparaître.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes sur la<br/>
mise au point des programmes, laquelle<br/>
est <strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'adage classique en débogage est :<br/>
« si l'on ne peut pas reproduire le<br/>
bug, on ne peut pas le corriger ».<br/>
La reproduction est l'étape<br/>
première, celle qui permet de<br/>
mesurer la qualité de la<br/>
correction.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La règle d'or consiste à corriger d'abord le bug, puis à essayer de le reproduire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est l'inverse qui est vrai<br/>
(donc cette affirmation est<br/>
bien la fausse). Il faut<br/>
d'abord <strong>reproduire</strong> le bug,<br/>
afin de pouvoir vérifier<br/>
ensuite que la correction est<br/>
effective, puis seulement<br/>
corriger.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La construction <code>try / except</code> permet de capturer des exceptions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est correcte.<br/>
C'est précisément le rôle du<br/>
mécanisme <code>try / except</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le profilage indique où, dans le code, le programme passe son temps</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est correcte.<br/>
C'est l'un des principaux<br/>
objectifs du profilage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une assertion qui échoue signale typiquement un bug dans le programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est correcte.<br/>
Une assertion représente une<br/>
vérification d'invariant : si<br/>
elle échoue, c'est qu'une<br/>
hypothèse fondamentale du<br/>
programme est violée.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q26 : Le mot-clé with</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est l'avantage d'écrire<br/>
<pre><code>with open("fichier.txt") as f:
    contenu = f.read()</code></pre><br/>
par rapport à<br/>
<pre><code>f = open("fichier.txt")
contenu = f.read()
f.close()</code></pre><br/>
?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le motif <code>with</code> est en réalité un<br/>
<strong>gestionnaire de contexte</strong> (<em>context<br/>
manager</em>). Tout objet implémentant<br/>
les méthodes <code>__enter__</code> et <code>__exit__</code><br/>
peut servir de contexte. C'est utile<br/>
pour les fichiers, les connexions<br/>
réseau, les verrous, les<br/>
transactions de base de données.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La construction <code>with</code> permet<br/>
d'écrire dans le fichier sans<br/>
ouvrir un mode d'écriture</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>with</code> n'a aucun effet<br/>
sur le mode d'ouverture. Pour<br/>
écrire dans un fichier, il faut<br/>
toujours préciser <code>mode='w'</code> ou<br/>
<code>'a'</code>, que l'on utilise <code>with</code> ou<br/>
non.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La construction <code>with</code> est<br/>
obligatoire en Python depuis la<br/>
version 3</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la construction <code>with</code><br/>
n'est pas obligatoire ; elle est<br/>
fortement recommandée. La<br/>
version manuelle avec <code>open</code> et<br/>
<code>close</code> reste valide<br/>
syntaxiquement, mais elle est<br/>
fragile face aux exceptions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La construction <code>with</code> est plus<br/>
rapide à l'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la performance est<br/>
identique. L'avantage est dans la<br/>
robustesse face aux exceptions, pas<br/>
dans la vitesse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La construction <code>with</code> ferme<br/>
automatiquement le fichier à<br/>
la sortie du bloc, même si une<br/>
exception est levée pendant la<br/>
lecture, ce qui évite les fuites<br/>
de descripteurs de fichier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est la principale<br/>
raison d'utiliser un gestionnaire<br/>
de contexte. Si une exception est<br/>
levée pendant le <code>read()</code> dans la<br/>
version sans <code>with</code>, l'instruction<br/>
<code>f.close()</code> ne sera jamais<br/>
exécutée, et le descripteur de<br/>
fichier reste ouvert. La construction<br/>
<code>with</code> garantit la fermeture, qu'il<br/>
y ait erreur ou non. Équivaut à un<br/>
<code>try / finally</code> propre.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q27 : Optimisation prématurée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Donald Knuth a écrit en 1974 :<br/>
« <strong>L'optimisation prématurée est la<br/>
racine de tous les maux</strong> ». Quelle est<br/>
la signification pratique de cette<br/>
maxime pour le développement logiciel ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma à appliquer : (1) écrire un<br/>
programme correct, lisible et<br/>
modulaire ; (2) le tester ; (3) si<br/>
les performances sont insuffisantes,<br/>
le profiler pour identifier les<br/>
véritables goulots ; (4) optimiser<br/>
ces goulots en mesurant l'impact ;<br/>
(5) revérifier que tous les tests<br/>
passent. Toute optimisation qui ne<br/>
suit pas ce schéma est suspecte.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il faut optimiser dès la première<br/>
ligne de code écrite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est exactement ce que<br/>
Knuth dénonce. Optimiser avant<br/>
d'avoir un programme correct<br/>
conduit souvent à du code complexe,<br/>
buggé, et qui n'apporte pas<br/>
forcément le gain attendu.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Cette maxime ne s'applique qu'aux<br/>
programmes anciens, pas aux<br/>
programmes modernes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la maxime reste plus que<br/>
jamais d'actualité. Avec la<br/>
montée en complexité des<br/>
programmes modernes, l'enjeu de<br/>
ne pas s'égarer dans des<br/>
optimisations inutiles est encore<br/>
plus important.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il ne faut jamais optimiser un<br/>
programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Knuth ne dit pas<br/>
d'abandonner toute optimisation,<br/>
mais d'éviter celle qui n'est pas<br/>
nécessaire ou qui se fait sans<br/>
mesure. Optimiser les vrais<br/>
goulots d'étranglement est<br/>
parfaitement légitime.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il faut d'abord écrire un code<br/>
correct et lisible, puis,<br/>
seulement si nécessaire et<br/>
après mesure, optimiser les<br/>
parties effectivement coûteuses<br/>
identifiées par le profilage</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : Knuth ajoutait<br/>
ensuite que « 97 % du temps, les<br/>
micro-optimisations sont à<br/>
oublier ». Sans mesure, on<br/>
optimise souvent les mauvaises<br/>
parties, on dégrade la lisibilité<br/>
et on introduit des bugs. Il faut<br/>
mesurer avant d'agir : on parle<br/>
de « pas d'optimisation aveugle ».</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
