{
  "chapter": {
    "id": "python-variables",
    "level": "snt",
    "theme": "Programmation",
    "title": "1. Variables et affectation",
    "description": "Premier chapitre de programmation : ce qu'est une variable, le sens du\nsigne égal, la réaffectation, l'ordre des instructions dans une\nséquence, la copie d'une valeur, l'échange de deux variables et\nl'écriture raccourcie des mises à jour.",
    "prerequisites": [],
    "references": []
  },
  "questions": [
    {
      "id": "q01",
      "difficulty": 1,
      "skills": [
        "affectation",
        "variables"
      ],
      "title": "Une variable mise à jour",
      "statement": "Un compte de réseau social gagne des abonnés.\n\n```python\nabonnes = 250\nabonnes = abonnes + 30\n```\n\nQue vaut `abonnes` après ces deux lignes ?",
      "options": [
        {
          "text": "`280`",
          "correct": true,
          "feedback": "Bonne réponse : la deuxième ligne calcule d'abord `abonnes + 30`\navec la valeur du moment, 250, puis range le résultat 280 dans\nla variable.\n"
        },
        {
          "text": "`250`",
          "correct": false,
          "feedback": "Erreur : la deuxième ligne remplace bien l'ancienne valeur. Une\nvariable garde la dernière valeur qu'on lui a affectée.\n"
        },
        {
          "text": "`30`",
          "correct": false,
          "feedback": "Erreur : 30 est ce qu'on ajoute, pas la nouvelle valeur. Le\ncalcul du membre de droite utilise l'ancienne valeur 250.\n"
        },
        {
          "text": "Une erreur, car `abonnes` apparaît des deux côtés",
          "correct": false,
          "feedback": "Erreur : c'est une écriture très courante. Python calcule\nd'abord la droite, avec la valeur actuelle, puis affecte le\nrésultat à gauche.\n"
        }
      ],
      "explanation": "Le signe `=` n'est pas une égalité mais une affectation : on calcule\nla valeur à droite, puis on la range dans la variable nommée à gauche.\n`abonnes = abonnes + 30` se lit « abonnes prend sa valeur plus 30 »."
    },
    {
      "id": "q02",
      "difficulty": 1,
      "skills": [
        "nommage",
        "variables"
      ],
      "title": "Un nom de variable correct",
      "statement": "Un programme compte des photographies. Lequel de ces noms de\nvariable est accepté par Python ?",
      "options": [
        {
          "text": "`2eme_photo`",
          "correct": false,
          "feedback": "Erreur : un nom de variable ne peut pas commencer par un\nchiffre. `photo_2` serait accepté.\n"
        },
        {
          "text": "`nombre-de-photos`",
          "correct": false,
          "feedback": "Erreur : le tiret est le signe de la soustraction. Python lirait\n`nombre - de - photos`, trois variables à soustraire.\n"
        },
        {
          "text": "`nombre_de_photos`",
          "correct": true,
          "feedback": "Bonne réponse : lettres, chiffres et tiret bas, sans commencer\npar un chiffre. C'est la forme habituelle des noms en Python.\n"
        },
        {
          "text": "`nombre de photos`",
          "correct": false,
          "feedback": "Erreur : un nom ne contient pas d'espace. Python verrait trois\nmots séparés et signalerait une erreur de syntaxe.\n"
        }
      ],
      "explanation": "Un nom de variable commence par une lettre ou un tiret bas, puis\nenchaîne lettres, chiffres et tirets bas, sans espace ni tiret. Un nom\nparlant comme `nombre_de_photos` rend le programme lisible."
    },
    {
      "id": "q03",
      "difficulty": 1,
      "skills": [
        "variables",
        "erreur"
      ],
      "title": "Une variable sans valeur",
      "statement": "```python\nlargeur = 800\nprint(largeur * hauteur)\n```\n\nQue se passe-t-il à l'exécution ?",
      "options": [
        {
          "text": "Python affiche 0, une variable inconnue vaut 0 par défaut",
          "correct": false,
          "feedback": "Erreur : une variable n'a aucune valeur par défaut. Tant qu'on\nne lui en a pas affecté une, elle n'existe pas.\n"
        },
        {
          "text": "Python signale une erreur, `hauteur` n'a jamais reçu de valeur",
          "correct": true,
          "feedback": "Bonne réponse : le message est `NameError: name 'hauteur' is not\ndefined`. Il faut affecter une valeur à `hauteur` avant de s'en\nservir.\n"
        },
        {
          "text": "Python affiche 800, la multiplication est ignorée",
          "correct": false,
          "feedback": "Erreur : Python n'ignore jamais une partie d'un calcul. Il ne\npeut pas multiplier par une variable qui n'existe pas et s'arrête.\n"
        },
        {
          "text": "Python affiche le texte `largeur * hauteur` tel quel",
          "correct": false,
          "feedback": "Erreur : sans guillemets, `largeur * hauteur` est un calcul à\neffectuer, pas un texte à afficher.\n"
        }
      ],
      "explanation": "Une variable n'existe qu'à partir de sa première affectation. Lire une\nvariable jamais définie déclenche une erreur `NameError`, qui indique\nle nom fautif."
    },
    {
      "id": "q04",
      "difficulty": 1,
      "skills": [
        "sequence",
        "trace"
      ],
      "title": "L'ordre des instructions",
      "statement": "```python\nprix = 20\nprix = prix * 2\nprix = prix - 5\nprint(prix)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`35`",
          "correct": true,
          "feedback": "Bonne réponse : 20 devient 40 après le doublement, puis 35\naprès la soustraction. Les instructions s'exécutent dans l'ordre.\n"
        },
        {
          "text": "`30`",
          "correct": false,
          "feedback": "Erreur : 30 correspondrait à soustraire d'abord, puis doubler.\nLe programme fait l'inverse, ligne après ligne.\n"
        },
        {
          "text": "`40`",
          "correct": false,
          "feedback": "Erreur : 40 est la valeur après la deuxième ligne. La troisième\nligne enlève encore 5 avant l'affichage.\n"
        },
        {
          "text": "`15`",
          "correct": false,
          "feedback": "Erreur : 15 serait 20 moins 5, sans le doublement. Les\ntrois lignes s'exécutent, dans l'ordre écrit.\n"
        }
      ],
      "explanation": "Un programme est une séquence : chaque instruction s'exécute après la\nprécédente, avec les valeurs du moment. Changer l'ordre de deux lignes\nchange en général le résultat.",
      "variants": [
        {
          "statement": "```python\nprix = 20\nprix = prix * 2\nprix = prix - 5\nprint(prix)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`35`",
              "correct": true,
              "feedback": "Bonne réponse : 20 devient 40 après le doublement, puis 35\naprès la soustraction. Les instructions s'exécutent dans l'ordre.\n"
            },
            {
              "text": "`30`",
              "correct": false,
              "feedback": "Erreur : 30 correspondrait à soustraire d'abord, puis doubler.\nLe programme fait l'inverse, ligne après ligne.\n"
            },
            {
              "text": "`40`",
              "correct": false,
              "feedback": "Erreur : 40 est la valeur après la deuxième ligne. La troisième\nligne enlève encore 5 avant l'affichage.\n"
            },
            {
              "text": "`15`",
              "correct": false,
              "feedback": "Erreur : 15 serait 20 moins 5, sans le doublement. Les\ntrois lignes s'exécutent, dans l'ordre écrit.\n"
            }
          ],
          "explanation": "Un programme est une séquence : chaque instruction s'exécute après la\nprécédente, avec les valeurs du moment. Changer l'ordre de deux lignes\nchange en général le résultat."
        },
        {
          "statement": "```python\nprix = 30\nprix = prix * 2\nprix = prix - 8\nprint(prix)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`52`",
              "correct": true,
              "feedback": "Bonne réponse : 30 devient 60 après le doublement, puis 52\naprès la soustraction. Les instructions s'exécutent dans l'ordre.\n"
            },
            {
              "text": "`44`",
              "correct": false,
              "feedback": "Erreur : 44 correspondrait à soustraire d'abord, puis doubler.\nLe programme fait l'inverse, ligne après ligne.\n"
            },
            {
              "text": "`60`",
              "correct": false,
              "feedback": "Erreur : 60 est la valeur après la deuxième ligne. La troisième\nligne enlève encore 8 avant l'affichage.\n"
            },
            {
              "text": "`22`",
              "correct": false,
              "feedback": "Erreur : 22 serait 30 moins 8, sans le doublement. Les\ntrois lignes s'exécutent, dans l'ordre écrit.\n"
            }
          ],
          "explanation": "Un programme est une séquence : chaque instruction s'exécute après la\nprécédente, avec les valeurs du moment. Changer l'ordre de deux lignes\nchange en général le résultat."
        },
        {
          "statement": "```python\nprix = 15\nprix = prix * 2\nprix = prix - 4\nprint(prix)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`26`",
              "correct": true,
              "feedback": "Bonne réponse : 15 devient 30 après le doublement, puis 26\naprès la soustraction. Les instructions s'exécutent dans l'ordre.\n"
            },
            {
              "text": "`22`",
              "correct": false,
              "feedback": "Erreur : 22 correspondrait à soustraire d'abord, puis doubler.\nLe programme fait l'inverse, ligne après ligne.\n"
            },
            {
              "text": "`30`",
              "correct": false,
              "feedback": "Erreur : 30 est la valeur après la deuxième ligne. La troisième\nligne enlève encore 4 avant l'affichage.\n"
            },
            {
              "text": "`11`",
              "correct": false,
              "feedback": "Erreur : 11 serait 15 moins 4, sans le doublement. Les\ntrois lignes s'exécutent, dans l'ordre écrit.\n"
            }
          ],
          "explanation": "Un programme est une séquence : chaque instruction s'exécute après la\nprécédente, avec les valeurs du moment. Changer l'ordre de deux lignes\nchange en général le résultat."
        }
      ]
    },
    {
      "id": "q05",
      "difficulty": 2,
      "skills": [
        "affectation",
        "trace"
      ],
      "title": "Une valeur copiée",
      "statement": "```python\na = 5\nb = a\na = 7\nprint(b)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`5`",
          "correct": true,
          "feedback": "Bonne réponse : `b = a` copie la valeur de `a` à cet instant, 5.\nModifier `a` ensuite ne touche pas `b`.\n"
        },
        {
          "text": "`7`",
          "correct": false,
          "feedback": "Erreur : `b` n'est pas lié à `a` pour toujours. Il a reçu une\ncopie de sa valeur au moment de l'affectation, avant le changement.\n"
        },
        {
          "text": "`12`",
          "correct": false,
          "feedback": "Erreur : aucune addition n'est écrite. `b = a` copie une valeur,\nelle n'additionne rien.\n"
        },
        {
          "text": "`a`",
          "correct": false,
          "feedback": "Erreur : sans guillemets, `a` désigne la variable, et `b = a`\nrange sa valeur dans `b`, pas son nom.\n"
        }
      ],
      "explanation": "Une affectation copie une valeur, pas un lien. Après `b = a`, les deux\nvariables ont la même valeur, mais chacune vit sa vie : changer l'une\nne change pas l'autre."
    },
    {
      "id": "q06",
      "difficulty": 2,
      "skills": [
        "echange",
        "trace"
      ],
      "title": "Un échange raté",
      "statement": "On voudrait échanger les deux coordonnées d'un point.\n\n```python\nx = 3\ny = 8\nx = y\ny = x\nprint(x, y)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`8 3`",
          "correct": false,
          "feedback": "Erreur : c'est l'échange espéré, mais la troisième ligne a\neffacé la valeur 3 de `x` avant qu'on puisse la donner à `y`.\n"
        },
        {
          "text": "`8 8`",
          "correct": true,
          "feedback": "Bonne réponse : `x = y` donne 8 à `x`, et l'ancienne valeur 3\nest perdue. Puis `y = x` copie ce 8 dans `y`.\n"
        },
        {
          "text": "`3 8`",
          "correct": false,
          "feedback": "Erreur : les deux affectations modifient bien les variables.\nAprès `x = y`, `x` vaut 8.\n"
        },
        {
          "text": "`3 3`",
          "correct": false,
          "feedback": "Erreur : la première affectation copie `y` dans `x`, pas\nl'inverse. C'est la valeur 8 qui se propage.\n"
        }
      ],
      "explanation": "Une affectation écrase l'ancienne valeur sans la garder. Pour échanger\ndeux variables, il faut d'abord mettre l'une d'elles à l'abri dans une\ntroisième variable.",
      "variants": [
        {
          "statement": "On voudrait échanger les deux coordonnées d'un point.\n\n```python\nx = 3\ny = 8\nx = y\ny = x\nprint(x, y)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`8 3`",
              "correct": false,
              "feedback": "Erreur : c'est l'échange espéré, mais la troisième ligne a\neffacé la valeur 3 de `x` avant qu'on puisse la donner à `y`.\n"
            },
            {
              "text": "`8 8`",
              "correct": true,
              "feedback": "Bonne réponse : `x = y` donne 8 à `x`, et l'ancienne valeur 3\nest perdue. Puis `y = x` copie ce 8 dans `y`.\n"
            },
            {
              "text": "`3 8`",
              "correct": false,
              "feedback": "Erreur : les deux affectations modifient bien les variables.\nAprès `x = y`, `x` vaut 8.\n"
            },
            {
              "text": "`3 3`",
              "correct": false,
              "feedback": "Erreur : la première affectation copie `y` dans `x`, pas\nl'inverse. C'est la valeur 8 qui se propage.\n"
            }
          ],
          "explanation": "Une affectation écrase l'ancienne valeur sans la garder. Pour échanger\ndeux variables, il faut d'abord mettre l'une d'elles à l'abri dans une\ntroisième variable."
        },
        {
          "statement": "On voudrait échanger les deux coordonnées d'un point.\n\n```python\nx = 5\ny = 2\nx = y\ny = x\nprint(x, y)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`2 5`",
              "correct": false,
              "feedback": "Erreur : c'est l'échange espéré, mais la troisième ligne a\neffacé la valeur 5 de `x` avant qu'on puisse la donner à `y`.\n"
            },
            {
              "text": "`2 2`",
              "correct": true,
              "feedback": "Bonne réponse : `x = y` donne 2 à `x`, et l'ancienne valeur 5\nest perdue. Puis `y = x` copie ce 2 dans `y`.\n"
            },
            {
              "text": "`5 2`",
              "correct": false,
              "feedback": "Erreur : les deux affectations modifient bien les variables.\nAprès `x = y`, `x` vaut 2.\n"
            },
            {
              "text": "`5 5`",
              "correct": false,
              "feedback": "Erreur : la première affectation copie `y` dans `x`, pas\nl'inverse. C'est la valeur 2 qui se propage.\n"
            }
          ],
          "explanation": "Une affectation écrase l'ancienne valeur sans la garder. Pour échanger\ndeux variables, il faut d'abord mettre l'une d'elles à l'abri dans une\ntroisième variable."
        },
        {
          "statement": "On voudrait échanger les deux coordonnées d'un point.\n\n```python\nx = 7\ny = 4\nx = y\ny = x\nprint(x, y)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`4 7`",
              "correct": false,
              "feedback": "Erreur : c'est l'échange espéré, mais la troisième ligne a\neffacé la valeur 7 de `x` avant qu'on puisse la donner à `y`.\n"
            },
            {
              "text": "`4 4`",
              "correct": true,
              "feedback": "Bonne réponse : `x = y` donne 4 à `x`, et l'ancienne valeur 7\nest perdue. Puis `y = x` copie ce 4 dans `y`.\n"
            },
            {
              "text": "`7 4`",
              "correct": false,
              "feedback": "Erreur : les deux affectations modifient bien les variables.\nAprès `x = y`, `x` vaut 4.\n"
            },
            {
              "text": "`7 7`",
              "correct": false,
              "feedback": "Erreur : la première affectation copie `y` dans `x`, pas\nl'inverse. C'est la valeur 4 qui se propage.\n"
            }
          ],
          "explanation": "Une affectation écrase l'ancienne valeur sans la garder. Pour échanger\ndeux variables, il faut d'abord mettre l'une d'elles à l'abri dans une\ntroisième variable."
        }
      ]
    },
    {
      "id": "q07",
      "difficulty": 2,
      "skills": [
        "echange",
        "affectation"
      ],
      "title": "L'échange avec une variable de secours",
      "statement": "`x` vaut 3 et `y` vaut 8. Quelle suite d'instructions échange leurs\nvaleurs, pour obtenir `x` égal à 8 et `y` égal à 3 ?",
      "options": [
        {
          "text": "`tmp = x`, puis `x = y`, puis `y = tmp`",
          "correct": true,
          "feedback": "Bonne réponse : `tmp` conserve 3, `x` reçoit 8, puis `y` reçoit\nle 3 mis à l'abri. Rien n'est perdu.\n"
        },
        {
          "text": "`x = y`, puis `y = x`",
          "correct": false,
          "feedback": "Erreur : après `x = y`, la valeur 3 n'existe plus nulle part. Les\ndeux variables finissent à 8.\n"
        },
        {
          "text": "`tmp = x`, puis `y = tmp`, puis `x = y`",
          "correct": false,
          "feedback": "Erreur : `y = tmp` écrase le 8 avec 3 avant que `x` l'ait reçu.\nLes deux variables finissent à 3.\n"
        },
        {
          "text": "`x = tmp`, puis `tmp = y`, puis `y = x`",
          "correct": false,
          "feedback": "Erreur : `tmp` n'a encore aucune valeur à la première ligne, le\nprogramme s'arrête sur une erreur.\n"
        }
      ],
      "explanation": "L'échange classique tient en trois affectations : sauvegarder une\nvaleur dans une variable temporaire, écraser, puis restituer. L'ordre\ndes trois lignes est ce qui compte."
    },
    {
      "id": "q08",
      "difficulty": 1,
      "skills": [
        "affectation",
        "trace"
      ],
      "title": "Trois modifications successives",
      "statement": "Un thermostat corrige une consigne de température.\n\n```python\nconsigne = 12\nconsigne = consigne + 3\nconsigne = consigne - 5\nconsigne = consigne * 2\nprint(consigne)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`20`",
          "correct": true,
          "feedback": "Bonne réponse : 12 devient 15, puis 10, puis\n20. Chaque ligne repart de la valeur laissée par la précédente.\n"
        },
        {
          "text": "`10`",
          "correct": false,
          "feedback": "Erreur : 10 est la valeur après la soustraction. La\ndernière ligne la double encore.\n"
        },
        {
          "text": "`24`",
          "correct": false,
          "feedback": "Erreur : 24 serait le double de 12, comme si les lignes\ndu milieu n'existaient pas. Elles s'exécutent toutes.\n"
        },
        {
          "text": "`14`",
          "correct": false,
          "feedback": "Erreur : 14 serait le double de 7, c'est-à-dire de\n12 moins 5, comme si la ligne qui ajoute 3 n'existait pas.\nAucune ligne n'est sautée.\n"
        }
      ],
      "explanation": "Pour suivre un programme, on tient à jour la valeur de chaque variable\nligne après ligne : c'est une trace. Ici, la consigne passe par 12,\n15, 10 et 20.",
      "variants": [
        {
          "statement": "Un thermostat corrige une consigne de température.\n\n```python\nconsigne = 12\nconsigne = consigne + 3\nconsigne = consigne - 5\nconsigne = consigne * 2\nprint(consigne)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`20`",
              "correct": true,
              "feedback": "Bonne réponse : 12 devient 15, puis 10, puis\n20. Chaque ligne repart de la valeur laissée par la précédente.\n"
            },
            {
              "text": "`10`",
              "correct": false,
              "feedback": "Erreur : 10 est la valeur après la soustraction. La\ndernière ligne la double encore.\n"
            },
            {
              "text": "`24`",
              "correct": false,
              "feedback": "Erreur : 24 serait le double de 12, comme si les lignes\ndu milieu n'existaient pas. Elles s'exécutent toutes.\n"
            },
            {
              "text": "`14`",
              "correct": false,
              "feedback": "Erreur : 14 serait le double de 7, c'est-à-dire de\n12 moins 5, comme si la ligne qui ajoute 3 n'existait pas.\nAucune ligne n'est sautée.\n"
            }
          ],
          "explanation": "Pour suivre un programme, on tient à jour la valeur de chaque variable\nligne après ligne : c'est une trace. Ici, la consigne passe par 12,\n15, 10 et 20."
        },
        {
          "statement": "Un thermostat corrige une consigne de température.\n\n```python\nconsigne = 18\nconsigne = consigne + 4\nconsigne = consigne - 7\nconsigne = consigne * 2\nprint(consigne)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`30`",
              "correct": true,
              "feedback": "Bonne réponse : 18 devient 22, puis 15, puis\n30. Chaque ligne repart de la valeur laissée par la précédente.\n"
            },
            {
              "text": "`15`",
              "correct": false,
              "feedback": "Erreur : 15 est la valeur après la soustraction. La\ndernière ligne la double encore.\n"
            },
            {
              "text": "`36`",
              "correct": false,
              "feedback": "Erreur : 36 serait le double de 18, comme si les lignes\ndu milieu n'existaient pas. Elles s'exécutent toutes.\n"
            },
            {
              "text": "`22`",
              "correct": false,
              "feedback": "Erreur : 22 serait le double de 11, c'est-à-dire de\n18 moins 7, comme si la ligne qui ajoute 4 n'existait pas.\nAucune ligne n'est sautée.\n"
            }
          ],
          "explanation": "Pour suivre un programme, on tient à jour la valeur de chaque variable\nligne après ligne : c'est une trace. Ici, la consigne passe par 18,\n22, 15 et 30."
        },
        {
          "statement": "Un thermostat corrige une consigne de température.\n\n```python\nconsigne = 14\nconsigne = consigne + 5\nconsigne = consigne - 8\nconsigne = consigne * 2\nprint(consigne)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`22`",
              "correct": true,
              "feedback": "Bonne réponse : 14 devient 19, puis 11, puis\n22. Chaque ligne repart de la valeur laissée par la précédente.\n"
            },
            {
              "text": "`11`",
              "correct": false,
              "feedback": "Erreur : 11 est la valeur après la soustraction. La\ndernière ligne la double encore.\n"
            },
            {
              "text": "`28`",
              "correct": false,
              "feedback": "Erreur : 28 serait le double de 14, comme si les lignes\ndu milieu n'existaient pas. Elles s'exécutent toutes.\n"
            },
            {
              "text": "`12`",
              "correct": false,
              "feedback": "Erreur : 12 serait le double de 6, c'est-à-dire de\n14 moins 8, comme si la ligne qui ajoute 5 n'existait pas.\nAucune ligne n'est sautée.\n"
            }
          ],
          "explanation": "Pour suivre un programme, on tient à jour la valeur de chaque variable\nligne après ligne : c'est une trace. Ici, la consigne passe par 14,\n19, 11 et 22."
        }
      ]
    },
    {
      "id": "q09",
      "difficulty": 2,
      "skills": [
        "incrementation",
        "affectation"
      ],
      "title": "L'écriture raccourcie",
      "statement": "```python\nscore = 40\nscore += 10\nscore -= 5\nprint(score)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`45`",
          "correct": true,
          "feedback": "Bonne réponse : `score += 10` signifie `score = score + 10`, et\n`score -= 5` signifie `score = score - 5`. 40 devient\n50 puis 45.\n"
        },
        {
          "text": "`55`",
          "correct": false,
          "feedback": "Erreur : `-=` retranche, il n'ajoute pas. Après 50, le\nscore descend à 45.\n"
        },
        {
          "text": "`50`",
          "correct": false,
          "feedback": "Erreur : 50 est la valeur après la deuxième ligne. La\ntroisième enlève encore 5.\n"
        },
        {
          "text": "Une erreur, l'opérateur `+=` n'existe pas en Python",
          "correct": false,
          "feedback": "Erreur : `+=` et `-=` existent bien. Ce sont des raccourcis très\nutilisés pour mettre une variable à jour.\n"
        }
      ],
      "explanation": "`x += 3` est un raccourci pour `x = x + 3` ; de même pour `-=`, `*=`\net `/=`. On lit toujours « la variable prend son ancienne valeur\nmodifiée ».",
      "variants": [
        {
          "statement": "```python\nscore = 40\nscore += 10\nscore -= 5\nprint(score)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`45`",
              "correct": true,
              "feedback": "Bonne réponse : `score += 10` signifie `score = score + 10`, et\n`score -= 5` signifie `score = score - 5`. 40 devient\n50 puis 45.\n"
            },
            {
              "text": "`55`",
              "correct": false,
              "feedback": "Erreur : `-=` retranche, il n'ajoute pas. Après 50, le\nscore descend à 45.\n"
            },
            {
              "text": "`50`",
              "correct": false,
              "feedback": "Erreur : 50 est la valeur après la deuxième ligne. La\ntroisième enlève encore 5.\n"
            },
            {
              "text": "Une erreur, l'opérateur `+=` n'existe pas en Python",
              "correct": false,
              "feedback": "Erreur : `+=` et `-=` existent bien. Ce sont des raccourcis très\nutilisés pour mettre une variable à jour.\n"
            }
          ],
          "explanation": "`x += 3` est un raccourci pour `x = x + 3` ; de même pour `-=`, `*=`\net `/=`. On lit toujours « la variable prend son ancienne valeur\nmodifiée »."
        },
        {
          "statement": "```python\nscore = 60\nscore += 15\nscore -= 8\nprint(score)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`67`",
              "correct": true,
              "feedback": "Bonne réponse : `score += 15` signifie `score = score + 15`, et\n`score -= 8` signifie `score = score - 8`. 60 devient\n75 puis 67.\n"
            },
            {
              "text": "`83`",
              "correct": false,
              "feedback": "Erreur : `-=` retranche, il n'ajoute pas. Après 75, le\nscore descend à 67.\n"
            },
            {
              "text": "`75`",
              "correct": false,
              "feedback": "Erreur : 75 est la valeur après la deuxième ligne. La\ntroisième enlève encore 8.\n"
            },
            {
              "text": "Une erreur, l'opérateur `+=` n'existe pas en Python",
              "correct": false,
              "feedback": "Erreur : `+=` et `-=` existent bien. Ce sont des raccourcis très\nutilisés pour mettre une variable à jour.\n"
            }
          ],
          "explanation": "`x += 3` est un raccourci pour `x = x + 3` ; de même pour `-=`, `*=`\net `/=`. On lit toujours « la variable prend son ancienne valeur\nmodifiée »."
        },
        {
          "statement": "```python\nscore = 25\nscore += 12\nscore -= 7\nprint(score)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`30`",
              "correct": true,
              "feedback": "Bonne réponse : `score += 12` signifie `score = score + 12`, et\n`score -= 7` signifie `score = score - 7`. 25 devient\n37 puis 30.\n"
            },
            {
              "text": "`44`",
              "correct": false,
              "feedback": "Erreur : `-=` retranche, il n'ajoute pas. Après 37, le\nscore descend à 30.\n"
            },
            {
              "text": "`37`",
              "correct": false,
              "feedback": "Erreur : 37 est la valeur après la deuxième ligne. La\ntroisième enlève encore 7.\n"
            },
            {
              "text": "Une erreur, l'opérateur `+=` n'existe pas en Python",
              "correct": false,
              "feedback": "Erreur : `+=` et `-=` existent bien. Ce sont des raccourcis très\nutilisés pour mettre une variable à jour.\n"
            }
          ],
          "explanation": "`x += 3` est un raccourci pour `x = x + 3` ; de même pour `-=`, `*=`\net `/=`. On lit toujours « la variable prend son ancienne valeur\nmodifiée »."
        }
      ]
    },
    {
      "id": "q10",
      "difficulty": 2,
      "skills": [
        "affectation",
        "erreur"
      ],
      "title": "Le sens du signe égal",
      "statement": "Une seule de ces lignes provoque une erreur. Laquelle ?",
      "options": [
        {
          "text": "`5 = nombre`",
          "correct": true,
          "feedback": "Bonne réponse : à gauche du signe `=`, il faut le nom de la\nvariable qui reçoit. On ne peut pas donner une valeur au nombre 5.\n"
        },
        {
          "text": "`nombre = 5`",
          "correct": false,
          "feedback": "Erreur : c'est une affectation ordinaire, `nombre` reçoit 5.\n"
        },
        {
          "text": "`nombre = nombre + 5`",
          "correct": false,
          "feedback": "Erreur : cette ligne est correcte dès que `nombre` a une valeur.\nElle l'augmente de 5.\n"
        },
        {
          "text": "`nombre = 5 + 5`",
          "correct": false,
          "feedback": "Erreur : Python calcule 10 puis le range dans `nombre`. Le membre\nde droite peut être n'importe quel calcul.\n"
        }
      ],
      "explanation": "Une affectation se lit de droite à gauche : la valeur calculée à\ndroite est rangée dans la variable nommée à gauche. Le membre de\ngauche doit donc être un nom de variable."
    },
    {
      "id": "q11",
      "difficulty": 2,
      "skills": [
        "trace",
        "affectation"
      ],
      "title": "Une valeur écrasée",
      "statement": "Un programme ajuste la luminosité d'un pixel.\n\n```python\npixel = 120\npixel = 255\npixel = pixel - 55\nprint(pixel)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`200`",
          "correct": true,
          "feedback": "Bonne réponse : la deuxième ligne remplace 120 par 255, et la\ntroisième enlève 55, ce qui donne 200.\n"
        },
        {
          "text": "`65`",
          "correct": false,
          "feedback": "Erreur : 65 serait 120 moins 55. Mais la valeur 120 a\nété écrasée par 255 avant la soustraction.\n"
        },
        {
          "text": "`175`",
          "correct": false,
          "feedback": "Erreur : 175 serait 120 plus 55. Aucune addition\nn'apparaît, et la valeur de départ a été remplacée.\n"
        },
        {
          "text": "`255`",
          "correct": false,
          "feedback": "Erreur : 255 est la valeur après la deuxième ligne. La troisième\nla diminue de 55 avant l'affichage.\n"
        }
      ],
      "explanation": "Une nouvelle affectation efface l'ancienne valeur, sans en garder de\ntrace. Seule la dernière valeur affectée compte pour la suite du\nprogramme.",
      "variants": [
        {
          "statement": "Un programme ajuste la luminosité d'un pixel.\n\n```python\npixel = 120\npixel = 255\npixel = pixel - 55\nprint(pixel)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`200`",
              "correct": true,
              "feedback": "Bonne réponse : la deuxième ligne remplace 120 par 255, et la\ntroisième enlève 55, ce qui donne 200.\n"
            },
            {
              "text": "`65`",
              "correct": false,
              "feedback": "Erreur : 65 serait 120 moins 55. Mais la valeur 120 a\nété écrasée par 255 avant la soustraction.\n"
            },
            {
              "text": "`175`",
              "correct": false,
              "feedback": "Erreur : 175 serait 120 plus 55. Aucune addition\nn'apparaît, et la valeur de départ a été remplacée.\n"
            },
            {
              "text": "`255`",
              "correct": false,
              "feedback": "Erreur : 255 est la valeur après la deuxième ligne. La troisième\nla diminue de 55 avant l'affichage.\n"
            }
          ],
          "explanation": "Une nouvelle affectation efface l'ancienne valeur, sans en garder de\ntrace. Seule la dernière valeur affectée compte pour la suite du\nprogramme."
        },
        {
          "statement": "Un programme ajuste la luminosité d'un pixel.\n\n```python\npixel = 90\npixel = 240\npixel = pixel - 60\nprint(pixel)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`180`",
              "correct": true,
              "feedback": "Bonne réponse : la deuxième ligne remplace 90 par 240, et la\ntroisième enlève 60, ce qui donne 180.\n"
            },
            {
              "text": "`30`",
              "correct": false,
              "feedback": "Erreur : 30 serait 90 moins 60. Mais la valeur 90 a\nété écrasée par 240 avant la soustraction.\n"
            },
            {
              "text": "`150`",
              "correct": false,
              "feedback": "Erreur : 150 serait 90 plus 60. Aucune addition\nn'apparaît, et la valeur de départ a été remplacée.\n"
            },
            {
              "text": "`240`",
              "correct": false,
              "feedback": "Erreur : 240 est la valeur après la deuxième ligne. La troisième\nla diminue de 60 avant l'affichage.\n"
            }
          ],
          "explanation": "Une nouvelle affectation efface l'ancienne valeur, sans en garder de\ntrace. Seule la dernière valeur affectée compte pour la suite du\nprogramme."
        },
        {
          "statement": "Un programme ajuste la luminosité d'un pixel.\n\n```python\npixel = 150\npixel = 230\npixel = pixel - 45\nprint(pixel)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`185`",
              "correct": true,
              "feedback": "Bonne réponse : la deuxième ligne remplace 150 par 230, et la\ntroisième enlève 45, ce qui donne 185.\n"
            },
            {
              "text": "`105`",
              "correct": false,
              "feedback": "Erreur : 105 serait 150 moins 45. Mais la valeur 150 a\nété écrasée par 230 avant la soustraction.\n"
            },
            {
              "text": "`195`",
              "correct": false,
              "feedback": "Erreur : 195 serait 150 plus 45. Aucune addition\nn'apparaît, et la valeur de départ a été remplacée.\n"
            },
            {
              "text": "`230`",
              "correct": false,
              "feedback": "Erreur : 230 est la valeur après la deuxième ligne. La troisième\nla diminue de 45 avant l'affichage.\n"
            }
          ],
          "explanation": "Une nouvelle affectation efface l'ancienne valeur, sans en garder de\ntrace. Seule la dernière valeur affectée compte pour la suite du\nprogramme."
        }
      ]
    },
    {
      "id": "q12",
      "difficulty": 3,
      "skills": [
        "trace",
        "variables"
      ],
      "title": "Deux variables qui dépendent l'une de l'autre",
      "statement": "```python\na = 2\nb = a + 3\na = b * 2\nb = a - b\nprint(a, b)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`10 5`",
          "correct": true,
          "feedback": "Bonne réponse : `b` vaut 5, puis `a` vaut 10, puis `b` vaut\n10 moins 5, soit 5.\n"
        },
        {
          "text": "`10 8`",
          "correct": false,
          "feedback": "Erreur : 8 serait 10 moins 2, avec l'ancienne valeur de\n`a` à la place de `b`. Or c'est `b`, qui vaut 5, que l'on\nsoustrait à la dernière ligne.\n"
        },
        {
          "text": "`2 5`",
          "correct": false,
          "feedback": "Erreur : la troisième ligne modifie `a`, qui passe de 2 à 10.\n"
        },
        {
          "text": "`4 -1`",
          "correct": false,
          "feedback": "Erreur : la troisième ligne multiplie `b` par 2, pas `a`. Elle\ndonne 10 à `a`, et non 4, et la dernière ligne calcule\nalors 10 moins 5.\n"
        }
      ],
      "explanation": "Dans une trace, on met à jour une variable à la fois, avec les valeurs\ndes autres au moment précis de la ligne. Écrire un tableau des\nvaleurs ligne par ligne évite les confusions.",
      "variants": [
        {
          "statement": "```python\na = 2\nb = a + 3\na = b * 2\nb = a - b\nprint(a, b)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`10 5`",
              "correct": true,
              "feedback": "Bonne réponse : `b` vaut 5, puis `a` vaut 10, puis `b` vaut\n10 moins 5, soit 5.\n"
            },
            {
              "text": "`10 8`",
              "correct": false,
              "feedback": "Erreur : 8 serait 10 moins 2, avec l'ancienne valeur de\n`a` à la place de `b`. Or c'est `b`, qui vaut 5, que l'on\nsoustrait à la dernière ligne.\n"
            },
            {
              "text": "`2 5`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne modifie `a`, qui passe de 2 à 10.\n"
            },
            {
              "text": "`4 -1`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne multiplie `b` par 2, pas `a`. Elle\ndonne 10 à `a`, et non 4, et la dernière ligne calcule\nalors 10 moins 5.\n"
            }
          ],
          "explanation": "Dans une trace, on met à jour une variable à la fois, avec les valeurs\ndes autres au moment précis de la ligne. Écrire un tableau des\nvaleurs ligne par ligne évite les confusions."
        },
        {
          "statement": "```python\na = 4\nb = a + 5\na = b * 3\nb = a - b\nprint(a, b)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`27 18`",
              "correct": true,
              "feedback": "Bonne réponse : `b` vaut 9, puis `a` vaut 27, puis `b` vaut\n27 moins 9, soit 18.\n"
            },
            {
              "text": "`27 23`",
              "correct": false,
              "feedback": "Erreur : 23 serait 27 moins 4, avec l'ancienne valeur de\n`a` à la place de `b`. Or c'est `b`, qui vaut 9, que l'on\nsoustrait à la dernière ligne.\n"
            },
            {
              "text": "`4 9`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne modifie `a`, qui passe de 4 à 27.\n"
            },
            {
              "text": "`12 3`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne multiplie `b` par 3, pas `a`. Elle\ndonne 27 à `a`, et non 12, et la dernière ligne calcule\nalors 27 moins 9.\n"
            }
          ],
          "explanation": "Dans une trace, on met à jour une variable à la fois, avec les valeurs\ndes autres au moment précis de la ligne. Écrire un tableau des\nvaleurs ligne par ligne évite les confusions."
        },
        {
          "statement": "```python\na = 3\nb = a + 4\na = b * 3\nb = a - b\nprint(a, b)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`21 14`",
              "correct": true,
              "feedback": "Bonne réponse : `b` vaut 7, puis `a` vaut 21, puis `b` vaut\n21 moins 7, soit 14.\n"
            },
            {
              "text": "`21 18`",
              "correct": false,
              "feedback": "Erreur : 18 serait 21 moins 3, avec l'ancienne valeur de\n`a` à la place de `b`. Or c'est `b`, qui vaut 7, que l'on\nsoustrait à la dernière ligne.\n"
            },
            {
              "text": "`3 7`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne modifie `a`, qui passe de 3 à 21.\n"
            },
            {
              "text": "`9 2`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne multiplie `b` par 3, pas `a`. Elle\ndonne 21 à `a`, et non 9, et la dernière ligne calcule\nalors 21 moins 7.\n"
            }
          ],
          "explanation": "Dans une trace, on met à jour une variable à la fois, avec les valeurs\ndes autres au moment précis de la ligne. Écrire un tableau des\nvaleurs ligne par ligne évite les confusions."
        }
      ]
    },
    {
      "id": "q13",
      "difficulty": 1,
      "skills": [
        "nommage",
        "erreur"
      ],
      "title": "Majuscule ou minuscule",
      "statement": "```python\nLatitude = 45.7\nprint(latitude)\n```\n\nQue se passe-t-il ?",
      "options": [
        {
          "text": "Python affiche 45.7, la casse des lettres n'a pas d'importance",
          "correct": false,
          "feedback": "Erreur : pour Python, `Latitude` et `latitude` sont deux noms\ndifférents. Le second n'a jamais reçu de valeur.\n"
        },
        {
          "text": "Python signale une erreur, `latitude` n'existe pas",
          "correct": true,
          "feedback": "Bonne réponse : les noms distinguent majuscules et minuscules.\nSeule `Latitude` a été définie, `latitude` provoque une erreur\n`NameError`.\n"
        },
        {
          "text": "Python affiche le mot Latitude, sans sa valeur",
          "correct": false,
          "feedback": "Erreur : `print` affiche la valeur d'une variable, jamais son\nnom. Et ici, la variable demandée n'existe pas.\n"
        },
        {
          "text": "Python affiche 0.0, valeur par défaut d'une variable",
          "correct": false,
          "feedback": "Erreur : il n'y a pas de valeur par défaut. Une variable jamais\naffectée n'existe pas.\n"
        }
      ],
      "explanation": "Python distingue majuscules et minuscules dans les noms. Pour éviter\nles erreurs, on écrit les noms de variables en minuscules, avec des\ntirets bas entre les mots."
    },
    {
      "id": "q14",
      "difficulty": 2,
      "skills": [
        "affectation",
        "trace"
      ],
      "title": "Une ligne qui ne change rien",
      "statement": "```python\nx = 4\nx = x\nx = x * x\nprint(x)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`16`",
          "correct": true,
          "feedback": "Bonne réponse : `x = x` remet dans `x` sa propre valeur, sans\neffet. Puis `x * x` vaut 4 fois 4.\n"
        },
        {
          "text": "`4`",
          "correct": false,
          "feedback": "Erreur : la troisième ligne modifie bien `x`, qui devient 16.\n"
        },
        {
          "text": "`8`",
          "correct": false,
          "feedback": "Erreur : `x * x` est une multiplication, 4 fois 4, et non une\naddition.\n"
        },
        {
          "text": "`44`",
          "correct": false,
          "feedback": "Erreur : `x * x` multiplie deux nombres, il ne colle pas deux\nchiffres. Le résultat est 16.\n"
        }
      ],
      "explanation": "La ligne `x = x` est inutile mais correcte : elle affecte à `x` sa\npropre valeur. Ce qui compte, c'est la dernière ligne, qui calcule\nle carré."
    },
    {
      "id": "q15",
      "difficulty": 2,
      "skills": [
        "sequence",
        "trace"
      ],
      "title": "Afficher avant de modifier",
      "statement": "```python\nniveau = 3\nprint(niveau)\nniveau = niveau + 1\nprint(niveau)\nniveau = niveau * 2\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`3` puis `4`",
          "correct": true,
          "feedback": "Bonne réponse : chaque `print` affiche la valeur du moment. Le\ndoublement final n'est jamais affiché.\n"
        },
        {
          "text": "`4` puis `8`",
          "correct": false,
          "feedback": "Erreur : le premier `print` vient avant l'ajout de 1, il affiche\n3. Et le doublement n'est suivi d'aucun affichage.\n"
        },
        {
          "text": "`3` puis `8`",
          "correct": false,
          "feedback": "Erreur : le second `print` vient avant le doublement, il affiche\n4.\n"
        },
        {
          "text": "`4` puis `4`",
          "correct": false,
          "feedback": "Erreur : le premier affichage a lieu quand `niveau` vaut encore\n3.\n"
        }
      ],
      "explanation": "`print` affiche la valeur d'une variable au moment où il s'exécute.\nUne modification faite après un affichage ne le change pas, et une\nmodification finale sans affichage reste invisible.",
      "variants": [
        {
          "statement": "```python\nniveau = 3\nprint(niveau)\nniveau = niveau + 1\nprint(niveau)\nniveau = niveau * 2\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`3` puis `4`",
              "correct": true,
              "feedback": "Bonne réponse : chaque `print` affiche la valeur du moment. Le\ndoublement final n'est jamais affiché.\n"
            },
            {
              "text": "`4` puis `8`",
              "correct": false,
              "feedback": "Erreur : le premier `print` vient avant l'ajout de 1, il affiche\n3. Et le doublement n'est suivi d'aucun affichage.\n"
            },
            {
              "text": "`3` puis `8`",
              "correct": false,
              "feedback": "Erreur : le second `print` vient avant le doublement, il affiche\n4.\n"
            },
            {
              "text": "`4` puis `4`",
              "correct": false,
              "feedback": "Erreur : le premier affichage a lieu quand `niveau` vaut encore\n3.\n"
            }
          ],
          "explanation": "`print` affiche la valeur d'une variable au moment où il s'exécute.\nUne modification faite après un affichage ne le change pas, et une\nmodification finale sans affichage reste invisible."
        },
        {
          "statement": "```python\nniveau = 6\nprint(niveau)\nniveau = niveau + 1\nprint(niveau)\nniveau = niveau * 2\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`6` puis `7`",
              "correct": true,
              "feedback": "Bonne réponse : chaque `print` affiche la valeur du moment. Le\ndoublement final n'est jamais affiché.\n"
            },
            {
              "text": "`7` puis `14`",
              "correct": false,
              "feedback": "Erreur : le premier `print` vient avant l'ajout de 1, il affiche\n6. Et le doublement n'est suivi d'aucun affichage.\n"
            },
            {
              "text": "`6` puis `14`",
              "correct": false,
              "feedback": "Erreur : le second `print` vient avant le doublement, il affiche\n7.\n"
            },
            {
              "text": "`7` puis `7`",
              "correct": false,
              "feedback": "Erreur : le premier affichage a lieu quand `niveau` vaut encore\n6.\n"
            }
          ],
          "explanation": "`print` affiche la valeur d'une variable au moment où il s'exécute.\nUne modification faite après un affichage ne le change pas, et une\nmodification finale sans affichage reste invisible."
        },
        {
          "statement": "```python\nniveau = 9\nprint(niveau)\nniveau = niveau + 1\nprint(niveau)\nniveau = niveau * 2\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`9` puis `10`",
              "correct": true,
              "feedback": "Bonne réponse : chaque `print` affiche la valeur du moment. Le\ndoublement final n'est jamais affiché.\n"
            },
            {
              "text": "`10` puis `20`",
              "correct": false,
              "feedback": "Erreur : le premier `print` vient avant l'ajout de 1, il affiche\n9. Et le doublement n'est suivi d'aucun affichage.\n"
            },
            {
              "text": "`9` puis `20`",
              "correct": false,
              "feedback": "Erreur : le second `print` vient avant le doublement, il affiche\n10.\n"
            },
            {
              "text": "`10` puis `10`",
              "correct": false,
              "feedback": "Erreur : le premier affichage a lieu quand `niveau` vaut encore\n9.\n"
            }
          ],
          "explanation": "`print` affiche la valeur d'une variable au moment où il s'exécute.\nUne modification faite après un affichage ne le change pas, et une\nmodification finale sans affichage reste invisible."
        }
      ]
    },
    {
      "id": "q16",
      "difficulty": 3,
      "skills": [
        "echange",
        "trace"
      ],
      "title": "Une rotation de trois valeurs",
      "statement": "```python\na = 1\nb = 2\nc = 3\ntmp = a\na = b\nb = c\nc = tmp\nprint(a, b, c)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`2 3 1`",
          "correct": true,
          "feedback": "Bonne réponse : `a` prend la valeur de `b`, `b` celle de `c`, et\n`c` récupère l'ancienne valeur de `a` gardée dans `tmp`.\n"
        },
        {
          "text": "`3 1 2`",
          "correct": false,
          "feedback": "Erreur : c'est la rotation dans l'autre sens. Ici `a = b` donne\n2 à `a`.\n"
        },
        {
          "text": "`1 2 3`",
          "correct": false,
          "feedback": "Erreur : les affectations modifient bien les trois variables, la\nvaleur de chacune se décale.\n"
        },
        {
          "text": "`2 3 3`",
          "correct": false,
          "feedback": "Erreur : `c = tmp` donne à `c` la valeur sauvegardée au début,\n1, et non celle de `b`.\n"
        }
      ],
      "explanation": "Une variable temporaire sert à ne perdre aucune valeur quand on fait\ntourner plusieurs variables. On suit les valeurs ligne par ligne :\n`tmp` vaut 1, puis `a` vaut 2, `b` vaut 3 et `c` vaut 1.",
      "variants": [
        {
          "statement": "```python\na = 1\nb = 2\nc = 3\ntmp = a\na = b\nb = c\nc = tmp\nprint(a, b, c)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`2 3 1`",
              "correct": true,
              "feedback": "Bonne réponse : `a` prend la valeur de `b`, `b` celle de `c`, et\n`c` récupère l'ancienne valeur de `a` gardée dans `tmp`.\n"
            },
            {
              "text": "`3 1 2`",
              "correct": false,
              "feedback": "Erreur : c'est la rotation dans l'autre sens. Ici `a = b` donne\n2 à `a`.\n"
            },
            {
              "text": "`1 2 3`",
              "correct": false,
              "feedback": "Erreur : les affectations modifient bien les trois variables, la\nvaleur de chacune se décale.\n"
            },
            {
              "text": "`2 3 3`",
              "correct": false,
              "feedback": "Erreur : `c = tmp` donne à `c` la valeur sauvegardée au début,\n1, et non celle de `b`.\n"
            }
          ],
          "explanation": "Une variable temporaire sert à ne perdre aucune valeur quand on fait\ntourner plusieurs variables. On suit les valeurs ligne par ligne :\n`tmp` vaut 1, puis `a` vaut 2, `b` vaut 3 et `c` vaut 1."
        },
        {
          "statement": "```python\na = 5\nb = 7\nc = 4\ntmp = a\na = b\nb = c\nc = tmp\nprint(a, b, c)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`7 4 5`",
              "correct": true,
              "feedback": "Bonne réponse : `a` prend la valeur de `b`, `b` celle de `c`, et\n`c` récupère l'ancienne valeur de `a` gardée dans `tmp`.\n"
            },
            {
              "text": "`4 5 7`",
              "correct": false,
              "feedback": "Erreur : c'est la rotation dans l'autre sens. Ici `a = b` donne\n7 à `a`.\n"
            },
            {
              "text": "`5 7 4`",
              "correct": false,
              "feedback": "Erreur : les affectations modifient bien les trois variables, la\nvaleur de chacune se décale.\n"
            },
            {
              "text": "`7 4 4`",
              "correct": false,
              "feedback": "Erreur : `c = tmp` donne à `c` la valeur sauvegardée au début,\n5, et non celle de `b`.\n"
            }
          ],
          "explanation": "Une variable temporaire sert à ne perdre aucune valeur quand on fait\ntourner plusieurs variables. On suit les valeurs ligne par ligne :\n`tmp` vaut 5, puis `a` vaut 7, `b` vaut 4 et `c` vaut 5."
        },
        {
          "statement": "```python\na = 8\nb = 3\nc = 6\ntmp = a\na = b\nb = c\nc = tmp\nprint(a, b, c)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`3 6 8`",
              "correct": true,
              "feedback": "Bonne réponse : `a` prend la valeur de `b`, `b` celle de `c`, et\n`c` récupère l'ancienne valeur de `a` gardée dans `tmp`.\n"
            },
            {
              "text": "`6 8 3`",
              "correct": false,
              "feedback": "Erreur : c'est la rotation dans l'autre sens. Ici `a = b` donne\n3 à `a`.\n"
            },
            {
              "text": "`8 3 6`",
              "correct": false,
              "feedback": "Erreur : les affectations modifient bien les trois variables, la\nvaleur de chacune se décale.\n"
            },
            {
              "text": "`3 6 6`",
              "correct": false,
              "feedback": "Erreur : `c = tmp` donne à `c` la valeur sauvegardée au début,\n8, et non celle de `b`.\n"
            }
          ],
          "explanation": "Une variable temporaire sert à ne perdre aucune valeur quand on fait\ntourner plusieurs variables. On suit les valeurs ligne par ligne :\n`tmp` vaut 8, puis `a` vaut 3, `b` vaut 6 et `c` vaut 8."
        }
      ]
    },
    {
      "id": "q17",
      "difficulty": 1,
      "skills": [
        "variables",
        "affectation"
      ],
      "title": "Ce qu'est une variable",
      "statement": "Dans l'instruction `capteur = 21`, que représente `capteur` ?",
      "options": [
        {
          "text": "Un nom qui désigne une valeur mémorisée, ici 21",
          "correct": true,
          "feedback": "Bonne réponse : une variable est un nom associé à une valeur\nrangée en mémoire. On retrouve la valeur en écrivant le nom.\n"
        },
        {
          "text": "Une égalité mathématique vérifiée par le programme",
          "correct": false,
          "feedback": "Erreur : le signe `=` de Python n'est pas celui des\nmathématiques. Il ordonne de ranger 21 sous le nom `capteur`.\n"
        },
        {
          "text": "Le texte `capteur = 21` qui s'affichera à l'écran",
          "correct": false,
          "feedback": "Erreur : une affectation n'affiche rien. Pour afficher, il faut\nappeler `print`.\n"
        },
        {
          "text": "Un capteur physique branché à l'ordinateur",
          "correct": false,
          "feedback": "Erreur : le nom est choisi par le programmeur pour rappeler ce\nque la valeur représente, mais ce n'est qu'un nom.\n"
        }
      ],
      "explanation": "Une variable est une case de la mémoire désignée par un nom. Le nom\nest choisi pour être parlant, la valeur peut changer au cours du\nprogramme."
    },
    {
      "id": "q18",
      "difficulty": 2,
      "skills": [
        "affectation",
        "trace"
      ],
      "title": "Copier avant de modifier",
      "statement": "```python\nancien = 100\nnouveau = ancien * 2\nancien = ancien + 1\nprint(ancien, nouveau)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`101 200`",
          "correct": true,
          "feedback": "Bonne réponse : `nouveau` est calculé avec la valeur 100, puis\n`ancien` passe à 101 sans que `nouveau` en soit affecté.\n"
        },
        {
          "text": "`101 202`",
          "correct": false,
          "feedback": "Erreur : `nouveau` ne se recalcule pas tout seul quand `ancien`\nchange. Il garde 200.\n"
        },
        {
          "text": "`100 200`",
          "correct": false,
          "feedback": "Erreur : la troisième ligne augmente `ancien`, qui vaut 101 à\nl'affichage.\n"
        },
        {
          "text": "`100 202`",
          "correct": false,
          "feedback": "Erreur : ni l'une ni l'autre : `ancien` devient 101, et\n`nouveau` reste 200.\n"
        }
      ],
      "explanation": "Une affectation calcule une valeur une fois pour toutes. `nouveau`\nne contient pas la formule `ancien * 2` mais le nombre 200 obtenu au\nmoment du calcul.",
      "variants": [
        {
          "statement": "```python\nancien = 100\nnouveau = ancien * 2\nancien = ancien + 1\nprint(ancien, nouveau)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`101 200`",
              "correct": true,
              "feedback": "Bonne réponse : `nouveau` est calculé avec la valeur 100, puis\n`ancien` passe à 101 sans que `nouveau` en soit affecté.\n"
            },
            {
              "text": "`101 202`",
              "correct": false,
              "feedback": "Erreur : `nouveau` ne se recalcule pas tout seul quand `ancien`\nchange. Il garde 200.\n"
            },
            {
              "text": "`100 200`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne augmente `ancien`, qui vaut 101 à\nl'affichage.\n"
            },
            {
              "text": "`100 202`",
              "correct": false,
              "feedback": "Erreur : ni l'une ni l'autre : `ancien` devient 101, et\n`nouveau` reste 200.\n"
            }
          ],
          "explanation": "Une affectation calcule une valeur une fois pour toutes. `nouveau`\nne contient pas la formule `ancien * 2` mais le nombre 200 obtenu au\nmoment du calcul."
        },
        {
          "statement": "```python\nancien = 45\nnouveau = ancien * 2\nancien = ancien + 1\nprint(ancien, nouveau)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`46 90`",
              "correct": true,
              "feedback": "Bonne réponse : `nouveau` est calculé avec la valeur 45, puis\n`ancien` passe à 46 sans que `nouveau` en soit affecté.\n"
            },
            {
              "text": "`46 92`",
              "correct": false,
              "feedback": "Erreur : `nouveau` ne se recalcule pas tout seul quand `ancien`\nchange. Il garde 90.\n"
            },
            {
              "text": "`45 90`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne augmente `ancien`, qui vaut 46 à\nl'affichage.\n"
            },
            {
              "text": "`45 92`",
              "correct": false,
              "feedback": "Erreur : ni l'une ni l'autre : `ancien` devient 46, et\n`nouveau` reste 90.\n"
            }
          ],
          "explanation": "Une affectation calcule une valeur une fois pour toutes. `nouveau`\nne contient pas la formule `ancien * 2` mais le nombre 90 obtenu au\nmoment du calcul."
        },
        {
          "statement": "```python\nancien = 250\nnouveau = ancien * 2\nancien = ancien + 1\nprint(ancien, nouveau)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`251 500`",
              "correct": true,
              "feedback": "Bonne réponse : `nouveau` est calculé avec la valeur 250, puis\n`ancien` passe à 251 sans que `nouveau` en soit affecté.\n"
            },
            {
              "text": "`251 502`",
              "correct": false,
              "feedback": "Erreur : `nouveau` ne se recalcule pas tout seul quand `ancien`\nchange. Il garde 500.\n"
            },
            {
              "text": "`250 500`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne augmente `ancien`, qui vaut 251 à\nl'affichage.\n"
            },
            {
              "text": "`250 502`",
              "correct": false,
              "feedback": "Erreur : ni l'une ni l'autre : `ancien` devient 251, et\n`nouveau` reste 500.\n"
            }
          ],
          "explanation": "Une affectation calcule une valeur une fois pour toutes. `nouveau`\nne contient pas la formule `ancien * 2` mais le nombre 500 obtenu au\nmoment du calcul."
        }
      ]
    },
    {
      "id": "q19",
      "difficulty": 3,
      "skills": [
        "trace",
        "affectation"
      ],
      "title": "Deux variables qui avancent ensemble",
      "statement": "Un robot avance par pas de plus en plus grands.\n\n```python\ndistance = 0\npas = 5\ndistance = distance + pas\npas = pas * 2\ndistance = distance + pas\npas = pas * 2\ndistance = distance + pas\nprint(distance, pas)\n```\n\nQu'affiche ce programme ?",
      "options": [
        {
          "text": "`35 20`",
          "correct": true,
          "feedback": "Bonne réponse : la distance reçoit 5, puis 10, puis 20, soit\n35. Le pas a été doublé deux fois, il vaut 20.\n"
        },
        {
          "text": "`15 20`",
          "correct": false,
          "feedback": "Erreur : 15 est la distance après deux ajouts. Le troisième\najoute encore 20.\n"
        },
        {
          "text": "`35 40`",
          "correct": false,
          "feedback": "Erreur : le pas n'est doublé que deux fois, il vaut 20 à la fin,\npas 40.\n"
        },
        {
          "text": "`30 20`",
          "correct": false,
          "feedback": "Erreur : 30 serait 10 plus 20, sans le premier\najout. Or celui-ci a lieu avec un pas de 5, avant tout\ndoublement : 5 plus 10 plus 20 font 35.\n"
        }
      ],
      "explanation": "Quand deux variables se modifient tour à tour, la trace ligne par\nligne est le seul moyen sûr : distance 5, pas 10, distance 15,\npas 20, distance 35.",
      "variants": [
        {
          "statement": "Un robot avance par pas de plus en plus grands.\n\n```python\ndistance = 0\npas = 5\ndistance = distance + pas\npas = pas * 2\ndistance = distance + pas\npas = pas * 2\ndistance = distance + pas\nprint(distance, pas)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`35 20`",
              "correct": true,
              "feedback": "Bonne réponse : la distance reçoit 5, puis 10, puis 20, soit\n35. Le pas a été doublé deux fois, il vaut 20.\n"
            },
            {
              "text": "`15 20`",
              "correct": false,
              "feedback": "Erreur : 15 est la distance après deux ajouts. Le troisième\najoute encore 20.\n"
            },
            {
              "text": "`35 40`",
              "correct": false,
              "feedback": "Erreur : le pas n'est doublé que deux fois, il vaut 20 à la fin,\npas 40.\n"
            },
            {
              "text": "`30 20`",
              "correct": false,
              "feedback": "Erreur : 30 serait 10 plus 20, sans le premier\najout. Or celui-ci a lieu avec un pas de 5, avant tout\ndoublement : 5 plus 10 plus 20 font 35.\n"
            }
          ],
          "explanation": "Quand deux variables se modifient tour à tour, la trace ligne par\nligne est le seul moyen sûr : distance 5, pas 10, distance 15,\npas 20, distance 35."
        },
        {
          "statement": "Un robot avance par pas de plus en plus grands.\n\n```python\ndistance = 0\npas = 3\ndistance = distance + pas\npas = pas * 2\ndistance = distance + pas\npas = pas * 2\ndistance = distance + pas\nprint(distance, pas)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`21 12`",
              "correct": true,
              "feedback": "Bonne réponse : la distance reçoit 3, puis 6, puis 12, soit\n21. Le pas a été doublé deux fois, il vaut 12.\n"
            },
            {
              "text": "`9 12`",
              "correct": false,
              "feedback": "Erreur : 9 est la distance après deux ajouts. Le troisième\najoute encore 12.\n"
            },
            {
              "text": "`21 24`",
              "correct": false,
              "feedback": "Erreur : le pas n'est doublé que deux fois, il vaut 12 à la fin,\npas 24.\n"
            },
            {
              "text": "`18 12`",
              "correct": false,
              "feedback": "Erreur : 18 serait 6 plus 12, sans le premier\najout. Or celui-ci a lieu avec un pas de 3, avant tout\ndoublement : 3 plus 6 plus 12 font 21.\n"
            }
          ],
          "explanation": "Quand deux variables se modifient tour à tour, la trace ligne par\nligne est le seul moyen sûr : distance 3, pas 6, distance 9,\npas 12, distance 21."
        },
        {
          "statement": "Un robot avance par pas de plus en plus grands.\n\n```python\ndistance = 0\npas = 8\ndistance = distance + pas\npas = pas * 2\ndistance = distance + pas\npas = pas * 2\ndistance = distance + pas\nprint(distance, pas)\n```\n\nQu'affiche ce programme ?",
          "options": [
            {
              "text": "`56 32`",
              "correct": true,
              "feedback": "Bonne réponse : la distance reçoit 8, puis 16, puis 32, soit\n56. Le pas a été doublé deux fois, il vaut 32.\n"
            },
            {
              "text": "`24 32`",
              "correct": false,
              "feedback": "Erreur : 24 est la distance après deux ajouts. Le troisième\najoute encore 32.\n"
            },
            {
              "text": "`56 64`",
              "correct": false,
              "feedback": "Erreur : le pas n'est doublé que deux fois, il vaut 32 à la fin,\npas 64.\n"
            },
            {
              "text": "`48 32`",
              "correct": false,
              "feedback": "Erreur : 48 serait 16 plus 32, sans le premier\najout. Or celui-ci a lieu avec un pas de 8, avant tout\ndoublement : 8 plus 16 plus 32 font 56.\n"
            }
          ],
          "explanation": "Quand deux variables se modifient tour à tour, la trace ligne par\nligne est le seul moyen sûr : distance 8, pas 16, distance 24,\npas 32, distance 56."
        }
      ]
    },
    {
      "id": "q20",
      "difficulty": 3,
      "skills": [
        "affectation",
        "erreur"
      ],
      "title": "Lire l'affectation dans le bon sens",
      "statement": "```python\ntotal = 10\ntotal + 5 = total\nprint(total)\n```\n\nQue se passe-t-il ?",
      "options": [
        {
          "text": "Python affiche 15, l'égalité se lit dans les deux sens",
          "correct": false,
          "feedback": "Erreur : l'affectation n'est pas une égalité. Python refuse de\nranger une valeur dans un calcul.\n"
        },
        {
          "text": "Python affiche 10, la deuxième ligne est ignorée",
          "correct": false,
          "feedback": "Erreur : Python n'ignore aucune ligne. Il s'arrête sur cette\nerreur de syntaxe avant même d'exécuter le programme.\n"
        },
        {
          "text": "Python signale une erreur, le membre de gauche n'est pas un nom de variable",
          "correct": true,
          "feedback": "Bonne réponse : à gauche du `=`, seule une variable peut recevoir\nune valeur. `total + 5` est un calcul, pas un nom.\n"
        },
        {
          "text": "Python affiche 5, la différence entre les deux membres",
          "correct": false,
          "feedback": "Erreur : Python ne résout pas d'équation. Une affectation range\nsimplement une valeur dans une variable.\n"
        }
      ],
      "explanation": "Le membre de gauche d'une affectation est toujours un nom de variable.\nPour augmenter `total` de 5, on écrit `total = total + 5` : le calcul\nà droite, le nom à gauche."
    },
    {
      "id": "q21",
      "difficulty": 1,
      "skills": [
        "affectation",
        "calcul"
      ],
      "title": "Un calcul rangé dans une variable",
      "statement": "Qu'affiche ce programme ?\n```python\nx = 3 * 4\nprint(x)\n```",
      "options": [
        {
          "text": "`12`",
          "correct": true,
          "feedback": "Bonne réponse : le calcul `3 * 4` est effectué d'abord, et\nson résultat 12 est rangé dans `x`.\n"
        },
        {
          "text": "`3 * 4`",
          "correct": false,
          "feedback": "Erreur : sans guillemets, `3 * 4` est un calcul, pas un\ntexte. C'est le résultat qui est mémorisé.\n"
        },
        {
          "text": "`7`",
          "correct": false,
          "feedback": "Erreur : `*` multiplie, il n'additionne pas.\n"
        },
        {
          "text": "`x`",
          "correct": false,
          "feedback": "Erreur : `print(x)` affiche la valeur de la variable, pas son\nnom.\n"
        }
      ],
      "explanation": "À droite du signe `=`, l'expression est calculée ; à gauche, la\nvariable reçoit le résultat.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nx = 3 * 4\nprint(x)\n```",
          "options": [
            {
              "text": "`12`",
              "correct": true,
              "feedback": "Bonne réponse : le calcul `3 * 4` est effectué d'abord, et\nson résultat 12 est rangé dans `x`.\n"
            },
            {
              "text": "`3 * 4`",
              "correct": false,
              "feedback": "Erreur : sans guillemets, `3 * 4` est un calcul, pas un\ntexte. C'est le résultat qui est mémorisé.\n"
            },
            {
              "text": "`7`",
              "correct": false,
              "feedback": "Erreur : `*` multiplie, il n'additionne pas.\n"
            },
            {
              "text": "`x`",
              "correct": false,
              "feedback": "Erreur : `print(x)` affiche la valeur de la variable, pas son\nnom.\n"
            }
          ],
          "explanation": "À droite du signe `=`, l'expression est calculée ; à gauche, la\nvariable reçoit le résultat."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nx = 6 * 7\nprint(x)\n```",
          "options": [
            {
              "text": "`42`",
              "correct": true,
              "feedback": "Bonne réponse : le calcul `6 * 7` est effectué d'abord, et\nson résultat 42 est rangé dans `x`.\n"
            },
            {
              "text": "`6 * 7`",
              "correct": false,
              "feedback": "Erreur : sans guillemets, `6 * 7` est un calcul, pas un\ntexte. C'est le résultat qui est mémorisé.\n"
            },
            {
              "text": "`13`",
              "correct": false,
              "feedback": "Erreur : `*` multiplie, il n'additionne pas.\n"
            },
            {
              "text": "`x`",
              "correct": false,
              "feedback": "Erreur : `print(x)` affiche la valeur de la variable, pas son\nnom.\n"
            }
          ],
          "explanation": "À droite du signe `=`, l'expression est calculée ; à gauche, la\nvariable reçoit le résultat."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nx = 9 * 5\nprint(x)\n```",
          "options": [
            {
              "text": "`45`",
              "correct": true,
              "feedback": "Bonne réponse : le calcul `9 * 5` est effectué d'abord, et\nson résultat 45 est rangé dans `x`.\n"
            },
            {
              "text": "`9 * 5`",
              "correct": false,
              "feedback": "Erreur : sans guillemets, `9 * 5` est un calcul, pas un\ntexte. C'est le résultat qui est mémorisé.\n"
            },
            {
              "text": "`14`",
              "correct": false,
              "feedback": "Erreur : `*` multiplie, il n'additionne pas.\n"
            },
            {
              "text": "`x`",
              "correct": false,
              "feedback": "Erreur : `print(x)` affiche la valeur de la variable, pas son\nnom.\n"
            }
          ],
          "explanation": "À droite du signe `=`, l'expression est calculée ; à gauche, la\nvariable reçoit le résultat."
        }
      ]
    },
    {
      "id": "q22",
      "difficulty": 1,
      "skills": [
        "affichage",
        "guillemets",
        "variable"
      ],
      "title": "Le nom ou la valeur",
      "statement": "Qu'affiche ce programme ?\n```python\nx = 7\nprint(\"x\")\nprint(x)\n```",
      "options": [
        {
          "text": "`x` puis `7`",
          "correct": true,
          "feedback": "Bonne réponse : entre guillemets, `\"x\"` est un texte d'une\nlettre ; sans guillemets, `x` désigne la variable et sa valeur\n7.\n"
        },
        {
          "text": "`7` puis `7`",
          "correct": false,
          "feedback": "Erreur : les guillemets de la première ligne en font un texte,\naffiché tel quel.\n"
        },
        {
          "text": "`x` puis `x`",
          "correct": false,
          "feedback": "Erreur : à la seconde ligne, `x` sans guillemets est la variable,\ndont la valeur est affichée.\n"
        },
        {
          "text": "Une erreur, car `x` ne peut pas être à la fois un texte et une variable",
          "correct": false,
          "feedback": "Erreur : `\"x\"` et `x` sont deux choses différentes, un texte et\nun nom de variable, qui coexistent sans conflit.\n"
        }
      ],
      "explanation": "Les guillemets changent tout : `\"x\"` est une chaîne, `x` est une\nvariable.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nx = 7\nprint(\"x\")\nprint(x)\n```",
          "options": [
            {
              "text": "`x` puis `7`",
              "correct": true,
              "feedback": "Bonne réponse : entre guillemets, `\"x\"` est un texte d'une\nlettre ; sans guillemets, `x` désigne la variable et sa valeur\n7.\n"
            },
            {
              "text": "`7` puis `7`",
              "correct": false,
              "feedback": "Erreur : les guillemets de la première ligne en font un texte,\naffiché tel quel.\n"
            },
            {
              "text": "`x` puis `x`",
              "correct": false,
              "feedback": "Erreur : à la seconde ligne, `x` sans guillemets est la variable,\ndont la valeur est affichée.\n"
            },
            {
              "text": "Une erreur, car `x` ne peut pas être à la fois un texte et une variable",
              "correct": false,
              "feedback": "Erreur : `\"x\"` et `x` sont deux choses différentes, un texte et\nun nom de variable, qui coexistent sans conflit.\n"
            }
          ],
          "explanation": "Les guillemets changent tout : `\"x\"` est une chaîne, `x` est une\nvariable."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nx = 42\nprint(\"x\")\nprint(x)\n```",
          "options": [
            {
              "text": "`x` puis `42`",
              "correct": true,
              "feedback": "Bonne réponse : entre guillemets, `\"x\"` est un texte d'une\nlettre ; sans guillemets, `x` désigne la variable et sa valeur\n42.\n"
            },
            {
              "text": "`42` puis `42`",
              "correct": false,
              "feedback": "Erreur : les guillemets de la première ligne en font un texte,\naffiché tel quel.\n"
            },
            {
              "text": "`x` puis `x`",
              "correct": false,
              "feedback": "Erreur : à la seconde ligne, `x` sans guillemets est la variable,\ndont la valeur est affichée.\n"
            },
            {
              "text": "Une erreur, car `x` ne peut pas être à la fois un texte et une variable",
              "correct": false,
              "feedback": "Erreur : `\"x\"` et `x` sont deux choses différentes, un texte et\nun nom de variable, qui coexistent sans conflit.\n"
            }
          ],
          "explanation": "Les guillemets changent tout : `\"x\"` est une chaîne, `x` est une\nvariable."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nx = 15\nprint(\"x\")\nprint(x)\n```",
          "options": [
            {
              "text": "`x` puis `15`",
              "correct": true,
              "feedback": "Bonne réponse : entre guillemets, `\"x\"` est un texte d'une\nlettre ; sans guillemets, `x` désigne la variable et sa valeur\n15.\n"
            },
            {
              "text": "`15` puis `15`",
              "correct": false,
              "feedback": "Erreur : les guillemets de la première ligne en font un texte,\naffiché tel quel.\n"
            },
            {
              "text": "`x` puis `x`",
              "correct": false,
              "feedback": "Erreur : à la seconde ligne, `x` sans guillemets est la variable,\ndont la valeur est affichée.\n"
            },
            {
              "text": "Une erreur, car `x` ne peut pas être à la fois un texte et une variable",
              "correct": false,
              "feedback": "Erreur : `\"x\"` et `x` sont deux choses différentes, un texte et\nun nom de variable, qui coexistent sans conflit.\n"
            }
          ],
          "explanation": "Les guillemets changent tout : `\"x\"` est une chaîne, `x` est une\nvariable."
        }
      ]
    },
    {
      "id": "q23",
      "difficulty": 1,
      "skills": [
        "affectation",
        "chaine",
        "concatenation"
      ],
      "title": "Un message construit avec une variable",
      "statement": "Qu'affiche ce programme ?\n```python\nprenom = \"Lou\"\nmessage = \"Bonjour \" + prenom\nprint(message)\n```",
      "options": [
        {
          "text": "`Bonjour Lou`",
          "correct": true,
          "feedback": "Bonne réponse : `+` entre deux chaînes les met bout à bout, et\n`prenom` est remplacé par sa valeur.\n"
        },
        {
          "text": "`Bonjour prenom`",
          "correct": false,
          "feedback": "Erreur : `prenom` sans guillemets est une variable, remplacée\npar son contenu.\n"
        },
        {
          "text": "`Bonjour + Lou`",
          "correct": false,
          "feedback": "Erreur : le signe `+` est l'opérateur de concaténation, il\nn'apparaît pas dans le résultat.\n"
        },
        {
          "text": "`BonjourLou`",
          "correct": false,
          "feedback": "Erreur : l'espace fait partie de la chaîne `\"Bonjour \"`, il est\ndonc conservé.\n"
        }
      ],
      "explanation": "Une variable peut contenir du texte, et `+` assemble des textes.\nLes espaces voulus doivent figurer dans les chaînes.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nprenom = \"Lou\"\nmessage = \"Bonjour \" + prenom\nprint(message)\n```",
          "options": [
            {
              "text": "`Bonjour Lou`",
              "correct": true,
              "feedback": "Bonne réponse : `+` entre deux chaînes les met bout à bout, et\n`prenom` est remplacé par sa valeur.\n"
            },
            {
              "text": "`Bonjour prenom`",
              "correct": false,
              "feedback": "Erreur : `prenom` sans guillemets est une variable, remplacée\npar son contenu.\n"
            },
            {
              "text": "`Bonjour + Lou`",
              "correct": false,
              "feedback": "Erreur : le signe `+` est l'opérateur de concaténation, il\nn'apparaît pas dans le résultat.\n"
            },
            {
              "text": "`BonjourLou`",
              "correct": false,
              "feedback": "Erreur : l'espace fait partie de la chaîne `\"Bonjour \"`, il est\ndonc conservé.\n"
            }
          ],
          "explanation": "Une variable peut contenir du texte, et `+` assemble des textes.\nLes espaces voulus doivent figurer dans les chaînes."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nprenom = \"Sami\"\nmessage = \"Bonjour \" + prenom\nprint(message)\n```",
          "options": [
            {
              "text": "`Bonjour Sami`",
              "correct": true,
              "feedback": "Bonne réponse : `+` entre deux chaînes les met bout à bout, et\n`prenom` est remplacé par sa valeur.\n"
            },
            {
              "text": "`Bonjour prenom`",
              "correct": false,
              "feedback": "Erreur : `prenom` sans guillemets est une variable, remplacée\npar son contenu.\n"
            },
            {
              "text": "`Bonjour + Sami`",
              "correct": false,
              "feedback": "Erreur : le signe `+` est l'opérateur de concaténation, il\nn'apparaît pas dans le résultat.\n"
            },
            {
              "text": "`BonjourSami`",
              "correct": false,
              "feedback": "Erreur : l'espace fait partie de la chaîne `\"Bonjour \"`, il est\ndonc conservé.\n"
            }
          ],
          "explanation": "Une variable peut contenir du texte, et `+` assemble des textes.\nLes espaces voulus doivent figurer dans les chaînes."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nprenom = \"Inès\"\nmessage = \"Bonjour \" + prenom\nprint(message)\n```",
          "options": [
            {
              "text": "`Bonjour Inès`",
              "correct": true,
              "feedback": "Bonne réponse : `+` entre deux chaînes les met bout à bout, et\n`prenom` est remplacé par sa valeur.\n"
            },
            {
              "text": "`Bonjour prenom`",
              "correct": false,
              "feedback": "Erreur : `prenom` sans guillemets est une variable, remplacée\npar son contenu.\n"
            },
            {
              "text": "`Bonjour + Inès`",
              "correct": false,
              "feedback": "Erreur : le signe `+` est l'opérateur de concaténation, il\nn'apparaît pas dans le résultat.\n"
            },
            {
              "text": "`BonjourInès`",
              "correct": false,
              "feedback": "Erreur : l'espace fait partie de la chaîne `\"Bonjour \"`, il est\ndonc conservé.\n"
            }
          ],
          "explanation": "Une variable peut contenir du texte, et `+` assemble des textes.\nLes espaces voulus doivent figurer dans les chaînes."
        }
      ]
    },
    {
      "id": "q24",
      "difficulty": 2,
      "skills": [
        "affectation-multiple"
      ],
      "title": "Deux variables en une ligne",
      "statement": "Qu'affiche ce programme ?\n```python\na, b = 3, 7\nprint(a)\n```",
      "options": [
        {
          "text": "`3`",
          "correct": true,
          "feedback": "Bonne réponse : l'affectation multiple donne la première valeur\nà la première variable et la seconde à la seconde. `a` vaut 3.\n"
        },
        {
          "text": "`7`",
          "correct": false,
          "feedback": "Erreur : 7 est rangé dans `b`, la seconde variable.\n"
        },
        {
          "text": "`3, 7`",
          "correct": false,
          "feedback": "Erreur : `print(a)` n'affiche que `a`, pas les deux variables.\n"
        },
        {
          "text": "Une erreur, une ligne ne pouvant affecter qu'une variable",
          "correct": false,
          "feedback": "Erreur : Python autorise l'affectation de plusieurs variables en\nune ligne, les valeurs étant prises dans l'ordre.\n"
        }
      ],
      "explanation": "`a, b = 3, 7` équivaut à `a = 3` suivi de `b = 7`. Les\nvaleurs sont distribuées dans l'ordre.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\na, b = 3, 7\nprint(a)\n```",
          "options": [
            {
              "text": "`3`",
              "correct": true,
              "feedback": "Bonne réponse : l'affectation multiple donne la première valeur\nà la première variable et la seconde à la seconde. `a` vaut 3.\n"
            },
            {
              "text": "`7`",
              "correct": false,
              "feedback": "Erreur : 7 est rangé dans `b`, la seconde variable.\n"
            },
            {
              "text": "`3, 7`",
              "correct": false,
              "feedback": "Erreur : `print(a)` n'affiche que `a`, pas les deux variables.\n"
            },
            {
              "text": "Une erreur, une ligne ne pouvant affecter qu'une variable",
              "correct": false,
              "feedback": "Erreur : Python autorise l'affectation de plusieurs variables en\nune ligne, les valeurs étant prises dans l'ordre.\n"
            }
          ],
          "explanation": "`a, b = 3, 7` équivaut à `a = 3` suivi de `b = 7`. Les\nvaleurs sont distribuées dans l'ordre."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\na, b = 10, 2\nprint(a)\n```",
          "options": [
            {
              "text": "`10`",
              "correct": true,
              "feedback": "Bonne réponse : l'affectation multiple donne la première valeur\nà la première variable et la seconde à la seconde. `a` vaut 10.\n"
            },
            {
              "text": "`2`",
              "correct": false,
              "feedback": "Erreur : 2 est rangé dans `b`, la seconde variable.\n"
            },
            {
              "text": "`10, 2`",
              "correct": false,
              "feedback": "Erreur : `print(a)` n'affiche que `a`, pas les deux variables.\n"
            },
            {
              "text": "Une erreur, une ligne ne pouvant affecter qu'une variable",
              "correct": false,
              "feedback": "Erreur : Python autorise l'affectation de plusieurs variables en\nune ligne, les valeurs étant prises dans l'ordre.\n"
            }
          ],
          "explanation": "`a, b = 10, 2` équivaut à `a = 10` suivi de `b = 2`. Les\nvaleurs sont distribuées dans l'ordre."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\na, b = 5, 8\nprint(a)\n```",
          "options": [
            {
              "text": "`5`",
              "correct": true,
              "feedback": "Bonne réponse : l'affectation multiple donne la première valeur\nà la première variable et la seconde à la seconde. `a` vaut 5.\n"
            },
            {
              "text": "`8`",
              "correct": false,
              "feedback": "Erreur : 8 est rangé dans `b`, la seconde variable.\n"
            },
            {
              "text": "`5, 8`",
              "correct": false,
              "feedback": "Erreur : `print(a)` n'affiche que `a`, pas les deux variables.\n"
            },
            {
              "text": "Une erreur, une ligne ne pouvant affecter qu'une variable",
              "correct": false,
              "feedback": "Erreur : Python autorise l'affectation de plusieurs variables en\nune ligne, les valeurs étant prises dans l'ordre.\n"
            }
          ],
          "explanation": "`a, b = 5, 8` équivaut à `a = 5` suivi de `b = 8`. Les\nvaleurs sont distribuées dans l'ordre."
        }
      ]
    },
    {
      "id": "q25",
      "difficulty": 2,
      "skills": [
        "echange",
        "affectation-multiple"
      ],
      "title": "L'échange en une ligne",
      "statement": "Qu'affiche ce programme ?\n```python\na = 1\nb = 2\na, b = b, a\nprint(a, b)\n```",
      "options": [
        {
          "text": "`2 1`",
          "correct": true,
          "feedback": "Bonne réponse : les valeurs de droite, `b` puis `a`, sont\ncalculées avant toute affectation, puis rangées dans `a` et `b`.\nLes deux variables sont échangées.\n"
        },
        {
          "text": "`1 2`",
          "correct": false,
          "feedback": "Erreur : la troisième ligne échange bien les contenus des deux\nvariables.\n"
        },
        {
          "text": "`2 2`",
          "correct": false,
          "feedback": "Erreur : ce serait le résultat de `a = b` suivi de `b = a`. Ici\nles deux valeurs sont lues avant d'être écrites.\n"
        },
        {
          "text": "Une erreur, `a` et `b` ne pouvant être modifiées en même temps",
          "correct": false,
          "feedback": "Erreur : l'affectation multiple est faite pour cela, et c'est la\nfaçon la plus simple d'échanger deux variables.\n"
        }
      ],
      "explanation": "`a, b = b, a` évalue d'abord le couple de droite avec les anciennes\nvaleurs, puis l'affecte. Pas besoin de variable de secours.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\na = 1\nb = 2\na, b = b, a\nprint(a, b)\n```",
          "options": [
            {
              "text": "`2 1`",
              "correct": true,
              "feedback": "Bonne réponse : les valeurs de droite, `b` puis `a`, sont\ncalculées avant toute affectation, puis rangées dans `a` et `b`.\nLes deux variables sont échangées.\n"
            },
            {
              "text": "`1 2`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne échange bien les contenus des deux\nvariables.\n"
            },
            {
              "text": "`2 2`",
              "correct": false,
              "feedback": "Erreur : ce serait le résultat de `a = b` suivi de `b = a`. Ici\nles deux valeurs sont lues avant d'être écrites.\n"
            },
            {
              "text": "Une erreur, `a` et `b` ne pouvant être modifiées en même temps",
              "correct": false,
              "feedback": "Erreur : l'affectation multiple est faite pour cela, et c'est la\nfaçon la plus simple d'échanger deux variables.\n"
            }
          ],
          "explanation": "`a, b = b, a` évalue d'abord le couple de droite avec les anciennes\nvaleurs, puis l'affecte. Pas besoin de variable de secours."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\na = 8\nb = 3\na, b = b, a\nprint(a, b)\n```",
          "options": [
            {
              "text": "`3 8`",
              "correct": true,
              "feedback": "Bonne réponse : les valeurs de droite, `b` puis `a`, sont\ncalculées avant toute affectation, puis rangées dans `a` et `b`.\nLes deux variables sont échangées.\n"
            },
            {
              "text": "`8 3`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne échange bien les contenus des deux\nvariables.\n"
            },
            {
              "text": "`3 3`",
              "correct": false,
              "feedback": "Erreur : ce serait le résultat de `a = b` suivi de `b = a`. Ici\nles deux valeurs sont lues avant d'être écrites.\n"
            },
            {
              "text": "Une erreur, `a` et `b` ne pouvant être modifiées en même temps",
              "correct": false,
              "feedback": "Erreur : l'affectation multiple est faite pour cela, et c'est la\nfaçon la plus simple d'échanger deux variables.\n"
            }
          ],
          "explanation": "`a, b = b, a` évalue d'abord le couple de droite avec les anciennes\nvaleurs, puis l'affecte. Pas besoin de variable de secours."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\na = 20\nb = 11\na, b = b, a\nprint(a, b)\n```",
          "options": [
            {
              "text": "`11 20`",
              "correct": true,
              "feedback": "Bonne réponse : les valeurs de droite, `b` puis `a`, sont\ncalculées avant toute affectation, puis rangées dans `a` et `b`.\nLes deux variables sont échangées.\n"
            },
            {
              "text": "`20 11`",
              "correct": false,
              "feedback": "Erreur : la troisième ligne échange bien les contenus des deux\nvariables.\n"
            },
            {
              "text": "`11 11`",
              "correct": false,
              "feedback": "Erreur : ce serait le résultat de `a = b` suivi de `b = a`. Ici\nles deux valeurs sont lues avant d'être écrites.\n"
            },
            {
              "text": "Une erreur, `a` et `b` ne pouvant être modifiées en même temps",
              "correct": false,
              "feedback": "Erreur : l'affectation multiple est faite pour cela, et c'est la\nfaçon la plus simple d'échanger deux variables.\n"
            }
          ],
          "explanation": "`a, b = b, a` évalue d'abord le couple de droite avec les anciennes\nvaleurs, puis l'affecte. Pas besoin de variable de secours."
        }
      ]
    },
    {
      "id": "q26",
      "difficulty": 2,
      "skills": [
        "affectation",
        "type",
        "remplacement"
      ],
      "title": "Une variable qui change de nature",
      "statement": "Qu'affiche ce programme ?\n```python\nx = 5\nx = \"cinq\"\nprint(x)\n```",
      "options": [
        {
          "text": "`cinq`",
          "correct": true,
          "feedback": "Bonne réponse : la seconde affectation remplace entièrement\nl'ancienne valeur. Une variable peut recevoir un texte après un\nnombre.\n"
        },
        {
          "text": "`5`",
          "correct": false,
          "feedback": "Erreur : l'ancienne valeur est écrasée par la seconde\naffectation.\n"
        },
        {
          "text": "`5 cinq`",
          "correct": false,
          "feedback": "Erreur : une variable ne contient qu'une seule valeur à la fois,\nla dernière reçue.\n"
        },
        {
          "text": "Une erreur, une variable numérique ne pouvant recevoir un texte",
          "correct": false,
          "feedback": "Erreur : en Python, une variable n'a pas de type fixé. Elle\nprend le type de la valeur qu'on lui donne.\n"
        }
      ],
      "explanation": "Chaque affectation remplace le contenu précédent, quel que soit son\ntype. Il ne reste que la dernière valeur.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nx = 5\nx = \"cinq\"\nprint(x)\n```",
          "options": [
            {
              "text": "`cinq`",
              "correct": true,
              "feedback": "Bonne réponse : la seconde affectation remplace entièrement\nl'ancienne valeur. Une variable peut recevoir un texte après un\nnombre.\n"
            },
            {
              "text": "`5`",
              "correct": false,
              "feedback": "Erreur : l'ancienne valeur est écrasée par la seconde\naffectation.\n"
            },
            {
              "text": "`5 cinq`",
              "correct": false,
              "feedback": "Erreur : une variable ne contient qu'une seule valeur à la fois,\nla dernière reçue.\n"
            },
            {
              "text": "Une erreur, une variable numérique ne pouvant recevoir un texte",
              "correct": false,
              "feedback": "Erreur : en Python, une variable n'a pas de type fixé. Elle\nprend le type de la valeur qu'on lui donne.\n"
            }
          ],
          "explanation": "Chaque affectation remplace le contenu précédent, quel que soit son\ntype. Il ne reste que la dernière valeur."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nx = 12\nx = \"douze\"\nprint(x)\n```",
          "options": [
            {
              "text": "`douze`",
              "correct": true,
              "feedback": "Bonne réponse : la seconde affectation remplace entièrement\nl'ancienne valeur. Une variable peut recevoir un texte après un\nnombre.\n"
            },
            {
              "text": "`12`",
              "correct": false,
              "feedback": "Erreur : l'ancienne valeur est écrasée par la seconde\naffectation.\n"
            },
            {
              "text": "`12 douze`",
              "correct": false,
              "feedback": "Erreur : une variable ne contient qu'une seule valeur à la fois,\nla dernière reçue.\n"
            },
            {
              "text": "Une erreur, une variable numérique ne pouvant recevoir un texte",
              "correct": false,
              "feedback": "Erreur : en Python, une variable n'a pas de type fixé. Elle\nprend le type de la valeur qu'on lui donne.\n"
            }
          ],
          "explanation": "Chaque affectation remplace le contenu précédent, quel que soit son\ntype. Il ne reste que la dernière valeur."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nx = 3\nx = \"trois\"\nprint(x)\n```",
          "options": [
            {
              "text": "`trois`",
              "correct": true,
              "feedback": "Bonne réponse : la seconde affectation remplace entièrement\nl'ancienne valeur. Une variable peut recevoir un texte après un\nnombre.\n"
            },
            {
              "text": "`3`",
              "correct": false,
              "feedback": "Erreur : l'ancienne valeur est écrasée par la seconde\naffectation.\n"
            },
            {
              "text": "`3 trois`",
              "correct": false,
              "feedback": "Erreur : une variable ne contient qu'une seule valeur à la fois,\nla dernière reçue.\n"
            },
            {
              "text": "Une erreur, une variable numérique ne pouvant recevoir un texte",
              "correct": false,
              "feedback": "Erreur : en Python, une variable n'a pas de type fixé. Elle\nprend le type de la valeur qu'on lui donne.\n"
            }
          ],
          "explanation": "Chaque affectation remplace le contenu précédent, quel que soit son\ntype. Il ne reste que la dernière valeur."
        }
      ]
    },
    {
      "id": "q27",
      "difficulty": 2,
      "skills": [
        "mise-a-jour",
        "trace"
      ],
      "title": "Une variable ajoutée à elle-même",
      "statement": "Qu'affiche ce programme ?\n```python\na = 1\na = a + a\na = a + a\nprint(a)\n```",
      "options": [
        {
          "text": "`4`",
          "correct": true,
          "feedback": "Bonne réponse : chaque ligne double la valeur courante : 1,\npuis 2, puis 4.\n"
        },
        {
          "text": "`2`",
          "correct": false,
          "feedback": "Erreur : 2 est la valeur après la première ligne `a = a +\na`. La seconde la double encore.\n"
        },
        {
          "text": "`1`",
          "correct": false,
          "feedback": "Erreur : `a = a + a` modifie bien `a`, elle ne la laisse pas\nintacte.\n"
        },
        {
          "text": "`1 + 1 + 1 + 1`",
          "correct": false,
          "feedback": "Erreur : les additions sont calculées, pas affichées telles\nquelles.\n"
        }
      ],
      "explanation": "Dans `a = a + a`, le `a` de droite est l'ancienne valeur, le `a` de\ngauche reçoit la nouvelle. Répétée, l'instruction double à chaque\nfois.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\na = 1\na = a + a\na = a + a\nprint(a)\n```",
          "options": [
            {
              "text": "`4`",
              "correct": true,
              "feedback": "Bonne réponse : chaque ligne double la valeur courante : 1,\npuis 2, puis 4.\n"
            },
            {
              "text": "`2`",
              "correct": false,
              "feedback": "Erreur : 2 est la valeur après la première ligne `a = a +\na`. La seconde la double encore.\n"
            },
            {
              "text": "`1`",
              "correct": false,
              "feedback": "Erreur : `a = a + a` modifie bien `a`, elle ne la laisse pas\nintacte.\n"
            },
            {
              "text": "`1 + 1 + 1 + 1`",
              "correct": false,
              "feedback": "Erreur : les additions sont calculées, pas affichées telles\nquelles.\n"
            }
          ],
          "explanation": "Dans `a = a + a`, le `a` de droite est l'ancienne valeur, le `a` de\ngauche reçoit la nouvelle. Répétée, l'instruction double à chaque\nfois."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\na = 3\na = a + a\na = a + a\nprint(a)\n```",
          "options": [
            {
              "text": "`12`",
              "correct": true,
              "feedback": "Bonne réponse : chaque ligne double la valeur courante : 3,\npuis 6, puis 12.\n"
            },
            {
              "text": "`6`",
              "correct": false,
              "feedback": "Erreur : 6 est la valeur après la première ligne `a = a +\na`. La seconde la double encore.\n"
            },
            {
              "text": "`3`",
              "correct": false,
              "feedback": "Erreur : `a = a + a` modifie bien `a`, elle ne la laisse pas\nintacte.\n"
            },
            {
              "text": "`3 + 3 + 3 + 3`",
              "correct": false,
              "feedback": "Erreur : les additions sont calculées, pas affichées telles\nquelles.\n"
            }
          ],
          "explanation": "Dans `a = a + a`, le `a` de droite est l'ancienne valeur, le `a` de\ngauche reçoit la nouvelle. Répétée, l'instruction double à chaque\nfois."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\na = 5\na = a + a\na = a + a\nprint(a)\n```",
          "options": [
            {
              "text": "`20`",
              "correct": true,
              "feedback": "Bonne réponse : chaque ligne double la valeur courante : 5,\npuis 10, puis 20.\n"
            },
            {
              "text": "`10`",
              "correct": false,
              "feedback": "Erreur : 10 est la valeur après la première ligne `a = a +\na`. La seconde la double encore.\n"
            },
            {
              "text": "`5`",
              "correct": false,
              "feedback": "Erreur : `a = a + a` modifie bien `a`, elle ne la laisse pas\nintacte.\n"
            },
            {
              "text": "`5 + 5 + 5 + 5`",
              "correct": false,
              "feedback": "Erreur : les additions sont calculées, pas affichées telles\nquelles.\n"
            }
          ],
          "explanation": "Dans `a = a + a`, le `a` de droite est l'ancienne valeur, le `a` de\ngauche reçoit la nouvelle. Répétée, l'instruction double à chaque\nfois."
        }
      ]
    },
    {
      "id": "q28",
      "difficulty": 2,
      "skills": [
        "initialisation",
        "erreur"
      ],
      "title": "Un compteur jamais créé",
      "statement": "Que produit ce programme ?\n```python\ncompteur = compteur + 1\nprint(compteur)\n```",
      "options": [
        {
          "text": "Une erreur, `compteur` n'ayant pas encore de valeur",
          "correct": true,
          "feedback": "Bonne réponse : pour calculer `compteur + 1`, Python doit lire\n`compteur`, qui n'existe pas encore. Il faut d'abord\n`compteur = 0`.\n"
        },
        {
          "text": "`1`, Python donnant zéro par défaut à toute variable inconnue",
          "correct": false,
          "feedback": "Erreur : aucune variable n'existe tant qu'elle n'a pas été\naffectée. Il n'y a pas de valeur par défaut.\n"
        },
        {
          "text": "`0`, la variable étant créée vide puis affichée",
          "correct": false,
          "feedback": "Erreur : une variable ne peut pas être créée vide. L'affectation\nexige une valeur calculable.\n"
        },
        {
          "text": "`compteur + 1`, affiché tel quel faute de valeur",
          "correct": false,
          "feedback": "Erreur : Python tente le calcul avant d'afficher quoi que ce\nsoit, et c'est le calcul qui échoue.\n"
        }
      ],
      "explanation": "Une variable doit être initialisée avant d'être utilisée dans un\ncalcul. Un compteur commence presque toujours par `compteur = 0`."
    },
    {
      "id": "q29",
      "difficulty": 3,
      "skills": [
        "affectation",
        "copie",
        "trace"
      ],
      "title": "Un total qui ne se met pas à jour",
      "statement": "Qu'affiche ce programme ?\n```python\nprix = 10\ntotal = prix * 3\nprix = 20\nprint(total)\n```",
      "options": [
        {
          "text": "`30`",
          "correct": true,
          "feedback": "Bonne réponse : `total` a été calculé quand `prix` valait 10.\nModifier `prix` ensuite ne recalcule rien.\n"
        },
        {
          "text": "`60`",
          "correct": false,
          "feedback": "Erreur : `total` ne suit pas les changements de `prix`. Pour\nobtenir 60, il faudrait refaire `total = prix * 3`.\n"
        },
        {
          "text": "`20`",
          "correct": false,
          "feedback": "Erreur : 20 est la nouvelle valeur de `prix`, pas celle de\n`total`.\n"
        },
        {
          "text": "`10`",
          "correct": false,
          "feedback": "Erreur : `total` contient le produit, pas l'ancien prix.\n"
        }
      ],
      "explanation": "Une affectation calcule une valeur une fois pour toutes. Rien ne\nrelie durablement `total` à `prix`.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nprix = 10\ntotal = prix * 3\nprix = 20\nprint(total)\n```",
          "options": [
            {
              "text": "`30`",
              "correct": true,
              "feedback": "Bonne réponse : `total` a été calculé quand `prix` valait 10.\nModifier `prix` ensuite ne recalcule rien.\n"
            },
            {
              "text": "`60`",
              "correct": false,
              "feedback": "Erreur : `total` ne suit pas les changements de `prix`. Pour\nobtenir 60, il faudrait refaire `total = prix * 3`.\n"
            },
            {
              "text": "`20`",
              "correct": false,
              "feedback": "Erreur : 20 est la nouvelle valeur de `prix`, pas celle de\n`total`.\n"
            },
            {
              "text": "`10`",
              "correct": false,
              "feedback": "Erreur : `total` contient le produit, pas l'ancien prix.\n"
            }
          ],
          "explanation": "Une affectation calcule une valeur une fois pour toutes. Rien ne\nrelie durablement `total` à `prix`."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nprix = 5\ntotal = prix * 4\nprix = 8\nprint(total)\n```",
          "options": [
            {
              "text": "`20`",
              "correct": true,
              "feedback": "Bonne réponse : `total` a été calculé quand `prix` valait 5.\nModifier `prix` ensuite ne recalcule rien.\n"
            },
            {
              "text": "`32`",
              "correct": false,
              "feedback": "Erreur : `total` ne suit pas les changements de `prix`. Pour\nobtenir 32, il faudrait refaire `total = prix * 4`.\n"
            },
            {
              "text": "`8`",
              "correct": false,
              "feedback": "Erreur : 8 est la nouvelle valeur de `prix`, pas celle de\n`total`.\n"
            },
            {
              "text": "`5`",
              "correct": false,
              "feedback": "Erreur : `total` contient le produit, pas l'ancien prix.\n"
            }
          ],
          "explanation": "Une affectation calcule une valeur une fois pour toutes. Rien ne\nrelie durablement `total` à `prix`."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nprix = 12\ntotal = prix * 2\nprix = 30\nprint(total)\n```",
          "options": [
            {
              "text": "`24`",
              "correct": true,
              "feedback": "Bonne réponse : `total` a été calculé quand `prix` valait 12.\nModifier `prix` ensuite ne recalcule rien.\n"
            },
            {
              "text": "`60`",
              "correct": false,
              "feedback": "Erreur : `total` ne suit pas les changements de `prix`. Pour\nobtenir 60, il faudrait refaire `total = prix * 2`.\n"
            },
            {
              "text": "`30`",
              "correct": false,
              "feedback": "Erreur : 30 est la nouvelle valeur de `prix`, pas celle de\n`total`.\n"
            },
            {
              "text": "`12`",
              "correct": false,
              "feedback": "Erreur : `total` contient le produit, pas l'ancien prix.\n"
            }
          ],
          "explanation": "Une affectation calcule une valeur une fois pour toutes. Rien ne\nrelie durablement `total` à `prix`."
        }
      ]
    },
    {
      "id": "q30",
      "difficulty": 3,
      "skills": [
        "affectation",
        "trace",
        "enchainement"
      ],
      "title": "Quatre affectations à suivre",
      "statement": "Qu'affiche ce programme ?\n```python\na = 5\nb = a\na = b + 1\nb = a * 2\nprint(a, b)\n```",
      "options": [
        {
          "text": "`6 12`",
          "correct": true,
          "feedback": "Bonne réponse : `b` reçoit 5, puis `a` devient 5 + 1 = 6,\npuis `b` devient 6 × 2 = 12.\n"
        },
        {
          "text": "`6 10`",
          "correct": false,
          "feedback": "Erreur : à la dernière ligne, `a` vaut déjà 6, et non 5.\nLe double est donc 12.\n"
        },
        {
          "text": "`5 5`",
          "correct": false,
          "feedback": "Erreur : les deux dernières lignes modifient `a` puis `b`.\n"
        },
        {
          "text": "`6 6`",
          "correct": false,
          "feedback": "Erreur : `b = a * 2` double la valeur de `a`, il ne la recopie\npas.\n"
        }
      ],
      "explanation": "Suivre un programme, c'est tenir à jour la valeur de chaque\nvariable ligne après ligne, en lisant chaque affectation de droite\nà gauche.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\na = 5\nb = a\na = b + 1\nb = a * 2\nprint(a, b)\n```",
          "options": [
            {
              "text": "`6 12`",
              "correct": true,
              "feedback": "Bonne réponse : `b` reçoit 5, puis `a` devient 5 + 1 = 6,\npuis `b` devient 6 × 2 = 12.\n"
            },
            {
              "text": "`6 10`",
              "correct": false,
              "feedback": "Erreur : à la dernière ligne, `a` vaut déjà 6, et non 5.\nLe double est donc 12.\n"
            },
            {
              "text": "`5 5`",
              "correct": false,
              "feedback": "Erreur : les deux dernières lignes modifient `a` puis `b`.\n"
            },
            {
              "text": "`6 6`",
              "correct": false,
              "feedback": "Erreur : `b = a * 2` double la valeur de `a`, il ne la recopie\npas.\n"
            }
          ],
          "explanation": "Suivre un programme, c'est tenir à jour la valeur de chaque\nvariable ligne après ligne, en lisant chaque affectation de droite\nà gauche."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\na = 2\nb = a\na = b + 1\nb = a * 2\nprint(a, b)\n```",
          "options": [
            {
              "text": "`3 6`",
              "correct": true,
              "feedback": "Bonne réponse : `b` reçoit 2, puis `a` devient 2 + 1 = 3,\npuis `b` devient 3 × 2 = 6.\n"
            },
            {
              "text": "`3 4`",
              "correct": false,
              "feedback": "Erreur : à la dernière ligne, `a` vaut déjà 3, et non 2.\nLe double est donc 6.\n"
            },
            {
              "text": "`2 2`",
              "correct": false,
              "feedback": "Erreur : les deux dernières lignes modifient `a` puis `b`.\n"
            },
            {
              "text": "`3 3`",
              "correct": false,
              "feedback": "Erreur : `b = a * 2` double la valeur de `a`, il ne la recopie\npas.\n"
            }
          ],
          "explanation": "Suivre un programme, c'est tenir à jour la valeur de chaque\nvariable ligne après ligne, en lisant chaque affectation de droite\nà gauche."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\na = 9\nb = a\na = b + 1\nb = a * 2\nprint(a, b)\n```",
          "options": [
            {
              "text": "`10 20`",
              "correct": true,
              "feedback": "Bonne réponse : `b` reçoit 9, puis `a` devient 9 + 1 = 10,\npuis `b` devient 10 × 2 = 20.\n"
            },
            {
              "text": "`10 18`",
              "correct": false,
              "feedback": "Erreur : à la dernière ligne, `a` vaut déjà 10, et non 9.\nLe double est donc 20.\n"
            },
            {
              "text": "`9 9`",
              "correct": false,
              "feedback": "Erreur : les deux dernières lignes modifient `a` puis `b`.\n"
            },
            {
              "text": "`10 10`",
              "correct": false,
              "feedback": "Erreur : `b = a * 2` double la valeur de `a`, il ne la recopie\npas.\n"
            }
          ],
          "explanation": "Suivre un programme, c'est tenir à jour la valeur de chaque\nvariable ligne après ligne, en lisant chaque affectation de droite\nà gauche."
        }
      ]
    }
  ]
}