<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Terminale/Programmation fonctionnelle</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Paradigme fonctionnel, fonctions pures, immuabilité, fonctions<br/>
de première classe et d'ordre supérieur (map, filter, reduce),<br/>
expressions lambda, récursivité, comparaison avec le paradigme<br/>
impératif.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q01 : Paradigme fonctionnel</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est l'idée centrale du <strong>paradigme fonctionnel</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Origines : le lambda-calcul de Church ($1936$) et le<br/>
langage Lisp ($1958$). Aujourd'hui, des langages<br/>
purement fonctionnels (Haskell, OCaml) coexistent avec<br/>
des langages multi-paradigmes (Python, JavaScript).</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>Composer des fonctions en évitant les effets de bord</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la programmation fonctionnelle<br/>
privilégie les fonctions sans effet de bord<br/>
(« fonctions pures »), l'immutabilité des données et<br/>
la composition de fonctions. Cela rend le code plus<br/>
prévisible et plus facile à raisonner.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Programmer uniquement avec des boucles <code>for</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la programmation fonctionnelle remplace<br/>
plutôt les boucles par de la récursivité ou des<br/>
fonctions d'ordre supérieur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Programmer en suivant l'ordre exact des instructions ligne par ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le paradigme <strong>impératif</strong>, dont la<br/>
programmation fonctionnelle est précisément une<br/>
alternative.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Programmer en utilisant uniquement des objets et des classes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le paradigme <strong>orienté objet</strong>, pas<br/>
fonctionnel.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q02 : Fonction pure</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'une <strong>fonction pure</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Fonction pure typique : <code>def carre(x): return x * x</code>.<br/>
Fonction <strong>impure</strong> : <code>def ajoute_a_liste(L, x): L.append(x)</code><br/>
modifie son argument, ce qui est un effet de bord.</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>Même résultat pour les mêmes arguments, sans effet de bord</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la pureté implique la prévisibilité<br/>
totale et la facilité de test. C'est aussi ce qui<br/>
permet la mémoïsation transparente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction qui modifie directement ses propres arguments</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'inverse d'une fonction pure. Modifier<br/>
ses arguments est un effet de bord, ce qui rend la<br/>
fonction impure.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction écrite uniquement en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la pureté est indépendante du langage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction qui ne contient aucun bug</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : « pure » est un terme technique précis,<br/>
pas un jugement de qualité.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q03 : Immutabilité</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que signifie qu'une donnée est <strong>immuable</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'immutabilité a plusieurs avantages : une donnée<br/>
partagée entre plusieurs fonctions ne subit aucune<br/>
modification inattendue (pas d'effet de bord), et<br/>
on peut raisonner sur sa valeur sans suivre toute<br/>
l'exécution du programme.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle est stockée en permanence sur le disque dur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec le stockage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle est protégée par un mot de passe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec la sécurité. C'est une<br/>
propriété structurelle de la donnée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle ne peut pas être modifiée après sa création</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour modifier, on crée une nouvelle<br/>
donnée à partir de l'ancienne, sans toucher à<br/>
l'originale. Exemple en Python : les chaînes, les<br/>
tuples sont immuables.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle ne peut pas être lue</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une donnée immuable peut être lue<br/>
librement, c'est seulement la modification qui est<br/>
interdite.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q04 : Fonctions de première classe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que signifie « les fonctions sont des objets de première<br/>
classe » dans un langage ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette propriété rend possibles les fonctions d'ordre<br/>
supérieur (<code>map</code>, <code>filter</code>, <code>sorted</code> avec <code>key</code>), qui<br/>
prennent ou renvoient des fonctions, et qui sont au cœur<br/>
du paradigme fonctionnel.</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>Elles sont les plus rapides du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de lien avec la performance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>On les passe, on les retourne et on les stocke comme des valeurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est une caractéristique majeure<br/>
des langages fonctionnels. Python, JavaScript,<br/>
OCaml, Haskell traitent les fonctions ainsi. C++,<br/>
Java l'ont ajouté plus tardivement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elles sont écrites en majuscules</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec la casse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elles sont systématiquement les premières instructions du programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec l'ordre des instructions.<br/>
Le terme est conceptuel.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q05 : Expression lambda</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>En Python, qu'est-ce qu'une <strong>expression lambda</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le mot <code>lambda</code> vient du lambda-calcul de Church. En<br/>
Python, les <code>lambda</code> sont limitées à une seule<br/>
expression. Pour une fonction plus complexe, on utilise<br/>
<code>def</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>Une variable globale</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec les variables globales.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une fonction anonyme sur une ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>lambda x: x <em> x</code> est une fonction<br/>
anonyme qui prend <code>x</code> et renvoie son carré.<br/>
Équivalent à <code>def f(x): return x </em> x</code> mais sans<br/>
nom, utilisable directement comme expression.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type de boucle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas une boucle. C'est une fonction<br/>
anonyme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une instruction spéciale dédiée au débogage</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec le débogage.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q06 : Fonction map</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait la fonction <code>map(f, L)</code> en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>map</code> et <code>filter</code> sont deux fonctions d'ordre supérieur<br/>
classiques : la première transforme chaque élément, la<br/>
seconde ne garde que ceux qui vérifient un critère. Elles<br/>
correspondent à des schémas d'usage très courants.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle filtre la liste selon un critère</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le rôle de <code>filter</code>, pas <code>map</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle réduit la liste à une seule valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>map</code> produit une valeur pour chaque élément<br/>
de <code>L</code>, elle ne les combine pas en une seule.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle applique <code>f</code> à chaque élément de <code>L</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour obtenir une liste, on fait<br/>
<code>list(map(f, L))</code>. Par exemple,<br/>
<code>list(map(lambda x: x * 2, [1, 2, 3]))</code> renvoie<br/>
<code>[2, 4, 6]</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle modifie la liste <code>L</code> en y appliquant <code>f</code> directement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>map</code> ne modifie pas la liste d'origine. Elle<br/>
produit de nouvelles valeurs et laisse <code>L</code> intacte.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q07 : Fonction filter</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait <code>filter(p, L)</code> en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Alternative idiomatique en Python avec<br/>
compréhension de liste :<br/>
<code>[x for x in L if p(x)]</code>. Souvent plus lisible que<br/>
<code>filter</code> en Python.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle compte le nombre d'éléments dans <code>L</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pour compter, on utilise <code>len</code> ou <code>sum</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle garde les éléments de <code>L</code> où <code>p</code> est vrai</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : par exemple,<br/>
<code>list(filter(lambda x: x &gt; 0, [-1, 0, 1, 2]))</code><br/>
renvoie <code>[1, 2]</code>. Les éléments pour lesquels <code>p</code><br/>
renvoie <code>True</code> sont conservés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle modifie directement chaque élément de <code>L</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est plutôt le rôle de <code>map</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle renvoie une liste vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>filter</code> renvoie un itérateur des éléments<br/>
conservés, pas vide.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q08 : Map avec une fonction booléenne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On définit la fonction suivante :</p>
<pre><code>def depasse_dix(x):
    return x &gt; 10</code></pre>
<p>Que vaut <code>list(map(depasse_dix, [4, 15, 10, 23]))</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>map(f, L)</code> renvoie un résultat <code>f(x)</code> pour chaque élément <code>x</code> de<br/>
<code>L</code>, tandis que <code>filter(f, L)</code> ne garde que les éléments pour<br/>
lesquels <code>f(x)</code> vaut <code>True</code>. Avec une fonction qui renvoie un<br/>
booléen, <code>map</code> donne donc des booléens.</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>[15, 23]</code> : les éléments qui dépassent $10$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le résultat de <code>filter</code>, qui ne garde que les éléments<br/>
pour lesquels la fonction renvoie <code>True</code>. <code>map</code> renvoie, pour chaque<br/>
élément, la valeur calculée par la fonction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>[False, True, False, True]</code> : un booléen par élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>map</code> applique <code>depasse_dix</code> à chaque élément et<br/>
rassemble les résultats : <code>4 &gt; 10</code> donne <code>False</code>, <code>15 &gt; 10</code> donne<br/>
<code>True</code>, <code>10 &gt; 10</code> donne <code>False</code> et <code>23 &gt; 10</code> donne <code>True</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[False, True, True, True]</code> : un booléen par élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>10 &gt; 10</code> vaut <code>False</code>, car $10$ n'est pas strictement<br/>
supérieur à $10$. Seul <code>10 &gt;= 10</code> vaudrait <code>True</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[4, 10]</code> : les éléments qui ne dépassent pas $10$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce sont les éléments écartés par le test. <code>map</code> ne retire<br/>
aucun élément : il renvoie autant de résultats que la liste contient<br/>
d'éléments.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q09 : Composition de fonctions</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que signifie « composer deux fonctions $f$ et $g$ » ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>En programmation fonctionnelle, on construit des<br/>
programmes complexes en composant des fonctions<br/>
simples. Ce style favorise la <strong>réutilisation</strong> et la<br/>
<strong>modularité</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>Les exécuter en parallèle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la composition est séquentielle (l'une<br/>
après l'autre).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Créer une fonction qui applique $g$ puis $f$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : $(f \circ g)(x) = f(g(x))$. La<br/>
composition de fonctions est la brique de base de la<br/>
programmation fonctionnelle, qui voit les programmes<br/>
comme des chaînes de transformations.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les écrire dans le même fichier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport. La composition est une<br/>
opération mathématique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les fusionner définitivement en une seule grosse fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la composition crée une nouvelle fonction<br/>
mais ne modifie pas $f$ ni $g$ ; elles restent<br/>
utilisables séparément.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q10 : Récursivité en programmation fonctionnelle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi la <strong>récursivité</strong> est-elle privilégiée à la<br/>
boucle dans le paradigme fonctionnel ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les langages fonctionnels purs (Haskell) n'ont même pas<br/>
de boucles : tout est exprimé par récursivité ou par<br/>
fonctions d'ordre supé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="0" format="html">
    <text><![CDATA[<p>Parce que les appels récursifs s'exécutent plus vite qu'une boucle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la récursivité est généralement aussi<br/>
rapide ou plus lente que les boucles, mais ce<br/>
n'est pas la raison de son emploi.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce qu'une boucle repose sur un compteur que l'on modifie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>for i in range(n)</code> modifie<br/>
implicitement <code>i</code> à chaque tour, ce qui contredit<br/>
l'immutabilité des données. Une approche purement<br/>
fonctionnelle évite cela en utilisant des appels<br/>
récursifs avec de nouveaux paramètres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les boucles n'existent tout simplement pas en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python a des boucles. C'est par<br/>
<strong>convention</strong> ou par <strong>style</strong> qu'on les évite en<br/>
programmation fonctionnelle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que c'est une habitude de style, sans justification de fond</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est une raison structurelle (éviter la<br/>
modification d'un état), pas un simple effet de<br/>
mode.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q11 : Identifier une fonction pure</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les fonctions Python suivantes, laquelle est<br/>
<strong>pure</strong> ?</p>
<pre><code>def f1(x): return x + 1
def f2(x): print(x); return x
def f3(L, x): L.append(x); return L
def f4(): return random.random()</code></pre>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les effets de bord typiques : modifier une variable<br/>
globale, écrire dans un fichier, appeler <code>print</code>,<br/>
utiliser le hasard, lire l'horloge système, etc. Toutes<br/>
ces opérations rendent une fonction impure.</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>f1</code> et <code>f4</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>f4</code> n'est pas pure. Pour les mêmes<br/>
arguments (aucun ici), elle renvoie des résultats<br/>
différents (génération aléatoire).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>f1</code> et <code>f2</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>f2</code> appelle <code>print</code>, ce qui est un effet<br/>
de bord (interaction avec le terminal).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>f1</code> seule</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>f1</code> ne modifie rien et retourne<br/>
toujours la même valeur pour le même argument. <code>f2</code><br/>
a un effet de bord (<code>print</code>), <code>f3</code> modifie son<br/>
argument, <code>f4</code> retourne un résultat différent à<br/>
chaque appel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les quatre fonctions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seule <code>f1</code> respecte les deux conditions de<br/>
pureté.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q12 : Lambda avec map</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie l'expression Python suivante ?<br/>
<pre><code>list(map(lambda x: x ** 2, [1, 2, 3, 4]))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette construction est très idiomatique en<br/>
programmation fonctionnelle. En Python, on peut aussi<br/>
écrire <code>[x ** 2 for x in [1, 2, 3, 4]]</code>, qui est<br/>
souvent considéré plus lisible.</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, 4, 9, 16]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la lambda calcule le carré, et <code>map</code><br/>
l'applique à chaque élément. On obtient<br/>
$[1^2, 2^2, 3^2, 4^2] = [1, 4, 9, 16]$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1, 2, 3, 4]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>map</code> applique la fonction à chaque<br/>
élément, donc transforme la liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1, 16]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>map</code> applique à <strong>chaque</strong> élément, on<br/>
n'en perd pas en chemin.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[2, 4, 6, 8]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait <code>lambda x: x * 2</code>, pas <code>x <strong> 2</code>.<br/>
<code></strong></code> est l'opérateur <strong>puissance</strong> en Python.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q13 : Filter pour les nombres pairs</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie cette expression ?<br/>
<pre><code>list(filter(lambda x: x % 2 == 0, range(10)))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Équivalent en compréhension de liste :<br/>
<code>[x for x in range(10) if x % 2 == 0]</code>. Les deux<br/>
formes sont fréquentes en Python.</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>[]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il y a bien des nombres pairs dans<br/>
<code>range(10)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1, 3, 5, 7, 9]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>x % 2 == 0</code> teste si <code>x</code> est <strong>pair</strong>.<br/>
Donc on garde les pairs, pas les impairs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[0, 1, 2, ..., 9]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait <code>range(10)</code> complet, sans filtre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>[0, 2, 4, 6, 8]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>filter</code> conserve les éléments pour<br/>
lesquels la condition est vraie. <code>range(10)</code> produit<br/>
$0, 1, \ldots, 9$ ; on garde les pairs $0, 2, 4, 6, 8$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q14 : Compréhension de liste</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la <strong>compréhension de liste</strong> Python équivalente<br/>
à <code>list(map(lambda x: x * 2, filter(lambda x: x &gt; 0, L)))</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les compréhensions de liste, inspirées des langages<br/>
fonctionnels, s'intègrent naturellement à Python.<br/>
Elles combinent élégamment <code>map</code> et <code>filter</code> en<br/>
une seule expression. Pour réduire une liste à une<br/>
valeur unique, on utilise <code>sum</code>, <code>max</code>, <code>min</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><code>[x &gt; 0 * 2 for x in L]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : syntaxiquement valide mais sémantiquement<br/>
faux. La condition est ailleurs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[x for x in L * 2]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cela multiplie la liste par $2$ (deux<br/>
répétitions de la liste), pas chaque élément. De<br/>
plus, le filtre est absent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[L if x &gt; 0 for x in L]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : syntaxe incorrecte de compréhension.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>[x * 2 for x in L if x &gt; 0]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on combine map et filter dans une<br/>
seule compréhension. Cette forme est plus lisible<br/>
et idiomatique en Python.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q15 : Fonction d'ordre supérieur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la définition d'une <strong>fonction d'ordre supérieur</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les fonctions d'ordre supérieur sont la signature du<br/>
paradigme fonctionnel. Elles permettent l'abstraction<br/>
du comportement : par exemple, <code>sorted(L, key=f)</code><br/>
laisse l'utilisateur définir comment trier sans changer<br/>
l'algorithme de tri.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction définie au niveau global du module</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec la portée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction qui appelle d'autres fonctions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la plupart des fonctions appellent d'autres<br/>
fonctions. Le critère est plus précis.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une fonction qui prend ou renvoie une fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>map</code>, <code>filter</code> et <code>sorted</code> (avec <code>key</code>)<br/>
sont des fonctions d'ordre supérieur. Elles manipulent<br/>
les fonctions comme n'importe quelle autre valeur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction très complexe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : « ordre supérieur » est un terme technique,<br/>
pas un jugement de complexité.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q17 : Des fonctions rangées dans un dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que vaut <code>resultat</code> après l'exécution de ce programme ?</p>
<pre><code>def ajouter(a, b):
    return a + b

def multiplier(a, b):
    return a * b

operations = {"+": ajouter, "*": multiplier}
resultat = operations["*"](4, 5)</code></pre>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les fonctions sont des valeurs : on peut les stocker dans un<br/>
dictionnaire et choisir laquelle appeler selon une clé.<br/>
<code>operations["*"](4, 5)</code> revient à <code>multiplier(4, 5)</code>, soit $20$.</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>9</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $9$ serait le résultat de <code>ajouter(4, 5)</code>, rangée sous la<br/>
clé <code>"+"</code>. La clé <code>"*"</code> désigne <code>multiplier</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>20</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>operations["*"]</code> désigne la fonction <code>multiplier</code>,<br/>
et les parenthèses <code>(4, 5)</code> l'appellent aussitôt : <code>multiplier(4, 5)</code><br/>
renvoie $20$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction <code>multiplier</code> elle-même, sans l'appeler</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>operations["*"]</code> seul serait la fonction, mais il est<br/>
suivi de <code>(4, 5)</code>, qui provoque son appel. <code>resultat</code> reçoit donc la<br/>
valeur renvoyée, $20$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car un dictionnaire ne peut pas contenir de fonctions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : en Python, une fonction est une valeur comme une autre. On<br/>
peut la ranger dans un dictionnaire, la passer en argument ou la<br/>
renvoyer.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q18 : Une remise qui lit une variable globale</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère le programme suivant :<br/>
<pre><code>taux = 0.1
def remise(prix):
    return prix - prix * taux
a = remise(200)
taux = 0.5
b = remise(200)</code></pre><br/>
Que valent <code>a</code> et <code>b</code>, et que peut-on en conclure ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une fonction pure ne dépend que de ses arguments. En lisant la<br/>
variable globale <code>taux</code>, <code>remise</code> renvoie des valeurs différentes<br/>
pour un même prix dès que <code>taux</code> change. Pour la rendre pure, on<br/>
passe le taux en paramètre : <code>remise(prix, taux)</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>180.0</code> et <code>100.0</code> : <code>remise</code> n'est pas une fonction pure</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la valeur de <code>taux</code> est lue à chaque appel, $0.1$<br/>
puis $0.5$. Le même argument $200$ donne deux résultats différents :<br/>
le résultat ne dépend pas que des arguments, la fonction n'est donc<br/>
pas pure.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>180.0</code> et <code>180.0</code> : <code>taux</code> est lu une fois, à la définition</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python lit <code>taux</code> au moment de chaque appel, pas lors de la<br/>
définition de <code>remise</code>. Le second appel utilise donc $0.5$ et<br/>
renvoie <code>100.0</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>180.0</code> et <code>100.0</code> : <code>remise</code> est pure, elle ne modifie rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ne rien modifier ne suffit pas. Une fonction pure doit<br/>
aussi renvoyer la même valeur pour les mêmes arguments, or<br/>
<code>remise(200)</code> vaut <code>180.0</code> puis <code>100.0</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur : <code>taux</code> n'est pas défini à l'intérieur de <code>remise</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une fonction peut lire une variable définie en dehors d'elle<br/>
sans <code>global</code>. Le mot-clé <code>global</code> n'est nécessaire que pour la<br/>
modifier.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q19 : Impératif vs fonctionnel</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est l'équivalent <strong>fonctionnel</strong> du code impératif<br/>
suivant ?</p>
<pre><code>total = 0
for x in L:
    if x &gt; 0:
        total += x ** 2</code></pre>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le code fonctionnel est plus court, sans variable<br/>
modifiable, et exprime directement l'<strong>intention</strong><br/>
(« la somme des carrés des positifs ») plutôt que la<br/>
<strong>mécanique</strong> d'accumulation.</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>sum(x ** 2 if x &gt; 0 for x in L)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : syntaxe invalide. <code>x ** 2 if x &gt; 0</code> sans <code>else</code><br/>
n'est pas une expression correcte : le filtre se place<br/>
après le <code>for</code>, sous la forme <code>for x in L if x &gt; 0</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>sum(x ** 2 for x in L if x &gt; 0)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le filtre <code>if x &gt; 0</code> écarte les valeurs<br/>
négatives ou nulles, <code>x ** 2</code> transforme chaque valeur<br/>
retenue et <code>sum</code> additionne le tout. Pas de variable<br/>
modifiée, pas de boucle explicite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>list(map(lambda x: x ** 2, filter(lambda x: x &gt; 0, L)))</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le filtrage et la mise au carré sont corrects,<br/>
mais cette expression renvoie la liste des carrés et non<br/>
leur somme. Pour <code>L = [2, -1, 3]</code>, elle donne <code>[4, 9]</code><br/>
au lieu de $13$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>for x in L: total += x ** 2</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est une boucle impérative qui modifie<br/>
<code>total</code>. On veut s'en abstraire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q20 : Récursivité sans boucle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction calcule <strong>récursivement</strong>, sans boucle, la somme des<br/>
éléments d'une liste <code>L</code>, l'appel <code>somme(L, 0)</code> devant renvoyer la<br/>
somme de toute la liste ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une fonction récursive a besoin d'un cas de base, qui arrête les<br/>
appels, et d'un appel sur un problème plus petit, ici la fin de la<br/>
liste à partir de <code>i + 1</code>. En Python, le nombre d'appels imbriqués<br/>
est limité : pour de très longues listes, on préfère <code>sum</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 somme(L, i):
    return L[i] + somme(L, i + 1)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il manque le cas de base. Quand <code>i</code> atteint <code>len(L)</code>,<br/>
<code>L[i]</code> n'existe pas : <code>somme([1, 2, 3], 0)</code> lève <code>IndexError</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def somme(L, i):
    total = 0
    for j in range(i, len(L)):
        total = total + L[j]
    return total</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le résultat est juste, mais la fonction utilise une boucle<br/>
et une variable <code>total</code> modifiée à chaque tour. C'est l'écriture<br/>
impérative, pas récursive.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def somme(L, i):
    if i == len(L):
        return 0
    return L[i] + somme(L, i + 1)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le cas de base traite l'indice qui dépasse la liste<br/>
en renvoyant $0$, et chaque appel ajoute <code>L[i]</code> à la somme des<br/>
éléments suivants. Aucune boucle, aucune variable modifiée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def somme(L, i):
    if i == len(L) - 1:
        return 0
    return L[i] + somme(L, i + 1)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le cas de base renvoie $0$ sur le dernier indice au lieu<br/>
d'ajouter <code>L[i]</code>, si bien que le dernier élément est oublié :<br/>
<code>somme([1, 2, 3], 0)</code> renvoie $3$ au lieu de $6$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q21 : Mélange de paradigmes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un programme Python utilise une boucle <code>for</code> pour<br/>
parcourir une liste, puis appelle <code>sorted</code> avec une<br/>
fonction lambda comme critère. Combien de paradigmes<br/>
de programmation différents ce code combine-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Python est un langage <strong>multi-paradigme</strong> : il<br/>
permet d'écrire dans le style impératif (boucles,<br/>
affectations), fonctionnel (lambda, <code>map</code>,<br/>
compréhensions) ou objet (classes), et de<br/>
combiner librement les trois selon les besoins.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun, ce n'est pas vraiment un programme correct et valide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est bien un programme valide, et il<br/>
utilise plusieurs paradigmes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Deux : impératif (la boucle) et fonctionnel (la lambda)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est exactement ce que dit le<br/>
programme officiel : « Dans un même programme,<br/>
on peut utiliser des paradigmes différents. »</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trois : impératif, fonctionnel et objet</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune classe ni objet n'est défini<br/>
dans cet exemple, donc le paradigme objet n'est<br/>
pas mobilisé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un seul, l'impératif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle <code>for</code> est bien impérative,<br/>
mais l'usage de <code>sorted</code> avec une lambda relève<br/>
du style fonctionnel.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q22 : Calculer la somme des carrés</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On veut calculer la somme des carrés des entiers<br/>
d'une liste <code>nombres</code>. Quel code suit le <strong>style fonctionnel</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le style fonctionnel privilégie les expressions<br/>
sans état modifiable. La compréhension de liste et<br/>
les fonctions comme <code>sum</code>, <code>map</code>, <code>filter</code><br/>
permettent souvent d'écrire des traitements de<br/>
données très concis dans ce style.</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>total = 0
for n in nombres:
    total = total + n * n</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce code est <strong>impératif</strong> : il modifie<br/>
une variable <code>total</code> à chaque itération.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>class Sommateur:
    def __init__(self):
        self.total = 0
    def ajouter(self, n):
        self.total += n * n</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce code définit une classe ; c'est le<br/>
style <strong>objet</strong>, pas fonctionnel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>total = nombres</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce code ne calcule pas du tout la<br/>
somme des carrés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>total = sum(n * n for n in nombres)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ce code est <strong>fonctionnel</strong> : il<br/>
construit une expression sans variable d'état<br/>
intermédiaire et passe le résultat à la fonction<br/>
<code>sum</code>. Pas d'effet de bord.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q23 : Choisir un paradigme</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour écrire un script court qui transforme une<br/>
liste de prix en y appliquant une remise de $10\%$,<br/>
quel <strong>paradigme</strong> est le plus naturel en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une même tâche peut souvent s'écrire dans plusieurs<br/>
paradigmes. Le bon choix dépend de la nature du<br/>
problème : transformations de données pour le<br/>
fonctionnel, modélisation d'entités pour l'objet,<br/>
séquences d'instructions pour l'impératif. Python<br/>
permet de mélanger les trois.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une approche fonctionnelle avec une compréhension de liste ou un <code>map</code> sur une lambda</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la transformation d'une liste en<br/>
une autre par une fonction simple est typique du<br/>
style fonctionnel. Une compréhension de liste<br/>
comme <code>[p * 0.9 for p in prix]</code> est concise et<br/>
claire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un paradigme logique type Prolog</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible théoriquement mais inadapté ici, et<br/>
Prolog n'est pas Python. Le paradigme logique<br/>
n'est pas étudié au lycée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une approche objet avec une classe <code>Remiseur</code> et une méthode <code>appliquer</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais nettement excessif pour une<br/>
transformation de liste de quelques lignes. La<br/>
POO se justifie quand on modélise des entités<br/>
avec un état et plusieurs comportements.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun paradigme : il faut tout écrire à la main, avec des <code>goto</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il n'existe pas de <code>goto</code> en Python, et<br/>
aucun paradigme moderne ne le promeut.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q24 : Programmation fonctionnelle et parallélisme</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi la programmation fonctionnelle est-elle<br/>
particulièrement adaptée au calcul <strong>parallèle</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est un argument fort à l'heure des processeurs à<br/>
plusieurs cœurs : des calculs sans effet de bord peuvent<br/>
être répartis entre plusieurs processus sans qu'ils se<br/>
gênent.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle utilise automatiquement davantage de cœurs du processeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas la cause, c'est l'effet<br/>
recherché. La cause est plus profonde.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle utilise moins de mémoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : au contraire, l'immutabilité peut consommer<br/>
plus de mémoire (création de nouveaux objets plutôt<br/>
que modification en place).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle est plus simple à apprendre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est subjectif, et de toute façon pas la<br/>
raison de l'aptitude au parallélisme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Sans effets de bord ni mutation, pas de conflit d'accès</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : en programmation impérative, deux calculs<br/>
menés en parallèle qui modifient la même variable doivent<br/>
se coordonner, ce qui est complexe et lent. Avec des<br/>
données qui ne changent pas, chaque calcul avance seul,<br/>
sans risque de conflit.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q25 : Comparaison des paradigmes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes, laquelle est <strong>vraie</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'idéal pragmatique : utiliser le bon paradigme pour<br/>
le bon problème. Une bonne formation NSI inclut donc<br/>
les deux pour développer la flexibilité de pensée<br/>
algorithmique.</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 programmation fonctionnelle remplace définitivement l'orientée objet</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux paradigmes coexistent et se<br/>
complètent. La plupart des langages modernes sont<br/>
multi-paradigmes (Python, JavaScript, Scala).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La programmation fonctionnelle ne fonctionne que sur les ordinateurs récents</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Lisp date de $1958$ et tournait sur les<br/>
premiers ordinateurs. La programmation fonctionnelle<br/>
est antérieure à l'orientée objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La programmation fonctionnelle interdit l'utilisation des classes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on peut utiliser des classes en<br/>
programmation fonctionnelle, surtout dans des<br/>
langages multi-paradigmes. Les puristes les évitent,<br/>
mais ce n'est pas une interdiction du paradigme<br/>
lui-même.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Fonctionnelle et objet sont complémentaires, selon les situations</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : OO modélise des entités avec état<br/>
et comportement (interfaces graphiques, simulation,<br/>
jeux). Fonctionnelle modélise des transformations<br/>
de données (calcul, science des données). Beaucoup<br/>
de programmes mélangent les deux.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q26 : Une fonction qui affiche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La fonction <code>double</code> est-elle pure ?<br/>
<pre><code>def double(x):
    print(x)
    return 2 * x</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une fonction pure ne fait que calculer sa valeur de retour :<br/>
afficher, écrire dans un fichier ou modifier une variable globale<br/>
sont des effets de bord.</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>Non, l'affichage est un effet de bord</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le résultat ne dépend que de <code>x</code>, mais la<br/>
fonction agit sur l'extérieur en écrivant à l'écran. Deux appels<br/>
identiques n'ont pas le même effet sur le monde.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, le résultat ne dépendant que de <code>x</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la pureté exige aussi l'absence de tout effet<br/>
extérieur, et <code>print</code> en est un.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, car <code>print</code> ne modifie aucune variable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : écrire à l'écran est un effet de bord même sans<br/>
variable modifiée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, car elle ne contient pas de boucle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la présence ou l'absence de boucle ne définit pas la<br/>
pureté.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q27 : Ajouter un élément sans rien modifier</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle version respecte l'immuabilité, en laissant intacte la<br/>
structure reçue ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'immuabilité se pratique en renvoyant de nouvelles valeurs : les<br/>
tuples s'y prêtent, les listes exigent une copie.</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>def ajoute(t, x): return t + (x,)</code>, avec <code>t</code> un tuple</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>t + (x,)</code> construit un nouveau tuple ; <code>t</code><br/>
reste inchangé pour tous ceux qui le partagent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>def ajoute(l, x): l.append(x)</code>, avec <code>l</code> une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>append</code> modifie la liste reçue, visible depuis<br/>
l'appelant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>def ajoute(l, x): l += [x]</code>, avec <code>l</code> une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sur une liste, <code>+=</code> modifie l'objet existant, comme<br/>
<code>append</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>def ajoute(l, x): l.insert(len(l), x)</code>, avec <code>l</code> une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>insert</code> modifie la liste en place.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q28 : Pureté et mémorisation des résultats</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi peut-on mémoriser les résultats d'une fonction pure dans<br/>
un dictionnaire pour éviter de les recalculer, alors que c'est<br/>
risqué pour une fonction quelconque ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La mémoïsation suppose qu'un résultat ne change pas d'un appel à<br/>
l'autre : c'est exactement ce que garantit la pureté.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une fonction pure renvoie toujours la même valeur pour les mêmes arguments</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le résultat mémorisé reste valable à tout<br/>
moment. Une fonction qui lit une variable globale ou l'heure<br/>
pourrait rendre une valeur différente au prochain appel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction pure s'exécute plus vite, le dictionnaire restant petit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la vitesse n'a rien à voir ; c'est la stabilité du<br/>
résultat qui compte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction pure n'accepte qu'un seul argument, facile à utiliser comme clé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une fonction pure peut avoir plusieurs arguments, un<br/>
tuple sert alors de clé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction pure ne peut pas lever d'exception, le dictionnaire reste cohérent</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une fonction pure peut lever une exception, par<br/>
exemple une division par zéro.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q29 : Calculer une somme sans réaffecter</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi ces façons de calculer la somme d'une liste <code>l</code>, laquelle ne<br/>
modifie aucune variable ni aucune structure ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le style fonctionnel compose des fonctions qui renvoient des<br/>
valeurs au lieu de mettre à jour des variables.</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 appel <code>sum(l)</code>, qui renvoie la somme sans rien changer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>sum</code> reçoit la liste et renvoie une valeur, sans<br/>
rien changer ni réaffecter.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une boucle <code>for</code> accumulant dans <code>total</code>, réaffecté à chaque tour</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>total</code> est réaffecté à chaque tour, c'est le style<br/>
impératif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une boucle remplaçant <code>l[0]</code> par <code>l[0] + l[1]</code> et retirant <code>l[1]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la liste est détruite au passage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un <code>l.append(sum(l))</code> suivi de la lecture de <code>l[-1]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la liste reçoit un élément de plus.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q30 : Un argument modifié par la fonction</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme, et la fonction <code>sans_tete</code> est-elle pure ?<br/>
<pre><code>def sans_tete(l):
    l.pop(0)
    return l

a = [1, 2, 3]
b = sans_tete(a)
print(a)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une version pure construirait une nouvelle liste, <code>l[1:]</code>, sans<br/>
toucher à celle reçue.</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>[2, 3]</code>, et la fonction n'est pas pure, elle modifie <code>a</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>pop(0)</code> retire le premier élément de la liste<br/>
reçue, qui est <code>a</code> elle-même. Un appel a changé une valeur<br/>
extérieure, c'est un effet de bord.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1, 2, 3]</code>, et la fonction est pure, elle renvoie une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>a</code> et <code>l</code> désignent la même liste, modifiée par<br/>
<code>pop</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[2, 3]</code>, et la fonction est pure, le résultat étant renvoyé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : renvoyer un résultat n'efface pas l'effet de bord sur<br/>
<code>a</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1, 2, 3]</code>, et la fonction n'est pas pure, elle utilise <code>pop</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction n'est effectivement pas pure, mais <code>a</code> a<br/>
bien été modifiée.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q31 : Tester une fonction pure</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi une fonction pure est-elle plus simple à tester qu'une<br/>
fonction qui lit et modifie des variables globales ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une fonction qui dépend d'un état global oblige à reconstruire cet<br/>
état avant chaque test et à le vérifier après.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il suffit de choisir des arguments et de vérifier la valeur renvoyée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : rien à préparer avant l'appel, rien à inspecter<br/>
après, sinon le résultat. Chaque test est indépendant des<br/>
autres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction pure n'a jamais besoin d'être testée, étant correcte par nature</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la pureté ne garantit pas que le calcul est juste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction pure s'exécute plus vite, les tests durent donc moins</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la vitesse n'est pas en cause, c'est l'absence d'état à<br/>
préparer.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les tests d'une fonction pure peuvent s'écrire sans connaître ses arguments</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un test appelle la fonction avec des arguments précis.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q32 : Où se trouve l'état d'un programme fonctionnel</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un programme impératif garde l'état du jeu dans des variables qu'il<br/>
met à jour. Comment un programme fonctionnel représente-t-il<br/>
l'évolution de cet état ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sans variable mutable, le temps qui passe se traduit par une suite<br/>
de valeurs, chacune calculée à partir de la précédente.</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>Chaque fonction reçoit l'état et renvoie un nouvel état</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'état circule dans les paramètres et les<br/>
valeurs de retour ; l'ancien état n'est jamais modifié, un<br/>
nouveau est construit à chaque étape.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il stocke l'état dans une variable globale lue par toutes les fonctions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est précisément ce que le style fonctionnel évite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il n'a pas d'état, un programme fonctionnel ne pouvant rien faire évoluer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'état évolue, mais par création de nouvelles valeurs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Chaque fonction modifie l'état reçu avant de le renvoyer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : modifier l'état reçu serait un effet de bord.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q33 : Déplacer un point en objet et en fonctionnel</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Deux programmes déplacent un point. Lequel relève du style<br/>
fonctionnel ?<br/>
<pre><code># Version A
p.deplace(2, 3)

# Version B
q = deplace(p, 2, 3)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>En objet, l'opération change l'objet ; en fonctionnel, elle produit<br/>
une nouvelle valeur et laisse l'ancienne intacte.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La version B, qui renvoie un nouveau point sans toucher à <code>p</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>deplace</code> reçoit <code>p</code> et renvoie un point<br/>
distinct ; <code>p</code> reste disponible tel quel. La version A modifie<br/>
l'état interne de l'objet <code>p</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La version A, qui regroupe la donnée et son comportement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : regrouper données et méthodes et modifier l'état est le<br/>
propre du style objet.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les deux, puisque toutes deux appellent une fonction <code>deplace</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : appeler une fonction ne suffit pas ; c'est l'absence de<br/>
modification qui compte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune, le style fonctionnel interdisant les objets comme <code>p</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : toute donnée peut être manipulée en style fonctionnel,<br/>
pourvu qu'on ne la modifie pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q34 : Les effets de bord inévitables</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un programme doit bien, à un moment, afficher un résultat ou écrire<br/>
un fichier. Comment le style fonctionnel compose-t-il avec ces<br/>
effets de bord nécessaires ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le style fonctionnel ne supprime pas les effets de bord, il les<br/>
cantonne aux frontières du programme.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il les isole dans quelques fonctions, le cœur du calcul restant pur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les fonctions pures calculent, et une mince<br/>
couche de fonctions impures affiche ou enregistre leurs<br/>
résultats. Le programme est pur presque partout.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il les interdit totalement, un programme fonctionnel n'affichant rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un programme qui ne produit aucun effet ne sert à<br/>
rien.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il les répartit dans toutes les fonctions, pour qu'aucune ne domine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : disperser les effets rend chaque fonction impure, c'est<br/>
l'inverse du but.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il les remplace par des valeurs de retour, sans jamais rien afficher</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : renvoyer une valeur ne l'affiche pas ; un effet reste<br/>
nécessaire au bout de la chaîne.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q35 : Une fonction fabriquée par une autre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>def multiplieur(k):
    return lambda x: k * x

f = multiplieur(3)
print(f(5))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une fonction peut en renvoyer une autre, qui garde en mémoire les<br/>
variables de l'appel qui l'a créée.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>15</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>multiplieur(3)</code> renvoie une fonction qui<br/>
multiplie son argument par $3$ ; <code>f(5)</code> vaut<br/>
$3 \times 5 = 15$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>8</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction renvoyée multiplie, elle n'additionne pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>3</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>f</code> n'est pas la valeur <code>3</code>, c'est une fonction qui<br/>
se souvient de <code>3</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, <code>k</code> ayant disparu</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction renvoyée conserve la valeur de <code>k</code>, c'est<br/>
une fermeture.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q36 : Trier avec une fonction de clé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie <code>sorted(['pomme', 'kiwi', 'banane'], key=len)</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le paramètre <code>key</code> de <code>sorted</code> reçoit une fonction : c'est un<br/>
exemple de fonction d'ordre supérieur dans la bibliothèque<br/>
standard.</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>['kiwi', 'pomme', 'banane']</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>key=len</code> indique de comparer les mots par leur<br/>
longueur ; la fonction <code>len</code> est passée en argument, sans être<br/>
appelée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>['banane', 'kiwi', 'pomme']</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait l'ordre alphabétique, sans <code>key</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>['banane', 'pomme', 'kiwi']</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'ordre est croissant, du plus court au plus long.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, <code>len</code> devant être appelée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la fonction elle-même qui est attendue, pas son<br/>
résultat.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q37 : Enchaîner des fonctions rangées dans une liste</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>def enchaine(fonctions, x):
    for f in fonctions:
        x = f(x)
    return x

print(enchaine([lambda x: x + 1, lambda x: x * 2], 3))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une liste de fonctions parcourue par une boucle réalise une<br/>
composition : l'ordre des éléments est l'ordre d'application.</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>8</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les fonctions s'appliquent dans l'ordre de la<br/>
liste, d'abord $+1$ puis $\times 2$ :<br/>
$(3 + 1) \times 2 = 8$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>7</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait l'ordre inverse, $\times 2$ puis $+1$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>4</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seule la première fonction aurait été appliquée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, une liste ne pouvant contenir des fonctions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les fonctions sont des valeurs comme les autres, une<br/>
liste peut en contenir.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
