<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Première/Spécification</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Spécifier une fonction : signature (nom, paramètres,<br/>
type de retour), préconditions, postconditions,<br/>
documentation par docstrings, exemples d'usage,<br/>
relation avec les tests.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q01 : Spécification</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce que la <strong>spécification</strong> d'une<br/>
fonction ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Adage : « bien spécifier = à moitié<br/>
implémenté ». Bien spécifier permet de<br/>
tester, de documenter, et de coder<br/>
correctement.</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>Son code source complet</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le code source décrit<br/>
<strong>comment</strong> la fonction<br/>
réalise sa tâche, alors<br/>
que la spécification<br/>
décrit <strong>ce qu'elle<br/>
doit faire</strong>. Les deux<br/>
notions sont<br/>
distinctes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Son nombre total de lignes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le nombre de lignes est<br/>
une mesure du code, sans<br/>
rapport avec ce que la<br/>
fonction est censée<br/>
accomplir.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Sa vitesse d'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La vitesse d'exécution est<br/>
une mesure de performance,<br/>
observable à l'usage. Ce<br/>
n'est pas la<br/>
spécification, qui décrit<br/>
le comportement attendu<br/>
de la fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La description précise de ce que la fonction doit faire (paramètres attendus, valeur renvoyée, conditions d'utilisation), indépendamment de l'implémentation</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la spécification est un<br/>
<strong>contrat</strong> entre l'auteur et<br/>
l'utilisateur. Elle précède<br/>
l'implémentation.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q02 : Signature</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'appelle-t-on la <strong>signature</strong> d'une fonction ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Deux fonctions de <strong>même signature</strong> sont<br/>
interchangeables du point de vue de<br/>
l'appelant. C'est la base de la modularité.</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 nom de l'auteur de la fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation<br/>
littérale n'a aucun<br/>
rapport avec le sens<br/>
technique du mot<br/>
« signature » en<br/>
programmation.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Son nom, ses paramètres (avec leurs types) et son type de retour</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est l'« en-tête »<br/>
identifiant uniquement la fonction. En<br/>
Python avec annotations :<br/>
def carre(x: int) -&gt; int:.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le numéro de ligne où la fonction est définie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La position dans le<br/>
fichier source ne fait<br/>
pas partie de la<br/>
signature : seuls le<br/>
nom, les paramètres et<br/>
le type de retour la<br/>
composent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La date de création</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La date de création n'a<br/>
aucun lien avec la<br/>
signature, qui désigne<br/>
uniquement l'en-tête<br/>
identifiant la<br/>
fonction.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q03 : Précondition</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'une <strong>précondition</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est l'utilisateur qui doit garantir la<br/>
précondition. La fonction peut faire<br/>
confiance à ses paramètres (sauf si elle<br/>
est défensive et vérifie elle-même).</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 condition d'arrêt de boucle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La condition d'arrêt<br/>
d'une boucle est une<br/>
notion liée au contrôle<br/>
de flux d'un programme,<br/>
et non à la<br/>
spécification d'une<br/>
fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une condition qui doit être vraie avant l'appel de la fonction (sur les paramètres)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : par exemple, pour une<br/>
fonction racine(x), la précondition<br/>
peut être « x ≥ 0 ». Si la précondition<br/>
n'est pas respectée, la fonction n'a<br/>
pas à fonctionner correctement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une condition après l'appel</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait une <strong>postcondition</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une condition tirée au hasard</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une précondition n'a rien<br/>
d'aléatoire. C'est une<br/>
contrainte explicite,<br/>
documentée par le<br/>
concepteur de la<br/>
fonction.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q04 : Postcondition</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'une <strong>postcondition</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Précondition + postcondition = <strong>contrat</strong><br/>
de la fonction. Cette approche est dite<br/>
« <strong>programmation par contrat</strong> ».</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 condition tirée au hasard</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une postcondition n'a<br/>
rien d'aléatoire. C'est<br/>
une garantie explicite<br/>
fournie par la fonction<br/>
sur son résultat.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le type de retour de la fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le type de retour fait<br/>
partie de la signature.<br/>
La postcondition est, elle,<br/>
une propriété logique<br/>
que la valeur renvoyée<br/>
doit vérifier (par<br/>
exemple, « le résultat<br/>
est positif »).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Ce que la fonction garantit sur la valeur de retour (ou sur l'effet) après son exécution, si la précondition est respectée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : par exemple, pour<br/>
racine(x), la postcondition est<br/>
« la valeur renvoyée r vérifie<br/>
r * r == x » (à epsilon près pour les<br/>
flottants).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une condition avant l'appel</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait une <strong>précondition</strong>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q05 : Docstring</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment <strong>documenter</strong> une fonction Python<br/>
conformément à la PEP 257 ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Docstring de qualité : description courte,<br/>
ligne vide, description détaillée,<br/>
paramètres, retour, exemples (&gt;&gt;&gt; ...).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec un commentaire placé en fin de fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La convention est de<br/>
placer la docstring en<br/>
tout début de corps de<br/>
fonction, juste après<br/>
la signature.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec une docstring (chaîne entre triples guillemets) en première instruction du corps</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : def f(x): puis sur<br/>
la ligne suivante """description...""".<br/>
Accessible via help(f) ou f.__doc__.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec un commentaire # au-dessus</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Lisible par l'humain mais inaccessible<br/>
dynamiquement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Dans un fichier README placé à part</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La documentation<br/>
générale d'un projet<br/>
peut être placée dans un<br/>
fichier README, mais la<br/>
documentation d'une<br/>
fonction se met<br/>
directement dans son<br/>
corps, à l'aide d'une<br/>
docstring.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q06 : Exemple complet</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la <strong>bonne pratique</strong> pour spécifier<br/>
une fonction Python valeur_absolue(x) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonnes pratiques : signature typée,<br/>
docstring claire, contrat<br/>
pré-/post-conditions documenté.</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>python<br/>
# x est un nombre<br/>
# renvoie sa valeur absolue<br/>
def valeur_absolue(x):<br/>
    return abs(x)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Acceptable mais moins idiomatique<br/>
(pas accessible via help).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def valeur_absolue(x):<br/>
    return abs(x)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Code correct mais non documenté. La<br/>
spécification est implicite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>``python<br/>
def valeur_absolue(x: float) -&gt; float:<br/>
    """Renvoie la valeur absolue de x.</p>
<p>Précondition : x est un nombre.<br/>
    Postcondition : le résultat est &gt;= 0.<br/>
    """<br/>
    return abs(x)<br/>
``</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : signature avec types,<br/>
docstring décrivant le but, pré- et<br/>
postconditions. Code self-documenting.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def valeur_absolue(x):<br/>
    # implementation<br/>
    pass<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Code non implémenté.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q07 : Pourquoi spécifier ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi spécifier une fonction <strong>avant</strong> de<br/>
l'écrire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sans spécification : code parfois<br/>
« qui marche », mais buggé sur des cas<br/>
limites non envisagés. Avec spécification :<br/>
cas limites pensés en amont.</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>Parce que c'est obligatoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas une obligation<br/>
syntaxique. C'est une bonne pratique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour ralentir l'exécution du code</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La spécification n'a<br/>
aucune incidence sur la<br/>
performance ; elle<br/>
précède l'écriture du<br/>
code et ne s'exécute<br/>
pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Pour clarifier le but de la fonction, faciliter la conception, permettre les tests, et servir de documentation</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la spécification<br/>
structure la pensée. On évite de coder<br/>
dans le brouillard. La fonction est<br/>
alors testable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour utiliser davantage de mémoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La spécification est un<br/>
document conceptuel<br/>
rédigé avant le code.<br/>
Elle n'a aucun rapport<br/>
avec la consommation<br/>
mémoire à l'exécution.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q08 : Annotations de type</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que produisent les <strong>annotations de type</strong> en<br/>
Python (x: int) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Annotations utiles pour : lisibilité, IDE<br/>
(auto-complétion, détection d'erreurs),<br/>
tests statiques. À combiner avec une<br/>
docstring claire.</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 de syntaxe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : syntaxe valide depuis Python 3.5.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une vérification automatique à l'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python n'applique pas les<br/>
annotations à l'exécution.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une transformation du type</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de coercition.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une documentation du type attendu, vérifiable par des outils externes (mypy)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : annotations<br/>
informatives, sans effet à l'exécution<br/>
par défaut. Mais des outils statiques<br/>
peuvent les vérifier (mypy,<br/>
pyright).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q09 : Doctest</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi servent les exemples &gt;&gt;&gt; ... dans une<br/>
docstring ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Format doctest :<br/>
`<code>python<br/>
"""<br/>
&gt;&gt;&gt; carre(3)<br/>
9<br/>
"""<br/>
</code><br/>
Lancement : python -m doctest fichier.py`.</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éclarer des constantes du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La déclaration de<br/>
constantes se fait par<br/>
affectation classique,<br/>
en dehors de toute<br/>
docstring.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>À fournir des exemples d'utilisation qui peuvent être exécutés automatiquement comme tests par le module doctest</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : double avantage,<br/>
documentation et tests vérifiés. Le<br/>
module doctest extrait ces exemples<br/>
et vérifie qu'ils fonctionnent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À rendre la documentation plus jolie visuellement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation est<br/>
trop superficielle. Ces<br/>
exemples ont un rôle<br/>
fonctionnel précis,<br/>
comme expliqué dans la<br/>
bonne réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À signaler une erreur dans le code</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucun rapport. Les<br/>
exemples &gt;&gt;&gt; sont des<br/>
extraits exécutables,<br/>
conçus pour illustrer<br/>
le comportement attendu<br/>
de la fonction.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q10 : Cas limites</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quels sont les <strong>cas limites</strong> typiques à<br/>
considérer en spécifiant une fonction sur une<br/>
liste ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour les nombres : 0, négatifs, très<br/>
grands, fractionnaires. Pour les chaînes :<br/>
vide, un caractère, accents, emojis. Pour<br/>
les listes : vide, un élément, doublons,<br/>
triée/non trié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 liste constituée d'éléments imaginaires</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation<br/>
n'a pas de sens en<br/>
informatique : on<br/>
travaille toujours avec<br/>
des données concrètes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Liste vide, liste à un élément, liste très longue</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ces cas révèlent<br/>
souvent des bugs. Toujours les inclure<br/>
dans les tests.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une liste de couleurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description est<br/>
trop spécifique : on<br/>
cherche ici les cas<br/>
limites génériques d'une<br/>
fonction sur une<br/>
liste, indépendamment<br/>
du type de ses<br/>
éléments.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun, le cas général suffit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les bugs sont souvent dans les<br/>
cas limites.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q11 : Programmation par contrat</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que signifie « <strong>programmation par contrat</strong> » ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bénéfices : robustesse, débogage facile<br/>
(violation de contrat = origine du bug).<br/>
Outils : assert en Python pour vérifier<br/>
pré/post à 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>Rédiger un contrat juridique pour chaque programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le mot « contrat » est<br/>
ici employé au sens<br/>
informatique, sans<br/>
rapport avec le droit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Programmer à plusieurs au sein d'une même équipe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation<br/>
littérale est sans<br/>
rapport avec le sens<br/>
technique de<br/>
l'expression<br/>
« programmation par<br/>
contrat ».</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Concevoir chaque fonction avec un contrat explicite (préconditions, postconditions, invariants), respecté par l'appelant et par la fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : approche introduite par<br/>
Bertrand Meyer (langage Eiffel).<br/>
Chacune des deux parties (appelant,<br/>
fonction) a des obligations.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Programmer en échange d'une rémunération financière</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation<br/>
littérale n'a aucun<br/>
rapport avec le sens<br/>
technique du terme.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q12 : Identifier la précondition</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour la fonction<br/>
`<code>python<br/>
def diviser(a, b):<br/>
    return a / b<br/>
</code>`<br/>
Quelle est une <strong>précondition</strong> essentielle ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonnes pratiques : (1) noter la<br/>
précondition dans la docstring ; (2) la<br/>
vérifier en début de fonction avec<br/>
assert ; (3) la tester explicitement.</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 précondition n'est nécessaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une précondition est<br/>
bien nécessaire :<br/>
b != 0, faute de quoi<br/>
la division provoque<br/>
une exception.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>a &gt; 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La division est<br/>
parfaitement définie<br/>
pour toute valeur de<br/>
a (positive, nulle ou<br/>
négative). Cette<br/>
contrainte n'est donc<br/>
pas une précondition<br/>
nécessaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>a == b</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'égalité entre a et<br/>
b ne joue aucun rôle<br/>
dans la division. Cette<br/>
contrainte n'est pas<br/>
une précondition<br/>
pertinente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>b != 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sans cette<br/>
précondition, on lève<br/>
ZeroDivisionError. À documenter<br/>
clairement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q13 : Bonne docstring</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que devrait contenir une <strong>bonne docstring</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Docstring minimale = description courte +<br/>
paramètres + retour. Docstring complète =<br/>
ajouter exemples, exceptions levées,<br/>
remarques.</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 description du but, des paramètres (avec types), de la valeur renvoyée, des conditions d'utilisation et idéalement des exemples</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : informations utiles à<br/>
l'utilisateur sans qu'il ait besoin de<br/>
lire le code. Plusieurs styles de<br/>
docstring : Google, NumPy, Sphinx.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Uniquement le nom de l'auteur de la fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le nom de l'auteur peut<br/>
y figurer en complément,<br/>
mais il ne suffit pas :<br/>
la docstring sert avant<br/>
tout à décrire le<br/>
comportement de la<br/>
fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le code source intégral de la fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La docstring décrit le<br/>
<strong>comportement</strong> de la<br/>
fonction. Reproduire<br/>
son code source serait<br/>
redondant : ce dernier<br/>
est déjà visible juste<br/>
après.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un poème ou un texte décoratif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation est<br/>
fantaisiste. La<br/>
docstring doit être<br/>
claire, factuelle et<br/>
informative.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q14 : help()</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait help(ma_fonction) en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>help() est un raccourci interactif. Sur<br/>
les IDE modernes, on a la même chose au<br/>
survol. Toujours documenter pour aider<br/>
les futurs lecteurs (y compris soi-même).</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 lance la documentation en ligne sur Internet</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description est<br/>
imprécise. La fonction<br/>
help consulte la<br/>
documentation locale,<br/>
fournie par les<br/>
docstrings du programme,<br/>
et non une ressource en<br/>
ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle exécute la fonction donnée en argument</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction help se<br/>
contente d'afficher la<br/>
documentation associée<br/>
à son argument ; elle<br/>
n'exécute pas la<br/>
fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Affiche la signature de la fonction et sa docstring (si elle en a une)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est pourquoi<br/>
documenter via docstring est utile.<br/>
Visible directement dans<br/>
l'interpréteur ou les IDE.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Renvoie le code source</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : help montre la docstring,<br/>
inspect.getsource donne le code.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q15 : Programmation défensive</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que signifie « programmation défensive » ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>`<code>python<br/>
def racine(x):<br/>
    if x &lt; 0:<br/>
        raise ValueError("x doit être ≥ 0")<br/>
    return x ** 0.5<br/>
</code>`<br/>
Plus robuste, mais plus verbeux. À doser<br/>
selon le contexte.</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>Programmer un système de sécurité physique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation<br/>
littérale ne correspond<br/>
pas au sens technique du<br/>
terme en programmation.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>S'abstenir d'écrire du code</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La programmation<br/>
défensive consiste au<br/>
contraire à ajouter des<br/>
vérifications dans le<br/>
code, et non à se<br/>
dispenser d'en écrire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Vérifier explicitement dans la fonction que les préconditions sont respectées (lever une exception si ce n'est pas le cas), au lieu de faire confiance à l'appelant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : compromis entre<br/>
robustesse et performance. Souvent<br/>
recommandé pour les fonctions exposées à<br/>
un usage extérieur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Ajouter des virus de défense au programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description<br/>
fantaisiste n'a aucun<br/>
rapport avec le sens<br/>
technique du terme.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q16 : Type de retour</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi spécifier le <strong>type de retour</strong> d'une<br/>
fonction ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Annotations de type : int, float,<br/>
str, bool, list[int], dict[str,<br/>
int], Optional[int] (= int | None).<br/>
Très utiles dans les gros projets.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Pour clarifier ce que reçoit l'appelant et permettre les vérifications statiques (mypy)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : par exemple,<br/>
def chercher(...) -&gt; int | None<br/>
indique qu'on peut recevoir None,<br/>
ce qui doit être traité par<br/>
l'appelant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour économiser de la mémoire à l'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les annotations de type<br/>
n'ont aucun effet sur<br/>
la consommation mémoire<br/>
d'un programme Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Cela rend la fonction plus rapide à l'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les annotations de type<br/>
n'ont aucun effet sur la<br/>
performance d'exécution<br/>
en Python : elles ne<br/>
servent qu'à<br/>
documenter.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>C'est obligatoire en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'annotation du type de<br/>
retour est facultative<br/>
en Python ; le langage<br/>
accepte parfaitement les<br/>
fonctions sans<br/>
annotation.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q17 : Bonne signature</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle signature est la <strong>plus claire</strong> pour<br/>
« calculer la moyenne d'une liste de notes » ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonnes pratiques de nommage : verbes pour<br/>
les fonctions (« calculer », « afficher »,<br/>
« valider »), noms explicites pour les<br/>
paramètres (notes plutôt que l).</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>def m(l):</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Noms peu informatifs. Pas idéal.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>def moyenne(x):</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Acceptable mais sans typage. On peut<br/>
mieux faire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>def moyenne(notes: list[float]) -&gt; float:</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : nom explicite, type du<br/>
paramètre, type de retour. Le lecteur<br/>
comprend tout sans lire le code.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>def calc(*args, kwargs):</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Trop générique : on ne sait pas ce que<br/>
la fonction fait.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q18 : Cas particuliers</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour la fonction moyenne(notes), quel <strong>cas<br/>
limite</strong> poserait problème ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Toujours penser : que se passe-t-il si<br/>
l'<strong>entrée est vide / unique / extrême</strong> ?<br/>
C'est typiquement là que se cachent les<br/>
bugs.</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 liste de cent notes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une liste contenant cent<br/>
notes constitue un cas<br/>
tout à fait standard,<br/>
sans difficulté<br/>
particulière.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La liste vide, qui provoque une division par zéro</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sum([]) / len([]) =<br/>
0 / 0 → ZeroDivisionError. À<br/>
décider : précondition « liste non<br/>
vide », ou retour spécial (None,<br/>
nan).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une note décimale, par exemple 12{,}5</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les notes à virgule ne<br/>
posent pas de problème<br/>
particulier au calcul<br/>
de la moyenne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une note négative</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une note négative n'a<br/>
rien d'un cas limite sur<br/>
le plan mathématique :<br/>
elle ne pose aucun<br/>
problème de calcul.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q19 : Spec et robustesse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment une bonne spécification améliore-t-elle<br/>
la <strong>robustesse</strong> d'un programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Citation : « Si vous ne pouvez pas<br/>
spécifier ce que doit faire votre code,<br/>
vous ne savez pas ce qu'il doit faire. »<br/>
Conséquence directe : difficile à coder,<br/>
tester, déboguer.</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>En forçant à réfléchir aux entrées valides, aux cas limites et aux comportements attendus, ce qui réduit les bugs et facilite les tests</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la rigueur de la<br/>
spécification se reflète dans la<br/>
qualité du code. Et permet de <strong>tester</strong><br/>
systématiquement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En réduisant le nombre de lignes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le nombre de lignes<br/>
dépend du style et des<br/>
contraintes du langage,<br/>
pas de la spécification.<br/>
Une bonne spec apporte<br/>
de la rigueur, pas de<br/>
la concision.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En écrivant le code plus rapidement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas garanti.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En obligeant à utiliser des types forts</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas spécifiquement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q20 : Outils Python</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quels <strong>outils Python</strong> aident à respecter une<br/>
spécification ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>assert preconditon, "message" est très<br/>
utilisé pour documenter et vérifier les<br/>
contrats. À utiliser en développement,<br/>
éventuellement désactivable en production<br/>
avec python -O.</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>Annotations de type + mypy (vérification statique), assert (vérification à l'exécution), doctest (tests d'exemples), unittest/pytest (tests unitaires)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : écosystème riche.<br/>
Combinés, ils permettent de garantir<br/>
la conformité aux spécifications avec<br/>
un fort niveau de confiance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il existe plusieurs outils.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un compilateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Python n'est pas compilé en standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Seulement print</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>print aide à déboguer, pas à<br/>
spécifier.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q21 : Spécification ambiguë</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel problème a la spécification suivante ?<br/>
« La fonction chercher(liste, valeur) cherche<br/>
la valeur dans la liste. »</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Signe d'une bonne spec : un autre<br/>
développeur peut implémenter la fonction<br/>
<strong>sans poser de question</strong> et son code<br/>
passe les tests fournis.</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</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : trop ambiguë.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Plusieurs zones d'ombre : que renvoyer si trouvée (indice, booléen) ? Si plusieurs occurrences (la première, toutes) ? Si absente (None, -1, exception) ?</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une bonne spec doit<br/>
lever toutes les ambiguïtés. Sinon,<br/>
deux développeurs feront deux<br/>
implémentations différentes,<br/>
incompatibles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction n'a pas assez de paramètres</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La signature chercher(liste,<br/>
valeur) est cohérente :<br/>
deux paramètres suffisent<br/>
pour décrire la recherche.<br/>
Le défaut de cette spec<br/>
tient à l'imprécision de<br/>
l'énoncé, pas au nombre<br/>
de paramètres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nom de la fonction est trop long</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas le problème.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q22 : Cas d'erreur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment doit-on <strong>spécifier le comportement en<br/>
cas d'erreur</strong> d'une fonction ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois écoles : Python privilégie les<br/>
<strong>exceptions</strong> (raise ValueError(...)) ;<br/>
C/Go préfèrent les <strong>codes de retour</strong> ;<br/>
certains langages forcent des types<br/>
Result/Option (Rust).</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>Faire planter le programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible (exception non rattrapée),<br/>
mais à documenter.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Renvoyer aléatoirement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un comportement aléatoire<br/>
en cas d'erreur rendrait<br/>
la fonction imprévisible<br/>
et inutilisable. Une bonne<br/>
spec définit toujours un<br/>
comportement déterministe :<br/>
valeur sentinelle, exception<br/>
ou précondition explicite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Décider explicitement : valeur de retour spéciale (None, -1), exception levée, ou contrat (précondition que l'utilisateur doit garantir)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : trois stratégies<br/>
principales. À documenter. Une fois<br/>
choisie, <strong>être cohérent</strong> dans tout<br/>
le projet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Ne pas y penser</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur classique : les bugs viennent<br/>
souvent de cas non spécifiés.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q23 : Spec et évolution</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi une spécification claire facilite-t-elle<br/>
la <strong>maintenance</strong> d'un programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Principe de <strong>boîte noire</strong> : la fonction<br/>
est opaque pour l'appelant. Sa spec est<br/>
l'interface, son implémentation reste<br/>
interne. C'est un pilier de la<br/>
programmation modulaire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce qu'on peut réécrire l'implémentation sans changer le contrat, donc sans casser le code qui l'utilise</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est l'<strong>abstraction</strong>.<br/>
Tant que la spec est respectée, l'code<br/>
appelant n'est pas affecté. Permet<br/>
d'optimiser, refactoriser, corriger<br/>
sans cascade de changements.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'une spécification est jolie à lire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'esthétique d'un<br/>
document est un<br/>
critère subjectif. Ce<br/>
n'est pas l'argument<br/>
qui justifie l'intérêt<br/>
pratique d'une<br/>
spécification.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que le code obtenu est plus court</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La longueur du code n'a<br/>
pas de lien direct avec<br/>
la qualité de la<br/>
spécification.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'elle élimine totalement les bugs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
trop optimiste. La<br/>
spécification ne supprime<br/>
pas tous les bugs, mais<br/>
elle <strong>structure</strong> le<br/>
travail et facilite<br/>
leur détection.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q24 : Développement piloté par les tests</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>En quoi consiste l'approche dite de<br/>
<strong>développement piloté par les tests</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les bénéfices de cette démarche sont un<br/>
code minimal et bien testé, ainsi qu'une<br/>
conception guidée par le besoin réel.<br/>
Elle requiert toutefois un apprentissage et<br/>
une discipline soutenue. Largement<br/>
reconnue dans l'industrie, elle n'est pas<br/>
pour autant universelle.</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>Tester manuellement le programme une fois qu'il est entièrement écrit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description correspond à un test<br/>
manuel classique, et non à l'approche<br/>
pilotée par les tests, qui inverse<br/>
précisément la chronologie habituelle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Faire générer automatiquement les tests par un programme d'intelligence artificielle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette approche est conduite par un<br/>
humain, et non par un système<br/>
automatique. Le programmeur écrit<br/>
lui-même les tests à partir de la<br/>
spécification.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Écrire d'abord les tests à partir de la spécification, puis le code juste suffisant pour les faire passer, et enfin retravailler la structure du code à tests inchangés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette démarche en trois étapes (test,<br/>
code, refactorisation) oblige à bien<br/>
spécifier le comportement attendu avant<br/>
de coder. Elle s'oppose à l'approche<br/>
intuitive, qui consiste à coder<br/>
d'abord et tester ensuite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Exécuter les tests sur un seul ordinateur, plutôt que sur plusieurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le matériel utilisé pour exécuter les<br/>
tests n'a aucun rapport avec cette<br/>
démarche.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes sur la<br/>
spécification, laquelle est <strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Mnémonique : <strong>pré</strong> comme « avant »<br/>
(responsabilité de l'appelant), <strong>post</strong><br/>
comme « après » (responsabilité de la<br/>
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>La précondition est une condition que la fonction doit garantir au moment de l'appel</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Faux (donc bonne réponse) : la<br/>
précondition est une condition que<br/>
l'<strong>appelant</strong> doit garantir avant<br/>
l'appel. La fonction garantit la<br/>
<strong>postcondition</strong> en sortie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La docstring permet d'accéder à la documentation via help()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte : la docstring<br/>
placée en tête d'une<br/>
fonction est récupérée<br/>
par help() et par<br/>
l'attribut __doc__.<br/>
Ce n'est donc pas la<br/>
mauvaise affirmation<br/>
recherchée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La signature comprend nom, paramètres et type de retour</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : définition standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une bonne spécification facilite la maintenance et la robustesse</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
juste : une spécification<br/>
claire réduit les<br/>
ambiguïtés, simplifie la<br/>
maintenance et limite<br/>
les bogues. Ce n'est<br/>
donc pas la mauvaise<br/>
affirmation recherchée.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q26 : Effet de bord vs valeur de retour</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une fonction de tri peut être spécifiée de<br/>
deux façons différentes. Comment la<br/>
spécification doit-elle distinguer<br/>
explicitement ces deux choix ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Convention Python : un nom impératif comme<br/>
sort désigne souvent une modification en<br/>
place ; un nom adjectivé comme sorted ou<br/>
participe reversed désigne une fonction<br/>
pure qui renvoie un nouvel objet. Toute<br/>
spécification doit préciser explicitement<br/>
ce point.</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 spécification indique clairement si la<br/>
fonction modifie la liste reçue (effet<br/>
de bord, exemple : liste.sort() qui<br/>
renvoie None), ou si elle construit<br/>
une nouvelle liste triée sans toucher à<br/>
la liste d'entrée (exemple : sorted(liste))</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est exactement la<br/>
distinction faite par Python entre<br/>
liste.sort() (en place, retourne None)<br/>
et sorted(liste) (renvoie une nouvelle<br/>
liste). La spécification doit toujours<br/>
préciser cela, sinon le comportement est<br/>
ambigu et bogué en pratique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La distinction se fait au moment de l'exécution, en fonction de la mémoire disponible</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait imprévisible et<br/>
rendrait le comportement non<br/>
reproductible. Une bonne spécification<br/>
fixe le comportement à l'avance, pas en<br/>
fonction de l'environnement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La distinction est purement esthétique et n'a pas d'effet réel</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la différence est<br/>
fondamentale. Modifier en place ou<br/>
renvoyer une copie n'a pas le même coût<br/>
mémoire, et expose à des erreurs<br/>
d'aliasage si plusieurs variables<br/>
référencent la même liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La distinction n'a pas d'importance, l'utilisateur s'adapte au comportement obtenu</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est exactement l'origine de<br/>
nombreux bugs en pratique. Si la<br/>
spécification ne dit pas si la liste est<br/>
modifiée ou si une nouvelle liste est<br/>
renvoyée, l'utilisateur peut écrire<br/>
liste = trier(liste) alors que<br/>
trier modifie déjà liste (et renvoie<br/>
None), ce qui détruit la liste.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Spécification — Q27 : Précondition, postcondition, invariant</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans une fonction qui parcourt une liste avec<br/>
une boucle, comment se distinguent<br/>
<strong>précondition</strong>, <strong>postcondition</strong> et<br/>
<strong>invariant de boucle</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma général d'une preuve : précondition à<br/>
l'entrée → invariant initialement vrai →<br/>
invariant conservé à chaque itération → en<br/>
sortie de boucle, l'invariant combiné à la<br/>
condition d'arrêt entraîne la postcondition.<br/>
Les trois notions s'articulent et ne se<br/>
remplacent pas.</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>L'invariant de boucle remplace la précondition et la postcondition</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les trois notions coexistent.<br/>
L'invariant de boucle est précisément<br/>
l'outil qui fait le pont entre<br/>
précondition et postcondition à<br/>
travers la boucle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La précondition porte sur les paramètres<br/>
au moment de l'appel ; la postcondition<br/>
porte sur la valeur renvoyée ou l'état<br/>
final ; l'invariant de boucle porte sur<br/>
une propriété conservée à chaque<br/>
itération de la boucle interne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : trois échelles<br/>
différentes. La précondition est le<br/>
contrat à l'entrée de la fonction, la<br/>
postcondition le contrat à la sortie, et<br/>
l'invariant de boucle un outil interne<br/>
qui sert à prouver la postcondition à<br/>
partir de la précondition.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La précondition est une postcondition imprécise</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ces deux notions ne sont pas<br/>
comparables, elles ont un statut<br/>
symétrique. La précondition est garantie<br/>
par l'appelant, la postcondition par la<br/>
fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Ce sont trois noms différents pour la même notion</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ces trois notions ne portent<br/>
pas sur la même chose. Elles concernent<br/>
respectivement l'entrée de la fonction,<br/>
sa sortie, et la boucle interne.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
