<?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 du tout 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 à l'exécution, qui interrompt le programme</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>try {
    risque()
} catch (Exception e) {
    print("Erreur :", e)
}</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe à accolades, avec<br/>
<code>catch</code>, est celle de Java ou de C++,<br/>
pas celle de Python, qui emploie <code>try</code><br/>
et <code>except</code> suivis de deux-points et<br/>
d'un bloc indenté.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>resultat = risque()
if resultat == error:
    print("Erreur :", resultat)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce code ne gère rien : si <code>risque()</code><br/>
lève une exception, le programme<br/>
s'arrête avant même d'atteindre le<br/>
<code>if</code>. 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 filtrer les messages selon leur niveau de gravité</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 du tout 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 — 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é complète 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 vérifiant que plusieurs modules marchent ensemble</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 menant à l'erreur</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 pour inspecter les variables</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 fichier du 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>Sans reproduction, impossible de vérifier la correction</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 l'entrée au cas le plus simple qui reproduit encore le bug</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 avec <code>raise</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse, par exemple :</p>
<pre><code>if x &lt; 0:
    raise ValueError("x doit être positif")</code></pre>
<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 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 par deux</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>Il capture toutes les exceptions, même les interruptions clavier</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 tout simplement 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 (nettoyage)</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 lorsqu'une erreur survient</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 qui empêche un bug corrigé de réapparaître plus tard</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 — 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 réellement exécutées</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 intégrale du code source du programme</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 toujours bien plus rapidement que les exceptions</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 signalent un bug, les exceptions gèrent des cas attendus</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>Inspecteur de variables, pas à pas et points d'arrêt</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 AZERTY ou 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 change dès qu'on tente de l'observer</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 absolument jamais à 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 — 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>Cibler la fenêtre temporelle de l'erreur, puis remonter à l'événement anormal</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 finisse par disparaître</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, isoler, corriger, puis ajouter un test de régression</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>Il faut corriger le bug d'abord, 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 automatiquement le fichier, même en cas d'exception</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>

</quiz>
