<?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 carre qui<br/>
prend x en paramètre et renvoie x * x ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Syntaxe canonique : def nom(params): corps.<br/>
Le mot-clé return 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[<p>`<code>python<br/>
def carre(x) -&gt; x * x<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : -&gt; 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[<p>`<code>python<br/>
carre = x * x<br/>
</code>`</p>]]></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[<p>`<code>python<br/>
function carre(x) {<br/>
    return x * x<br/>
}<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : syntaxe JavaScript, pas Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def carre(x):<br/>
    return x * x<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : mot-clé def, parenthèses,<br/>
deux-points, indentation, return.</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 def carre(x): return x * x, comment<br/>
appelle-t-on cette fonction sur la valeur 5 ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sans parenthèses, carre désigne la fonction<br/>
elle-même (un objet). Avec parenthèses,<br/>
carre(...) 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>carre(5)</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>carre 5</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>call carre(5)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de mot-clé call en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>carre[5]</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 return ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Différence essentielle entre print et<br/>
return : print affiche un message à<br/>
l'utilisateur ; return produit une valeur<br/>
utilisable dans le code (par exemple,<br/>
y = carre(3)).</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é return 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/>
return, 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 print. return 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 global.</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 (def f(x, y):) et pour les valeurs<br/>
qu'on lui passe à l'appel (f(3, 5)).</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/>
def f(x):<br/>
    return x<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un seul paramètre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def f():<br/>
    return 0<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : zéro paramètre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def f(x; y):<br/>
    return x + y<br/>
</code>`</p>]]></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[<p>`<code>python<br/>
def f(x, y):<br/>
    return x + y<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : deux paramètres x et y<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/>
return</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/>
x = print(...)). Mais elle existe (None).</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>None</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : Python renvoie<br/>
implicitement None (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 ""</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la valeur par défaut est None.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>0</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 : print, input,<br/>
len, range, type, int, float, str,<br/>
bool, min, max, sum, abs, round,<br/>
sorted, 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>carre(...)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : carre 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>type(...)</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>len(...)</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>max(...)</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>``python<br/>
def double(x):<br/>
    return x * 2</p>
<p>a = double(3)<br/>
b = double(double(5))<br/>
<code><br/>
Que valent a et b</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Composition de fonctions : f(g(x)) évalue<br/>
d'abord g(x) puis applique f. 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 : double(double(5)) =<br/>
double(10) = 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/>
`<code>python<br/>
def carre(x):<br/>
    """Renvoie le carré de x."""<br/>
    return x * x<br/>
</code>`</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 help(carre) ou carre.__doc__</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 assert.</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/>
``python<br/>
def f():<br/>
    x = 5</p>
<p>f()<br/>
print(x)<br/>
``</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 0</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 None</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 : x est <strong>locale</strong> à f, pas<br/>
accessible à l'extérieur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Oui : NameError car x n'est pas définie hors de f</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/>
``python<br/>
def saluer(nom):<br/>
    print("Bonjour", nom)</p>
<p>saluer("Alice")<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Distinguer print (afficher quelque chose à<br/>
l'écran) de return (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 Bonjour Alice</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la fonction reçoit nom =<br/>
"Alice", puis print 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 "Bonjour Alice" mais sans afficher</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : print affiche, et la fonction n'a<br/>
pas de return.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>N'affiche rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : print 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/>
``python<br/>
def saluer(nom="ami"):<br/>
    return "Bonjour " + nom</p>
<p>print(saluer())<br/>
print(saluer("Alice"))<br/>
``</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[<p>`<code><br/>
Erreur<br/>
Bonjour Alice<br/>
</code>`</p>]]></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[<p>`<code><br/>
Bonjour ami<br/>
Bonjour Alice<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : nom="ami" est la valeur<br/>
par défaut. Si on n'en passe pas,<br/>
le paramètre vaut "ami".</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
Bonjour ami<br/>
Bonjour ami<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le second appel passe "Alice",<br/>
qui remplace la valeur par défaut.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
Bonjour<br/>
Bonjour Alice<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la valeur par défaut est "ami",<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/>
puissance(2, 10) et<br/>
puissance(base=2, exposant=10) ?</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 plt.plot(x, y,<br/>
color="red", linestyle="--")).</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 def puissance(base, exposant):</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/>
``python<br/>
x = 10</p>
<p>def f():<br/>
    return x + 1</p>
<p>print(f())<br/>
``</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 : f 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 : x est une variable<br/>
<strong>globale</strong>. La fonction peut la lire,<br/>
mais pas la modifier (sans global).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune sortie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : print(f()) 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 global.<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>nonlocal</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas tout à fait : nonlocal 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>global</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : global x au début de la<br/>
fonction permet d'<strong>écrire</strong> dans x<br/>
global. Sans cela, x = ... créerait une<br/>
locale qui masque la globale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>outer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de mot-clé outer en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>var</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/>
`<code>python<br/>
def min_max(liste):<br/>
    return min(liste), max(liste)<br/>
</code>`</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 (min, max)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : Python utilise les tuples<br/>
pour les retours multiples. À la<br/>
réception : mn, mx = min_max(liste)<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 {}.</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>``python<br/>
def carre(x): return x * x</p>
<p>f = carre<br/>
print(f(3))<br/>
``<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 (map, filter, 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/>
f pointe vers la même fonction que<br/>
carre. f(3) appelle la fonction sur 3.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Affiche &lt;function carre&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : f(3) 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>``python<br/>
x = 10</p>
<p>def f():<br/>
    x = 20<br/>
    print(x)</p>
<p>f()<br/>
print(x)<br/>
``<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[<p>`<code><br/>
10<br/>
10<br/>
</code>`</p>]]></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[<p>`<code><br/>
20<br/>
20<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le x interne à f est une<br/>
variable <strong>locale</strong> distincte de la<br/>
variable globale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code><br/>
20<br/>
10<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'affectation x = 20<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 def carre(x): print(x<em>x)<br/>
au lieu de def carre(x): return x</em>x. Avec la<br/>
première version, on ne peut pas faire<br/>
y = carre(3) * 2 : y vaut None. La<br/>
seconde version permet bien y = 18.</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>print est plus rapide que return</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 return ; une fonction qui affiche écrit à l'écran avec print 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. print se contente<br/>
d'écrire un texte à l'écran. Si on a besoin<br/>
de la valeur, il faut un return.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>return n'existe pas en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : return 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. print 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/>
``python<br/>
def carre(x):<br/>
    return x * x</p>
<p>carre(5)<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Confusion classique des débutants : penser<br/>
que return affiche. print et return<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 : carre(5) est bien un appel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que 5 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 return 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 print(carre(5)) ou modifier la<br/>
fonction pour utiliser print (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>``python<br/>
x = 10</p>
<p>def f():<br/>
    x = 20<br/>
    return x</p>
<p>print(f())<br/>
print(x)<br/>
``<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[<p>`<code><br/>
10<br/>
10<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : f() renvoie sa propre x locale<br/>
(= 20).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
20<br/>
20<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans global x, le x = 20 dans<br/>
f 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[<p>`<code><br/>
20<br/>
10<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : x à l'intérieur de f<br/>
est local et masque la globale. À l'extérieur,<br/>
la globale x 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>`<code>python<br/>
def signe(x):<br/>
    if x &gt; 0:<br/>
        return 1<br/>
    if x &lt; 0:<br/>
        return -1<br/>
    return 0<br/>
</code><br/>
Pourquoi ce code marche-t-il sans elif` ?</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 return interrompt la fonction : si x &gt; 0, le premier return 1 empêche l'exécution des suivants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : return est plus fort<br/>
qu'un break, il quitte la fonction<br/>
entièrement. Pas besoin d'elif. 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 return quitte la<br/>
fonction immédiatement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les if sont équivalents à des elif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ils ne sont pas mutuellement<br/>
exclusifs sans return (chaque if<br/>
serait testé).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'il n'y a qu'un seul else</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il n'y a aucun else.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fonctions — Q23 : Paramètre mutable</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>``python<br/>
def ajouter(liste, x):<br/>
    liste.append(x)</p>
<p>ma_liste = [1, 2]<br/>
ajouter(ma_liste, 3)<br/>
print(ma_liste)<br/>
``<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>[3]</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>[1, 2, 3]</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>[1, 2]</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>``python<br/>
def ajouter(x, liste=[]):<br/>
    liste.append(x)<br/>
    return liste</p>
<p>print(ajouter(1))<br/>
print(ajouter(2))<br/>
``<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/>
None 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[<p>`<code><br/>
[1]<br/>
[1, 2]<br/>
</code>`</p>]]></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 [] est<br/>
partagé entre tous les appels. Solution :<br/>
utiliser liste=None puis<br/>
if liste is None: liste = [].</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
[1, 2]<br/>
[1, 2]<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seulement le premier appel reçoit<br/>
juste [1].</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
[1]<br/>
[2]<br/>
</code>`</p>]]></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. return a, b).</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 return renvoie implicitement None</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>
<p>``python<br/>
def carre(x):<br/>
    return x * x</p>
<p>def incremente(x):<br/>
    return x + 1</p>
<p>a = carre(incremente(3))<br/>
`</p>
<p>Quelle est la valeur de a` après l'exécution ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour évaluer une expression f(g(x)), Python<br/>
calcule d'abord g(x), puis applique f à 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/>
incremente(3) = 4 à un autre nombre. Mais<br/>
carre calcule un carré, pas une somme. La bonne<br/>
opération est 4 × 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/>
incremente(3) est évalué d'abord, puis le<br/>
résultat est passé à carre.</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 carre(3), sans<br/>
tenir compte de incremente. Or incremente<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 incremente(3) = 4, puis<br/>
applique carre à ce résultat : 4 × 4 = 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>
<p>`<code>python<br/>
def aire(longueur: float, largeur: float) -&gt; float:<br/>
</code></p>
<p>Que signifie la flèche -&gt; et l'annotation float`<br/>
qui la suit ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'annotation param: type documente le type<br/>
attendu d'un paramètre, l'annotation -&gt; type<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/>
mypy 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 return, 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/>
(mypy, 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>
<p>``python<br/>
def ajouter_zero(t):<br/>
    t.append(0)</p>
<p>ma_liste = [1, 2, 3]<br/>
ajouter_zero(ma_liste)<br/>
print(ma_liste)<br/>
`</p>
<p>Que va afficher print` ?</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>[1, 2, 3, 0]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : t et ma_liste désignent le<br/>
<strong>même objet liste</strong> en mémoire. La méthode<br/>
append modifie cet objet ; après l'appel,<br/>
ma_liste reflète donc le changement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le code lève une erreur car t n'est pas connu en dehors de la fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : t 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>[1, 2, 3]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction modifie effectivement la<br/>
liste passée en paramètre. La méthode append<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>[0, 1, 2, 3]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : append ajoute en fin de liste, pas<br/>
en début. Pour insérer à l'index 0, il<br/>
faudrait écrire t.insert(0, 0).</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 est_pair(n) qui<br/>
renvoie True si l'entier n est pair, False<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 True ou False est<br/>
appelée <strong>prédicat</strong>. Convention : nommer ces<br/>
fonctions avec un préfixe est_, a_, verifie_<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[<p>`<code>python<br/>
def est_pair(n):<br/>
    if n % 2 == 0:<br/>
        return True<br/>
    else:<br/>
        return False<br/>
</code>`</p>]]></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/>
return n % 2 == 0, qui exprime directement<br/>
l'idée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def est_pair(n):<br/>
    return n % 2 == 0<br/>
</code>`</p>]]></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/>
if. 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[<p>`<code>python<br/>
def est_pair(n):<br/>
    return n / 2<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la division n / 2 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 %), pas le<br/>
quotient.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def est_pair(n):<br/>
    print(n % 2 == 0)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction ne renvoie rien (elle<br/>
renvoie None). Elle ne peut donc pas être<br/>
utilisée dans un test comme<br/>
if est_pair(x):. Préférer return plutôt<br/>
que print.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
