{
  "chapter": {
    "id": "algorithmique-listes",
    "level": "premiere-specialite",
    "theme": "Algorithmique et programmation",
    "title": "Algorithmique et listes",
    "description": "Notion de liste : générer une liste en extension, par ajouts\nsuccessifs ou en compréhension, manipuler ses éléments et leurs\nindices, la parcourir. Algorithmes du programme : termes, sommes et\nseuils d'une suite, factorielle, suite de Fibonacci, sécantes,\nméthode de Newton, méthode d'Euler, Monte-Carlo, espérance.",
    "parties": [
      {
        "id": "listes",
        "title": "Générer et manipuler une liste"
      },
      {
        "id": "parcours",
        "title": "Parcourir une liste"
      },
      {
        "id": "suites",
        "title": "Suites et algorithmes"
      },
      {
        "id": "methodes",
        "title": "Méthodes numériques et probabilités"
      }
    ],
    "prerequisites": [],
    "references": []
  },
  "questions": [
    {
      "id": "q01",
      "difficulty": 1,
      "skills": [
        "liste",
        "indice"
      ],
      "title": "Le premier élément d'une liste",
      "partie": "listes",
      "statement": "On pose `L = [4, 9, 2, 7]`. Que vaut `L[1]` ?",
      "options": [
        {
          "text": "$9$",
          "correct": true,
          "feedback": "Bonne réponse : les indices commencent à $0$. `L[0]` vaut $4$ et\n`L[1]` vaut $9$."
        },
        {
          "text": "$4$",
          "correct": false,
          "feedback": "Erreur : $4$ est `L[0]`. Le premier élément porte l'indice $0$."
        },
        {
          "text": "$2$",
          "correct": false,
          "feedback": "Erreur : $2$ est `L[2]`, le troisième élément de la liste."
        },
        {
          "text": "$1$",
          "correct": false,
          "feedback": "Erreur : `L[1]` désigne l'élément d'indice $1$, pas le nombre\n$1$."
        }
      ],
      "explanation": "Dans une liste de $n$ éléments, les indices vont de $0$ à $n - 1$ :\n`L[0]` est le premier élément, `L[n - 1]` le dernier."
    },
    {
      "id": "q02",
      "difficulty": 1,
      "skills": [
        "liste",
        "longueur"
      ],
      "title": "Longueur et dernier élément",
      "partie": "listes",
      "statement": "On pose `L = [3, 8, 5, 1, 6]`. Quelle expression désigne le dernier\nélément de `L` ?",
      "options": [
        {
          "text": "`L[len(L) - 1]`",
          "correct": true,
          "feedback": "Bonne réponse : `len(L)` vaut $5$, et le dernier indice est\n$5 - 1 = 4$ : `L[4]` vaut $6$."
        },
        {
          "text": "`L[len(L)]`",
          "correct": false,
          "feedback": "Erreur : l'indice $5$ n'existe pas, ce qui provoque une erreur\nd'exécution. Les indices s'arrêtent à $4$."
        },
        {
          "text": "`len(L)`",
          "correct": false,
          "feedback": "Erreur : `len(L)` est le nombre d'éléments, ici $5$, pas le\ndernier élément."
        },
        {
          "text": "`L[len(L) - 2]`",
          "correct": false,
          "feedback": "Erreur : l'indice $5 - 2 = 3$ désigne l'avant-dernier élément, $1$."
        }
      ],
      "explanation": "`len(L)` renvoie le nombre d'éléments. Le dernier élément est\n`L[len(L) - 1]`."
    },
    {
      "id": "q03",
      "difficulty": 1,
      "skills": [
        "liste",
        "ajout"
      ],
      "title": "Ajouter un élément",
      "partie": "listes",
      "statement": "Que contient `L` après ces instructions ?\n\n```python\nL = [5, 2]\nL.append(8)\nL.append(1)\n```",
      "options": [
        {
          "text": "`[5, 2, 8, 1]`",
          "correct": true,
          "feedback": "Bonne réponse : `append` ajoute l'élément à la fin de la liste,\ndans l'ordre des instructions."
        },
        {
          "text": "`[8, 1, 5, 2]`",
          "correct": false,
          "feedback": "Erreur : `append` ajoute en fin de liste, pas au début."
        },
        {
          "text": "`[5, 2, 9]`",
          "correct": false,
          "feedback": "Erreur : les éléments ajoutés ne s'additionnent pas. Chacun\ndevient un nouvel élément."
        },
        {
          "text": "`[1, 2, 5, 8]`",
          "correct": false,
          "feedback": "Erreur : une liste ne se trie pas d'elle-même. L'ordre des\najouts est conservé."
        }
      ],
      "explanation": "`L.append(x)` ajoute `x` à la fin de `L`. Partir de `[]` puis\najouter dans une boucle, c'est générer une liste par ajouts\nsuccessifs."
    },
    {
      "id": "q04",
      "difficulty": 2,
      "skills": [
        "liste",
        "comprehension"
      ],
      "title": "Une liste en compréhension",
      "partie": "listes",
      "statement": "Que contient la liste `[k ** 2 for k in range(5)]` ?",
      "options": [
        {
          "text": "`[0, 1, 4, 9, 16]`",
          "correct": true,
          "feedback": "Bonne réponse : `k` parcourt $0$, $1$, $2$, $3$, $4$, et la\nliste contient leurs carrés."
        },
        {
          "text": "`[1, 4, 9, 16, 25]`",
          "correct": false,
          "feedback": "Erreur : `range(5)` commence à $0$ et s'arrête à $4$. Le carré\nde $5$ n'y figure pas."
        },
        {
          "text": "`[0, 2, 4, 6, 8]`",
          "correct": false,
          "feedback": "Erreur : `k ** 2` est le carré de `k`, pas son double."
        },
        {
          "text": "`[0, 1, 2, 3, 4]`",
          "correct": false,
          "feedback": "Erreur : ce sont les valeurs de `k`, avant d'appliquer\nl'expression `k ** 2`."
        }
      ],
      "explanation": "`[expression for k in range(n)]` construit la liste des valeurs de\nl'expression pour `k` allant de $0$ à $n - 1$."
    },
    {
      "id": "q05",
      "difficulty": 2,
      "skills": [
        "liste",
        "comprehension",
        "condition"
      ],
      "title": "Une compréhension avec condition",
      "partie": "listes",
      "statement": "Que contient la liste `[n for n in range(1, 20) if n % 4 == 0]` ?",
      "options": [
        {
          "text": "`[4, 8, 12, 16]`",
          "correct": true,
          "feedback": "Bonne réponse : on garde les entiers de $1$ à $19$ dont le reste\ndans la division par $4$ est nul, c'est-à-dire les multiples de\n$4$."
        },
        {
          "text": "`[4, 8, 12, 16, 20]`",
          "correct": false,
          "feedback": "Erreur : `range(1, 20)` s'arrête à $19$. L'entier $20$ n'est pas\nexaminé."
        },
        {
          "text": "`[0, 4, 8, 12, 16]`",
          "correct": false,
          "feedback": "Erreur : le parcours commence à $1$, donc $0$ n'est pas examiné."
        },
        {
          "text": "`[1, 2, 3, 4]`",
          "correct": false,
          "feedback": "Erreur : la condition filtre les entiers, elle ne compte pas les\nmultiples."
        }
      ],
      "explanation": "La condition placée après `if` filtre les valeurs : c'est la\ntraduction en Python d'un ensemble défini par une propriété,\n$\\{n \\in \\{1, \\ldots, 19\\} \\mid 4 \\text{ divise } n\\}$."
    },
    {
      "id": "q06",
      "difficulty": 2,
      "skills": [
        "liste",
        "modification"
      ],
      "title": "Modifier un élément par son indice",
      "partie": "listes",
      "statement": "Que contient `L` après ces instructions ?\n\n```python\nL = [10, 20, 30, 40]\nL[2] = L[0] + L[3]\n```",
      "options": [
        {
          "text": "`[10, 20, 50, 40]`",
          "correct": true,
          "feedback": "Bonne réponse : `L[0] + L[3]` vaut $10 + 40 = 50$, et cette\nvaleur remplace l'élément d'indice $2$, qui valait $30$."
        },
        {
          "text": "`[10, 50, 30, 40]`",
          "correct": false,
          "feedback": "Erreur : l'élément d'indice $2$ est le troisième. C'est $30$ qui\nest remplacé, pas $20$."
        },
        {
          "text": "`[10, 20, 30, 40, 50]`",
          "correct": false,
          "feedback": "Erreur : une affectation `L[2] = …` remplace un élément, elle\nn'ajoute rien à la liste."
        },
        {
          "text": "`[10, 20, 60, 40]`",
          "correct": false,
          "feedback": "Erreur : `L[3]` vaut $40$ et non $30$ : les indices commencent\nà $0$."
        }
      ],
      "explanation": "`L[i] = valeur` remplace l'élément d'indice `i`. La longueur de la\nliste ne change pas."
    },
    {
      "id": "q07",
      "difficulty": 2,
      "skills": [
        "liste",
        "suppression"
      ],
      "title": "Supprimer un élément",
      "partie": "listes",
      "statement": "Que contient `L` après ces instructions ?\n\n```python\nL = [7, 3, 9, 3]\nL.remove(3)\n```",
      "options": [
        {
          "text": "`[7, 9, 3]`",
          "correct": true,
          "feedback": "Bonne réponse : `remove(3)` supprime la **première** occurrence\nde la valeur $3$ seulement."
        },
        {
          "text": "`[7, 9]`",
          "correct": false,
          "feedback": "Erreur : `remove` ne supprime qu'une occurrence, la première\nrencontrée."
        },
        {
          "text": "`[7, 3, 3]`",
          "correct": false,
          "feedback": "Erreur : `remove(3)` supprime la valeur $3$, pas l'élément\nd'indice $3$ ni celui d'indice $2$."
        },
        {
          "text": "`[7, 3, 9]`",
          "correct": false,
          "feedback": "Erreur : c'est la première occurrence de $3$ qui disparaît, pas\nla dernière."
        }
      ],
      "explanation": "`L.remove(x)` retire la première occurrence de la valeur `x` ;\n`del L[i]` retire l'élément d'indice `i`."
    },
    {
      "id": "q08",
      "difficulty": 3,
      "skills": [
        "liste",
        "ajouts-successifs"
      ],
      "title": "Générer une liste par ajouts successifs",
      "partie": "listes",
      "statement": "Que contient `L` à la fin de ce programme ?\n\n```python\nL = []\nfor k in range(1, 5):\n    L.append(3 * k - 1)\n```",
      "options": [
        {
          "text": "`[2, 5, 8, 11]`",
          "correct": true,
          "feedback": "Bonne réponse : pour `k` de $1$ à $4$, on ajoute $3k - 1$, soit\n$2$, $5$, $8$ et $11$."
        },
        {
          "text": "`[-1, 2, 5, 8]`",
          "correct": false,
          "feedback": "Erreur : le parcours commence à $k = 1$ et non à $k = 0$."
        },
        {
          "text": "`[2, 5, 8, 11, 14]`",
          "correct": false,
          "feedback": "Erreur : `range(1, 5)` s'arrête à $4$. La valeur $k = 5$ n'est\npas prise."
        },
        {
          "text": "`[11]`",
          "correct": false,
          "feedback": "Erreur : `append` ajoute un élément à chaque tour, sans effacer\nles précédents."
        }
      ],
      "explanation": "Le même résultat s'obtient en compréhension :\n`[3 * k - 1 for k in range(1, 5)]`."
    },
    {
      "id": "q09",
      "difficulty": 1,
      "skills": [
        "parcours",
        "iteration"
      ],
      "title": "Itérer sur les éléments",
      "partie": "parcours",
      "statement": "Qu'affiche ce programme ?\n\n```python\ns = 0\nfor x in [4, 1, 6]:\n    s = s + x\nprint(s)\n```",
      "options": [
        {
          "text": "$11$",
          "correct": true,
          "feedback": "Bonne réponse : `x` prend successivement les valeurs $4$, $1$ et\n$6$, que l'on additionne."
        },
        {
          "text": "$24$",
          "correct": false,
          "feedback": "Erreur : les éléments sont additionnés, pas multipliés. La\nvariable `s` part de $0$ et reçoit `s + x`."
        },
        {
          "text": "$6$",
          "correct": false,
          "feedback": "Erreur : `s` accumule toutes les valeurs, elle ne garde pas\nseulement la dernière."
        },
        {
          "text": "$3$, soit $0 + 1 + 2$",
          "correct": false,
          "feedback": "Erreur : `for x in L` parcourt les **éléments** de la liste, pas\nses indices."
        }
      ],
      "explanation": "`for x in L:` donne à `x` chacun des éléments de `L`, dans l'ordre.\nOn parle d'itération sur les éléments."
    },
    {
      "id": "q10",
      "difficulty": 2,
      "skills": [
        "parcours",
        "indices"
      ],
      "title": "Parcourir par les indices",
      "partie": "parcours",
      "statement": "Qu'affiche ce programme ?\n\n```python\nL = [5, 8, 2, 9]\nfor i in range(len(L)):\n    if L[i] > 6:\n        print(i)\n```",
      "options": [
        {
          "text": "`1` puis `3`",
          "correct": true,
          "feedback": "Bonne réponse : les éléments supérieurs à $6$ sont $8$ et $9$,\nd'indices $1$ et $3$. Le programme affiche les indices."
        },
        {
          "text": "`8` puis `9`",
          "correct": false,
          "feedback": "Erreur : le programme affiche `i`, l'indice, et non `L[i]`,\nl'élément."
        },
        {
          "text": "`2` puis `4`",
          "correct": false,
          "feedback": "Erreur : ce seraient les positions en comptant à partir de $1$.\nLes indices Python commencent à $0$."
        },
        {
          "text": "`2`",
          "correct": false,
          "feedback": "Erreur : $2$ est le nombre d'éléments supérieurs à $6$, mais le\nprogramme affiche chaque indice trouvé."
        }
      ],
      "explanation": "`for i in range(len(L))` parcourt les indices ; on accède à\nl'élément par `L[i]`. Ce parcours sert quand la position compte."
    },
    {
      "id": "q11",
      "difficulty": 2,
      "skills": [
        "parcours",
        "maximum"
      ],
      "title": "Chercher le maximum",
      "partie": "parcours",
      "statement": "La fonction suivante doit renvoyer le plus grand élément d'une liste\nnon vide. Quelle ligne compléter ?\n\n```python\ndef maximum(L):\n    m = L[0]\n    for x in L:\n        if x > m:\n            ...\n    return m\n```",
      "options": [
        {
          "text": "`m = x`",
          "correct": true,
          "feedback": "Bonne réponse : dès qu'un élément dépasse le maximum provisoire,\nil le remplace."
        },
        {
          "text": "`x = m`",
          "correct": false,
          "feedback": "Erreur : l'affectation est à l'envers. `m` ne change jamais et\nreste égal à `L[0]`."
        },
        {
          "text": "`return x`",
          "correct": false,
          "feedback": "Erreur : la fonction s'arrêterait au premier élément plus grand\nque `L[0]`, sans examiner la suite."
        },
        {
          "text": "`m = m + x`",
          "correct": false,
          "feedback": "Erreur : `m` deviendrait une somme partielle, pas un maximum."
        }
      ],
      "explanation": "Recherche d'un maximum : on part du premier élément, on parcourt la\nliste et on met à jour la valeur retenue à chaque élément plus grand."
    },
    {
      "id": "q12",
      "difficulty": 2,
      "skills": [
        "parcours",
        "frequence"
      ],
      "title": "Compter des occurrences",
      "partie": "parcours",
      "statement": "Que renvoie `compte([1, 3, 1, 1, 2], 1)` ?\n\n```python\ndef compte(L, v):\n    c = 0\n    for x in L:\n        if x == v:\n            c = c + 1\n    return c / len(L)\n```",
      "options": [
        {
          "text": "$0{,}6$",
          "correct": true,
          "feedback": "Bonne réponse : la valeur $1$ apparaît $3$ fois sur $5$\néléments. La fonction renvoie la fréquence $\\dfrac{3}{5}$."
        },
        {
          "text": "$3$",
          "correct": false,
          "feedback": "Erreur : $3$ est l'effectif. La division par `len(L)` le\ntransforme en fréquence."
        },
        {
          "text": "$0{,}2$",
          "correct": false,
          "feedback": "Erreur : le compteur augmente à chaque occurrence, pas une seule\nfois."
        },
        {
          "text": "$1{,}6$",
          "correct": false,
          "feedback": "Erreur : la fonction compte les éléments égaux à `v`, elle\nn'additionne pas les valeurs."
        }
      ],
      "explanation": "Cette fonction calcule la fréquence d'une valeur dans une série. Le\nmême principe sert à étudier la fréquence des lettres d'un texte."
    },
    {
      "id": "q13",
      "difficulty": 3,
      "skills": [
        "parcours",
        "moyenne"
      ],
      "title": "Moyenne d'une série avec effectifs",
      "partie": "parcours",
      "statement": "Les listes `V` et `E` contiennent les valeurs d'une série et leurs\neffectifs. Que renvoie `moy([2, 5, 10], [3, 1, 1])` ?\n\n```python\ndef moy(V, E):\n    s = 0\n    for i in range(len(V)):\n        s = s + V[i] * E[i]\n    return s / sum(E)\n```",
      "options": [
        {
          "text": "$4{,}2$",
          "correct": true,
          "feedback": "Bonne réponse : $2 \\times 3 + 5 \\times 1 + 10 \\times 1 = 21$,\ndivisé par l'effectif total $5$."
        },
        {
          "text": "$5{,}\\overline{6}$",
          "correct": false,
          "feedback": "Erreur : c'est la moyenne des trois valeurs sans tenir compte\ndes effectifs."
        },
        {
          "text": "$21$",
          "correct": false,
          "feedback": "Erreur : $21$ est la somme pondérée. Il reste à la diviser par\nl'effectif total."
        },
        {
          "text": "$7$",
          "correct": false,
          "feedback": "Erreur : la somme pondérée est divisée par l'effectif total,\n`sum(E)`, et non par le nombre de valeurs distinctes."
        }
      ],
      "explanation": "Moyenne pondérée : $\\bar{x} = \\dfrac{\\sum n_i x_i}{\\sum n_i}$. Le\nparcours par indices permet d'associer chaque valeur à son effectif."
    },
    {
      "id": "q14",
      "difficulty": 3,
      "skills": [
        "parcours",
        "esperance"
      ],
      "title": "Espérance d'une loi donnée par deux listes",
      "partie": "parcours",
      "statement": "Une variable aléatoire prend les valeurs de la liste `X` avec les\nprobabilités de la liste `P`. Quelle fonction renvoie son\nespérance ?",
      "options": [
        {
          "text": "```python\ndef esperance(X, P):\n    return sum([X[i] * P[i] for i in range(len(X))])\n```",
          "correct": true,
          "feedback": "Bonne réponse : $E = \\sum x_i \\, p_i$. La liste en compréhension\ncontient les produits, `sum` les additionne."
        },
        {
          "text": "```python\ndef esperance(X, P):\n    return sum(X) / len(X)\n```",
          "correct": false,
          "feedback": "Erreur : c'est la moyenne des valeurs, qui ignore les\nprobabilités. Elle ne coïncide avec l'espérance que dans le cas\néquiprobable."
        },
        {
          "text": "```python\ndef esperance(X, P):\n    return sum(X) * sum(P)\n```",
          "correct": false,
          "feedback": "Erreur : `sum(P)` vaut $1$, donc cette fonction renvoie la somme\ndes valeurs, sans pondération."
        },
        {
          "text": "```python\ndef esperance(X, P):\n    return sum([X[i] * P[i] for i in range(len(X))]) / len(X)\n```",
          "correct": false,
          "feedback": "Erreur : la somme des $x_i \\, p_i$ est déjà l'espérance ; la\ndivision par le nombre de valeurs est de trop."
        }
      ],
      "explanation": "L'espérance est la somme des produits valeur × probabilité. Les\nprobabilités ont une somme égale à $1$, d'où l'absence de division."
    },
    {
      "id": "q15",
      "difficulty": 1,
      "skills": [
        "suite",
        "recurrence"
      ],
      "title": "Calculer un terme par une boucle",
      "partie": "suites",
      "statement": "La suite $(u_n)$ vérifie $u_0 = 3$ et $u_{n+1} = u_n + 2$.\nQue renvoie `terme(3)` ?\n\n```python\ndef terme(n):\n    u = 3\n    for i in range(n):\n        u = u + (2)\n    return u\n```",
      "options": [
        {
          "text": "$9$",
          "correct": true,
          "feedback": "Bonne réponse : la boucle fait $3$ tours et passe de $u_0$ à\n$u_{3}$."
        },
        {
          "text": "$7$",
          "correct": false,
          "feedback": "Erreur : $7$ est $u_{3 - 1}$. La boucle fait bien $3$\ntours."
        },
        {
          "text": "$11$",
          "correct": false,
          "feedback": "Erreur : un tour de trop. `range(3)` produit $3$ valeurs de\n`i`."
        },
        {
          "text": "$24$",
          "correct": false,
          "feedback": "Erreur : la suite est arithmétique. On ajoute la raison à chaque\ntour, on ne multiplie pas."
        }
      ],
      "explanation": "Pour calculer $u_n$ à partir d'une relation de récurrence, on\ninitialise avec $u_0$ et l'on applique $n$ fois la relation.",
      "variants": [
        {
          "statement": "La suite $(u_n)$ vérifie $u_0 = 3$ et $u_{n+1} = u_n + 2$.\nQue renvoie `terme(3)` ?\n\n```python\ndef terme(n):\n    u = 3\n    for i in range(n):\n        u = u + (2)\n    return u\n```",
          "options": [
            {
              "text": "$9$",
              "correct": true,
              "feedback": "Bonne réponse : la boucle fait $3$ tours et passe de $u_0$ à\n$u_{3}$."
            },
            {
              "text": "$7$",
              "correct": false,
              "feedback": "Erreur : $7$ est $u_{3 - 1}$. La boucle fait bien $3$\ntours."
            },
            {
              "text": "$11$",
              "correct": false,
              "feedback": "Erreur : un tour de trop. `range(3)` produit $3$ valeurs de\n`i`."
            },
            {
              "text": "$24$",
              "correct": false,
              "feedback": "Erreur : la suite est arithmétique. On ajoute la raison à chaque\ntour, on ne multiplie pas."
            }
          ],
          "explanation": "Pour calculer $u_n$ à partir d'une relation de récurrence, on\ninitialise avec $u_0$ et l'on applique $n$ fois la relation."
        },
        {
          "statement": "La suite $(u_n)$ vérifie $u_0 = 1$ et $u_{n+1} = u_n + 5$.\nQue renvoie `terme(4)` ?\n\n```python\ndef terme(n):\n    u = 1\n    for i in range(n):\n        u = u + (5)\n    return u\n```",
          "options": [
            {
              "text": "$21$",
              "correct": true,
              "feedback": "Bonne réponse : la boucle fait $4$ tours et passe de $u_0$ à\n$u_{4}$."
            },
            {
              "text": "$16$",
              "correct": false,
              "feedback": "Erreur : $16$ est $u_{4 - 1}$. La boucle fait bien $4$\ntours."
            },
            {
              "text": "$26$",
              "correct": false,
              "feedback": "Erreur : un tour de trop. `range(4)` produit $4$ valeurs de\n`i`."
            },
            {
              "text": "$625$",
              "correct": false,
              "feedback": "Erreur : la suite est arithmétique. On ajoute la raison à chaque\ntour, on ne multiplie pas."
            }
          ],
          "explanation": "Pour calculer $u_n$ à partir d'une relation de récurrence, on\ninitialise avec $u_0$ et l'on applique $n$ fois la relation."
        },
        {
          "statement": "La suite $(u_n)$ vérifie $u_0 = 10$ et $u_{n+1} = u_n - 3$.\nQue renvoie `terme(3)` ?\n\n```python\ndef terme(n):\n    u = 10\n    for i in range(n):\n        u = u + (-3)\n    return u\n```",
          "options": [
            {
              "text": "$1$",
              "correct": true,
              "feedback": "Bonne réponse : la boucle fait $3$ tours et passe de $u_0$ à\n$u_{3}$."
            },
            {
              "text": "$4$",
              "correct": false,
              "feedback": "Erreur : $4$ est $u_{3 - 1}$. La boucle fait bien $3$\ntours."
            },
            {
              "text": "$-2$",
              "correct": false,
              "feedback": "Erreur : un tour de trop. `range(3)` produit $3$ valeurs de\n`i`."
            },
            {
              "text": "$-270$",
              "correct": false,
              "feedback": "Erreur : la suite est arithmétique. On ajoute la raison à chaque\ntour, on ne multiplie pas."
            }
          ],
          "explanation": "Pour calculer $u_n$ à partir d'une relation de récurrence, on\ninitialise avec $u_0$ et l'on applique $n$ fois la relation."
        }
      ]
    },
    {
      "id": "q16",
      "difficulty": 2,
      "skills": [
        "suite",
        "liste-termes"
      ],
      "title": "Liste des premiers termes",
      "partie": "suites",
      "statement": "Que renvoie `termes(4)` ?\n\n```python\ndef termes(n):\n    u = 1\n    L = [u]\n    for i in range(n):\n        u = 2 * u + 1\n        L.append(u)\n    return L\n```",
      "options": [
        {
          "text": "`[1, 3, 7, 15, 31]`",
          "correct": true,
          "feedback": "Bonne réponse : la liste contient $u_0 = 1$, puis les $4$ termes\nsuivants calculés par $u_{n+1} = 2u_n + 1$."
        },
        {
          "text": "`[3, 7, 15, 31]`",
          "correct": false,
          "feedback": "Erreur : la liste est initialisée avec $u_0$ avant la boucle, il\nfaut le compter."
        },
        {
          "text": "`[1, 3, 7, 15]`",
          "correct": false,
          "feedback": "Erreur : la boucle fait $4$ tours et ajoute $4$ termes à $u_0$ :\nla liste en contient $5$."
        },
        {
          "text": "`[1, 3, 5, 7, 9]`",
          "correct": false,
          "feedback": "Erreur : chaque terme est le double du précédent augmenté de\n$1$ ; ajouter $2$ à chaque fois donnerait une suite\narithmétique."
        }
      ],
      "explanation": "Pour obtenir la liste $[u_0, \\ldots, u_n]$, on range $u_0$ dans la\nliste, puis on ajoute chaque nouveau terme dans la boucle."
    },
    {
      "id": "q17",
      "difficulty": 2,
      "skills": [
        "suite",
        "somme"
      ],
      "title": "Somme des termes d'une suite",
      "partie": "suites",
      "statement": "Que renvoie `somme(3)` ?\n\n```python\ndef somme(n):\n    u = 2\n    s = 0\n    for k in range(n + 1):\n        s = s + u\n        u = 3 * u\n    return s\n```",
      "options": [
        {
          "text": "$80$",
          "correct": true,
          "feedback": "Bonne réponse : on additionne $u_0$ à $u_3$ de la suite\ngéométrique de premier terme $2$ et de raison $3$ :\n$2 + 6 + 18 + 54 = 80$."
        },
        {
          "text": "$26$",
          "correct": false,
          "feedback": "Erreur : `range(n + 1)` fait $4$ tours pour $n = 3$, donc quatre\ntermes sont additionnés, pas trois."
        },
        {
          "text": "$54$",
          "correct": false,
          "feedback": "Erreur : $54$ est le terme $u_3$. La fonction renvoie la somme\ndes termes."
        },
        {
          "text": "$242$",
          "correct": false,
          "feedback": "Erreur : le terme $162$ est calculé au dernier tour, mais après\nl'ajout, donc il n'entre pas dans la somme."
        }
      ],
      "explanation": "La formule donne le même résultat :\n$2 \\times \\dfrac{3^4 - 1}{3 - 1} = 80$. L'ordre des deux\ninstructions dans la boucle décide des termes additionnés."
    },
    {
      "id": "q18",
      "difficulty": 3,
      "skills": [
        "suite",
        "seuil"
      ],
      "title": "Un algorithme de seuil décroissant",
      "partie": "suites",
      "statement": "Une population de $5\\,000$ individus diminue de $10\\ \\%$ par an. Que\nrenvoie la fonction suivante ?\n\n```python\ndef seuil():\n    p = 5000\n    n = 0\n    while p >= 2500:\n        p = 0.9 * p\n        n = n + 1\n    return n\n```",
      "options": [
        {
          "text": "Le premier rang où la population passe sous $2\\,500$",
          "correct": true,
          "feedback": "Bonne réponse : la boucle s'arrête dès que $p < 2\\,500$, et `n`\ncompte les années écoulées. On trouve $n = 7$."
        },
        {
          "text": "La population restante après $2\\,500$ années",
          "correct": false,
          "feedback": "Erreur : $2\\,500$ est un seuil de population, et la fonction\nrenvoie `n`, un nombre d'années."
        },
        {
          "text": "La dernière année où la population dépasse $2\\,500$",
          "correct": false,
          "feedback": "Erreur : à la sortie de la boucle, la condition `p >= 2500` est\nfausse : l'année renvoyée est la première sous le seuil."
        },
        {
          "text": "Le nombre d'individus perdus chaque année",
          "correct": false,
          "feedback": "Erreur : la perte annuelle n'est pas calculée. `n` compte les\ntours de boucle, donc les années."
        }
      ],
      "explanation": "Algorithme de seuil : la boucle `while` tourne tant que le seuil\nn'est pas franchi. Ici $0{,}9^6 \\approx 0{,}53$ et\n$0{,}9^7 \\approx 0{,}48$, d'où $n = 7$."
    },
    {
      "id": "q19",
      "difficulty": 2,
      "skills": [
        "factorielle",
        "boucle"
      ],
      "title": "Calcul d'une factorielle",
      "partie": "suites",
      "statement": "On note $n! = 1 \\times 2 \\times \\cdots \\times n$. Quelle fonction\nrenvoie $n!$ pour un entier $n \\geq 1$ ?",
      "options": [
        {
          "text": "```python\ndef fact(n):\n    p = 1\n    for k in range(1, n + 1):\n        p = p * k\n    return p\n```",
          "correct": true,
          "feedback": "Bonne réponse : le produit démarre à $1$ et `k` parcourt les\nentiers de $1$ à $n$."
        },
        {
          "text": "```python\ndef fact(n):\n    p = 0\n    for k in range(1, n + 1):\n        p = p * k\n    return p\n```",
          "correct": false,
          "feedback": "Erreur : un produit initialisé à $0$ reste nul. Le produit vide\nvaut $1$."
        },
        {
          "text": "```python\ndef fact(n):\n    p = 1\n    for k in range(n):\n        p = p * k\n    return p\n```",
          "correct": false,
          "feedback": "Erreur : `range(n)` commence à $0$, donc le produit vaut $0$ dès\nle premier tour."
        },
        {
          "text": "```python\ndef fact(n):\n    p = 1\n    for k in range(1, n + 1):\n        p = p + k\n    return p\n```",
          "correct": false,
          "feedback": "Erreur : cette fonction calcule une somme, $1 + 1 + 2 + \\cdots +\nn$, et non un produit."
        }
      ],
      "explanation": "Accumulateur de produit : initialisation à $1$, multiplication à\nchaque tour. Pour une somme, on initialise à $0$ et l'on ajoute."
    },
    {
      "id": "q20",
      "difficulty": 3,
      "skills": [
        "fibonacci",
        "liste"
      ],
      "title": "La suite de Fibonacci",
      "partie": "suites",
      "statement": "Que renvoie `fibo(7)` ?\n\n```python\ndef fibo(n):\n    L = [1, 1]\n    while len(L) < n:\n        L.append(L[-1] + L[-2])\n    return L\n```\n\nOn rappelle que `L[-1]` et `L[-2]` désignent le dernier et\nl'avant-dernier élément de `L`.",
      "options": [
        {
          "text": "`[1, 1, 2, 3, 5, 8, 13]`",
          "correct": true,
          "feedback": "Bonne réponse : chaque nouveau terme est la somme des deux\nprécédents, et la boucle s'arrête quand la liste contient $7$\néléments."
        },
        {
          "text": "`[1, 1, 2, 3, 5, 8, 13, 21]`",
          "correct": false,
          "feedback": "Erreur : la condition `len(L) < 7` devient fausse dès que la\nliste compte $7$ éléments. Aucun huitième terme n'est ajouté."
        },
        {
          "text": "`[1, 2, 3, 4, 5, 6, 7]`",
          "correct": false,
          "feedback": "Erreur : on ajoute la somme des deux derniers termes, pas le\nterme précédent augmenté de $1$."
        },
        {
          "text": "`[1, 1, 2, 4, 8, 16, 32]`",
          "correct": false,
          "feedback": "Erreur : chaque terme est la somme des **deux** derniers, pas le\ndouble du dernier."
        }
      ],
      "explanation": "Suite de Fibonacci : $F_0 = F_1 = 1$ et $F_{n+2} = F_{n+1} + F_n$.\nElle modélise le problème des lapins posé par Fibonacci."
    },
    {
      "id": "q21",
      "difficulty": 3,
      "skills": [
        "syracuse",
        "boucle-non-bornee"
      ],
      "title": "Une suite de Syracuse",
      "partie": "suites",
      "statement": "On part de l'entier $6$ et l'on applique la règle suivante : un\nentier pair est divisé par $2$, un entier impair est remplacé par\nson triple augmenté de $1$. Que renvoie `syracuse(6)` ?\n\n```python\ndef syracuse(n):\n    L = [n]\n    while n != 1:\n        if n % 2 == 0:\n            n = n // 2\n        else:\n            n = 3 * n + 1\n        L.append(n)\n    return L\n```",
      "options": [
        {
          "text": "`[6, 3, 10, 5, 16, 8, 4, 2, 1]`",
          "correct": true,
          "feedback": "Bonne réponse : $6 \\to 3 \\to 10 \\to 5 \\to 16 \\to 8 \\to 4 \\to 2\n\\to 1$, et la boucle s'arrête quand $n$ vaut $1$."
        },
        {
          "text": "`[3, 10, 5, 16, 8, 4, 2, 1]`",
          "correct": false,
          "feedback": "Erreur : la liste est initialisée avec la valeur de départ $6$."
        },
        {
          "text": "`[6, 3, 10, 5, 16, 8, 4, 2]`",
          "correct": false,
          "feedback": "Erreur : la valeur $1$ est ajoutée à la liste avant que la\ncondition `n != 1` ne soit testée à nouveau."
        },
        {
          "text": "`[6, 3, 9, 27, 82, 41]`",
          "correct": false,
          "feedback": "Erreur : un entier impair est remplacé par $3n + 1$ : $3$ donne\n$10$, pas $9$."
        }
      ],
      "explanation": "On observe sur les exemples que la suite finit toujours par\natteindre $1$, mais personne n'a jamais su le démontrer : c'est la\nconjecture de Syracuse."
    },
    {
      "id": "q22",
      "difficulty": 2,
      "skills": [
        "secantes",
        "taux-variation"
      ],
      "title": "Les pentes des sécantes",
      "partie": "methodes",
      "statement": "Que renvoie `pentes(1)` pour $f(x) = x^2$ ?\n\n```python\ndef f(x):\n    return x ** 2\n\ndef pentes(a):\n    return [(f(a + h) - f(a)) / h for h in [1, 0.1, 0.01]]\n```",
      "options": [
        {
          "text": "`[3.0, 2.1, 2.01]` environ",
          "correct": true,
          "feedback": "Bonne réponse : le taux de variation de $x^2$ entre $1$ et\n$1 + h$ vaut $2 + h$. Ces pentes se rapprochent de\n$f'(1) = 2$."
        },
        {
          "text": "`[4, 1.21, 1.0201]` environ",
          "correct": false,
          "feedback": "Erreur : ce sont les images $f(1 + h)$, pas les taux de\nvariation."
        },
        {
          "text": "`[2, 2, 2]`",
          "correct": false,
          "feedback": "Erreur : $2$ est la limite des pentes, le nombre dérivé. Les\npentes des sécantes en diffèrent de $h$."
        },
        {
          "text": "`[1, 0.1, 0.01]`",
          "correct": false,
          "feedback": "Erreur : ce sont les valeurs du pas `h`, pas les pentes des\nsécantes."
        }
      ],
      "explanation": "La pente de la sécante entre les points d'abscisses $a$ et $a + h$\nest $\\dfrac{f(a + h) - f(a)}{h}$. Quand $h$ se rapproche de $0$,\nelle se rapproche du nombre dérivé $f'(a)$."
    },
    {
      "id": "q23",
      "difficulty": 3,
      "skills": [
        "newton",
        "tangente"
      ],
      "title": "Une étape de la méthode de Newton",
      "partie": "methodes",
      "statement": "La méthode de Newton approche une solution de $f(x) = 0$ en\nremplaçant $x$ par l'abscisse du point où la tangente en $x$ coupe\nl'axe des abscisses. Pour $f(x) = x^2 - 2$ et $x = 1$, quelle est la\nnouvelle valeur ?",
      "options": [
        {
          "text": "$1{,}5$",
          "correct": true,
          "feedback": "Bonne réponse : la tangente en $1$ a pour équation\n$y = f'(1)(x - 1) + f(1) = 2(x - 1) - 1$ ; elle coupe l'axe pour\n$x = 1{,}5$."
        },
        {
          "text": "$0{,}5$",
          "correct": false,
          "feedback": "Erreur de signe : la nouvelle valeur est\n$x - \\dfrac{f(x)}{f'(x)} = 1 - \\dfrac{-1}{2}$."
        },
        {
          "text": "$2$",
          "correct": false,
          "feedback": "Erreur : la tangente en $1$ a pour pente $f'(1) = 2$, pas $1$.\nOn divise $f(1)$ par cette pente."
        },
        {
          "text": "$\\sqrt{2}$",
          "correct": false,
          "feedback": "Erreur : $\\sqrt{2}$ est la solution cherchée. Une étape de la\nméthode n'en donne qu'une valeur approchée."
        }
      ],
      "explanation": "Une étape de Newton remplace $x$ par $x - \\dfrac{f(x)}{f'(x)}$. Pour\n$x^2 - 2$, les valeurs $1$, $1{,}5$, $1{,}41\\overline{6}$…\ns'approchent très vite de $\\sqrt{2}$."
    },
    {
      "id": "q24",
      "difficulty": 3,
      "skills": [
        "newton",
        "python"
      ],
      "title": "Programmer la méthode de Newton",
      "partie": "methodes",
      "statement": "On définit `f` et sa dérivée `df`. Quelle ligne compléter pour\nprogrammer la méthode de Newton ?\n\n```python\ndef newton(x, n):\n    for i in range(n):\n        ...\n    return x\n```",
      "options": [
        {
          "text": "`x = x - f(x) / df(x)`",
          "correct": true,
          "feedback": "Bonne réponse : c'est l'abscisse du point d'intersection de la\ntangente en $x$ avec l'axe des abscisses."
        },
        {
          "text": "`x = x + f(x) / df(x)`",
          "correct": false,
          "feedback": "Erreur de signe : la tangente coupe l'axe en\n$x - \\dfrac{f(x)}{f'(x)}$."
        },
        {
          "text": "`x = x - df(x) / f(x)`",
          "correct": false,
          "feedback": "Erreur : le quotient est renversé. On divise $f(x)$ par la\npente $f'(x)$."
        },
        {
          "text": "`x = f(x) / df(x)`",
          "correct": false,
          "feedback": "Erreur : il manque le point de départ $x$. On corrige la valeur\nactuelle, on ne la remplace pas par le quotient."
        }
      ],
      "explanation": "La tangente en $x_n$ a pour équation\n$y = f'(x_n)(t - x_n) + f(x_n)$ ; elle s'annule pour\n$t = x_n - \\dfrac{f(x_n)}{f'(x_n)}$, lorsque $f'(x_n) \\neq 0$."
    },
    {
      "id": "q25",
      "difficulty": 3,
      "skills": [
        "euler",
        "exponentielle"
      ],
      "title": "La méthode d'Euler pour l'exponentielle",
      "partie": "methodes",
      "statement": "L'exponentielle vérifie $f' = f$ et $f(0) = 1$. La méthode d'Euler\nde pas $h$ remplace $f(x + h)$ par l'approximation affine\n$f(x) + h f'(x)$. Avec $h = 0{,}5$, quelle valeur approchée de\n$f(1)$ obtient-on en deux pas ?",
      "options": [
        {
          "text": "$2{,}25$",
          "correct": true,
          "feedback": "Bonne réponse : chaque pas multiplie par $1 + h = 1{,}5$ :\n$f(0{,}5) \\approx 1{,}5$ puis $f(1) \\approx 1{,}5^2 = 2{,}25$."
        },
        {
          "text": "$2$",
          "correct": false,
          "feedback": "Erreur : $1 + 0{,}5 + 0{,}5$ ajoute deux fois le même\naccroissement, alors que la pente change : au second pas, elle\nvaut $1{,}5$."
        },
        {
          "text": "$e \\approx 2{,}718$",
          "correct": false,
          "feedback": "Erreur : c'est la valeur exacte. La méthode d'Euler n'en donne\nqu'une approximation, d'autant meilleure que le pas est petit."
        },
        {
          "text": "$1{,}5$",
          "correct": false,
          "feedback": "Erreur : $1{,}5$ approche $f(0{,}5)$. Il faut un second pas pour\natteindre $x = 1$."
        }
      ],
      "explanation": "Pour l'exponentielle, un pas d'Euler donne\n$f(x + h) \\approx (1 + h) f(x)$. En $n$ pas de longueur\n$\\dfrac{1}{n}$, on obtient $\\left(1 + \\dfrac{1}{n}\\right)^n$, qui\nse rapproche de $e$ quand $n$ grandit."
    },
    {
      "id": "q26",
      "difficulty": 2,
      "skills": [
        "euler",
        "suite",
        "e"
      ],
      "title": "Approcher le nombre e",
      "partie": "methodes",
      "statement": "On calcule $\\left(1 + \\dfrac{1}{n}\\right)^n$ pour $n = 10$, $100$,\n$1\\,000$ et on obtient environ $2{,}594$, $2{,}705$ et $2{,}717$. Que\nsuggèrent ces valeurs ?",
      "options": [
        {
          "text": "Elles se rapprochent de $e$",
          "correct": true,
          "feedback": "Bonne réponse : ces valeurs s'approchent de\n$e \\approx 2{,}718$ à mesure que $n$ grandit."
        },
        {
          "text": "Elles se rapprochent de $1$, car $1 + \\dfrac{1}{n}$ tend vers $1$",
          "correct": false,
          "feedback": "Erreur : l'exposant $n$ grandit en même temps. Les valeurs\ncalculées augmentent et s'éloignent de $1$."
        },
        {
          "text": "Elles augmentent sans limite, comme $n$",
          "correct": false,
          "feedback": "Erreur : les écarts entre valeurs successives diminuent\nnettement : rien ne suggère une croissance sans limite."
        },
        {
          "text": "Elles sont toutes égales à $e$",
          "correct": false,
          "feedback": "Erreur : ce sont des valeurs approchées, distinctes et\ncroissantes, qui se rapprochent de $e$ sans l'atteindre."
        }
      ],
      "explanation": "Le programme propose d'approcher $e$ à l'aide de la suite\n$\\left(\\left(1 + \\dfrac{1}{n}\\right)^n\\right)$, lien direct avec la\nméthode d'Euler appliquée à l'exponentielle."
    },
    {
      "id": "q27",
      "difficulty": 2,
      "skills": [
        "monte-carlo",
        "pi"
      ],
      "title": "Estimer pi par Monte-Carlo",
      "partie": "methodes",
      "statement": "Le module `random` est importé. Que renvoie `estime(100000)`,\nenviron ?\n\n```python\ndef estime(n):\n    c = 0\n    for i in range(n):\n        x = random.random()\n        y = random.random()\n        if x ** 2 + y ** 2 <= 1:\n            c = c + 1\n    return 4 * c / n\n```",
      "options": [
        {
          "text": "Une valeur proche de $\\pi$",
          "correct": true,
          "feedback": "Bonne réponse : le quart de disque de rayon $1$ occupe une\nproportion $\\dfrac{\\pi}{4}$ du carré unité. La fréquence\nmultipliée par $4$ approche $\\pi$."
        },
        {
          "text": "Une valeur proche de $\\dfrac{\\pi}{4}$",
          "correct": false,
          "feedback": "Erreur : $\\dfrac{c}{n}$ approche $\\dfrac{\\pi}{4}$, mais la\nfonction multiplie cette fréquence par $4$."
        },
        {
          "text": "Exactement $\\pi$",
          "correct": false,
          "feedback": "Erreur : le résultat dépend du hasard. Il fluctue autour de\n$\\pi$ et varie d'un appel à l'autre."
        },
        {
          "text": "Une valeur proche de $1$",
          "correct": false,
          "feedback": "Erreur : les points ne tombent pas tous dans le quart de disque :\nceux proches du coin $(1\\,;\\,1)$ en sortent."
        }
      ],
      "explanation": "Méthode de Monte-Carlo : on tire des points au hasard dans le carré\n$[0\\,;\\,1] \\times [0\\,;\\,1]$ ; la fréquence des points sous l'arc\nde cercle approche l'aire du quart de disque, $\\dfrac{\\pi}{4}$."
    },
    {
      "id": "q28",
      "difficulty": 3,
      "skills": [
        "monte-carlo",
        "aire"
      ],
      "title": "Aire sous la parabole par Monte-Carlo",
      "partie": "methodes",
      "statement": "Pour estimer l'aire sous la courbe de $x \\mapsto x^2$ entre $0$ et\n$1$, on tire des points au hasard dans le carré unité. Quelle\ncondition compte les points situés sous la courbe ?\n\n```python\nx = random.random()\ny = random.random()\nif ...:\n    c = c + 1\n```",
      "options": [
        {
          "text": "`y <= x ** 2`",
          "correct": true,
          "feedback": "Bonne réponse : le point $(x\\,;\\,y)$ est sous la courbe lorsque\nson ordonnée ne dépasse pas l'image $x^2$."
        },
        {
          "text": "`x <= y ** 2`",
          "correct": false,
          "feedback": "Erreur : les rôles de $x$ et de $y$ sont échangés. On compare\nl'ordonnée du point à l'image de son abscisse."
        },
        {
          "text": "`y >= x ** 2`",
          "correct": false,
          "feedback": "Erreur : cette condition compte les points **au-dessus** de la\ncourbe. Leur fréquence approche $1$ moins l'aire cherchée."
        },
        {
          "text": "`x ** 2 + y ** 2 <= 1`",
          "correct": false,
          "feedback": "Erreur : cette condition caractérise le quart de disque, qui\nsert à estimer $\\pi$."
        }
      ],
      "explanation": "La fréquence des points sous la courbe approche l'aire cherchée,\nqui vaut $\\dfrac{1}{3}$ ; en terminale, le calcul intégral confirme\ncette valeur."
    },
    {
      "id": "q29",
      "difficulty": 2,
      "skills": [
        "archimede",
        "pi"
      ],
      "title": "La méthode d'Archimède",
      "partie": "methodes",
      "statement": "Pour approcher $\\pi$, Archimède inscrit dans un cercle de rayon $1$\ndes polygones réguliers dont il double le nombre de côtés. Que\ndevient le demi-périmètre de ces polygones ?",
      "options": [
        {
          "text": "Il se rapproche de $\\pi$ en restant inférieur à $\\pi$",
          "correct": true,
          "feedback": "Bonne réponse : un polygone inscrit a un périmètre plus petit que\ncelui du cercle, $2\\pi$, et s'en rapproche quand le nombre de\ncôtés augmente."
        },
        {
          "text": "Il se rapproche de $\\pi$ en restant supérieur à $\\pi$",
          "correct": false,
          "feedback": "Erreur : ce serait le cas de polygones **circonscrits**, qui\nentourent le cercle."
        },
        {
          "text": "Il reste égal à $3$ quel que soit le nombre de côtés",
          "correct": false,
          "feedback": "Erreur : $3$ est le demi-périmètre de l'hexagone inscrit. Il\naugmente quand on double le nombre de côtés."
        },
        {
          "text": "Il augmente sans limite avec le nombre de côtés",
          "correct": false,
          "feedback": "Erreur : le polygone reste à l'intérieur du cercle, donc son\npérimètre ne dépasse jamais $2\\pi$."
        }
      ],
      "explanation": "En encadrant le cercle entre polygones inscrits et circonscrits à\n$96$ côtés, Archimède obtient\n$3 + \\dfrac{10}{71} < \\pi < 3 + \\dfrac{1}{7}$."
    },
    {
      "id": "q30",
      "difficulty": 3,
      "skills": [
        "simulation",
        "variable-aleatoire"
      ],
      "title": "Moyenne simulée d'un gain",
      "partie": "methodes",
      "statement": "Le module `random` est importé. Un jeu fait gagner $10$ euros avec\nprobabilité $0{,}2$ et perdre $2$ euros sinon. Autour de quelle\nvaleur la fonction suivante renvoie-t-elle ses résultats pour\n`n = 100000` ?\n\n```python\ndef gain_moyen(n):\n    s = 0\n    for i in range(n):\n        if random.random() < 0.2:\n            s = s + 10\n        else:\n            s = s - 2\n    return s / n\n```",
      "options": [
        {
          "text": "$0{,}4$",
          "correct": true,
          "feedback": "Bonne réponse : la moyenne des gains simulés est proche de\nl'espérance $10 \\times 0{,}2 - 2 \\times 0{,}8 = 0{,}4$."
        },
        {
          "text": "$4$",
          "correct": false,
          "feedback": "Erreur : la moyenne de $10$ et de $-2$ ignore les probabilités.\nLe gain de $10$ euros n'arrive qu'une fois sur cinq."
        },
        {
          "text": "$1{,}6$",
          "correct": false,
          "feedback": "Erreur : $2 \\times 0{,}8 = 1{,}6$ est la perte moyenne. Il faut\nla retrancher du gain moyen $10 \\times 0{,}2 = 2$."
        },
        {
          "text": "$0{,}2$",
          "correct": false,
          "feedback": "Erreur : $0{,}2$ est la probabilité de gagner, pas le gain\nmoyen."
        }
      ],
      "explanation": "Sur un grand nombre de parties, la moyenne des gains simulés se\nrapproche de l'espérance de la variable aléatoire."
    },
    {
      "id": "q31",
      "difficulty": 1,
      "skills": [
        "parcours",
        "somme",
        "accumulateur"
      ],
      "title": "Somme des éléments d'une liste par parcours",
      "partie": "parcours",
      "statement": "Qu'affiche ce programme ?\n```python\nL = [4, 7, 1]\ns = 0\nfor x in L:\n    s = s + x\nprint(s)\n```",
      "options": [
        {
          "text": "`12`",
          "correct": true,
          "feedback": "Bonne réponse : la boucle ajoute chaque élément à `s`, qui\nfinit par contenir la somme $12$.\n"
        },
        {
          "text": "`7`",
          "correct": false,
          "feedback": "Erreur : $7$ est le plus grand élément, pas la somme.\n"
        },
        {
          "text": "`3`",
          "correct": false,
          "feedback": "Erreur : $3$ est le nombre d'éléments.\n"
        },
        {
          "text": "`0`",
          "correct": false,
          "feedback": "Erreur : `s` est modifié à chaque tour, il ne reste pas à $0$.\n"
        }
      ],
      "explanation": "Parcours par éléments avec un accumulateur : le schéma de base de\nla somme d'une liste.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [4, 7, 1]\ns = 0\nfor x in L:\n    s = s + x\nprint(s)\n```",
          "options": [
            {
              "text": "`12`",
              "correct": true,
              "feedback": "Bonne réponse : la boucle ajoute chaque élément à `s`, qui\nfinit par contenir la somme $12$.\n"
            },
            {
              "text": "`7`",
              "correct": false,
              "feedback": "Erreur : $7$ est le plus grand élément, pas la somme.\n"
            },
            {
              "text": "`3`",
              "correct": false,
              "feedback": "Erreur : $3$ est le nombre d'éléments.\n"
            },
            {
              "text": "`0`",
              "correct": false,
              "feedback": "Erreur : `s` est modifié à chaque tour, il ne reste pas à $0$.\n"
            }
          ],
          "explanation": "Parcours par éléments avec un accumulateur : le schéma de base de\nla somme d'une liste."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [2, 9, 5, 4]\ns = 0\nfor x in L:\n    s = s + x\nprint(s)\n```",
          "options": [
            {
              "text": "`20`",
              "correct": true,
              "feedback": "Bonne réponse : la boucle ajoute chaque élément à `s`, qui\nfinit par contenir la somme $20$.\n"
            },
            {
              "text": "`9`",
              "correct": false,
              "feedback": "Erreur : $9$ est le plus grand élément, pas la somme.\n"
            },
            {
              "text": "`4`",
              "correct": false,
              "feedback": "Erreur : $4$ est le nombre d'éléments.\n"
            },
            {
              "text": "`0`",
              "correct": false,
              "feedback": "Erreur : `s` est modifié à chaque tour, il ne reste pas à $0$.\n"
            }
          ],
          "explanation": "Parcours par éléments avec un accumulateur : le schéma de base de\nla somme d'une liste."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [10, 3, 8]\ns = 0\nfor x in L:\n    s = s + x\nprint(s)\n```",
          "options": [
            {
              "text": "`21`",
              "correct": true,
              "feedback": "Bonne réponse : la boucle ajoute chaque élément à `s`, qui\nfinit par contenir la somme $21$.\n"
            },
            {
              "text": "`10`",
              "correct": false,
              "feedback": "Erreur : $10$ est le plus grand élément, pas la somme.\n"
            },
            {
              "text": "`3`",
              "correct": false,
              "feedback": "Erreur : $3$ est le nombre d'éléments.\n"
            },
            {
              "text": "`0`",
              "correct": false,
              "feedback": "Erreur : `s` est modifié à chaque tour, il ne reste pas à $0$.\n"
            }
          ],
          "explanation": "Parcours par éléments avec un accumulateur : le schéma de base de\nla somme d'une liste."
        }
      ]
    },
    {
      "id": "q32",
      "difficulty": 2,
      "skills": [
        "parcours",
        "minimum",
        "comparaison"
      ],
      "title": "Minimum d'une liste par parcours",
      "partie": "parcours",
      "statement": "Qu'affiche ce programme ?\n```python\nL = [5, 2, 8, 3]\nm = L[0]\nfor x in L:\n    if x < m:\n        m = x\nprint(m)\n```",
      "options": [
        {
          "text": "`2`",
          "correct": true,
          "feedback": "Bonne réponse : `m` est remplacé chaque fois qu'un élément plus\npetit apparaît ; à la fin, il contient le minimum $2$.\n"
        },
        {
          "text": "`8`",
          "correct": false,
          "feedback": "Erreur : le test `x < m` cherche le plus **petit** ; le maximum\ndemanderait `x > m`.\n"
        },
        {
          "text": "`5`",
          "correct": false,
          "feedback": "Erreur : $5$ n'est que la valeur initiale de `m`.\n"
        },
        {
          "text": "`0`",
          "correct": false,
          "feedback": "Erreur : `m` est initialisé à `L[0]`, pas à $0$.\n"
        }
      ],
      "explanation": "Initialiser `m` au premier élément puis comparer chaque élément :\nle minimum sans fonction prédéfinie.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [5, 2, 8, 3]\nm = L[0]\nfor x in L:\n    if x < m:\n        m = x\nprint(m)\n```",
          "options": [
            {
              "text": "`2`",
              "correct": true,
              "feedback": "Bonne réponse : `m` est remplacé chaque fois qu'un élément plus\npetit apparaît ; à la fin, il contient le minimum $2$.\n"
            },
            {
              "text": "`8`",
              "correct": false,
              "feedback": "Erreur : le test `x < m` cherche le plus **petit** ; le maximum\ndemanderait `x > m`.\n"
            },
            {
              "text": "`5`",
              "correct": false,
              "feedback": "Erreur : $5$ n'est que la valeur initiale de `m`.\n"
            },
            {
              "text": "`0`",
              "correct": false,
              "feedback": "Erreur : `m` est initialisé à `L[0]`, pas à $0$.\n"
            }
          ],
          "explanation": "Initialiser `m` au premier élément puis comparer chaque élément :\nle minimum sans fonction prédéfinie."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [7, 9, 4, 6]\nm = L[0]\nfor x in L:\n    if x < m:\n        m = x\nprint(m)\n```",
          "options": [
            {
              "text": "`4`",
              "correct": true,
              "feedback": "Bonne réponse : `m` est remplacé chaque fois qu'un élément plus\npetit apparaît ; à la fin, il contient le minimum $4$.\n"
            },
            {
              "text": "`9`",
              "correct": false,
              "feedback": "Erreur : le test `x < m` cherche le plus **petit** ; le maximum\ndemanderait `x > m`.\n"
            },
            {
              "text": "`7`",
              "correct": false,
              "feedback": "Erreur : $7$ n'est que la valeur initiale de `m`.\n"
            },
            {
              "text": "`0`",
              "correct": false,
              "feedback": "Erreur : `m` est initialisé à `L[0]`, pas à $0$.\n"
            }
          ],
          "explanation": "Initialiser `m` au premier élément puis comparer chaque élément :\nle minimum sans fonction prédéfinie."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [3, 1, 5]\nm = L[0]\nfor x in L:\n    if x < m:\n        m = x\nprint(m)\n```",
          "options": [
            {
              "text": "`1`",
              "correct": true,
              "feedback": "Bonne réponse : `m` est remplacé chaque fois qu'un élément plus\npetit apparaît ; à la fin, il contient le minimum $1$.\n"
            },
            {
              "text": "`5`",
              "correct": false,
              "feedback": "Erreur : le test `x < m` cherche le plus **petit** ; le maximum\ndemanderait `x > m`.\n"
            },
            {
              "text": "`3`",
              "correct": false,
              "feedback": "Erreur : $3$ n'est que la valeur initiale de `m`.\n"
            },
            {
              "text": "`0`",
              "correct": false,
              "feedback": "Erreur : `m` est initialisé à `L[0]`, pas à $0$.\n"
            }
          ],
          "explanation": "Initialiser `m` au premier élément puis comparer chaque élément :\nle minimum sans fonction prédéfinie."
        }
      ]
    },
    {
      "id": "q33",
      "difficulty": 2,
      "skills": [
        "parcours",
        "compteur",
        "condition"
      ],
      "title": "Compter les éléments au-dessus d'un seuil",
      "partie": "parcours",
      "statement": "Qu'affiche ce programme ?\n```python\nnotes = [12, 7, 15, 9, 20]\nc = 0\nfor n in notes:\n    if n >= 10:\n        c = c + 1\nprint(c)\n```",
      "options": [
        {
          "text": "`3`",
          "correct": true,
          "feedback": "Bonne réponse : le compteur augmente pour chaque note\nsupérieure ou égale à $10$ ; il y en a $3$.\n"
        },
        {
          "text": "`5`",
          "correct": false,
          "feedback": "Erreur : $5$ est le nombre total de notes, sans la condition.\n"
        },
        {
          "text": "`47`",
          "correct": false,
          "feedback": "Erreur : $47$ est la somme des notes ; le programme compte, il\nn'additionne pas les valeurs.\n"
        },
        {
          "text": "`10`",
          "correct": false,
          "feedback": "Erreur : $10$ est le seuil, pas le résultat.\n"
        }
      ],
      "explanation": "Compteur conditionnel : incrémenter seulement quand le test est\nvrai.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nnotes = [12, 7, 15, 9, 20]\nc = 0\nfor n in notes:\n    if n >= 10:\n        c = c + 1\nprint(c)\n```",
          "options": [
            {
              "text": "`3`",
              "correct": true,
              "feedback": "Bonne réponse : le compteur augmente pour chaque note\nsupérieure ou égale à $10$ ; il y en a $3$.\n"
            },
            {
              "text": "`5`",
              "correct": false,
              "feedback": "Erreur : $5$ est le nombre total de notes, sans la condition.\n"
            },
            {
              "text": "`47`",
              "correct": false,
              "feedback": "Erreur : $47$ est la somme des notes ; le programme compte, il\nn'additionne pas les valeurs.\n"
            },
            {
              "text": "`10`",
              "correct": false,
              "feedback": "Erreur : $10$ est le seuil, pas le résultat.\n"
            }
          ],
          "explanation": "Compteur conditionnel : incrémenter seulement quand le test est\nvrai."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nnotes = [3, 14, 8, 11]\nc = 0\nfor n in notes:\n    if n >= 10:\n        c = c + 1\nprint(c)\n```",
          "options": [
            {
              "text": "`2`",
              "correct": true,
              "feedback": "Bonne réponse : le compteur augmente pour chaque note\nsupérieure ou égale à $10$ ; il y en a $2$.\n"
            },
            {
              "text": "`4`",
              "correct": false,
              "feedback": "Erreur : $4$ est le nombre total de notes, sans la condition.\n"
            },
            {
              "text": "`36`",
              "correct": false,
              "feedback": "Erreur : $36$ est la somme des notes ; le programme compte, il\nn'additionne pas les valeurs.\n"
            },
            {
              "text": "`10`",
              "correct": false,
              "feedback": "Erreur : $10$ est le seuil, pas le résultat.\n"
            }
          ],
          "explanation": "Compteur conditionnel : incrémenter seulement quand le test est\nvrai."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nnotes = [16, 18, 5]\nc = 0\nfor n in notes:\n    if n >= 10:\n        c = c + 1\nprint(c)\n```",
          "options": [
            {
              "text": "`2`",
              "correct": true,
              "feedback": "Bonne réponse : le compteur augmente pour chaque note\nsupérieure ou égale à $10$ ; il y en a $2$.\n"
            },
            {
              "text": "`3`",
              "correct": false,
              "feedback": "Erreur : $3$ est le nombre total de notes, sans la condition.\n"
            },
            {
              "text": "`39`",
              "correct": false,
              "feedback": "Erreur : $39$ est la somme des notes ; le programme compte, il\nn'additionne pas les valeurs.\n"
            },
            {
              "text": "`10`",
              "correct": false,
              "feedback": "Erreur : $10$ est le seuil, pas le résultat.\n"
            }
          ],
          "explanation": "Compteur conditionnel : incrémenter seulement quand le test est\nvrai."
        }
      ]
    },
    {
      "id": "q34",
      "difficulty": 3,
      "skills": [
        "parcours",
        "indice-maximum",
        "egalite"
      ],
      "title": "L'indice du maximum en cas d'égalité",
      "partie": "parcours",
      "statement": "Qu'affiche ce programme ?\n```python\nL = [4, 9, 2, 9]\nimax = 0\nfor i in range(len(L)):\n    if L[i] >= L[imax]:\n        imax = i\nprint(imax)\n```",
      "options": [
        {
          "text": "`3`, la dernière occurrence de $9$",
          "correct": true,
          "feedback": "Bonne réponse : avec `>=`, une égalité remplace `imax` ; le\nprogramme retient la **dernière** position du maximum.\n"
        },
        {
          "text": "`1`, la première occurrence de $9$",
          "correct": false,
          "feedback": "Erreur : ce serait le résultat avec `>` strict ; `>=` continue\nde mettre `imax` à jour en cas d'égalité.\n"
        },
        {
          "text": "`9`, la valeur du maximum",
          "correct": false,
          "feedback": "Erreur : le programme affiche un indice, pas une valeur.\n"
        },
        {
          "text": "`0`, `imax` ne changeant jamais",
          "correct": false,
          "feedback": "Erreur : dès qu'un élément dépasse ou égale `L[0]`, `imax`\nchange.\n"
        }
      ],
      "explanation": "Le choix entre `>` et `>=` décide quelle occurrence du maximum\nest retenue : la première ou la dernière.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [4, 9, 2, 9]\nimax = 0\nfor i in range(len(L)):\n    if L[i] >= L[imax]:\n        imax = i\nprint(imax)\n```",
          "options": [
            {
              "text": "`3`, la dernière occurrence de $9$",
              "correct": true,
              "feedback": "Bonne réponse : avec `>=`, une égalité remplace `imax` ; le\nprogramme retient la **dernière** position du maximum.\n"
            },
            {
              "text": "`1`, la première occurrence de $9$",
              "correct": false,
              "feedback": "Erreur : ce serait le résultat avec `>` strict ; `>=` continue\nde mettre `imax` à jour en cas d'égalité.\n"
            },
            {
              "text": "`9`, la valeur du maximum",
              "correct": false,
              "feedback": "Erreur : le programme affiche un indice, pas une valeur.\n"
            },
            {
              "text": "`0`, `imax` ne changeant jamais",
              "correct": false,
              "feedback": "Erreur : dès qu'un élément dépasse ou égale `L[0]`, `imax`\nchange.\n"
            }
          ],
          "explanation": "Le choix entre `>` et `>=` décide quelle occurrence du maximum\nest retenue : la première ou la dernière."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [7, 3, 7, 1]\nimax = 0\nfor i in range(len(L)):\n    if L[i] >= L[imax]:\n        imax = i\nprint(imax)\n```",
          "options": [
            {
              "text": "`2`, la dernière occurrence de $7$",
              "correct": true,
              "feedback": "Bonne réponse : avec `>=`, une égalité remplace `imax` ; le\nprogramme retient la **dernière** position du maximum.\n"
            },
            {
              "text": "`0`, la première occurrence de $7$",
              "correct": false,
              "feedback": "Erreur : ce serait le résultat avec `>` strict ; `>=` continue\nde mettre `imax` à jour en cas d'égalité.\n"
            },
            {
              "text": "`7`, la valeur du maximum",
              "correct": false,
              "feedback": "Erreur : le programme affiche un indice, pas une valeur.\n"
            },
            {
              "text": "`0`, `imax` ne changeant jamais",
              "correct": false,
              "feedback": "Erreur : dès qu'un élément dépasse ou égale `L[0]`, `imax`\nchange.\n"
            }
          ],
          "explanation": "Le choix entre `>` et `>=` décide quelle occurrence du maximum\nest retenue : la première ou la dernière."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [5, 8, 8, 2, 8]\nimax = 0\nfor i in range(len(L)):\n    if L[i] >= L[imax]:\n        imax = i\nprint(imax)\n```",
          "options": [
            {
              "text": "`4`, la dernière occurrence de $8$",
              "correct": true,
              "feedback": "Bonne réponse : avec `>=`, une égalité remplace `imax` ; le\nprogramme retient la **dernière** position du maximum.\n"
            },
            {
              "text": "`1`, la première occurrence de $8$",
              "correct": false,
              "feedback": "Erreur : ce serait le résultat avec `>` strict ; `>=` continue\nde mettre `imax` à jour en cas d'égalité.\n"
            },
            {
              "text": "`8`, la valeur du maximum",
              "correct": false,
              "feedback": "Erreur : le programme affiche un indice, pas une valeur.\n"
            },
            {
              "text": "`0`, `imax` ne changeant jamais",
              "correct": false,
              "feedback": "Erreur : dès qu'un élément dépasse ou égale `L[0]`, `imax`\nchange.\n"
            }
          ],
          "explanation": "Le choix entre `>` et `>=` décide quelle occurrence du maximum\nest retenue : la première ou la dernière."
        }
      ]
    },
    {
      "id": "q35",
      "difficulty": 1,
      "skills": [
        "suites",
        "recurrence",
        "boucle"
      ],
      "title": "Un terme d'une suite récurrente par une boucle",
      "partie": "suites",
      "statement": "La suite $(u_n)$ est définie par $u_0 = 1$ et\n$u_{n+1} = 2u_n + 1$. Qu'affiche ce programme ?\n```python\nu = 1\nfor k in range(3):\n    u = 2 * u + 1\nprint(u)\n```",
      "options": [
        {
          "text": "`15`, la valeur de $u_3$",
          "correct": true,
          "feedback": "Bonne réponse : trois tours de boucle calculent $u_1$, $u_2$\npuis $u_3 = 15$.\n"
        },
        {
          "text": "`7`, la valeur de $u_2$",
          "correct": false,
          "feedback": "Erreur : `range(3)` fait trois tours, pas deux.\n"
        },
        {
          "text": "`31`, la valeur de $u_4$",
          "correct": false,
          "feedback": "Erreur : `range(3)` fait trois tours, pas quatre.\n"
        },
        {
          "text": "`1`, la valeur de $u_0$",
          "correct": false,
          "feedback": "Erreur : `u` est modifié à chaque tour.\n"
        }
      ],
      "explanation": "Pour calculer $u_n$, on part de $u_0$ et on applique $n$ fois la\nrelation de récurrence : `range(n)` fait exactement $n$ tours.",
      "variants": [
        {
          "statement": "La suite $(u_n)$ est définie par $u_0 = 1$ et\n$u_{n+1} = 2u_n + 1$. Qu'affiche ce programme ?\n```python\nu = 1\nfor k in range(3):\n    u = 2 * u + 1\nprint(u)\n```",
          "options": [
            {
              "text": "`15`, la valeur de $u_3$",
              "correct": true,
              "feedback": "Bonne réponse : trois tours de boucle calculent $u_1$, $u_2$\npuis $u_3 = 15$.\n"
            },
            {
              "text": "`7`, la valeur de $u_2$",
              "correct": false,
              "feedback": "Erreur : `range(3)` fait trois tours, pas deux.\n"
            },
            {
              "text": "`31`, la valeur de $u_4$",
              "correct": false,
              "feedback": "Erreur : `range(3)` fait trois tours, pas quatre.\n"
            },
            {
              "text": "`1`, la valeur de $u_0$",
              "correct": false,
              "feedback": "Erreur : `u` est modifié à chaque tour.\n"
            }
          ],
          "explanation": "Pour calculer $u_n$, on part de $u_0$ et on applique $n$ fois la\nrelation de récurrence : `range(n)` fait exactement $n$ tours."
        },
        {
          "statement": "La suite $(u_n)$ est définie par $u_0 = 2$ et\n$u_{n+1} = 2u_n + 1$. Qu'affiche ce programme ?\n```python\nu = 2\nfor k in range(3):\n    u = 2 * u + 1\nprint(u)\n```",
          "options": [
            {
              "text": "`23`, la valeur de $u_3$",
              "correct": true,
              "feedback": "Bonne réponse : trois tours de boucle calculent $u_1$, $u_2$\npuis $u_3 = 23$.\n"
            },
            {
              "text": "`11`, la valeur de $u_2$",
              "correct": false,
              "feedback": "Erreur : `range(3)` fait trois tours, pas deux.\n"
            },
            {
              "text": "`47`, la valeur de $u_4$",
              "correct": false,
              "feedback": "Erreur : `range(3)` fait trois tours, pas quatre.\n"
            },
            {
              "text": "`2`, la valeur de $u_0$",
              "correct": false,
              "feedback": "Erreur : `u` est modifié à chaque tour.\n"
            }
          ],
          "explanation": "Pour calculer $u_n$, on part de $u_0$ et on applique $n$ fois la\nrelation de récurrence : `range(n)` fait exactement $n$ tours."
        },
        {
          "statement": "La suite $(u_n)$ est définie par $u_0 = 0$ et\n$u_{n+1} = 2u_n + 1$. Qu'affiche ce programme ?\n```python\nu = 0\nfor k in range(3):\n    u = 2 * u + 1\nprint(u)\n```",
          "options": [
            {
              "text": "`7`, la valeur de $u_3$",
              "correct": true,
              "feedback": "Bonne réponse : trois tours de boucle calculent $u_1$, $u_2$\npuis $u_3 = 7$.\n"
            },
            {
              "text": "`3`, la valeur de $u_2$",
              "correct": false,
              "feedback": "Erreur : `range(3)` fait trois tours, pas deux.\n"
            },
            {
              "text": "`15`, la valeur de $u_4$",
              "correct": false,
              "feedback": "Erreur : `range(3)` fait trois tours, pas quatre.\n"
            },
            {
              "text": "`0`, la valeur de $u_0$",
              "correct": false,
              "feedback": "Erreur : `u` est modifié à chaque tour.\n"
            }
          ],
          "explanation": "Pour calculer $u_n$, on part de $u_0$ et on applique $n$ fois la\nrelation de récurrence : `range(n)` fait exactement $n$ tours."
        }
      ]
    },
    {
      "id": "q36",
      "difficulty": 2,
      "skills": [
        "suites",
        "liste",
        "comprehension"
      ],
      "title": "Liste des premiers termes d'une suite arithmétique",
      "partie": "suites",
      "statement": "Qu'affiche `print([3 + 2 * k for k in range(5)])` ?",
      "options": [
        {
          "text": "`[3, 5, 7, 9, 11]`",
          "correct": true,
          "feedback": "Bonne réponse : pour `k` de $0$ à $4$, on obtient les cinq\npremiers termes de la suite arithmétique de premier terme $3$\net de raison $2$.\n"
        },
        {
          "text": "`[5, 7, 9, 11, 13]`",
          "correct": false,
          "feedback": "Erreur : `range(5)` commence à $0$, le premier terme est donc\n$3$.\n"
        },
        {
          "text": "`[3, 5, 7, 9]`",
          "correct": false,
          "feedback": "Erreur : `range(5)` produit cinq valeurs, de $0$ à $4$.\n"
        },
        {
          "text": "`[3, 6, 12, 24, 48]`",
          "correct": false,
          "feedback": "Erreur : `3 + 2 * k` est une expression affine, pas une\npuissance ; la suite est arithmétique.\n"
        }
      ],
      "explanation": "Une liste en compréhension génère les termes $u_k = 3 + 2k$ :\nune suite arithmétique sous forme explicite.",
      "variants": [
        {
          "statement": "Qu'affiche `print([3 + 2 * k for k in range(5)])` ?",
          "options": [
            {
              "text": "`[3, 5, 7, 9, 11]`",
              "correct": true,
              "feedback": "Bonne réponse : pour `k` de $0$ à $4$, on obtient les cinq\npremiers termes de la suite arithmétique de premier terme $3$\net de raison $2$.\n"
            },
            {
              "text": "`[5, 7, 9, 11, 13]`",
              "correct": false,
              "feedback": "Erreur : `range(5)` commence à $0$, le premier terme est donc\n$3$.\n"
            },
            {
              "text": "`[3, 5, 7, 9]`",
              "correct": false,
              "feedback": "Erreur : `range(5)` produit cinq valeurs, de $0$ à $4$.\n"
            },
            {
              "text": "`[3, 6, 12, 24, 48]`",
              "correct": false,
              "feedback": "Erreur : `3 + 2 * k` est une expression affine, pas une\npuissance ; la suite est arithmétique.\n"
            }
          ],
          "explanation": "Une liste en compréhension génère les termes $u_k = 3 + 2k$ :\nune suite arithmétique sous forme explicite."
        },
        {
          "statement": "Qu'affiche `print([1 + 4 * k for k in range(5)])` ?",
          "options": [
            {
              "text": "`[1, 5, 9, 13, 17]`",
              "correct": true,
              "feedback": "Bonne réponse : pour `k` de $0$ à $4$, on obtient les cinq\npremiers termes de la suite arithmétique de premier terme $1$\net de raison $4$.\n"
            },
            {
              "text": "`[5, 9, 13, 17, 21]`",
              "correct": false,
              "feedback": "Erreur : `range(5)` commence à $0$, le premier terme est donc\n$1$.\n"
            },
            {
              "text": "`[1, 5, 9, 13]`",
              "correct": false,
              "feedback": "Erreur : `range(5)` produit cinq valeurs, de $0$ à $4$.\n"
            },
            {
              "text": "`[1, 4, 16, 64, 256]`",
              "correct": false,
              "feedback": "Erreur : `1 + 4 * k` est une expression affine, pas une\npuissance ; la suite est arithmétique.\n"
            }
          ],
          "explanation": "Une liste en compréhension génère les termes $u_k = 1 + 4k$ :\nune suite arithmétique sous forme explicite."
        },
        {
          "statement": "Qu'affiche `print([10 + 3 * k for k in range(5)])` ?",
          "options": [
            {
              "text": "`[10, 13, 16, 19, 22]`",
              "correct": true,
              "feedback": "Bonne réponse : pour `k` de $0$ à $4$, on obtient les cinq\npremiers termes de la suite arithmétique de premier terme $10$\net de raison $3$.\n"
            },
            {
              "text": "`[13, 16, 19, 22, 25]`",
              "correct": false,
              "feedback": "Erreur : `range(5)` commence à $0$, le premier terme est donc\n$10$.\n"
            },
            {
              "text": "`[10, 13, 16, 19]`",
              "correct": false,
              "feedback": "Erreur : `range(5)` produit cinq valeurs, de $0$ à $4$.\n"
            },
            {
              "text": "`[10, 30, 90, 270, 810]`",
              "correct": false,
              "feedback": "Erreur : `10 + 3 * k` est une expression affine, pas une\npuissance ; la suite est arithmétique.\n"
            }
          ],
          "explanation": "Une liste en compréhension génère les termes $u_k = 10 + 3k$ :\nune suite arithmétique sous forme explicite."
        }
      ]
    },
    {
      "id": "q37",
      "difficulty": 3,
      "skills": [
        "suites",
        "seuil",
        "while"
      ],
      "title": "Un algorithme de seuil pour une suite croissante",
      "partie": "suites",
      "statement": "Qu'affiche ce programme ?\n```python\nu = 10\nn = 0\nwhile u < 100:\n    u = 1.5 * u\n    n = n + 1\nprint(n)\n```",
      "options": [
        {
          "text": "`6`, premier rang où $u_n \\geq 100$",
          "correct": true,
          "feedback": "Bonne réponse : chaque tour multiplie `u` par $1{,}5$ et\nincrémente `n` ; la boucle s'arrête quand `u` atteint ou\ndépasse $100$, soit $u_{6} \\approx 113{,}9$, après $6$\ntours.\n"
        },
        {
          "text": "`5`, dernier rang où $u_n < 100$",
          "correct": false,
          "feedback": "Erreur : au rang $5$, `u` est encore sous le seuil ; la\nboucle fait un tour de plus.\n"
        },
        {
          "text": "`113{,}9`, la valeur finale de `u`",
          "correct": false,
          "feedback": "Erreur : le programme affiche `n`, pas `u`.\n"
        },
        {
          "text": "`100`, le seuil de la boucle",
          "correct": false,
          "feedback": "Erreur : $100$ est le seuil, pas le nombre de tours.\n"
        }
      ],
      "explanation": "Un algorithme de seuil répète la relation de récurrence jusqu'à\ndépasser la valeur visée et compte les étapes.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nu = 10\nn = 0\nwhile u < 100:\n    u = 1.5 * u\n    n = n + 1\nprint(n)\n```",
          "options": [
            {
              "text": "`6`, premier rang où $u_n \\geq 100$",
              "correct": true,
              "feedback": "Bonne réponse : chaque tour multiplie `u` par $1{,}5$ et\nincrémente `n` ; la boucle s'arrête quand `u` atteint ou\ndépasse $100$, soit $u_{6} \\approx 113{,}9$, après $6$\ntours.\n"
            },
            {
              "text": "`5`, dernier rang où $u_n < 100$",
              "correct": false,
              "feedback": "Erreur : au rang $5$, `u` est encore sous le seuil ; la\nboucle fait un tour de plus.\n"
            },
            {
              "text": "`113{,}9`, la valeur finale de `u`",
              "correct": false,
              "feedback": "Erreur : le programme affiche `n`, pas `u`.\n"
            },
            {
              "text": "`100`, le seuil de la boucle",
              "correct": false,
              "feedback": "Erreur : $100$ est le seuil, pas le nombre de tours.\n"
            }
          ],
          "explanation": "Un algorithme de seuil répète la relation de récurrence jusqu'à\ndépasser la valeur visée et compte les étapes."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nu = 4\nn = 0\nwhile u < 50:\n    u = 1.5 * u\n    n = n + 1\nprint(n)\n```",
          "options": [
            {
              "text": "`7`, premier rang où $u_n \\geq 50$",
              "correct": true,
              "feedback": "Bonne réponse : chaque tour multiplie `u` par $1{,}5$ et\nincrémente `n` ; la boucle s'arrête quand `u` atteint ou\ndépasse $50$, soit $u_{7} \\approx 68{,}3$, après $7$\ntours.\n"
            },
            {
              "text": "`6`, dernier rang où $u_n < 50$",
              "correct": false,
              "feedback": "Erreur : au rang $6$, `u` est encore sous le seuil ; la\nboucle fait un tour de plus.\n"
            },
            {
              "text": "`68{,}3`, la valeur finale de `u`",
              "correct": false,
              "feedback": "Erreur : le programme affiche `n`, pas `u`.\n"
            },
            {
              "text": "`50`, le seuil de la boucle",
              "correct": false,
              "feedback": "Erreur : $50$ est le seuil, pas le nombre de tours.\n"
            }
          ],
          "explanation": "Un algorithme de seuil répète la relation de récurrence jusqu'à\ndépasser la valeur visée et compte les étapes."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nu = 20\nn = 0\nwhile u < 200:\n    u = 1.5 * u\n    n = n + 1\nprint(n)\n```",
          "options": [
            {
              "text": "`6`, premier rang où $u_n \\geq 200$",
              "correct": true,
              "feedback": "Bonne réponse : chaque tour multiplie `u` par $1{,}5$ et\nincrémente `n` ; la boucle s'arrête quand `u` atteint ou\ndépasse $200$, soit $u_{6} \\approx 227{,}8$, après $6$\ntours.\n"
            },
            {
              "text": "`5`, dernier rang où $u_n < 200$",
              "correct": false,
              "feedback": "Erreur : au rang $5$, `u` est encore sous le seuil ; la\nboucle fait un tour de plus.\n"
            },
            {
              "text": "`227{,}8`, la valeur finale de `u`",
              "correct": false,
              "feedback": "Erreur : le programme affiche `n`, pas `u`.\n"
            },
            {
              "text": "`200`, le seuil de la boucle",
              "correct": false,
              "feedback": "Erreur : $200$ est le seuil, pas le nombre de tours.\n"
            }
          ],
          "explanation": "Un algorithme de seuil répète la relation de récurrence jusqu'à\ndépasser la valeur visée et compte les étapes."
        }
      ]
    },
    {
      "id": "q38",
      "difficulty": 1,
      "skills": [
        "liste",
        "sum",
        "len"
      ],
      "title": "Moyenne avec sum et len",
      "partie": "listes",
      "statement": "Avec `L = [4, 7, 1]`, que vaut `sum(L) / len(L)` ?",
      "options": [
        {
          "text": "`4.0`, le quotient de $12$ par $3$",
          "correct": true,
          "feedback": "Bonne réponse : `sum(L)` vaut $12$, `len(L)` vaut $3$, et la\ndivision `/` donne un flottant.\n"
        },
        {
          "text": "`12`, la somme des éléments seule",
          "correct": false,
          "feedback": "Erreur : la somme est ensuite divisée par `len(L)`.\n"
        },
        {
          "text": "`3`, le nombre d'éléments seul",
          "correct": false,
          "feedback": "Erreur : `len(L)` est le diviseur, pas le résultat.\n"
        },
        {
          "text": "`4`, un quotient entier de $12$ par $3$",
          "correct": false,
          "feedback": "Erreur : `/` renvoie toujours un flottant, ici `4.0`.\n"
        }
      ],
      "explanation": "`sum` et `len` suffisent pour calculer une moyenne sans boucle."
    },
    {
      "id": "q39",
      "difficulty": 2,
      "skills": [
        "liste",
        "concatenation"
      ],
      "title": "Additionner deux listes",
      "partie": "listes",
      "statement": "Que vaut `[1, 2] + [3]` ?",
      "options": [
        {
          "text": "`[1, 2, 3]`, les deux listes mises bout à bout",
          "correct": true,
          "feedback": "Bonne réponse : entre deux listes, `+` concatène.\n"
        },
        {
          "text": "`[4, 5]`, chaque élément augmenté de $3$",
          "correct": false,
          "feedback": "Erreur : `+` ne fait pas de calcul terme à terme sur les\nlistes.\n"
        },
        {
          "text": "`[[1, 2], 3]`, la seconde liste ajoutée comme élément",
          "correct": false,
          "feedback": "Erreur : ce serait le résultat de `[[1, 2]] + [3]` ou\nd'un `append`.\n"
        },
        {
          "text": "Une erreur, les listes n'ayant pas la même longueur",
          "correct": false,
          "feedback": "Erreur : la concaténation n'impose aucune longueur.\n"
        }
      ],
      "explanation": "Comme pour les chaînes, `+` juxtapose deux listes."
    },
    {
      "id": "q40",
      "difficulty": 3,
      "skills": [
        "liste",
        "comprehension",
        "condition"
      ],
      "title": "Transformer et filtrer une liste",
      "partie": "listes",
      "statement": "Avec `L = [2, 5, 3]`, que vaut `[x * 2 for x in L if x > 2]` ?",
      "options": [
        {
          "text": "`[10, 6]`, les éléments supérieurs à $2$ doublés",
          "correct": true,
          "feedback": "Bonne réponse : seuls $5$ et $3$ passent le filtre, puis\nchacun est doublé.\n"
        },
        {
          "text": "`[4, 10, 6]`, tous les éléments doublés",
          "correct": false,
          "feedback": "Erreur : la condition `if x > 2` écarte $2$.\n"
        },
        {
          "text": "`[5, 3]`, les éléments retenus sans transformation",
          "correct": false,
          "feedback": "Erreur : l'expression `x * 2` s'applique à chaque élément\nretenu.\n"
        },
        {
          "text": "`[10, 6, 4]`, les éléments doublés puis rangés",
          "correct": false,
          "feedback": "Erreur : une compréhension ne trie pas et exclut $2$.\n"
        }
      ],
      "explanation": "Dans une compréhension, le filtre `if` sélectionne les éléments et\nl'expression de tête les transforme."
    },
    {
      "id": "q41",
      "difficulty": 2,
      "skills": [
        "parcours",
        "while",
        "recherche"
      ],
      "title": "Chercher une valeur avec une boucle tant que",
      "partie": "parcours",
      "statement": "Qu'affiche ce programme ?\n```python\nL = [6, 2, 8, 2, 5]\ni = 0\nwhile L[i] != 2:\n    i = i + 1\nprint(i)\n```",
      "options": [
        {
          "text": "`1`, l'indice de la première occurrence de $2$",
          "correct": true,
          "feedback": "Bonne réponse : la boucle avance tant que `L[i]` diffère de\n$2$ et s'arrête sur la première case qui le contient.\n"
        },
        {
          "text": "`3`, l'indice de la dernière occurrence de $2$",
          "correct": false,
          "feedback": "Erreur : la boucle s'arrête dès la première occurrence.\n"
        },
        {
          "text": "`2`, la valeur cherchée",
          "correct": false,
          "feedback": "Erreur : le programme affiche l'indice `i`, pas la valeur.\n"
        },
        {
          "text": "`5`, la longueur de la liste",
          "correct": false,
          "feedback": "Erreur : la boucle s'arrête avant d'avoir parcouru toute la\nliste.\n"
        }
      ],
      "explanation": "Une boucle `while` permet d'arrêter un parcours dès que la valeur\ncherchée est trouvée.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [6, 2, 8, 2, 5]\ni = 0\nwhile L[i] != 2:\n    i = i + 1\nprint(i)\n```",
          "options": [
            {
              "text": "`1`, l'indice de la première occurrence de $2$",
              "correct": true,
              "feedback": "Bonne réponse : la boucle avance tant que `L[i]` diffère de\n$2$ et s'arrête sur la première case qui le contient.\n"
            },
            {
              "text": "`3`, l'indice de la dernière occurrence de $2$",
              "correct": false,
              "feedback": "Erreur : la boucle s'arrête dès la première occurrence.\n"
            },
            {
              "text": "`2`, la valeur cherchée",
              "correct": false,
              "feedback": "Erreur : le programme affiche l'indice `i`, pas la valeur.\n"
            },
            {
              "text": "`5`, la longueur de la liste",
              "correct": false,
              "feedback": "Erreur : la boucle s'arrête avant d'avoir parcouru toute la\nliste.\n"
            }
          ],
          "explanation": "Une boucle `while` permet d'arrêter un parcours dès que la valeur\ncherchée est trouvée."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [5, 1, 4, 4]\ni = 0\nwhile L[i] != 4:\n    i = i + 1\nprint(i)\n```",
          "options": [
            {
              "text": "`2`, l'indice de la première occurrence de $4$",
              "correct": true,
              "feedback": "Bonne réponse : la boucle avance tant que `L[i]` diffère de\n$4$ et s'arrête sur la première case qui le contient.\n"
            },
            {
              "text": "`3`, l'indice de la dernière occurrence de $4$",
              "correct": false,
              "feedback": "Erreur : la boucle s'arrête dès la première occurrence.\n"
            },
            {
              "text": "`4`, la valeur cherchée",
              "correct": false,
              "feedback": "Erreur : le programme affiche l'indice `i`, pas la valeur.\n"
            },
            {
              "text": "`4`, la longueur de la liste",
              "correct": false,
              "feedback": "Erreur : la boucle s'arrête avant d'avoir parcouru toute la\nliste.\n"
            }
          ],
          "explanation": "Une boucle `while` permet d'arrêter un parcours dès que la valeur\ncherchée est trouvée."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nL = [9, 9, 3]\ni = 0\nwhile L[i] != 9:\n    i = i + 1\nprint(i)\n```",
          "options": [
            {
              "text": "`0`, l'indice de la première occurrence de $9$",
              "correct": true,
              "feedback": "Bonne réponse : la boucle avance tant que `L[i]` diffère de\n$9$ et s'arrête sur la première case qui le contient.\n"
            },
            {
              "text": "`1`, l'indice de la dernière occurrence de $9$",
              "correct": false,
              "feedback": "Erreur : la boucle s'arrête dès la première occurrence.\n"
            },
            {
              "text": "`9`, la valeur cherchée",
              "correct": false,
              "feedback": "Erreur : le programme affiche l'indice `i`, pas la valeur.\n"
            },
            {
              "text": "`3`, la longueur de la liste",
              "correct": false,
              "feedback": "Erreur : la boucle s'arrête avant d'avoir parcouru toute la\nliste.\n"
            }
          ],
          "explanation": "Une boucle `while` permet d'arrêter un parcours dès que la valeur\ncherchée est trouvée."
        }
      ]
    },
    {
      "id": "q42",
      "difficulty": 2,
      "skills": [
        "suite",
        "recurrence",
        "boucle"
      ],
      "title": "Une récurrence qui dépend du rang",
      "partie": "suites",
      "statement": "Qu'affiche ce programme ?\n```python\nu = 1\nfor n in range(4):\n    u = u + 2 * n + 1\nprint(u)\n```",
      "options": [
        {
          "text": "`17`, soit $1 + 4^2$",
          "correct": true,
          "feedback": "Bonne réponse : les ajouts valent $1, 3, 5, \\ldots$ pour\n$n = 0, 1, 2, \\ldots$ ; leur somme sur $4$ tours vaut $4^2$.\n"
        },
        {
          "text": "`26`, un tour de plus",
          "correct": false,
          "feedback": "Erreur : `range(4)` fait exactement $4$ tours, de $n = 0$\nà $n = 3$.\n"
        },
        {
          "text": "`8`, le dernier ajout seul",
          "correct": false,
          "feedback": "Erreur : `u` accumule tous les ajouts depuis $1$.\n"
        },
        {
          "text": "`16`, sans le terme initial",
          "correct": false,
          "feedback": "Erreur : `u` part de $1$, pas de $0$.\n"
        }
      ],
      "explanation": "Quand la relation de récurrence fait intervenir $n$, la variable de\nboucle fournit ce rang à chaque tour.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nu = 1\nfor n in range(4):\n    u = u + 2 * n + 1\nprint(u)\n```",
          "options": [
            {
              "text": "`17`, soit $1 + 4^2$",
              "correct": true,
              "feedback": "Bonne réponse : les ajouts valent $1, 3, 5, \\ldots$ pour\n$n = 0, 1, 2, \\ldots$ ; leur somme sur $4$ tours vaut $4^2$.\n"
            },
            {
              "text": "`26`, un tour de plus",
              "correct": false,
              "feedback": "Erreur : `range(4)` fait exactement $4$ tours, de $n = 0$\nà $n = 3$.\n"
            },
            {
              "text": "`8`, le dernier ajout seul",
              "correct": false,
              "feedback": "Erreur : `u` accumule tous les ajouts depuis $1$.\n"
            },
            {
              "text": "`16`, sans le terme initial",
              "correct": false,
              "feedback": "Erreur : `u` part de $1$, pas de $0$.\n"
            }
          ],
          "explanation": "Quand la relation de récurrence fait intervenir $n$, la variable de\nboucle fournit ce rang à chaque tour."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nu = 1\nfor n in range(5):\n    u = u + 2 * n + 1\nprint(u)\n```",
          "options": [
            {
              "text": "`26`, soit $1 + 5^2$",
              "correct": true,
              "feedback": "Bonne réponse : les ajouts valent $1, 3, 5, \\ldots$ pour\n$n = 0, 1, 2, \\ldots$ ; leur somme sur $5$ tours vaut $5^2$.\n"
            },
            {
              "text": "`37`, un tour de plus",
              "correct": false,
              "feedback": "Erreur : `range(5)` fait exactement $5$ tours, de $n = 0$\nà $n = 4$.\n"
            },
            {
              "text": "`10`, le dernier ajout seul",
              "correct": false,
              "feedback": "Erreur : `u` accumule tous les ajouts depuis $1$.\n"
            },
            {
              "text": "`25`, sans le terme initial",
              "correct": false,
              "feedback": "Erreur : `u` part de $1$, pas de $0$.\n"
            }
          ],
          "explanation": "Quand la relation de récurrence fait intervenir $n$, la variable de\nboucle fournit ce rang à chaque tour."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nu = 1\nfor n in range(3):\n    u = u + 2 * n + 1\nprint(u)\n```",
          "options": [
            {
              "text": "`10`, soit $1 + 3^2$",
              "correct": true,
              "feedback": "Bonne réponse : les ajouts valent $1, 3, 5, \\ldots$ pour\n$n = 0, 1, 2, \\ldots$ ; leur somme sur $3$ tours vaut $3^2$.\n"
            },
            {
              "text": "`17`, un tour de plus",
              "correct": false,
              "feedback": "Erreur : `range(3)` fait exactement $3$ tours, de $n = 0$\nà $n = 2$.\n"
            },
            {
              "text": "`6`, le dernier ajout seul",
              "correct": false,
              "feedback": "Erreur : `u` accumule tous les ajouts depuis $1$.\n"
            },
            {
              "text": "`9`, sans le terme initial",
              "correct": false,
              "feedback": "Erreur : `u` part de $1$, pas de $0$.\n"
            }
          ],
          "explanation": "Quand la relation de récurrence fait intervenir $n$, la variable de\nboucle fournit ce rang à chaque tour."
        }
      ]
    },
    {
      "id": "q43",
      "difficulty": 3,
      "skills": [
        "suite",
        "somme",
        "seuil",
        "while"
      ],
      "title": "Somme harmonique dépassant un seuil",
      "partie": "suites",
      "statement": "Qu'affiche ce programme ?\n```python\ns = 0\nn = 0\nwhile s < 2:\n    n = n + 1\n    s = s + 1 / n\nprint(n)\n```",
      "options": [
        {
          "text": "`4`, premier rang où la somme atteint $2$",
          "correct": true,
          "feedback": "Bonne réponse : les sommes successives valent $1$ ; $1{,}5$ ;\nenviron $1{,}83$ ; environ $2{,}08$ : la boucle s'arrête au\nquatrième terme.\n"
        },
        {
          "text": "`3`, dernier rang où la somme reste sous $2$",
          "correct": false,
          "feedback": "Erreur : pour $n = 3$, `s` vaut environ $1{,}83 < 2$ et la\nboucle continue.\n"
        },
        {
          "text": "`2.083…`, la valeur finale de la somme `s`",
          "correct": false,
          "feedback": "Erreur : le programme affiche `n`, pas `s`.\n"
        },
        {
          "text": "`2`, le seuil comparé à la somme",
          "correct": false,
          "feedback": "Erreur : $2$ est la valeur comparée, pas le nombre de termes.\n"
        }
      ],
      "explanation": "Un algorithme de seuil sur une somme ajoute les termes un à un et\ncompte le rang atteint."
    },
    {
      "id": "q44",
      "difficulty": 2,
      "skills": [
        "simulation",
        "probabilite",
        "random"
      ],
      "title": "Simuler un succès de probabilité 0,3",
      "partie": "methodes",
      "statement": "Qu'affiche ce programme ?\n```python\nfrom random import random\nc = 0\nfor i in range(1000):\n    if random() < 0.3:\n        c = c + 1\nprint(c / 1000)\n```",
      "options": [
        {
          "text": "Un nombre proche de `0.3`, variable d'une exécution à l'autre",
          "correct": true,
          "feedback": "Bonne réponse : `random() < 0.3` est vrai avec une probabilité\n$0{,}3$ ; la fréquence observée sur $1000$ essais s'en\napproche sans être exacte.\n"
        },
        {
          "text": "Exactement `0.3`, la probabilité programmée",
          "correct": false,
          "feedback": "Erreur : une fréquence simulée fluctue autour de la\nprobabilité.\n"
        },
        {
          "text": "`300`, le nombre de succès",
          "correct": false,
          "feedback": "Erreur : le programme divise `c` par $1000$ et `c` n'est pas\nexactement $300$.\n"
        },
        {
          "text": "Un nombre proche de `0.5`, `random` étant uniforme",
          "correct": false,
          "feedback": "Erreur : `random()` est uniforme sur $[0 ; 1[$, donc inférieur\nà $0{,}3$ trois fois sur dix en moyenne.\n"
        }
      ],
      "explanation": "Comparer `random()` à $p$ simule une épreuve de succès de\nprobabilité $p$."
    },
    {
      "id": "q45",
      "difficulty": 3,
      "skills": [
        "balayage",
        "fonction",
        "while"
      ],
      "title": "Balayage au pas de un dixième",
      "partie": "methodes",
      "statement": "Qu'affiche ce programme ?\n```python\ndef f(x):\n    return x ** 2 - 2\n\nk = 0\nwhile f(1 + k / 10) < 0:\n    k = k + 1\nprint(1 + k / 10)\n```",
      "options": [
        {
          "text": "`1.5`, première valeur où $f(x) \\geq 0$",
          "correct": true,
          "feedback": "Bonne réponse : $f(1{,}4) = -0{,}04 < 0$ et $f(1{,}5) = 0{,}25$ ;\nla boucle s'arrête pour $k = 5$.\n"
        },
        {
          "text": "`1.4`, dernière valeur où $f(x) < 0$",
          "correct": false,
          "feedback": "Erreur : en $1{,}4$ la condition est encore vraie, la boucle\ncontinue.\n"
        },
        {
          "text": "`1.4142…`, la racine carrée de $2$",
          "correct": false,
          "feedback": "Erreur : le balayage ne s'arrête que sur les valeurs\n$1 + \\frac{k}{10}$.\n"
        },
        {
          "text": "`5`, le nombre de tours de la boucle",
          "correct": false,
          "feedback": "Erreur : le programme affiche `1 + k / 10`, pas `k`.\n"
        }
      ],
      "explanation": "Le balayage à pas fixe encadre la solution de $f(x) = 0$ entre deux\nvaleurs consécutives de signes contraires."
    }
  ]
}