<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Première/Fonctions</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Définition de fonctions en Python, paramètres et valeur<br/>
de retour, portée locale et globale, fonctions natives,<br/>
fonctions sans retour, paramètres par défaut, documentation<br/>
(docstrings).</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q01 : Définir une fonction</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment définit-on une fonction <code>carre</code> qui<br/>
prend <code>x</code> en paramètre et renvoie <code>x * x</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Syntaxe canonique : <code>def nom(params): corps</code>.<br/>
Le mot-clé <code>return</code> produit la valeur que la<br/>
fonction renvoie à l'appelant.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def carre(x) -&gt; x * x</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>-&gt;</code> indique le type de retour<br/>
(annotation), pas l'expression. Il manque<br/>
le corps de la fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>carre = x * x</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on définirait une variable, pas<br/>
une fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>function carre(x) {
    return x * x
}</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : syntaxe JavaScript, pas Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def carre(x):
    return x * x</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : mot-clé <code>def</code>, parenthèses,<br/>
deux-points, indentation, <code>return</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q02 : Appel de fonction</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Après <code>def carre(x): return x * x</code>, comment<br/>
appelle-t-on cette fonction sur la valeur 5 ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sans parenthèses, <code>carre</code> désigne la fonction<br/>
elle-même (un objet). Avec parenthèses,<br/>
<code>carre(...)</code> invoque la fonction.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>carre(5)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : parenthèses obligatoires,<br/>
même pour un seul paramètre. Renvoie 25.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>carre 5</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il faut des parenthèses pour<br/>
appeler une fonction en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>call carre(5)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de mot-clé <code>call</code> en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>carre[5]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les crochets sont pour<br/>
l'indexation, pas l'appel de fonction.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q03 : Mot-clé return</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert l'instruction <code>return</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Différence essentielle entre <code>print</code> et<br/>
<code>return</code> : <code>print</code> affiche un message à<br/>
l'utilisateur ; <code>return</code> produit une valeur<br/>
utilisable dans le code (par exemple,<br/>
<code>y = carre(3)</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>À redémarrer la fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le mot-clé <code>return</code> met<br/>
fin à l'exécution de la<br/>
fonction et fournit une<br/>
valeur à l'appelant. Il<br/>
ne relance jamais la<br/>
fonction depuis le début.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>À renvoyer une valeur à l'appelant et terminer la fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la fonction s'arrête au<br/>
<code>return</code>, et la valeur passée est<br/>
disponible pour l'appelant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À afficher le résultat sur la console</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est <code>print</code>. <code>return</code> produit<br/>
une valeur de retour, sans affichage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À déclarer une variable globale</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est <code>global</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q04 : Paramètres</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction a <strong>deux</strong> paramètres ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Vocabulaire : on parle de <strong>paramètres</strong> d'une<br/>
fonction, à la fois pour leur nom dans la<br/>
définition (<code>def f(x, y):</code>) et pour les valeurs<br/>
qu'on lui passe à l'appel (<code>f(3, 5)</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[<pre><code>def f(x):
    return x</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un seul paramètre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def f():
    return 0</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : zéro paramètre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def f(x; y):
    return x + y</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le séparateur est la virgule, pas<br/>
le point-virgule.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def f(x, y):
    return x + y</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : deux paramètres <code>x</code> et <code>y</code><br/>
séparés par une virgule.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q05 : Fonction sans return</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie une fonction qui ne contient <strong>aucun<br/>
<code>return</code></strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Souvent, on n'utilise pas la valeur de retour<br/>
de telles fonctions (on ne fait pas<br/>
<code>x = print(...)</code>). Mais elle existe (<code>None</code>).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>None</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : Python renvoie<br/>
implicitement <code>None</code> (la valeur « rien »).<br/>
C'est le cas typique des fonctions qui se<br/>
contentent d'afficher ou de modifier<br/>
quelque chose, sans renvoyer de valeur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas d'erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une chaîne vide <code>""</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la valeur par défaut est <code>None</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>0</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas la valeur par défaut.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q06 : Fonctions natives</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les suivants, lequel n'est <strong>pas</strong> une<br/>
fonction native de Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Fonctions natives utiles : <code>print</code>, <code>input</code>,<br/>
<code>len</code>, <code>range</code>, <code>type</code>, <code>int</code>, <code>float</code>, <code>str</code>,<br/>
<code>bool</code>, <code>min</code>, <code>max</code>, <code>sum</code>, <code>abs</code>, <code>round</code>,<br/>
<code>sorted</code>, etc.</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>carre(...)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>carre</code> n'est pas natif,<br/>
c'est une fonction qu'il faut définir<br/>
soi-même.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>type(...)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est bien une fonction native (renvoie le<br/>
type).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>len(...)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est bien une fonction native (longueur).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>max(...)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est bien une fonction native (maximum).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q07 : Plusieurs appels</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>def double(x):
    return x * 2

a = double(3)
b = double(double(5))</code></pre><br/>
Que valent <code>a</code> et <code>b</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Composition de fonctions : <code>f(g(x))</code> évalue<br/>
d'abord <code>g(x)</code> puis applique <code>f</code>. Lecture de<br/>
l'intérieur vers l'extérieur.</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>a = 6, b = 20</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : a = double(3) = 6 ;<br/>
b = double(double(5)) = double(10) = 20.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>a = 6, b = 25</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 25 = 5², mais on multiplie par 2,<br/>
pas un carré.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>a = 3, b = 5</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on n'a pas appelé la fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>a = 6, b = 10</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur sur b : <code>double(double(5))</code> =<br/>
<code>double(10)</code> = 20.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q08 : Docstring</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait la première ligne en triples<br/>
guillemets dans une fonction ?<br/>
<pre><code>def carre(x):
    """Renvoie le carré de x."""
    return x * x</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : toujours documenter ses<br/>
fonctions. PEP 257 décrit les conventions<br/>
(description courte sur la première ligne,<br/>
puis détails).</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>C'est une docstring : la documentation de la fonction, accessible par <code>help(carre)</code> ou <code>carre.__doc__</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : standard Python pour<br/>
documenter ses fonctions. Très utile pour<br/>
la maintenance et l'aide automatique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>C'est obligatoire pour que la fonction marche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : facultatif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>C'est un commentaire ignoré par Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est plus qu'un commentaire, c'est<br/>
une <strong>docstring</strong> accessible<br/>
dynamiquement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>C'est un test unitaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un test serait un <code>assert</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q09 : Variable locale</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le code suivant lève-t-il une erreur ?<br/>
<pre><code>def f():
    x = 5

f()
print(x)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Notion clé : la <strong>portée</strong> (ou scope). Une<br/>
variable créée dans une fonction n'existe<br/>
qu'à l'intérieur de cette 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>Non, il affiche <code>0</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune valeur par défaut.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, mais il affiche <code>None</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de retour silencieux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, il affiche 5</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>x</code> est <strong>locale</strong> à <code>f</code>, pas<br/>
accessible à l'extérieur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Oui : <code>NameError</code> car <code>x</code> n'est pas définie hors de <code>f</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la <strong>portée</strong> des variables<br/>
locales est limitée à la fonction.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q10 : Trace simple</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait ce code ?<br/>
<pre><code>def saluer(nom):
    print("Bonjour", nom)

saluer("Alice")</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Distinguer <code>print</code> (afficher quelque chose à<br/>
l'écran) de <code>return</code> (renvoyer une valeur à<br/>
l'appelant). Ici, la fonction se contente<br/>
d'afficher.</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ève une erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : code valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Affiche <code>Bonjour Alice</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la fonction reçoit <code>nom =<br/>
"Alice"</code>, puis <code>print</code> affiche les deux<br/>
paramètres séparés par un espace.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Renvoie la chaîne <code>"Bonjour Alice"</code> mais sans afficher</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>print</code> affiche, et la fonction n'a<br/>
pas de <code>return</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>N'affiche rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>print</code> produit un affichage.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q11 : Paramètre par défaut</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que donne ce code ?<br/>
<pre><code>def saluer(nom="ami"):
    return "Bonjour " + nom

print(saluer())
print(saluer("Alice"))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les paramètres par défaut rendent les<br/>
fonctions plus flexibles. Convention : les<br/>
paramètres avec valeur par défaut viennent<br/>
<strong>après</strong> les paramètres sans.</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[<pre><code>Erreur
Bonjour Alice</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : avec un paramètre par défaut,<br/>
l'appel sans paramètre est valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>Bonjour ami
Bonjour Alice</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>nom="ami"</code> est la valeur<br/>
par défaut. Si on n'en passe pas,<br/>
le paramètre vaut <code>"ami"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>Bonjour ami
Bonjour ami</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le second appel passe <code>"Alice"</code>,<br/>
qui remplace la valeur par défaut.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>Bonjour
Bonjour Alice</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la valeur par défaut est <code>"ami"</code>,<br/>
pas une chaîne vide.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q12 : Paramètres nommés</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence entre<br/>
<code>puissance(2, 10)</code> et<br/>
<code>puissance(base=2, exposant=10)</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les paramètres nommés améliorent la lisibilité,<br/>
surtout quand un appel a beaucoup de<br/>
paramètres (par exemple <code>plt.plot(x, y,<br/>
color="red", linestyle="--")</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>La seconde forme ne marche que pour les fonctions natives</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les paramètres nommés marchent<br/>
pour toutes les fonctions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La première forme est obsolète</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : très utilisée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La seconde forme est plus rapide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune différence de performance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Aucune, les deux sont équivalents si la fonction est <code>def puissance(base, exposant):</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on peut passer des<br/>
paramètres <strong>positionnellement</strong> (par<br/>
ordre) ou <strong>nommés</strong> (par mot-clé).<br/>
L'ordre n'importe pas pour les nommés.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q13 : Variable globale</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est le résultat ?<br/>
<pre><code>x = 10

def f():
    return x + 1

print(f())</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle d'or : préférer <strong>passer en paramètre</strong><br/>
plutôt qu'utiliser des variables globales.<br/>
Code plus testable et plus prévisible.</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>Erreur (x non défini)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>f</code> peut <strong>lire</strong> les variables du<br/>
scope englobant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>11</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>x</code> est une variable<br/>
<strong>globale</strong>. La fonction peut la lire,<br/>
mais pas la modifier (sans <code>global</code>).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune sortie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>print(f())</code> affiche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>10</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ajoute 1.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q14 : Modifier une globale</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour modifier une variable globale dans une<br/>
fonction, quel mot-clé utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : limiter l'usage de <code>global</code>.<br/>
Préférer le passage par paramètre + retour<br/>
explicite, beaucoup plus clair et testable.</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>nonlocal</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas tout à fait : <code>nonlocal</code> est pour les<br/>
fonctions imbriquées (variable du scope<br/>
intermédiaire), pas pour les globales.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>global</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>global x</code> au début de la<br/>
fonction permet d'<strong>écrire</strong> dans <code>x</code><br/>
global. Sans cela, <code>x = ...</code> créerait une<br/>
locale qui masque la globale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>outer</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de mot-clé <code>outer</code> en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>var</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas en Python (JavaScript, oui).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q15 : Retour multiple</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie cette fonction ?<br/>
<pre><code>def min_max(liste):
    return min(liste), max(liste)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Idiome courant : renvoyer plusieurs valeurs<br/>
sans définir de classe ad hoc. Pratique pour<br/>
les petites fonctions « utilitaires ».</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un tuple <code>(min, max)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : Python utilise les tuples<br/>
pour les retours multiples. À la<br/>
réception : <code>mn, mx = min_max(liste)</code><br/>
(déballage).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une liste de deux éléments</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : virgule sans crochets = tuple.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un dictionnaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un dict s'écrit avec <code>{}</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Erreur : on ne peut pas avoir deux retours</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python le permet via le tuple.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q16 : Fonction comme valeur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>def carre(x): return x * x

f = carre
print(f(3))</code></pre><br/>
Que se passe-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette propriété rend possibles : les<br/>
callbacks, les décorateurs, la programmation<br/>
fonctionnelle (<code>map</code>, <code>filter</code>, etc.).</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>Erreur : on ne peut pas affecter une fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python permet d'affecter des<br/>
fonctions à des variables.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Affiche 3</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction est bien appelée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Affiche 9</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : en Python, les fonctions<br/>
sont des <strong>objets de première classe</strong>.<br/>
<code>f</code> pointe vers la même fonction que<br/>
<code>carre</code>. <code>f(3)</code> appelle la fonction sur 3.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Affiche <code>&lt;function carre&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>f(3)</code> appelle, donc renvoie 9.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q17 : Portée locale</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>x = 10

def f():
    x = 20
    print(x)

f()
print(x)</code></pre><br/>
Qu'affiche ce code ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Notion de <strong>portée</strong> (scope) : une variable<br/>
définie dans une fonction n'existe qu'à<br/>
l'intérieur. C'est précieux pour<br/>
l'isolation, mais source de confusion<br/>
classique.</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[<pre><code>10
10</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction affiche bien 20 (sa<br/>
locale).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : code valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>20
20</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le <code>x</code> interne à <code>f</code> est une<br/>
variable <strong>locale</strong> distincte de la<br/>
variable globale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>20
10</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'affectation <code>x = 20</code><br/>
dans la fonction crée une variable<br/>
<strong>locale</strong> ; elle masque la globale le<br/>
temps de l'appel mais ne la modifie pas.<br/>
Après l'appel, la globale vaut toujours<br/>
10.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q18 : Renvoyer ou afficher ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence entre une fonction qui<br/>
<strong>renvoie</strong> une valeur et une fonction qui<br/>
<strong>affiche</strong> une valeur ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bug classique : écrire <code>def carre(x): print(x<em>x)</code><br/>
au lieu de <code>def carre(x): return x</em>x</code>. Avec la<br/>
première version, on ne peut pas faire<br/>
<code>y = carre(3) * 2</code> : <code>y</code> vaut <code>None</code>. La<br/>
seconde version permet bien <code>y = 18</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>print</code> est plus rapide que <code>return</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la performance n'est pas le sujet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une fonction qui renvoie produit une valeur réutilisable par l'appelant via <code>return</code> ; une fonction qui affiche écrit à l'écran avec <code>print</code> mais ne renvoie rien d'utilisable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une valeur renvoyée peut être<br/>
stockée dans une variable, transmise à une<br/>
autre fonction, comparée. <code>print</code> se contente<br/>
d'écrire un texte à l'écran. Si on a besoin<br/>
de la valeur, il faut un <code>return</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>return</code> n'existe pas en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>return</code> est l'instruction standard<br/>
pour renvoyer une valeur depuis une<br/>
fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune différence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la confusion entre les deux est l'un<br/>
des bugs les plus classiques. <code>print</code> ne<br/>
rend rien d'exploitable.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q19 : print vs return</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi ce code n'affiche-t-il <strong>rien</strong> sur la<br/>
console ?<br/>
<pre><code>def carre(x):
    return x * x

carre(5)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Confusion classique des débutants : penser<br/>
que <code>return</code> affiche. <code>print</code> et <code>return</code><br/>
sont <strong>deux mécanismes différents</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>Parce que la fonction n'est pas appelée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>carre(5)</code> est bien un appel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que <code>5</code> n'est pas un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 5 est un entier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que <code>return</code> ne fait pas d'affichage : la valeur 25 est calculée puis ignorée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour voir un affichage,<br/>
écrire <code>print(carre(5))</code> ou modifier la<br/>
fonction pour utiliser <code>print</code> (mais<br/>
alors plus de retour).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que la fonction est buggée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction est correcte, elle<br/>
renvoie 25.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q20 : Décomposer</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi est-il recommandé de <strong>décomposer</strong> un<br/>
programme en fonctions ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Maxime : « une fonction = une responsabilité ».<br/>
Si une fonction fait plusieurs choses, la<br/>
découper en plusieurs petites.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour économiser de la mémoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas un avantage notable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que le compilateur le demande</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python est interprété, et il ne<br/>
l'exige pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Pour la lisibilité, la réutilisation et la testabilité : chaque fonction fait une chose, on peut la tester séparément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est l'un des principes<br/>
fondamentaux du génie logiciel<br/>
(« divide and conquer »). Une fonction<br/>
courte et bien nommée vaut mieux qu'un<br/>
gros bloc de code.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que c'est plus court d'écrire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas forcément plus court : c'est même<br/>
parfois plus long.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q21 : Piège de portée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>x = 10

def f():
    x = 20
    return x

print(f())
print(x)</code></pre><br/>
Quel est le résultat ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cas typique d'<strong>ombrage</strong> (shadowing). Source<br/>
de confusion fréquente. Pour éviter,<br/>
privilégier le passage en paramètre.</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[<pre><code>10
10</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>f()</code> renvoie sa propre <code>x</code> locale<br/>
(= 20).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>20
20</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans <code>global x</code>, le <code>x = 20</code> dans<br/>
<code>f</code> crée une variable <strong>locale</strong>, qui ne<br/>
modifie pas la globale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>20
10</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>x</code> à l'intérieur de <code>f</code><br/>
est local et masque la globale. À l'extérieur,<br/>
la globale <code>x</code> reste à 10.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune erreur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q22 : Retours multiples</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>def signe(x):
    if x &gt; 0:
        return 1
    if x &lt; 0:
        return -1
    return 0</code></pre><br/>
Pourquoi ce code marche-t-il sans <code>elif</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Idiome « early return » : sortir tôt des cas<br/>
particuliers, simplifier la logique.</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 que <code>return</code> interrompt la fonction : si <code>x &gt; 0</code>, le premier <code>return 1</code> empêche l'exécution des suivants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>return</code> est plus fort<br/>
qu'un break, il quitte la fonction<br/>
entièrement. Pas besoin d'<code>elif</code>. Code<br/>
plus plat et lisible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que Python comprend automatiquement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Python n'a aucune capacité<br/>
d'inférence sur l'intention<br/>
du code. Si chaque branche<br/>
fonctionne correctement<br/>
ici, c'est uniquement parce<br/>
que <code>return</code> quitte la<br/>
fonction immédiatement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les <code>if</code> sont équivalents à des <code>elif</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ils ne sont pas mutuellement<br/>
exclusifs sans <code>return</code> (chaque <code>if</code><br/>
serait testé).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'il n'y a qu'un seul <code>else</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il n'y a aucun <code>else</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q23 : Paramètre mutable</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>def ajouter(liste, x):
    liste.append(x)

ma_liste = [1, 2]
ajouter(ma_liste, 3)
print(ma_liste)</code></pre><br/>
Que produit ce code ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>En Python, lorsqu'on passe une variable à une<br/>
fonction, on transmet une référence vers la<br/>
même valeur. Pour les types <strong>mutables</strong><br/>
(listes, dicts), les modifications dans la<br/>
fonction affectent donc l'original. Pour les<br/>
<strong>immuables</strong> (int, str, tuple), aucun effet<br/>
de bord n'est possible.</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>[3]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on <strong>ajoute</strong>, on ne remplace pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>[1, 2, 3]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les listes sont passées<br/>
par <strong>référence</strong>. La fonction modifie<br/>
donc directement la liste de l'appelant,<br/>
ce qui peut surprendre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : code valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1, 2]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la liste <strong>est</strong> modifiée par la<br/>
fonction.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q24 : Piège du défaut mutable</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>def ajouter(x, liste=[]):
    liste.append(x)
    return liste

print(ajouter(1))
print(ajouter(2))</code></pre><br/>
Quel résultat (surprenant) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : ne jamais utiliser un<br/>
mutable comme valeur par défaut. Préférer<br/>
<code>None</code> et 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>Erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : code valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>[1]
[1, 2]</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est l'un des <strong>pièges<br/>
célèbres</strong> de Python. Le défaut <code>[]</code> est<br/>
partagé entre tous les appels. Solution :<br/>
utiliser <code>liste=None</code> puis<br/>
<code>if liste is None: liste = []</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>[1, 2]
[1, 2]</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seulement le premier appel reçoit<br/>
juste <code>[1]</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>[1]
[2]</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On pourrait s'y attendre, mais c'est faux.<br/>
Python évalue la valeur par défaut <strong>une<br/>
seule fois</strong>, à la définition de la<br/>
fonction.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes sur les<br/>
fonctions Python, laquelle est <strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Mnémonique : portée = « ce qui est défini<br/>
dans une fonction reste dans la fonction »<br/>
(sauf retour 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>Les fonctions Python peuvent être passées comme paramètres d'autres fonctions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : objets de première classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On peut renvoyer plusieurs valeurs avec un tuple (ex. <code>return a, b</code>).</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : idiome Python pour les retours<br/>
multiples.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction sans <code>return</code> renvoie implicitement <code>None</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : convention Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les variables locales d'une fonction sont accessibles depuis l'extérieur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Faux (donc bonne réponse) : les variables<br/>
locales sont confinées à la fonction.<br/>
C'est le principe de la <strong>portée</strong> (scope).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q26 : Composition d'appels de fonctions</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère le code suivant :</p>
<pre><code>def carre(x):
    return x * x

def incremente(x):
    return x + 1

a = carre(incremente(3))</code></pre>
<p>Quelle est la valeur de <code>a</code> après l'exécution ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour évaluer une expression <code>f(g(x))</code>, Python<br/>
calcule d'abord <code>g(x)</code>, puis applique <code>f</code> à ce<br/>
résultat. Cette composition est l'un des moyens<br/>
les plus simples de combiner des fonctions<br/>
réutilisables, sans variables intermédiaires.</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>$10$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on a additionné le résultat de<br/>
<code>incremente(3) = 4</code> à un autre nombre. Mais<br/>
<code>carre</code> calcule un carré, pas une somme. La bonne<br/>
opération est $4 \times 4$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$7$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : confusion sur l'ordre des opérations.<br/>
Python évalue toujours les fonctions de<br/>
l'intérieur vers l'extérieur, donc<br/>
<code>incremente(3)</code> est évalué d'abord, puis le<br/>
résultat est passé à <code>carre</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$9$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on a appliqué seulement <code>carre(3)</code>, sans<br/>
tenir compte de <code>incremente</code>. Or <code>incremente</code><br/>
est appliqué en premier, à $3$, ce qui donne $4$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$16$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : Python évalue d'abord l'argument<br/>
le plus interne, soit <code>incremente(3) = 4</code>, puis<br/>
applique <code>carre</code> à ce résultat : $4 \times 4 =<br/>
16$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q27 : Annotations de type</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On lit la signature suivante :</p>
<pre><code>def aire(longueur: float, largeur: float) -&gt; float:</code></pre>
<p>Que signifie la flèche <code>-&gt;</code> et l'annotation <code>float</code><br/>
qui la suit ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'annotation <code>param: type</code> documente le type<br/>
attendu d'un paramètre, l'annotation <code>-&gt; type</code><br/>
documente celui de la valeur de retour. Ces<br/>
indications n'ont aucun effet à l'exécution mais<br/>
sont précieuses pour la lecture du code et pour les<br/>
analyseurs statiques.</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>C'est une annotation indiquant que la fonction est censée renvoyer un flottant ; cela documente l'intention sans imposer de vérification à l'exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la flèche introduit<br/>
l'annotation du type renvoyé. Comme les<br/>
annotations de paramètres, elle est optionnelle<br/>
et purement informative ; les outils comme<br/>
<code>mypy</code> peuvent ensuite vérifier la cohérence<br/>
des types statiquement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La syntaxe est invalide en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les annotations de type sont<br/>
parfaitement valides depuis Python $3{.}5$. Elles<br/>
sont aujourd'hui largement utilisées pour<br/>
améliorer la lisibilité et la sûreté du code.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La flèche transforme le résultat en flottant avant de le renvoyer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les annotations n'effectuent <strong>aucune<br/>
conversion</strong>. La fonction renvoie strictement la<br/>
valeur retournée par son <code>return</code>, sans<br/>
modification.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction renvoie obligatoirement un nombre flottant, sinon Python lève une exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python ne vérifie pas les annotations à<br/>
l'exécution. La fonction peut tout à fait<br/>
renvoyer un autre type sans erreur. Les<br/>
annotations servent uniquement à la<br/>
documentation et aux outils d'analyse statique<br/>
(<code>mypy</code>, IDE).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q28 : Effet de bord sur une liste paramètre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On exécute le code suivant :</p>
<pre><code>def ajouter_zero(t):
    t.append(0)

ma_liste = [1, 2, 3]
ajouter_zero(ma_liste)
print(ma_liste)</code></pre>
<p>Que va afficher <code>print</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Quand un paramètre est un objet <strong>mutable</strong> (liste,<br/>
dictionnaire, ensemble), une fonction peut le<br/>
modifier en place sans avoir à le renvoyer. C'est un<br/>
effet de bord, à utiliser avec parcimonie : il rend<br/>
le comportement moins prévisible et complique la<br/>
lecture du code.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>[1, 2, 3, 0]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>t</code> et <code>ma_liste</code> désignent le<br/>
<strong>même objet liste</strong> en mémoire. La méthode<br/>
<code>append</code> modifie cet objet ; après l'appel,<br/>
<code>ma_liste</code> reflète donc le changement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le code lève une erreur car <code>t</code> n'est pas connu en dehors de la fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>t</code> n'est utilisé qu'à l'intérieur de<br/>
la fonction, mais la liste qu'il référence<br/>
continue d'exister à l'extérieur. Python passe<br/>
les paramètres par <strong>référence d'objet</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1, 2, 3]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction modifie effectivement la<br/>
liste passée en paramètre. La méthode <code>append</code><br/>
agit sur l'objet partagé entre l'appelant et la<br/>
fonction, donc la modification est visible à<br/>
l'extérieur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[0, 1, 2, 3]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>append</code> ajoute en fin de liste, pas<br/>
en début. Pour insérer à l'index $0$, il<br/>
faudrait écrire <code>t.insert(0, 0)</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q29 : Fonction prédicat</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On souhaite écrire une fonction <code>est_pair(n)</code> qui<br/>
renvoie <code>True</code> si l'entier <code>n</code> est pair, <code>False</code><br/>
sinon. Quelle écriture est la plus claire et la plus<br/>
idiomatique ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une fonction qui renvoie <code>True</code> ou <code>False</code> est<br/>
appelée <strong>prédicat</strong>. Convention : nommer ces<br/>
fonctions avec un préfixe <code>est_</code>, <code>a_</code>, <code>verifie_</code><br/>
ou similaire, pour signaler immédiatement qu'elles<br/>
renvoient un booléen.</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[<pre><code>def est_pair(n):
    if n % 2 == 0:
        return True
    else:
        return False</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Code correct mais redondant : on construit un<br/>
booléen à partir d'un test booléen. Préférer<br/>
<code>return n % 2 == 0</code>, qui exprime directement<br/>
l'idée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def est_pair(n):
    return n % 2 == 0</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on renvoie directement la<br/>
valeur du test booléen, sans passer par un<br/>
<code>if</code>. C'est plus court, plus lisible, et c'est<br/>
l'idiome Python pour ce qu'on appelle un<br/>
<strong>prédicat</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def est_pair(n):
    return n / 2</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la division <code>n / 2</code> renvoie un<br/>
flottant (par exemple $1{,}5$ ou $2{,}0$),<br/>
pas un booléen. Pour tester la parité, il faut<br/>
utiliser le <strong>reste</strong> (modulo <code>%</code>), pas le<br/>
quotient.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def est_pair(n):
    print(n % 2 == 0)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction ne renvoie rien (elle<br/>
renvoie <code>None</code>). Elle ne peut donc pas être<br/>
utilisée dans un test comme<br/>
<code>if est_pair(x):</code>. Préférer <code>return</code> plutôt<br/>
que <code>print</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
