<?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="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="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 for</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 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 : def carre(x): return x * x.<br/>
Fonction <strong>impure</strong> : def ajoute_a_liste(L, x): L.append(x)<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="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 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>
  <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 écrite uniquement en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la pureté est indépendante du langage.</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="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>
  <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>
</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 (map, filter, sorted avec key), 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 lambda vient du lambda-calcul de Church. En<br/>
Python, les lambda sont limitées à une seule<br/>
expression. Pour une fonction plus complexe, on utilise<br/>
def.</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 anonyme sur une ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : lambda x: x <em> x est une fonction<br/>
anonyme qui prend x et renvoie son carré.<br/>
Équivalent à def f(x): return x </em> x mais sans<br/>
nom, utilisable directement comme expression.</p>]]></text>
    </feedback>
  </answer>
  <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="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>
  <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>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q06 : Fonction map</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait la fonction map(f, L) en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>map et filter 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 réduit la liste à une seule valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : map produit une valeur pour chaque élément<br/>
de L, elle ne les combine pas en une seule.</p>]]></text>
    </feedback>
  </answer>
  <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 filter, pas map.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle applique f à chaque élément de L</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour obtenir une liste, on fait<br/>
list(map(f, L)). Par exemple,<br/>
list(map(lambda x: x * 2, [1, 2, 3])) renvoie<br/>
[2, 4, 6].</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle modifie la liste L en y appliquant f directement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : map ne modifie pas la liste d'origine. Elle<br/>
produit de nouvelles valeurs et laisse L 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 filter(p, L) en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Alternative idiomatique en Python avec<br/>
compréhension de liste :<br/>
[x for x in L if p(x)]. Souvent plus lisible que<br/>
filter 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 L</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pour compter, on utilise len ou sum.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle garde les éléments de L où p est vrai</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : par exemple,<br/>
list(filter(lambda x: x &gt; 0, [-1, 0, 1, 2]))<br/>
renvoie [1, 2]. Les éléments pour lesquels p<br/>
renvoie True sont conservés.</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 : filter renvoie un itérateur des éléments<br/>
conservés, pas vide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle modifie directement chaque élément de L</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est plutôt le rôle de map.</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>
<p>`<code>python<br/>
def depasse_dix(x):<br/>
    return x &gt; 10<br/>
</code></p>
<p>Que vaut list(map(depasse_dix, [4, 15, 10, 23]))` ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>map(f, L) renvoie un résultat f(x) pour chaque élément x de<br/>
L, tandis que filter(f, L) ne garde que les éléments pour<br/>
lesquels f(x) vaut True. Avec une fonction qui renvoie un<br/>
booléen, map 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>[4, 10] : 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. map ne retire<br/>
aucun élément : il renvoie autant de résultats que la liste contient<br/>
d'éléments.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>[False, True, False, True] : un booléen par élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : map applique depasse_dix à chaque élément et<br/>
rassemble les résultats : 4 &gt; 10 donne False, 15 &gt; 10 donne<br/>
True, 10 &gt; 10 donne False et 23 &gt; 10 donne True.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[False, True, True, True] : un booléen par élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 10 &gt; 10 vaut False, car 10 n'est pas strictement<br/>
supérieur à 10. Seul 10 &gt;= 10 vaudrait True.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[15, 23] : les éléments qui dépassent 10</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le résultat de filter, qui ne garde que les éléments<br/>
pour lesquels la fonction renvoie True. map renvoie, pour chaque<br/>
élément, la valeur calculée par la fonction.</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 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>
  <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="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 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>
</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="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>
  <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 : for i in range(n) modifie<br/>
implicitement i à 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>
</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>
<p>`<code>python<br/>
def f1(x): return x + 1<br/>
def f2(x): print(x); return x<br/>
def f3(L, x): L.append(x); return L<br/>
def f4(): return random.random()<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les effets de bord typiques : modifier une variable<br/>
globale, écrire dans un fichier, appeler print,<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>f1 et f4</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : f4 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>Les quatre fonctions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seule f1 respecte les deux conditions de<br/>
pureté.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>f1 et f2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : f2 appelle print, ce qui est un effet<br/>
de bord (interaction avec le terminal).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>f1 seule</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : f1 ne modifie rien et retourne<br/>
toujours la même valeur pour le même argument. f2<br/>
a un effet de bord (print), f3 modifie son<br/>
argument, f4 retourne un résultat différent à<br/>
chaque appel.</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/>
`<code>python<br/>
list(map(lambda x: x ** 2, [1, 2, 3, 4]))<br/>
</code>`</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 [x ** 2 for x in [1, 2, 3, 4]], 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>[1, 4, 9, 16]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la lambda calcule le carré, et map<br/>
l'applique à chaque élément. On obtient<br/>
[1², 2², 3², 4²] = [1, 4, 9, 16].</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[1, 2, 3, 4]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : map applique la fonction à chaque<br/>
élément, donc transforme la liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[2, 4, 6, 8]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait lambda x: x * 2, pas x <strong> 2.<br/>
</strong> est l'opérateur <strong>puissance</strong> en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[1, 16]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : map applique à <strong>chaque</strong> élément, on<br/>
n'en perd pas en chemin.</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/>
`<code>python<br/>
list(filter(lambda x: x % 2 == 0, range(10)))<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Équivalent en compréhension de liste :<br/>
[x for x in range(10) if x % 2 == 0]. 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>[1, 3, 5, 7, 9]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : x % 2 == 0 teste si x est <strong>pair</strong>.<br/>
Donc on garde les pairs, pas les impairs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>[0, 2, 4, 6, 8]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : filter conserve les éléments pour<br/>
lesquels la condition est vraie. range(10) produit<br/>
0, 1, \ldots, 9 ; on garde les pairs 0, 2, 4, 6, 8.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[0, 1, 2, ..., 9]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait range(10) complet, sans filtre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il y a bien des nombres pairs dans<br/>
range(10).</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/>
à list(map(lambda x: x * 2, filter(lambda x: x &gt; 0, L))) ?</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 map et filter en<br/>
une seule expression. Pour réduire une liste à une<br/>
valeur unique, on utilise sum, max, min, 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>[x for x in L * 2]</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="100" format="html">
    <text><![CDATA[<p>[x * 2 for x in L if x &gt; 0]</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>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[x &gt; 0 * 2 for x in L]</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>[L if x &gt; 0 for x in L]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : syntaxe incorrecte de compréhension.</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, sorted(L, key=f)<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 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>
  <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 : map, filter et sorted (avec key)<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 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="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>
</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 resultat après l'exécution de ce programme ?</p>
<p>``python<br/>
def ajouter(a, b):<br/>
    return a + b</p>
<p>def multiplier(a, b):<br/>
    return a * b</p>
<p>operations = {"+": ajouter, "<em>": multiplier}<br/>
resultat = operations["</em>"](4, 5)<br/>
``</p>]]></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/>
operations["*"](4, 5) revient à multiplier(4, 5), 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>La fonction multiplier elle-même, sans l'appeler</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : operations["*"] seul serait la fonction, mais il est<br/>
suivi de (4, 5), qui provoque son appel. resultat reçoit donc la<br/>
valeur renvoyée, 20.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>9</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 9 serait le résultat de ajouter(4, 5), rangée sous la<br/>
clé "+". La clé "*" désigne multiplier.</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>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>20</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : operations["*"] désigne la fonction multiplier,<br/>
et les parenthèses (4, 5) l'appellent aussitôt : multiplier(4, 5)<br/>
renvoie 20.</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/>
`<code>python<br/>
taux = 0.1<br/>
def remise(prix):<br/>
    return prix - prix * taux<br/>
a = remise(200)<br/>
taux = 0.5<br/>
b = remise(200)<br/>
</code><br/>
Que valent a et b`, 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 taux, remise renvoie des valeurs différentes<br/>
pour un même prix dès que taux change. Pour la rendre pure, on<br/>
passe le taux en paramètre : remise(prix, taux).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur : taux n'est pas défini à l'intérieur de remise</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une fonction peut lire une variable définie en dehors d'elle<br/>
sans global. Le mot-clé global n'est nécessaire que pour la<br/>
modifier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>180.0 et 180.0 : taux est lu une fois, à la définition</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python lit taux au moment de chaque appel, pas lors de la<br/>
définition de remise. Le second appel utilise donc 0.5 et<br/>
renvoie 100.0.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>180.0 et 100.0 : remise 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/>
remise(200) vaut 180.0 puis 100.0.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>180.0 et 100.0 : remise n'est pas une fonction pure</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la valeur de taux 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>
</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>
<p>`<code>python<br/>
total = 0<br/>
for x in L:<br/>
    if x &gt; 0:<br/>
        total += x ** 2<br/>
</code>`</p>]]></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>for x in L: total += x ** 2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est une boucle impérative qui modifie<br/>
total. On veut s'en abstraire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>list(map(lambda x: x ** 2, filter(lambda x: x &gt; 0, L)))</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 L = [2, -1, 3], elle donne [4, 9]<br/>
au lieu de 13.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>sum(x ** 2 if x &gt; 0 for x in L)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : syntaxe invalide. x ** 2 if x &gt; 0 sans else<br/>
n'est pas une expression correcte : le filtre se place<br/>
après le for, sous la forme for x in L if x &gt; 0.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>sum(x ** 2 for x in L if x &gt; 0)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le filtre if x &gt; 0 écarte les valeurs<br/>
négatives ou nulles, x ** 2 transforme chaque valeur<br/>
retenue et sum additionne le tout. Pas de variable<br/>
modifiée, pas de boucle explicite.</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 L, l'appel somme(L, 0) 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 i + 1. En Python, le nombre d'appels imbriqués<br/>
est limité : pour de très longues listes, on préfère sum.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def somme(L, i):<br/>
    if i == len(L):<br/>
        return 0<br/>
    return L[i] + somme(L, i + 1)<br/>
</code>`</p>]]></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 L[i] à la somme des<br/>
éléments suivants. Aucune boucle, aucune variable modifiée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def somme(L, i):<br/>
    if i == len(L) - 1:<br/>
        return 0<br/>
    return L[i] + somme(L, i + 1)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le cas de base renvoie 0 sur le dernier indice au lieu<br/>
d'ajouter L[i], si bien que le dernier élément est oublié :<br/>
somme([1, 2, 3], 0) renvoie 3 au lieu de 6.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def somme(L, i):<br/>
    return L[i] + somme(L, i + 1)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il manque le cas de base. Quand i atteint len(L),<br/>
L[i] n'existe pas : somme([1, 2, 3], 0) lève IndexError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def somme(L, i):<br/>
    total = 0<br/>
    for j in range(i, len(L)):<br/>
        total = total + L[j]<br/>
    return total<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le résultat est juste, mais la fonction utilise une boucle<br/>
et une variable total modifiée à chaque tour. C'est l'écriture<br/>
impérative, pas récursive.</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 for pour<br/>
parcourir une liste, puis appelle sorted 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, map,<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>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>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>Un seul, l'impératif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle for est bien impérative,<br/>
mais l'usage de sorted 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 nombres. 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 sum, map, filter<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="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
total = sum(n * n for n in nombres)<br/>
</code>`</p>]]></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/>
sum. Pas d'effet de bord.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
total = 0<br/>
for n in nombres:<br/>
    total = total + n * n<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce code est <strong>impératif</strong> : il modifie<br/>
une variable total à chaque itération.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
total = nombres<br/>
</code>`</p>]]></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="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
class Sommateur:<br/>
    def __init__(self):<br/>
        self.total = 0<br/>
    def ajouter(self, n):<br/>
        self.total += n * n<br/>
</code>`</p>]]></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>
</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 map 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 [p * 0.9 for p in prix] 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>Aucun paradigme : il faut tout écrire à la main, avec des goto</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il n'existe pas de goto en Python, et<br/>
aucun paradigme moderne ne le promeut.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une approche objet avec une classe Remiseur et une méthode appliquer</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>
</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 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>
  <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>
</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 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>
  <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>
</question>

<question type="multichoice">
  <name>
    <text>Programmation fonctionnelle — Q26 : Une fonction qui affiche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La fonction double est-elle pure ?<br/>
`<code>python<br/>
def double(x):<br/>
    print(x)<br/>
    return 2 * x<br/>
</code>`</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="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>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, car print 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>Oui, le résultat ne dépendant que de x</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la pureté exige aussi l'absence de tout effet<br/>
extérieur, et print en est un.</p>]]></text>
    </feedback>
  </answer>
  <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 x, 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>
</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="0" format="html">
    <text><![CDATA[<p>def ajoute(l, x): l += [x], avec l une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sur une liste, += modifie l'objet existant, comme<br/>
append.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>def ajoute(l, x): l.insert(len(l), x), avec l une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : insert modifie la liste en place.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>def ajoute(t, x): return t + (x,), avec t un tuple</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : t + (x,) construit un nouveau tuple ; t<br/>
reste inchangé pour tous ceux qui le partagent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>def ajoute(l, x): l.append(x), avec l une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : append modifie la liste reçue, visible depuis<br/>
l'appelant.</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="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="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 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 l, 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 sum(l), qui renvoie la somme sans rien changer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sum 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 for accumulant dans total, réaffecté à chaque tour</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : total est réaffecté à chaque tour, c'est le style<br/>
impératif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un l.append(sum(l)) suivi de la lecture de l[-1]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la liste reçoit un élément de plus.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une boucle remplaçant l[0] par l[0] + l[1] et retirant l[1]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la liste est détruite au passage.</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 sans_tete est-elle pure ?<br/>
``python<br/>
def sans_tete(l):<br/>
    l.pop(0)<br/>
    return l</p>
<p>a = [1, 2, 3]<br/>
b = sans_tete(a)<br/>
print(a)<br/>
``</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une version pure construirait une nouvelle liste, l[1:], 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>[2, 3], et la fonction n'est pas pure, elle modifie a</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pop(0) retire le premier élément de la liste<br/>
reçue, qui est a 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>[1, 2, 3], et la fonction n'est pas pure, elle utilise pop</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction n'est effectivement pas pure, mais a a<br/>
bien été modifiée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[1, 2, 3], et la fonction est pure, elle renvoie une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : a et l désignent la même liste, modifiée par<br/>
pop.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[2, 3], 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/>
a.</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="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="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>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="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>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>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>
  <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>
</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/>
``python<br/>
# Version A<br/>
p.deplace(2, 3)</p>
<p># Version B<br/>
q = deplace(p, 2, 3)<br/>
``</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="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="100" format="html">
    <text><![CDATA[<p>La version B, qui renvoie un nouveau point sans toucher à p</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : deplace reçoit p et renvoie un point<br/>
distinct ; p reste disponible tel quel. La version A modifie<br/>
l'état interne de l'objet p.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les deux, puisque toutes deux appellent une fonction deplace</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 p</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="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="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 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>
  <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>
</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/>
``python<br/>
def multiplieur(k):<br/>
    return lambda x: k * x</p>
<p>f = multiplieur(3)<br/>
print(f(5))<br/>
``</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>15</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : multiplieur(3) renvoie une fonction qui<br/>
multiplie son argument par 3 ; f(5) vaut<br/>
3 × 5 = 15.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, k ayant disparu</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction renvoyée conserve la valeur de k, c'est<br/>
une fermeture.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>8</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>3</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : f n'est pas la valeur 3, c'est une fonction qui<br/>
se souvient de 3.</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 sorted(['pomme', 'kiwi', 'banane'], key=len) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le paramètre key de sorted 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="0" format="html">
    <text><![CDATA[<p>['banane', 'kiwi', 'pomme']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait l'ordre alphabétique, sans key.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>['banane', 'pomme', 'kiwi']</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, len 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>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>['kiwi', 'pomme', 'banane']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : key=len indique de comparer les mots par leur<br/>
longueur ; la fonction len est passée en argument, sans être<br/>
appelée.</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/>
``python<br/>
def enchaine(fonctions, x):<br/>
    for f in fonctions:<br/>
        x = f(x)<br/>
    return x</p>
<p>print(enchaine([lambda x: x + 1, lambda x: x * 2], 3))<br/>
``</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="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>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>8</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 × 2 :<br/>
(3 + 1) × 2 = 8.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>4</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>7</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait l'ordre inverse, × 2 puis +1.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
