<?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>Variante utile : <code>except ValueError:</code> pour ne capturer qu'un<br/>
type d'exception précis. Bonne pratique : capturer un type<br/>
d'exception précis plutôt qu'utiliser un <code>except</code> nu, qui<br/>
masquerait aussi les erreurs imprévues.</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 : Chaîne de documentation d'une fonction</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère la fonction suivante :</p>
<pre><code>def moyenne(notes):
    """Renvoie la moyenne des nombres de la liste notes, supposée non vide."""
    total = 0
    for note in notes:
        total = total + note
    return total / len(notes)</code></pre>
<p>À quoi sert la chaîne écrite entre triples guillemets sous la<br/>
ligne <code>def</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Documenter une fonction, c'est écrire ce qu'elle fait, ce qu'elle<br/>
attend de ses paramètres et ce qu'elle renvoie. Cette<br/>
documentation informe le programmeur qui l'utilise, mais ne<br/>
protège de rien : pour faire respecter une précondition, on<br/>
ajoute une assertion.</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>À vérifier, à chaque appel, que la liste n'est pas vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python ne vérifie jamais le contenu de cette chaîne.<br/>
Pour contrôler la précondition à l'exécution, il faudrait une<br/>
assertion comme <code>assert len(notes) &gt; 0</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>À décrire le rôle de la fonction et ce qu'elle suppose</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : cette chaîne documente la fonction, son résultat<br/>
et sa précondition (liste non vide). On la lit dans le code, ou<br/>
avec <code>help(moyenne)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À afficher ce texte dans la console à chaque appel</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien n'est affiché lors d'un appel. <code>moyenne([12, 15])</code><br/>
renvoie simplement <code>13.5</code> ; seul un <code>print</code> produit un<br/>
affichage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À fixer la valeur renvoyée quand la liste est vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la chaîne n'a aucun effet sur le calcul. Avec une liste<br/>
vide, la division par <code>len(notes)</code> lève une <code>ZeroDivisionError</code>,<br/>
que la chaîne soit présente ou non.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q04 : Ce que prouve un jeu de tests réussi</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une fonction écrite par Léa passe avec succès les cinq tests<br/>
qu'elle a préparés. Que peut-on en conclure ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un jeu de tests augmente la confiance dans un programme sans la<br/>
rendre totale. On le choisit avec soin (cas ordinaires, cas<br/>
limites, valeurs aux bornes) et on le complète dès qu'un bug est<br/>
découvert.</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>Elle donne le bon résultat pour toutes les entrées possibles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cinq tests ne vérifient que cinq cas. Un bug peut se<br/>
cacher dans une entrée non testée, par exemple une liste vide ou<br/>
une valeur placée en dernière position.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Écrire d'autres tests pour cette fonction ne servirait à rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : de nouveaux tests, en particulier sur les cas limites,<br/>
peuvent encore révéler un bug. La qualité et le nombre des tests<br/>
comptent autant que leur succès.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle est juste sur ces cinq cas, sans garantie pour les autres</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un test réussi montre que la fonction se comporte<br/>
comme prévu sur ce cas précis. Le succès d'un jeu de tests ne<br/>
garantit pas la correction du programme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle est sans erreur de syntaxe, sans rien dire de ses résultats</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un test compare le résultat obtenu au résultat attendu.<br/>
Son succès dit donc bien quelque chose des résultats, sur les cas<br/>
qu'il examine.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q06 : Choisir les cas d'un jeu de tests</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On veut tester une fonction <code>maximum(t)</code> qui renvoie le plus grand<br/>
élément d'une liste non vide de nombres. Quel choix de listes<br/>
forme le jeu de tests le plus pertinent ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un bon jeu de tests vise les situations où un bug a le plus de<br/>
chances d'apparaître : les cas limites (liste à un élément) et les<br/>
valeurs placées aux bornes (premier et dernier élément). Mieux<br/>
vaut quelques cas bien choisis que beaucoup de cas semblables.</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 seule liste de mille nombres tirés au hasard</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une seule liste, même longue, ne teste qu'une position<br/>
du maximum. Une fonction qui oublierait le premier ou le dernier<br/>
élément pourrait passer ce test sans être détectée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Plusieurs listes dont le maximum est toujours le dernier élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ces listes testent toutes le même cas. Une fonction qui<br/>
renverrait simplement le dernier élément les passerait toutes,<br/>
sans être correcte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Maximum en tête, au milieu, en fin, et liste à un élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ces cas couvrent chaque position possible du<br/>
maximum et le plus petit cas autorisé. Une boucle qui commence ou<br/>
s'arrête un indice trop tôt échoue sur au moins l'un d'eux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Des listes dont tous les éléments sont égaux entre eux</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : quand tous les éléments sont égaux, n'importe quel<br/>
élément de la liste est une réponse juste. Ces tests ne peuvent<br/>
donc révéler presque aucun bug.</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 : Une conditionnelle incomplète</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère la fonction suivante :</p>
<pre><code>def mention(note):
    if note &gt;= 16:
        return "très bien"
    elif note &gt;= 14:
        return "bien"
    elif note &gt;= 12:
        return "assez bien"
    elif note &gt;= 10:
        return "passable"</code></pre>
<p>Qu'affiche l'instruction <code>print(mention(8))</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une conditionnelle doit prévoir tous les cas possibles. Sinon, une<br/>
fonction peut renvoyer <code>None</code> sans aucun message, et l'erreur<br/>
apparaît plus loin, quand on utilise ce résultat. Terminer par un<br/>
<code>else</code> rend la conditionnelle exhaustive.</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>passable</code>, le texte de la dernière branche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la branche <code>elif note &gt;= 10</code> n'est exécutée que si sa<br/>
condition est vraie. Pour <code>8</code>, les quatre conditions sont fausses<br/>
et aucun <code>return</code> n'est atteint.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>None</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : aucune condition n'est vraie pour <code>8</code>, la fonction<br/>
atteint sa fin sans <code>return</code> et renvoie donc <code>None</code>, que <code>print</code><br/>
affiche. Il manque un cas final, par exemple<br/>
<code>else: return "insuffisant"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car aucune branche ne correspond à <code>8</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python n'exige pas qu'une branche soit choisie. Quand<br/>
toutes les conditions sont fausses, il passe simplement à la<br/>
suite, ici la fin de la fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une ligne vide, puisque la fonction ne renvoie rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une fonction qui se termine sans <code>return</code> renvoie la<br/>
valeur <code>None</code>, et <code>print(None)</code> affiche bien le mot <code>None</code>, pas<br/>
une ligne vide.</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>La réduction au cas minimal localise<br/>
la cause d'un bug : on simplifie<br/>
l'entrée pas à pas en conservant le<br/>
comportement fautif. Le petit cas<br/>
obtenu est facile à suivre à la main,<br/>
puis il rejoint le jeu de tests.</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/>
un petit test à ajouter au jeu de<br/>
tests.</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 : Signaler un argument invalide</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>Une assertion placée en tête de<br/>
fonction exprime et vérifie sa<br/>
précondition. Contrairement à une<br/>
valeur de retour spéciale, elle ne<br/>
peut pas être ignorée par l'appelant :<br/>
le programme s'arrête sur un message<br/>
explicite.</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>Vérifier la précondition dès l'entrée avec <code>assert x &gt;= 0</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse, par exemple :</p>
<pre><code>def racine_carree(x):
    assert x &gt;= 0, "x doit être positif"
    ...</code></pre>
<p>Si la condition est fausse,<br/>
l'assertion interrompt aussitôt<br/>
l'exécution sur une <code>AssertionError</code><br/>
qui porte le message : l'appel<br/>
fautif est désigné clairement.</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 repousse le problème :<br/>
le calcul échoue plus loin, sur un<br/>
message qui ne désigne pas l'appel<br/>
fautif, ou produit une valeur<br/>
aberrante, ce qui rend le bug très<br/>
difficile à diagnostiquer ensuite.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q12 : Une saisie jamais convertie</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On exécute le programme suivant et l'on saisit <code>2009</code> au clavier :</p>
<pre><code>annee = input("Année de naissance : ")
age = 2026 - annee
print("Tu as", age, "ans")</code></pre>
<p>Que se passe-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le type d'une valeur décide des opérations permises. Une saisie au<br/>
clavier est une chaîne : pour calculer avec, on la convertit avec<br/>
<code>int</code> ou <code>float</code>. Le message d'une <code>TypeError</code> nomme les deux types<br/>
en conflit, ce qui oriente directement vers la conversion<br/>
oubliée.</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 affiche <code>Tu as 17 ans</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>input</code> renvoie toujours une chaîne de caractères, ici<br/>
<code>"2009"</code>. Python ne la convertit pas en nombre de lui-même, et la<br/>
soustraction échoue.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une <code>ValueError</code>, car la saisie <code>2009</code> ne décrit pas un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>"2009"</code> décrit bien un entier, et <code>int("2009")</code><br/>
réussirait. Aucune conversion n'est tentée ici : l'erreur vient<br/>
de l'opération entre deux types incompatibles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une <code>TypeError</code>, car <code>input</code> renvoie une chaîne non convertie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>2026 - "2009"</code> soustrait une chaîne d'un<br/>
entier. Python s'arrête sur<br/>
<code>TypeError: unsupported operand type(s) for -: 'int' and 'str'</code>.<br/>
Il faut écrire <code>annee = int(input("Année de naissance : "))</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une <code>TypeError</code>, car <code>print</code> refuse de mêler texte et nombres</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>print</code> accepte des valeurs de types différents séparées<br/>
par des virgules. Le programme n'atteint d'ailleurs jamais cette<br/>
ligne : il s'arrête dès la soustraction.</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 : Une liste modifiée par une fonction</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère le programme suivant :<br/>
<pre><code>def ajouter_bonus(notes):
    for i in range(len(notes)):
        notes[i] = notes[i] + 1
    return notes
notes_classe = [12, 15, 9]
bonus = ajouter_bonus(notes_classe)
print(notes_classe)</code></pre><br/>
Qu'affiche la dernière instruction ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une liste passée en paramètre n'est pas copiée : la modifier dans<br/>
la fonction la modifie aussi pour l'appelant. Si ce n'est pas<br/>
voulu, la fonction construit une nouvelle liste, par exemple<br/>
<code>[note + 1 for note in notes]</code>, et la renvoie.</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>[12, 15, 9]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction ne reçoit pas une copie de la liste mais la<br/>
liste elle-même. Chaque affectation <code>notes[i] = ...</code> modifie donc<br/>
<code>notes_classe</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>[13, 16, 10]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>notes</code> et <code>notes_classe</code> désignent la même<br/>
liste. La fonction la modifie en place, et <code>bonus</code> désigne lui<br/>
aussi cette même liste. Les notes d'origine sont perdues : c'est<br/>
un effet de bord.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[14, 17, 11]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le bonus n'est ajouté qu'une fois. L'affectation<br/>
<code>bonus = ajouter_bonus(notes_classe)</code> ne relance aucun calcul :<br/>
elle nomme la liste renvoyée, qui est la liste déjà modifiée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, une fonction ne pouvant modifier une liste reçue</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien n'interdit à une fonction de modifier les éléments<br/>
d'une liste passée en paramètre. Le programme s'exécute sans<br/>
erreur, ce qui rend l'effet de bord d'autant plus discret.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q15 : Une inégalité stricte de trop</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La fonction suivante doit renvoyer le nombre de notes supérieures<br/>
ou égales à $10$ :</p>
<pre><code>def compter_admis(notes):
    n = 0
    for note in notes:
        if note &gt; 10:
            n = n + 1
    return n</code></pre>
<p>Or <code>compter_admis([8.5, 10, 14, 9.5])</code> renvoie <code>1</code> au lieu de <code>2</code>.<br/>
Quelle condition corrige la fonction pour toutes les notes,<br/>
entières ou décimales ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le passage de la spécification au code demande de choisir entre<br/>
<code>&lt;</code> et <code>&lt;=</code> : c'est une source classique de bug. Un test sur la<br/>
valeur frontière, ici une note de <code>10</code>, suffit à le révéler.</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>if note &gt; 9:</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette condition fonctionne pour des notes entières, mais<br/>
elle compte aussi <code>9.5</code>. L'appel donnerait <code>3</code> au lieu de <code>2</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>if note &gt; 10.0:</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : écrire <code>10.0</code> au lieu de <code>10</code> ne change pas la<br/>
comparaison. L'inégalité reste stricte, la note <code>10</code> est toujours<br/>
écartée et l'appel renvoie encore <code>1</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>if note == 10:</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette condition ne compte plus que les notes égales à<br/>
<code>10</code> et oublie <code>14</code>. L'appel renvoie <code>1</code>, et le résultat serait<br/>
faux pour toute liste contenant une note au-dessus de <code>10</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>if note &gt;= 10:</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'inégalité large traduit exactement « supérieure<br/>
ou égale à $10$ ». L'appel compte <code>10</code> et <code>14</code>, et renvoie <code>2</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q16 : Une variable qui cache une fonction</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On exécute le programme suivant :</p>
<pre><code>notes = [12, 17, 9]
max = 0
for note in notes:
    if note &gt; max:
        max = note
print(max)
print(max(notes))</code></pre>
<p>Il affiche <code>17</code>, puis s'arrête sur<br/>
<code>TypeError: 'int' object is not callable</code>. Quelle est la cause de<br/>
ce bug ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un nom de variable doit être explicite et ne pas reprendre celui<br/>
d'une fonction existante (<code>max</code>, <code>min</code>, <code>sum</code>, <code>len</code>, <code>list</code>).<br/>
Sinon la fonction devient inaccessible, et l'erreur survient loin<br/>
de l'affectation qui l'a causée.</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 fonction <code>max</code> de Python exige une liste déjà triée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>max</code> accepte une liste dans n'importe quel ordre.<br/>
D'ailleurs, l'erreur ne parle pas d'ordre : elle signale qu'on<br/>
tente d'appeler un entier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La variable <code>max</code> remplace la fonction <code>max</code>, devenue un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : après <code>max = 0</code>, le nom <code>max</code> désigne un entier,<br/>
qui vaut <code>17</code> à la fin de la boucle. <code>max(notes)</code> revient à<br/>
écrire <code>17(notes)</code>, d'où l'erreur. Il suffit de renommer la<br/>
variable, par exemple <code>plus_grande</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La boucle a remplacé la liste <code>notes</code> par un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle affecte <code>note</code>, sans <code>s</code>, et ne modifie jamais<br/>
<code>notes</code>. La liste vaut toujours <code>[12, 17, 9]</code> ; c'est le nom <code>max</code><br/>
qui a changé de sens.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction <code>max</code> compare deux nombres et refuse une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>max</code> accepte aussi une liste, et <code>max([12, 17, 9])</code><br/>
vaut <code>17</code> dans un programme où ce nom n'a pas été réutilisé.</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>On obtient une trace en affichant,<br/>
par exemple à chaque tour de boucle<br/>
ou à chaque appel de fonction, la<br/>
valeur des variables utiles. Le<br/>
résultat est verbeux mais permet de<br/>
suivre pas à pas un comportement<br/>
inattendu.</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/>
On peut l'obtenir simplement avec<br/>
des <code>print</code> placés aux étapes<br/>
clé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 vérifie une hypothèse<br/>
du programmeur, comme une<br/>
précondition : si elle échoue, le<br/>
programme contient un bug. Une saisie<br/>
mal formée, elle, est un cas<br/>
prévisible : on capture l'exception<br/>
avec <code>try / except</code> pour réagir<br/>
proprement.</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>try / except</code> exprime « cela peut<br/>
arriver, et voici comment je le<br/>
gère ».</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q20 : Un indice qui sort de la liste</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La fonction suivante doit renvoyer l'indice du premier nombre<br/>
négatif de la liste <code>t</code>, ou <code>len(t)</code> s'il n'y en a aucun :</p>
<pre><code>def indice_premier_negatif(t):
    i = 0
    while t[i] &gt;= 0:
        i = i + 1
    return i</code></pre>
<p>L'appel <code>indice_premier_negatif([3, 5, 2])</code> s'arrête sur<br/>
<code>IndexError: list index out of range</code>. Quelle condition de boucle<br/>
corrige la fonction ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un parcours par <code>while</code> doit garantir que l'indice reste dans la<br/>
liste avant chaque lecture. Placer le test <code>i &lt; len(t)</code> en premier<br/>
profite de l'évaluation séquentielle de <code>and</code> : la lecture <code>t[i]</code><br/>
n'a lieu que si l'indice est valide.</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>while t[i] &gt;= 0 and i &lt; len(t):</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>and</code> évalue d'abord la condition de gauche. Pour<br/>
<code>i = 3</code>, Python lit <code>t[3]</code> avant de tester <code>i &lt; len(t)</code>, et<br/>
l'<code>IndexError</code> se produit toujours.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>while i &lt; len(t) and t[i] &gt;= 0:</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour <code>i = 3</code>, <code>i &lt; len(t)</code> est faux, donc <code>and</code><br/>
n'évalue pas <code>t[3]</code>. La boucle s'arrête et la fonction renvoie<br/>
<code>3</code>, soit <code>len(t)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>while i &lt;= len(t) and t[i] &gt;= 0:</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'indice <code>len(t)</code> n'existe pas, le dernier est<br/>
<code>len(t) - 1</code>. Pour <code>i = 3</code>, le test <code>3 &lt;= 3</code> est vrai et Python<br/>
lit <code>t[3]</code> : l'<code>IndexError</code> demeure.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>while t[i] &gt;= 0 or i &lt; len(t):</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : avec <code>or</code>, la boucle continue dès qu'une condition est<br/>
vraie. Tant que <code>i &lt; len(t)</code>, elle ne s'arrête jamais, même sur un<br/>
nombre négatif, et finit par lire <code>t[3]</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q21 : Une boucle qui rate sa cible</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On exécute le programme suivant :</p>
<pre><code>x = 0
n = 0
while x != 1:
    x = x + 0.1
    n = n + 1
print(n)</code></pre>
<p>Que se passe-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les calculs sur les flottants sont approchés : il faut éviter de<br/>
tester l'égalité de deux flottants. Ici, on écrirait plutôt<br/>
<code>while x &lt; 1:</code>, ou mieux une boucle bornée<br/>
<code>for n in range(10):</code> qui ne dépend pas d'arrondis.</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 affiche <code>10</code>, après dix ajouts de <code>0.1</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>0.1</code> n'a pas d'écriture binaire exacte. Après dix<br/>
ajouts, <code>x</code> vaut <code>0.9999999999999999</code>, qui est différent de <code>1</code> :<br/>
la boucle continue.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>11</code>, <code>!=</code> faisant faire un tour de trop</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : au onzième tour, <code>x</code> vaut <code>1.0999999999999999</code>, lui<br/>
aussi différent de <code>1</code>. Aucune valeur de <code>x</code> n'est jamais égale à<br/>
<code>1</code>, la boucle ne s'arrête donc à aucun tour.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La boucle ne s'arrête jamais</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les arrondis s'accumulent et <code>x</code> passe de<br/>
<code>0.9999999999999999</code> à <code>1.0999999999999999</code> sans jamais valoir<br/>
exactement <code>1</code>. La condition <code>x != 1</code> reste vraie indéfiniment.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, un flottant ne se comparant pas à un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python compare sans problème un flottant et un entier,<br/>
par exemple <code>1.0 == 1</code> vaut <code>True</code>. Le programme ne s'arrête sur<br/>
aucune erreur ; il boucle.</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 : horodater chaque<br/>
ligne du journal. En cas d'incident,<br/>
filtrer le journal sur la fenêtre<br/>
temporelle de l'erreur permet de<br/>
reconstituer rapidement la chaîne<br/>
d'événements 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 du cas fautif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette méthodologie est éprouvée.<br/>
Sauter une étape, en particulier<br/>
l'ajout au jeu de tests du cas qui<br/>
faisait échouer le programme,<br/>
expose à voir le bug réapparaître<br/>
lors d'une modification ultérieure.</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 succès d'un jeu de tests ne garantit pas la correction du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est correcte. Un<br/>
test ne vérifie que le cas qu'il<br/>
examine : un bug peut se cacher dans<br/>
une entrée que personne n'a testée.</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 bloc <code>with</code> délimite la durée<br/>
d'utilisation du fichier : dès que<br/>
l'on sort du bloc indenté,<br/>
normalement ou à cause d'une<br/>
exception, le fichier est fermé.<br/>
C'est la forme à privilégier pour<br/>
lire ou écrire un fichier.</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 <code>with</code>. Si une<br/>
exception est levée pendant le<br/>
<code>read()</code> dans la version sans <code>with</code>,<br/>
l'instruction <code>f.close()</code> ne sera<br/>
jamais exécutée, et le fichier reste<br/>
ouvert. La construction <code>with</code><br/>
garantit la fermeture, qu'il y ait<br/>
erreur ou non.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q27 : Une égalité entre flottants</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que vaut l'expression <code>0.1 + 0.2 == 0.3</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Tester l'égalité de deux flottants est un piège classique : on<br/>
teste plutôt que leur écart est petit.</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><code>False</code>, la somme valant <code>0.30000000000000004</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : $0{,}1$ et $0{,}2$ n'ont pas d'écriture binaire<br/>
exacte, et les arrondis s'accumulent. On compare des flottants<br/>
à une tolérance près, <code>abs(a - b) &lt; 1e-9</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>True</code>, l'addition de deux décimaux étant exacte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : en binaire, $0{,}1$ est une fraction infinie, arrondie<br/>
au stockage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, deux flottants ne pouvant être comparés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la comparaison est permise, c'est son résultat qui<br/>
surprend.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>True</code>, Python arrondissant avant de comparer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun arrondi n'est fait à la comparaison.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q28 : Une grille dont les lignes sont la même liste</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>grille = [[0] * 3] * 3
grille[0][0] = 1
print(grille)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Multiplier une liste répète des références, pas des copies : le<br/>
piège touche toutes les structures imbriqué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="100" format="html">
    <text><![CDATA[<p><code>[[1, 0, 0], [1, 0, 0], [1, 0, 0]]</code>, les trois lignes étant la même liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>[liste] * 3</code> répète trois fois la même<br/>
référence ; modifier une ligne modifie les trois. Il faut<br/>
construire chaque ligne séparément, par exemple avec une boucle<br/>
ou une compréhension.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[[1, 0, 0], [0, 0, 0], [0, 0, 0]]</code>, seule la première ligne changeant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait le cas avec trois listes distinctes, ce que<br/>
<code>* 3</code> ne crée pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[[1, 1, 1], [0, 0, 0], [0, 0, 0]]</code>, la ligne entière valant <code>1</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seule la case d'indice $0$ est modifiée, mais dans<br/>
chaque ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, une liste de listes ne pouvant être multipliée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la multiplication est permise, et c'est elle qui crée<br/>
le piège.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q29 : Une valeur par défaut partagée entre les appels</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche la dernière ligne ?<br/>
<pre><code>def ajoute(x, l=[]):
    l.append(x)
    return l

ajoute(1)
print(ajoute(2))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour une valeur par défaut mutable, on écrit <code>l=None</code> et l'on crée<br/>
la liste dans la fonction.</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><code>[1, 2]</code>, la liste par défaut étant créée une seule fois</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la valeur par défaut est évaluée à la<br/>
définition de la fonction, puis partagée par tous les appels<br/>
qui ne fournissent pas <code>l</code>. Le premier appel y a laissé <code>1</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[2]</code>, chaque appel repartant d'une liste vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la liste vide n'est pas recréée à chaque appel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1]</code>, le second appel n'ayant rien ajouté</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le second appel ajoute bien <code>2</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, une liste ne pouvant servir de valeur par défaut</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est permis, et c'est précisément le piège.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q30 : Deux listes égales mais distinctes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affichent les deux <code>print</code> ?<br/>
<pre><code>a = [1, 2]
b = [1, 2]
print(a == b)
print(a is b)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>is</code> ne sert qu'à tester <code>None</code> ou l'identité d'objets ; pour<br/>
comparer des valeurs, on utilise <code>==</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><code>True</code> puis <code>False</code>, deux listes de même contenu mais distinctes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>==</code> compare les contenus, <code>is</code> demande si les<br/>
deux noms désignent le même objet en mémoire. Ici deux listes<br/>
ont été créées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>True</code> puis <code>True</code>, les deux listes étant identiques</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : deux crochets, deux listes ; <code>is</code> les distingue.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>False</code> puis <code>False</code>, deux listes n'étant jamais égales</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>==</code> sur des listes compare élément par élément.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>False</code> puis <code>True</code>, <code>is</code> étant plus tolérant que <code>==</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'inverse, <code>is</code> est le test le plus strict.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q31 : Un retour placé dans la boucle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>def somme(l):
    total = 0
    for x in l:
        total = total + x
        return total

print(somme([1, 2, 3]))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une erreur d'indentation ne provoque aucun message : seul le<br/>
résultat trahit le <code>return</code> mal placé.</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><code>1</code>, la boucle s'arrêtant dès le premier tour</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : indenté dans le corps de la boucle, <code>return</code><br/>
s'exécute dès le premier élément. Il doit être au niveau du<br/>
<code>for</code>, après la boucle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>6</code>, la somme de tous les éléments de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle ne va pas jusqu'au bout.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>3</code>, le dernier élément de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le premier élément qui est renvoyé, pas le<br/>
dernier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>0</code>, le <code>return</code> précédant toute addition</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'addition de la ligne précédente a déjà eu lieu.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q32 : Lire un message de type</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un programme s'arrête sur ce message. Quelle instruction l'a<br/>
provoqué ?<br/>
<pre><code>TypeError: can only concatenate str (not "int") to str</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le nom de l'exception et son message désignent la nature de<br/>
l'erreur ; les lire évite de chercher au hasard.</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><code>"Âge : " + 17</code>, une chaîne concaténée à un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>+</code> entre une chaîne et un entier est refusé ;<br/>
il faut convertir avec <code>str(17)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>10 / 0</code>, une division par zéro dans un calcul</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait une <code>ZeroDivisionError</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>liste[5]</code> sur une liste de trois éléments seulement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait une <code>IndexError</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>print(age)</code> sans avoir défini la variable <code>age</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait une <code>NameError</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q33 : Une conversion qui échoue</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle exception lève <code>int("12a")</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>TypeError</code> signale un type inadapté, <code>ValueError</code> une valeur<br/>
inadaptée pour un type accepté.</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><code>ValueError</code>, le type est bon mais la valeur ne se convertit pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>int</code> accepte une chaîne, mais <code>"12a"</code> ne<br/>
représente pas un entier. C'est la valeur qui est en cause.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>TypeError</code>, une chaîne ne pouvant devenir un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>int("12")</code> fonctionne, le type chaîne est accepté.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SyntaxError</code>, la lettre <code>a</code> étant mal placée dans le nombre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe du programme est correcte ; l'erreur<br/>
survient à l'exécution.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune, Python gardant les chiffres et renvoyant <code>12</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python ne tronque pas, il refuse.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q34 : Une exception que la fonction ne capture pas</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une exception est levée dans une fonction qui ne contient aucun<br/>
<code>try</code>. Que devient-elle ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La trace d'erreur montre cette remontée : la pile des appels, de<br/>
l'appel initial jusqu'à la ligne fautive.</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>Elle remonte à l'appelant, qui la capture ou laisse le programme s'arrêter</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'exception interrompt la fonction et remonte<br/>
d'appel en appel jusqu'à un <code>try</code> qui la capture ; sans lui, le<br/>
programme s'arrête avec la trace.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle est ignorée et la fonction renvoie <code>None</code> à l'appelant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une exception n'est jamais ignorée en silence.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle arrête seulement la fonction, le programme continuant après l'appel</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'appelant est interrompu à son tour, sauf s'il la<br/>
capture.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle est capturée automatiquement par Python, qui affiche un avertissement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python affiche la trace et arrête le programme, ce<br/>
n'est pas un simple avertissement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q35 : Ce qu'il faut placer dans un bloc try</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle portion de code placer dans un bloc <code>try</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un <code>try</code> exprime une attente précise : telle instruction peut<br/>
échouer de telle façon, et voici quoi faire.</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 seule instruction risquée, pour ne pas masquer d'autres erreurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un <code>try</code> trop large capture aussi les<br/>
exceptions inattendues, et cache alors de vrais bugs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Tout le programme, pour qu'il ne s'arrête jamais en cours de route</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un programme qui continue après une erreur inconnue<br/>
produit des résultats faux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les définitions de fonctions, où naissent les erreurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : définir une fonction ne lève rien ; c'est son appel<br/>
qui peut échouer.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les appels de <code>print</code>, seules instructions pouvant échouer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>print</code> est une des instructions les plus sûres.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q36 : Une clé absente du dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que produit <code>notes["zoe"]</code> si le dictionnaire <code>notes</code> ne contient<br/>
pas la clé <code>"zoe"</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Chaque structure a son exception d'accès : <code>IndexError</code> pour les<br/>
listes, <code>KeyError</code> pour les dictionnaires.</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>Une <code>KeyError</code>, la clé n'existant pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : lire une clé absente est une erreur ; on teste<br/>
d'abord <code>"zoe" in notes</code>, ou l'on utilise <code>notes.get("zoe")</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une <code>IndexError</code>, comme pour une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>IndexError</code> concerne les indices entiers des listes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>None</code>, sans aucune erreur ni message</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est <code>notes.get("zoe")</code> qui renvoie <code>None</code>, pas les<br/>
crochets.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>0</code>, la valeur par défaut des notes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un dictionnaire n'a pas de valeur par défaut.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q37 : Une exception au milieu d'une boucle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que se passe-t-il si un seul élément de <code>textes</code> n'est pas<br/>
convertible ?<br/>
<pre><code>nombres = []
for t in textes:
    try:
        nombres.append(int(t))
    except ValueError:
        print("valeur ignorée")</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La place du <code>try</code> décide de ce qui est abandonné : un tour de<br/>
boucle, ou la boucle entière.</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 est signalé et sauté, les autres éléments étant convertis</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le <code>try</code> est dans la boucle ; l'exception est<br/>
traitée au tour fautif et le tour suivant commence normalement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La boucle s'arrête à cet élément, les suivants étant perdus</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait le cas avec le <code>try</code> autour de la boucle<br/>
entière.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le programme s'arrête malgré le <code>try</code>, l'erreur étant fatale</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'exception est bien une <code>ValueError</code>, capturée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Tous les éléments sont ignorés par précaution, la liste restant vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seul le tour où l'exception est levée passe dans le<br/>
<code>except</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q38 : Un test qui échoue après une modification</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Tous les tests passaient. Après une modification du programme,<br/>
l'un d'eux échoue. Qu'en conclure ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Relancer tous les tests après chaque modification protège contre<br/>
les régressions, ces bugs introduits en corrigeant autre chose.</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 modification a cassé un comportement qui fonctionnait</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est le rôle des tests conservés d'une version<br/>
à l'autre, dits de non-régression ; ils signalent aussitôt ce<br/>
que la modification a dégradé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le test est forcément faux, puisqu'il passait avant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un test qui passait décrit un comportement attendu ;<br/>
c'est le programme qui a changé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il faut supprimer ce test pour retrouver une série au vert</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : supprimer le test cache le problème sans le résoudre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le programme n'a jamais fonctionné, les anciens tests étant trop faibles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien ne permet de le dire ; le test échoue à cause de<br/>
la modification.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Mise au point et débogage — Q39 : Localiser un bug dans un long programme</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un programme de deux cents lignes donne un résultat faux, sans<br/>
message d'erreur. Comment localiser efficacement la ligne fautive ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La mise au point suit la même logique que les algorithmes : réduire<br/>
l'espace de recherche à chaque étape.</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>Vérifier l'état à mi-parcours, puis chercher dans la moitié fautive</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : comme une recherche dichotomique, chaque<br/>
vérification divise par deux la zone à inspecter ; quelques<br/>
affichages suffisent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Relire le programme en entier du début à la fin, autant de fois que nécessaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une relecture sans point de repère rate souvent<br/>
l'erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Commencer par la dernière ligne, où le résultat est affiché</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'affichage final est rarement fautif ; l'erreur est en<br/>
amont.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Réécrire le programme entièrement, en espérant ne pas refaire l'erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : réécrire coûte cher et reproduit souvent les mêmes<br/>
erreurs.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
