<?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 try et except, 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 try / except<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 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 # et n'ont<br/>
aucun effet sur l'exécution.</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/>
ValueError, TypeError, IndexError,<br/>
KeyError. 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 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>
</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 : except ValueError: 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 except 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="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
try:<br/>
    risque()<br/>
except Exception as e:<br/>
    print("Erreur :", e)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le bloc try tente l'exécution. En<br/>
cas d'exception, le bloc except<br/>
prend le relais et permet de gérer<br/>
proprement l'erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
resultat = risque()<br/>
if resultat == error:<br/>
    print("Erreur :", resultat)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce code ne gère rien : si risque()<br/>
lève une exception, le programme<br/>
s'arrête avant même d'atteindre le<br/>
if. 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>
  <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/>
try / except pour intercepter une<br/>
exception et poursuivre l'exécution.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
try {<br/>
    risque()<br/>
} catch (Exception e) {<br/>
    print("Erreur :", e)<br/>
}<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe à accolades, avec<br/>
catch, est celle de Java ou de C++,<br/>
pas celle de Python, qui emploie try<br/>
et except suivis de deux-points et<br/>
d'un bloc indenté.</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>
<p>`<code>python<br/>
def moyenne(notes):<br/>
    """Renvoie la moyenne des nombres de la liste notes, supposée non vide."""<br/>
    total = 0<br/>
    for note in notes:<br/>
        total = total + note<br/>
    return total / len(notes)<br/>
</code></p>
<p>À quoi sert la chaîne écrite entre triples guillemets sous la<br/>
ligne def` ?</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>À 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. moyenne([12, 15])<br/>
renvoie simplement 13.5 ; seul un print produit un<br/>
affichage.</p>]]></text>
    </feedback>
  </answer>
  <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 assert len(notes) &gt; 0.</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 len(notes) lève une ZeroDivisionError,<br/>
que la chaîne soit présente ou non.</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 help(moyenne).</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>É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>
  <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>
</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 maximum(t) 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="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>
  <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>
</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>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>
  <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>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>
</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>
<p>`<code>python<br/>
def mention(note):<br/>
    if note &gt;= 16:<br/>
        return "très bien"<br/>
    elif note &gt;= 14:<br/>
        return "bien"<br/>
    elif note &gt;= 12:<br/>
        return "assez bien"<br/>
    elif note &gt;= 10:<br/>
        return "passable"<br/>
</code></p>
<p>Qu'affiche l'instruction print(mention(8))` ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une conditionnelle doit prévoir tous les cas possibles. Sinon, une<br/>
fonction peut renvoyer None sans aucun message, et l'erreur<br/>
apparaît plus loin, quand on utilise ce résultat. Terminer par un<br/>
else 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>Une ligne vide, puisque la fonction ne renvoie rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une fonction qui se termine sans return renvoie la<br/>
valeur None, et print(None) affiche bien le mot None, pas<br/>
une ligne vide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>passable, le texte de la dernière branche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la branche elif note &gt;= 10 n'est exécutée que si sa<br/>
condition est vraie. Pour 8, les quatre conditions sont fausses<br/>
et aucun return n'est atteint.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car aucune branche ne correspond à 8</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="100" format="html">
    <text><![CDATA[<p>None</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : aucune condition n'est vraie pour 8, la fonction<br/>
atteint sa fin sans return et renvoie donc None, que print<br/>
affiche. Il manque un cas final, par exemple<br/>
else: return "insuffisant".</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="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 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="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="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>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="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>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 racine_carree(x), on<br/>
souhaite <strong>signaler une erreur</strong> lorsque<br/>
x 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="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>
  <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 print puis renvoyer la valeur 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'appel à print 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="100" format="html">
    <text><![CDATA[<p>Vérifier la précondition dès l'entrée avec assert x &gt;= 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse, par exemple :</p>
<p>`<code>python<br/>
def racine_carree(x):<br/>
    assert x &gt;= 0, "x doit être positif"<br/>
    ...<br/>
</code></p>
<p>Si la condition est fausse,<br/>
l'assertion interrompt aussitôt<br/>
l'exécution sur une AssertionError`<br/>
qui porte le message : l'appel<br/>
fautif est désigné clairement.</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 2009 au clavier :</p>
<p>`<code>python<br/>
annee = input("Année de naissance : ")<br/>
age = 2026 - annee<br/>
print("Tu as", age, "ans")<br/>
</code>`</p>
<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/>
int ou float. Le message d'une TypeError 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>Une ValueError, car la saisie 2009 ne décrit pas un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : "2009" décrit bien un entier, et int("2009")<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="0" format="html">
    <text><![CDATA[<p>Une TypeError, car print refuse de mêler texte et nombres</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : print 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>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une TypeError, car input renvoie une chaîne non convertie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : 2026 - "2009" soustrait une chaîne d'un<br/>
entier. Python s'arrête sur<br/>
TypeError: unsupported operand type(s) for -: 'int' and 'str'.<br/>
Il faut écrire annee = int(input("Année de naissance : ")).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche Tu as 17 ans</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : input renvoie toujours une chaîne de caractères, ici<br/>
"2009". Python ne la convertit pas en nombre de lui-même, et la<br/>
soustraction échoue.</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 except: 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="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 except<br/>
nu, comme expliqué dans la bonne<br/>
réponse.</p>]]></text>
    </feedback>
  </answer>
  <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/>
except Exception: (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 que la syntaxe except: 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>
  <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/>
except nu intercepte trop de<br/>
choses.</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/>
`<code>python<br/>
def ajouter_bonus(notes):<br/>
    for i in range(len(notes)):<br/>
        notes[i] = notes[i] + 1<br/>
    return notes<br/>
notes_classe = [12, 15, 9]<br/>
bonus = ajouter_bonus(notes_classe)<br/>
print(notes_classe)<br/>
</code>`<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/>
[note + 1 for note in notes], 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>[12, 15, 9]</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 notes[i] = ... modifie donc<br/>
notes_classe.</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>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[14, 17, 11]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le bonus n'est ajouté qu'une fois. L'affectation<br/>
bonus = ajouter_bonus(notes_classe) 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="100" format="html">
    <text><![CDATA[<p>[13, 16, 10]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : notes et notes_classe désignent la même<br/>
liste. La fonction la modifie en place, et bonus 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>
</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>
<p>`<code>python<br/>
def compter_admis(notes):<br/>
    n = 0<br/>
    for note in notes:<br/>
        if note &gt; 10:<br/>
            n = n + 1<br/>
    return n<br/>
</code></p>
<p>Or compter_admis([8.5, 10, 14, 9.5]) renvoie 1 au lieu de 2`.<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/>
&lt; et &lt;= : c'est une source classique de bug. Un test sur la<br/>
valeur frontière, ici une note de 10, 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="100" format="html">
    <text><![CDATA[<p>if note &gt;= 10:</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 10 et 14, et renvoie 2.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>if note == 10:</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette condition ne compte plus que les notes égales à<br/>
10 et oublie 14. L'appel renvoie 1, et le résultat serait<br/>
faux pour toute liste contenant une note au-dessus de 10.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>if note &gt; 10.0:</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : écrire 10.0 au lieu de 10 ne change pas la<br/>
comparaison. L'inégalité reste stricte, la note 10 est toujours<br/>
écartée et l'appel renvoie encore 1.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>if note &gt; 9:</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette condition fonctionne pour des notes entières, mais<br/>
elle compte aussi 9.5. L'appel donnerait 3 au lieu de 2.</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>
<p>`<code>python<br/>
notes = [12, 17, 9]<br/>
max = 0<br/>
for note in notes:<br/>
    if note &gt; max:<br/>
        max = note<br/>
print(max)<br/>
print(max(notes))<br/>
</code></p>
<p>Il affiche 17, puis s'arrête sur<br/>
TypeError: 'int' object is not callable`. 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 (max, min, sum, len, list).<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 max de Python exige une liste déjà triée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : max 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="0" format="html">
    <text><![CDATA[<p>La boucle a remplacé la liste notes par un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle affecte note, sans s, et ne modifie jamais<br/>
notes. La liste vaut toujours [12, 17, 9] ; c'est le nom max<br/>
qui a changé de sens.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La variable max remplace la fonction max, devenue un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : après max = 0, le nom max désigne un entier,<br/>
qui vaut 17 à la fin de la boucle. max(notes) revient à<br/>
écrire 17(notes), d'où l'erreur. Il suffit de renommer la<br/>
variable, par exemple plus_grande.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction max compare deux nombres et refuse une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : max accepte aussi une liste, et max([12, 17, 9])<br/>
vaut 17 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 print placés aux étapes<br/>
clés.</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>
  <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>
</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 try / except 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>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="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="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 : assert<br/>
exprime « cela ne doit jamais<br/>
arriver », tandis que<br/>
try / except 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 t, ou len(t) s'il n'y en a aucun :</p>
<p>`<code>python<br/>
def indice_premier_negatif(t):<br/>
    i = 0<br/>
    while t[i] &gt;= 0:<br/>
        i = i + 1<br/>
    return i<br/>
</code></p>
<p>L'appel indice_premier_negatif([3, 5, 2]) s'arrête sur<br/>
IndexError: list index out of range`. Quelle condition de boucle<br/>
corrige la fonction ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un parcours par while doit garantir que l'indice reste dans la<br/>
liste avant chaque lecture. Placer le test i &lt; len(t) en premier<br/>
profite de l'évaluation séquentielle de and : la lecture t[i]<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>while t[i] &gt;= 0 and i &lt; len(t):</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : and évalue d'abord la condition de gauche. Pour<br/>
i = 3, Python lit t[3] avant de tester i &lt; len(t), et<br/>
l'IndexError se produit toujours.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>while i &lt; len(t) and t[i] &gt;= 0:</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour i = 3, i &lt; len(t) est faux, donc and<br/>
n'évalue pas t[3]. La boucle s'arrête et la fonction renvoie<br/>
3, soit len(t).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>while t[i] &gt;= 0 or i &lt; len(t):</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : avec or, la boucle continue dès qu'une condition est<br/>
vraie. Tant que i &lt; len(t), elle ne s'arrête jamais, même sur un<br/>
nombre négatif, et finit par lire t[3].</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>while i &lt;= len(t) and t[i] &gt;= 0:</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'indice len(t) n'existe pas, le dernier est<br/>
len(t) - 1. Pour i = 3, le test 3 &lt;= 3 est vrai et Python<br/>
lit t[3] : l'IndexError demeure.</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>
<p>`<code>python<br/>
x = 0<br/>
n = 0<br/>
while x != 1:<br/>
    x = x + 0.1<br/>
    n = n + 1<br/>
print(n)<br/>
</code>`</p>
<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/>
while x &lt; 1:, ou mieux une boucle bornée<br/>
for n in range(10): 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>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 1.0 == 1 vaut True. Le programme ne s'arrête sur<br/>
aucune erreur ; il boucle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche 11, != faisant faire un tour de trop</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : au onzième tour, x vaut 1.0999999999999999, lui<br/>
aussi différent de 1. Aucune valeur de x n'est jamais égale à<br/>
1, la boucle ne s'arrête donc à aucun tour.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche 10, après dix ajouts de 0.1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 0.1 n'a pas d'écriture binaire exacte. Après dix<br/>
ajouts, x vaut 0.9999999999999999, qui est différent de 1 :<br/>
la boucle continue.</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 x passe de<br/>
0.9999999999999999 à 1.0999999999999999 sans jamais valoir<br/>
exactement 1. La condition x != 1 reste vraie indéfiniment.</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>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="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="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 grep,<br/>
tail, 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>
  <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>
</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="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>La construction try / except 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 try / except.</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>
  <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>
</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/>
`<code>python<br/>
with open("fichier.txt") as f:<br/>
    contenu = f.read()<br/>
</code><br/>
par rapport à<br/>
<code>python<br/>
f = open("fichier.txt")<br/>
contenu = f.read()<br/>
f.close()<br/>
</code>`<br/>
?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le bloc with 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="100" format="html">
    <text><![CDATA[<p>La construction with 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 with. Si une<br/>
exception est levée pendant le<br/>
read() dans la version sans with,<br/>
l'instruction f.close() ne sera<br/>
jamais exécutée, et le fichier reste<br/>
ouvert. La construction with<br/>
garantit la fermeture, qu'il y ait<br/>
erreur ou non.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La construction with est<br/>
obligatoire en Python depuis la<br/>
version 3</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la construction with<br/>
n'est pas obligatoire ; elle est<br/>
fortement recommandée. La<br/>
version manuelle avec open et<br/>
close 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 with 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="0" format="html">
    <text><![CDATA[<p>La construction with permet<br/>
d'écrire dans le fichier sans<br/>
ouvrir un mode d'écriture</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : with n'a aucun effet<br/>
sur le mode d'ouverture. Pour<br/>
écrire dans un fichier, il faut<br/>
toujours préciser mode='w' ou<br/>
'a', que l'on utilise with ou<br/>
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 0.1 + 0.2 == 0.3 ?</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="0" format="html">
    <text><![CDATA[<p>True, 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="100" format="html">
    <text><![CDATA[<p>False, la somme valant 0.30000000000000004</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, abs(a - b) &lt; 1e-9.</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>True, 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/>
`<code>python<br/>
grille = [[0] <em> 3] </em> 3<br/>
grille[0][0] = 1<br/>
print(grille)<br/>
</code>`</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="0" format="html">
    <text><![CDATA[<p>[[1, 1, 1], [0, 0, 0], [0, 0, 0]], la ligne entière valant 1</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>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[[1, 0, 0], [0, 0, 0], [0, 0, 0]], 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/>
* 3 ne crée pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>[[1, 0, 0], [1, 0, 0], [1, 0, 0]], les trois lignes étant la même liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : [liste] * 3 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>
</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/>
``python<br/>
def ajoute(x, l=[]):<br/>
    l.append(x)<br/>
    return l</p>
<p>ajoute(1)<br/>
print(ajoute(2))<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour une valeur par défaut mutable, on écrit l=None 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="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>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>[1, 2], 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 l. Le premier appel y a laissé 1.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[2], 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>[1], le second appel n'ayant rien ajouté</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le second appel ajoute bien 2.</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 print ?<br/>
`<code>python<br/>
a = [1, 2]<br/>
b = [1, 2]<br/>
print(a == b)<br/>
print(a is b)<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>is ne sert qu'à tester None ou l'identité d'objets ; pour<br/>
comparer des valeurs, on utilise ==.</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>True puis True, les deux listes étant identiques</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : deux crochets, deux listes ; is les distingue.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>True puis False, deux listes de même contenu mais distinctes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : == compare les contenus, is 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>False puis False, deux listes n'étant jamais égales</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : == sur des listes compare élément par élément.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>False puis True, is étant plus tolérant que ==</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'inverse, is 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/>
``python<br/>
def somme(l):<br/>
    total = 0<br/>
    for x in l:<br/>
        total = total + x<br/>
        return total</p>
<p>print(somme([1, 2, 3]))<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une erreur d'indentation ne provoque aucun message : seul le<br/>
résultat trahit le return 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="0" format="html">
    <text><![CDATA[<p>6, 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="100" format="html">
    <text><![CDATA[<p>1, 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, return<br/>
s'exécute dès le premier élément. Il doit être au niveau du<br/>
for, après la boucle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>3, 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>0, le return 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/>
`<code><br/>
TypeError: can only concatenate str (not "int") to str<br/>
</code>`</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>"Âge : " + 17, une chaîne concaténée à un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : + entre une chaîne et un entier est refusé ;<br/>
il faut convertir avec str(17).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>liste[5] sur une liste de trois éléments seulement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait une IndexError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>10 / 0, une division par zéro dans un calcul</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait une ZeroDivisionError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>print(age) sans avoir défini la variable age</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait une NameError.</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 int("12a") ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>TypeError signale un type inadapté, ValueError 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="0" format="html">
    <text><![CDATA[<p>SyntaxError, la lettre a é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>TypeError, une chaîne ne pouvant devenir un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : int("12") fonctionne, le type chaîne est accepté.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune, Python gardant les chiffres et renvoyant 12</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python ne tronque pas, il refuse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>ValueError, le type est bon mais la valeur ne se convertit pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : int accepte une chaîne, mais "12a" ne<br/>
représente pas un entier. C'est la valeur qui est en cause.</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/>
try. 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="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>
  <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 try 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 None à 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>
</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 try ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un try 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="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 appels de print, seules instructions pouvant échouer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : print est une des instructions les plus sûres.</p>]]></text>
    </feedback>
  </answer>
  <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 try 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>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>
</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 notes["zoe"] si le dictionnaire notes ne contient<br/>
pas la clé "zoe" ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Chaque structure a son exception d'accès : IndexError pour les<br/>
listes, KeyError 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="0" format="html">
    <text><![CDATA[<p>0, 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>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une KeyError, 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 "zoe" in notes, ou l'on utilise notes.get("zoe").</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une IndexError, comme pour une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : IndexError concerne les indices entiers des listes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>None, sans aucune erreur ni message</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est notes.get("zoe") qui renvoie None, pas les<br/>
crochets.</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 textes n'est pas<br/>
convertible ?<br/>
`<code>python<br/>
nombres = []<br/>
for t in textes:<br/>
    try:<br/>
        nombres.append(int(t))<br/>
    except ValueError:<br/>
        print("valeur ignorée")<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La place du try 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="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/>
except.</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 try autour de la boucle<br/>
entière.</p>]]></text>
    </feedback>
  </answer>
  <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 try 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>Le programme s'arrête malgré le try, l'erreur étant fatale</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'exception est bien une ValueError, capturée.</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="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 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="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 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="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>
  <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>
</question>

</quiz>
