<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Première/Dictionnaires</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Type construit <code>dict</code> en Python : association<br/>
clé-valeur, création, accès, parcours, méthodes<br/>
<code>keys</code>, <code>values</code> et <code>items</code>, test <code>in</code>. Comparaison<br/>
avec les listes, applications classiques (comptage,<br/>
indexation), implémentation par table de hachage.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q01 : Notion de dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>dictionnaire</strong> Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les clés d'un dictionnaire jouent le rôle<br/>
des indices d'une liste, mais elles peuvent<br/>
être des chaînes, des entiers ou des<br/>
p-uplets : on retrouve une valeur par sa<br/>
clé, sans connaître sa position.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier au format CSV chargé en mémoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un fichier CSV est un format de<br/>
stockage de données tabulaires,<br/>
alors qu'un dictionnaire est<br/>
une structure de données interne<br/>
au programme. On peut<br/>
néanmoins construire un<br/>
dictionnaire à partir d'un<br/>
fichier CSV.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une liste dont les indices sont des entiers consécutifs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description correspond<br/>
précisément à une <strong>liste</strong>, et<br/>
non à un dictionnaire. Une liste<br/>
est indexée par des positions<br/>
entières ; un dictionnaire est<br/>
indexé par des clés<br/>
quelconques.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une structure qui associe des clés à des valeurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'accès à une valeur se<br/>
fait directement par sa clé, rapidement.<br/>
On peut le voir comme un index<br/>
ou un annuaire. Un dictionnaire<br/>
est aussi appelé « tableau<br/>
associatif » dans certains<br/>
langages.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une chaîne de caractères ordonnée, indexée par position</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une chaîne de caractères est<br/>
une séquence ordonnée de<br/>
caractères, alors qu'un<br/>
dictionnaire est une<br/>
structure associative.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q02 : Création</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment crée-t-on un dictionnaire<br/>
vide en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour créer un dictionnaire avec<br/>
des valeurs initiales :<br/>
<code>d = {"alice": 17, "bob": 16}</code>.<br/>
Les paires sont séparées par des<br/>
virgules, et chaque paire est<br/>
formée d'une clé et d'une valeur<br/>
séparées par deux-points.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la syntaxe <code>d = ()</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe crée un <strong>tuple</strong><br/>
vide, et non un dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la syntaxe <code>d = []</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe crée une <strong>liste</strong><br/>
vide, et non un dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec la syntaxe <code>d = {}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On utilise des accolades. Une<br/>
forme alternative consiste à<br/>
écrire <code>d = dict()</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la syntaxe <code>d = dict[]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe n'est pas valide<br/>
en Python.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q03 : Accès par clé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment accède-t-on à la <strong>valeur</strong><br/>
associée à la clé <code>"nom"</code> dans le<br/>
dictionnaire <code>d = {"nom": "Alice"}</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour éviter une <code>KeyError</code>, on<br/>
teste d'abord la présence de la<br/>
clé avec <code>if "nom" in d:</code> avant<br/>
de lire <code>d["nom"]</code>. Le test<br/>
<code>"age" in d</code> vaut <code>False</code> si le<br/>
dictionnaire n'a pas de clé<br/>
<code>"age"</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d(nom)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les parenthèses correspondent<br/>
à un appel de fonction, pas à<br/>
un accès dans un<br/>
dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d.nom</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe est utilisée pour<br/>
accéder aux attributs d'un<br/>
objet, et non aux clés d'un<br/>
dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec <code>d["nom"]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On utilise les crochets, en<br/>
plaçant la clé entre<br/>
guillemets s'il s'agit d'une<br/>
chaîne. Si la clé n'existe<br/>
pas, Python lève une<br/>
exception <code>KeyError</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d-&gt;nom</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe est utilisée en<br/>
C ou en PHP, mais pas en<br/>
Python.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q04 : Ajouter une entrée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment ajoute-t-on la paire<br/>
<code>"age": 17</code> à un dictionnaire <code>d</code><br/>
en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La même syntaxe permet à la fois<br/>
la création d'une nouvelle<br/>
entrée et la mise à jour d'une<br/>
entrée existante. On ne fait<br/>
pas de distinction syntaxique<br/>
entre l'ajout et la<br/>
modification.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d.append("age", 17)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode <code>append</code> n'existe<br/>
pas pour les dictionnaires.<br/>
Elle est définie pour les<br/>
listes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d.put("age", 17)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe est utilisée en<br/>
Java ou en Go, mais pas en<br/>
Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d.add("age": 17)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode <code>add</code> n'existe pas<br/>
pour les dictionnaires ; elle<br/>
appartient aux ensembles, un<br/>
autre type de collection qui<br/>
n'est pas au programme de<br/>
première.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec <code>d["age"] = 17</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Si la clé n'existe pas, elle<br/>
est créée. Si elle existait<br/>
déjà, sa valeur est tout<br/>
simplement mise à jour.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q05 : Longueur d'un dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment connaître le <strong>nombre de paires</strong> clé-valeur d'un<br/>
dictionnaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'égalité <code>len(d) == 0</code> revient<br/>
à dire que le dictionnaire est<br/>
vide. Comme pour les listes, le<br/>
test <code>if d:</code> est plus<br/>
idiomatique en Python : il est<br/>
vrai si et seulement si le<br/>
dictionnaire n'est pas vide.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d.length</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'attribut <code>length</code> n'existe<br/>
pas pour les dictionnaires<br/>
en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec <code>len(d)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction native <code>len</code><br/>
fonctionne sur les<br/>
dictionnaires comme sur<br/>
d'autres conteneurs (listes,<br/>
chaînes, ensembles, tuples).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d.size()</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode <code>size</code> n'existe<br/>
pas pour les dictionnaires<br/>
en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>count(d)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction <code>count</code> n'est pas<br/>
définie sur les<br/>
dictionnaires.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q06 : Parcourir un dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que parcourt par défaut la boucle<br/>
<code>for x in d:</code>, où <code>d</code> est un<br/>
dictionnaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un idiome très courant :</p>
<pre><code>for cle, valeur in d.items():
    print(cle, valeur)</code></pre>
<p>Cette construction est très<br/>
pratique pour parcourir un<br/>
dictionnaire tout en conservant<br/>
l'association entre clé et<br/>
valeur.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les paires clé-valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour parcourir les paires<br/>
clé-valeur, il faut<br/>
explicitement écrire<br/>
<code>for k, v in d.items():</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les clés du dictionnaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette boucle est équivalente à<br/>
<code>for x in d.keys():</code>. Pour<br/>
parcourir les valeurs, on<br/>
écrit <code>for v in d.values():</code>.<br/>
Pour parcourir les paires<br/>
clé-valeur, on utilise<br/>
<code>for k, v in d.items():</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les valeurs du dictionnaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Par défaut, la boucle parcourt<br/>
les <strong>clés</strong> du dictionnaire,<br/>
et non ses valeurs. Pour<br/>
accéder aux valeurs, on<br/>
utilise <code>d.values()</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les indices du dictionnaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un dictionnaire n'a pas<br/>
d'indices entiers comme une<br/>
liste. Il a uniquement des<br/>
clés, qui peuvent être de<br/>
types variés.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q07 : Tester la présence d'une clé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment teste-t-on si la clé<br/>
<code>"nom"</code> existe dans le<br/>
dictionnaire <code>d</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour tester la présence parmi<br/>
les <strong>valeurs</strong>, on écrit<br/>
<code>valeur in d.values()</code>. Cette<br/>
opération est en moyenne en<br/>
$O(n)$, donc plus coûteuse que<br/>
la recherche d'une clé.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d["nom"]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe accède<br/>
directement à la valeur<br/>
associée à la clé. Elle<br/>
provoque une exception<br/>
<code>KeyError</code> si la clé est<br/>
absente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d.has("nom")</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode <code>has</code> n'existe pas<br/>
en Python 3. Une méthode<br/>
<code>has_key</code> existait en Python<br/>
2, mais elle a été supprimée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>d.contains("nom")</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode <code>contains</code> n'existe<br/>
pas pour les dictionnaires en<br/>
Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec <code>"nom" in d</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'opérateur <code>in</code> testé sur un<br/>
dictionnaire vérifie la<br/>
présence parmi les <strong>clés</strong>.<br/>
Cette opération est en<br/>
$O(1)$ en moyenne.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q08 : Méthode keys</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Soit <code>d = {"a": 1, "b": 2}</code>. Que vaut<br/>
<code>list(d.keys())</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois vues sur un dictionnaire : <code>keys()</code> (les<br/>
clés), <code>values()</code> (les valeurs) et <code>items()</code> (les<br/>
couples). Parcourir directement <code>d</code> revient à<br/>
parcourir <code>d.keys()</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1, 2]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce sont les <strong>valeurs</strong>, que renvoie<br/>
<code>d.values()</code>. La méthode <code>keys</code> ne fournit que<br/>
les clés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>['a', 'b']</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>d.keys()</code> fournit les clés du<br/>
dictionnaire, dans l'ordre d'insertion, et<br/>
<code>list(...)</code> les range dans une liste. C'est<br/>
aussi ce que parcourt <code>for k in d:</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[('a', 1), ('b', 2)]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les couples <code>(clé, valeur)</code> sont<br/>
fournis par <code>d.items()</code>, pas par <code>keys</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>['a', 1, 'b', 2]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : clés et valeurs ne sont jamais<br/>
mélangées dans une même liste. <code>keys</code> ne<br/>
renvoie que les clés, <code>values</code> que les valeurs.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q09 : Cas d'usage typique</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel des cas suivants est un<br/>
usage <strong>typique</strong> d'un<br/>
dictionnaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Quelques cas d'usage classiques :<br/>
indexation (mot vers<br/>
définition), comptage (mot vers<br/>
nombre d'occurrences),<br/>
configuration (option vers<br/>
valeur).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Associer un identifiant à des informations, comme un nom à un âge</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est précisément le rôle<br/>
d'un dictionnaire. Il offre<br/>
une recherche rapide à<br/>
partir de la clé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Compresser efficacement de grandes quantités de données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La compression de données<br/>
est une fonctionnalité<br/>
spécifique, sans lien<br/>
direct avec la structure de<br/>
dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Stocker une séquence ordonnée de notes d'élèves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour ce cas, une liste est<br/>
plus adaptée. Le<br/>
dictionnaire excelle<br/>
plutôt pour l'association<br/>
entre une clé et une<br/>
valeur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trier une liste de valeurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le tri d'une liste est une<br/>
opération qui n'a rien à voir<br/>
avec les dictionnaires.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q10 : Clé fournie par une variable</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que produit ce code ?<br/>
<pre><code>nom = "Alice"
d = {"Alice": 17}
print(d[nom])</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La clé entre crochets est une expression quelconque :<br/>
un littéral (<code>d["Alice"]</code>), une variable (<code>d[nom]</code>)<br/>
ou un calcul. Distinguer <code>d[nom]</code> (valeur de la<br/>
variable) de <code>d["nom"]</code> (chaîne littérale) évite<br/>
bien des <code>KeyError</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il lève une <code>KeyError</code>, car <code>nom</code> n'est pas une clé de <code>d</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : entre les crochets, Python évalue<br/>
d'abord l'expression <code>nom</code>, qui vaut<br/>
<code>"Alice"</code>. C'est cette chaîne qui sert de clé,<br/>
et elle est bien présente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il affiche <code>17</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>d[nom]</code> équivaut à<br/>
<code>d["Alice"]</code>, puisque <code>nom</code> contient la chaîne<br/>
<code>"Alice"</code>. La valeur associée, $17$, est<br/>
affichée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>Alice</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'accès par clé renvoie la <strong>valeur</strong><br/>
associée, pas la clé elle-même. <code>Alice</code> n'est<br/>
que le contenu de la variable <code>nom</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il lève une <code>KeyError</code>, car il manque les guillemets autour de <code>nom</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : avec des guillemets, <code>d["nom"]</code><br/>
chercherait la clé <code>"nom"</code>, absente, et c'est<br/>
là que <code>KeyError</code> surviendrait. Sans<br/>
guillemets, <code>nom</code> est une variable dont la<br/>
valeur <code>"Alice"</code> sert de clé.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q11 : Compter les occurrences</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel code <strong>compte</strong> le nombre<br/>
d'occurrences de chaque mot dans<br/>
une liste <code>mots</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Ce motif « tester puis créer ou incrémenter »<br/>
s'applique à tout comptage avec un dictionnaire :<br/>
la clé est l'objet compté, la valeur le nombre de<br/>
rencontres. Le test <code>in</code> évite la <code>KeyError</code><br/>
qu'entraînerait la lecture d'une clé absente.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>c = {}
for m in mots:
    if m in c:
        c[m] = c[m] + 1
    else:
        c[m] = 1</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est le motif classique du<br/>
comptage. Le test <code>m in c</code> distingue la<br/>
première rencontre d'un mot (compteur créé<br/>
à $1$) des suivantes (compteur incrémenté).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>c = {}
for m in mots:
    c[m] = c[m] + 1</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>c[m] + 1</code> lit <code>c[m]</code> avant d'écrire.<br/>
À la première occurrence d'un mot, la clé<br/>
n'existe pas encore et Python lève <code>KeyError</code>.<br/>
Il manque le test <code>if m in c</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>c = {}
for m in mots:
    if m in c:
        c[m] = c[m] + 1
    else:
        c[m] = 0</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la première occurrence est comptée<br/>
pour $0$ au lieu de $1$. Chaque mot finit avec<br/>
un compte inférieur d'une unité au vrai nombre<br/>
d'occurrences : sur <code>["a", "b", "a"]</code>, on<br/>
obtient <code>{"a": 1, "b": 0}</code> au lieu de<br/>
<code>{"a": 2, "b": 1}</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>c = {}
for m in mots:
    c[m] = 1</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque occurrence remet le compteur à<br/>
$1$ au lieu de l'incrémenter. À la fin, tous<br/>
les mots ont pour valeur $1$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q12 : Une valeur qui est une liste</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que produit ce code ?</p>
<pre><code>d = {"fruits": ["pomme"]}
d["fruits"].append("poire")
print(d)</code></pre>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une valeur de dictionnaire peut être une liste, un<br/>
tuple ou un autre dictionnaire. Comme<br/>
<code>d["fruits"]</code> renvoie l'objet lui-même, les<br/>
méthodes qui modifient une liste agissent<br/>
directement sur la valeur stockée.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il affiche <code>{'fruits': ['pomme', 'poire']}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>d["fruits"]</code> renvoie la liste<br/>
rangée dans le dictionnaire, pas une copie.<br/>
L'appel <code>append</code> allonge donc cette liste, et<br/>
le changement est visible dans <code>d</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>{'fruits': ['pomme']}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'accès <code>d["fruits"]</code> ne copie pas la<br/>
liste. <code>append</code> agit sur l'objet même qui est<br/>
stocké dans le dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>{'fruits': ['poire']}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>append</code> ajoute un élément à la fin de<br/>
la liste sans effacer les autres. Seule une<br/>
affectation <code>d["fruits"] = ["poire"]</code><br/>
remplacerait la valeur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il lève une <code>AttributeError</code>, car un dictionnaire n'a pas de méthode <code>append</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la méthode n'est pas appelée sur <code>d</code><br/>
mais sur <code>d["fruits"]</code>, qui est une liste. Une<br/>
liste possède bien la méthode <code>append</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q13 : Méthode items</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie l'appel <code>d.items()</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois vues complémentaires sont<br/>
disponibles : <code>keys()</code> pour les<br/>
clés, <code>values()</code> pour les<br/>
valeurs, et <code>items()</code> pour les<br/>
paires. Elles sont<br/>
dynamiques : elles reflètent<br/>
les modifications du<br/>
dictionnaire au fur et à<br/>
mesure.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une liste contenant uniquement l'ensemble des clés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description correspond<br/>
plutôt à <code>d.keys()</code>. La<br/>
méthode <code>items</code> renvoie<br/>
autre chose.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un ensemble contenant les valeurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour obtenir les valeurs,<br/>
on utilise plutôt<br/>
<code>d.values()</code>. La méthode<br/>
<code>items</code> renvoie les paires<br/>
complètes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La taille du dictionnaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La taille du dictionnaire<br/>
s'obtient avec la fonction<br/>
<code>len(d)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une vue itérable sur les paires <code>(clé, valeur)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette vue permet d'itérer<br/>
sur les deux à la fois,<br/>
avec la syntaxe<br/>
<code>for k, v in d.items():</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q14 : Clés autorisées dans un dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel des types suivants ne peut<br/>
<strong>pas</strong> être utilisé comme clé de<br/>
dictionnaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La règle est la suivante : la<br/>
clé doit être <strong>immuable</strong>.<br/>
Un tuple composé d'éléments<br/>
immuables est donc autorisé,<br/>
mais un tuple contenant une<br/>
liste ne l'est pas.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le type <code>str</code> (chaîne)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les chaînes sont sans<br/>
doute le type de clé le<br/>
plus utilisé dans la<br/>
pratique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le type <code>tuple</code>, à condition que tous ses éléments soient eux-mêmes utilisables comme clés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un tuple est autorisé<br/>
comme clé tant que tous<br/>
ses éléments sont eux-mêmes<br/>
immuables.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le type <code>list</code> (liste)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les listes sont <strong>mutables</strong>,<br/>
ce qui les empêche d'être<br/>
utilisées comme clés.<br/>
Tenter d'écrire<br/>
<code>d[[1, 2]] = 5</code> provoque<br/>
une <code>TypeError</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le type <code>int</code> (entier)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les entiers sont<br/>
parfaitement utilisables<br/>
comme clés de<br/>
dictionnaire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q15 : Dictionnaire et liste</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour rechercher une valeur à<br/>
partir d'un identifiant (par<br/>
exemple « l'élève dont<br/>
l'identifiant est $42$ »),<br/>
pourquoi préfère-t-on un<br/>
dictionnaire à une liste ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Compromis : le dictionnaire<br/>
consomme plus de mémoire,<br/>
mais offre une recherche<br/>
très rapide par clé. La liste,<br/>
plus compacte, doit être<br/>
parcourue pour retrouver un<br/>
identifiant.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Pour la rapidité de l'accès par clé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on accède directement à la<br/>
valeur par sa clé, alors qu'avec une liste il<br/>
faut parcourir les éléments un à un jusqu'à<br/>
trouver l'identifiant, avec un coût linéaire.<br/>
Sur de gros volumes de données, la<br/>
différence est considérable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'une liste ne peut pas contenir d'identifiants numériques</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
fausse. Les listes<br/>
peuvent contenir tout<br/>
type de valeurs,<br/>
notamment des nombres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour économiser une part importante de la mémoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Au contraire, un<br/>
dictionnaire occupe en<br/>
général plus de mémoire<br/>
qu'une liste équivalente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune raison, les deux structures se valent pour cet usage</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il existe une différence majeure<br/>
de performance. Avec une liste, il faut<br/>
parcourir les éléments un à un jusqu'à<br/>
trouver l'identifiant.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q16 : Représenter une table de traduction</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment représenter une <strong>table de traduction</strong> simple du<br/>
français vers l'anglais en<br/>
Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour une <strong>petite</strong> table de<br/>
traduction, un dictionnaire<br/>
simple convient. Pour des<br/>
bases volumineuses, on a<br/>
plutôt recours à une base<br/>
de données ou à des<br/>
fichiers indexés.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>{"chat": "cat", "chien": "dog"}</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On utilise un dictionnaire,<br/>
ce qui permet un accès<br/>
immédiat :<br/>
<code>traduction["chat"]</code><br/>
renvoie <code>"cat"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>("chat", "cat")</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce tuple ne contient<br/>
qu'un seul couple. Il ne<br/>
permet pas de stocker<br/>
l'ensemble des<br/>
traductions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>["chat", "cat", "chien", "dog"]</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette structure est une<br/>
liste plate qui ne<br/>
permet pas une recherche<br/>
rapide par mot<br/>
français. Il faudrait<br/>
parcourir la liste pour<br/>
retrouver la<br/>
traduction.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>chat = "cat"; chien = "dog"</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Définir une variable par<br/>
mot est très peu<br/>
pratique : la solution<br/>
ne passe pas à<br/>
l'échelle dès que le<br/>
nombre de mots<br/>
augmente.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q17 : Construction depuis deux listes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p><pre><code>noms = ["Lou", "Max"]
ages = [16, 17]
d = {}
for i in range(len(noms)):
    d[noms[i]] = ages[i]
print(d)</code></pre><br/>
Que produit ce code ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le parcours par indice <code>range(len(noms))</code> permet<br/>
d'apparier deux listes de même longueur, et<br/>
l'affectation <code>d[cle] = valeur</code> remplit le<br/>
dictionnaire entrée par entrée. C'est une façon<br/>
courante de construire un dictionnaire à partir de<br/>
données tabulaires.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il affiche <code>{'Lou': 16, 'Max': 17}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : à chaque tour, <code>noms[i]</code> fournit<br/>
la clé et <code>ages[i]</code> la valeur de même rang.<br/>
L'affectation <code>d[cle] = valeur</code> crée l'entrée<br/>
si la clé est absente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>{16: 'Lou', 17: 'Max'}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : dans <code>d[noms[i]] = ages[i]</code>,<br/>
l'expression entre crochets est la <strong>clé</strong>.<br/>
Ce sont donc les noms qui servent de clés et<br/>
les âges qui sont les valeurs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche <code>{0: 'Lou', 1: 'Max'}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'indice <code>i</code> ne sert qu'à lire les deux<br/>
listes au même rang ; il n'est jamais utilisé<br/>
comme clé. La clé est <code>noms[i]</code>, une chaîne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il lève une <code>KeyError</code>, car les clés <code>'Lou'</code> et <code>'Max'</code> n'existent pas encore</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>KeyError</code> ne concerne que la<br/>
<strong>lecture</strong> d'une clé absente. Ici on écrit<br/>
dans <code>d</code>, et l'affectation crée la clé si elle<br/>
n'existe pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q19 : Trier des fruits selon leur stock</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un épicier veut lister ses fruits du moins au plus<br/>
approvisionné :</p>
<pre><code>stock = {"pommes": 12, "poires": 5, "kiwis": 8}

def quantite(fruit):
    return stock[fruit]

print(sorted(stock, key=quantite))</code></pre>
<p>Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>sorted</code> appliqué à un dictionnaire trie ses clés. Avec une<br/>
fonction clé comme <code>quantite</code>, qui renvoie la valeur associée<br/>
à chaque clé, on obtient les clés rangées selon leurs valeurs.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>['poires', 'kiwis', 'pommes']</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>sorted(stock)</code> trie les clés, et<br/>
<code>key=quantite</code> les compare selon la valeur<br/>
associée : $5$, puis $8$, puis $12$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[5, 8, 12]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : parcourir un dictionnaire, c'est parcourir<br/>
ses clés. <code>sorted</code> renvoie donc des noms de fruits ;<br/>
les quantités servent seulement à les comparer.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>['kiwis', 'poires', 'pommes']</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'ordre alphabétique, obtenu avec<br/>
<code>sorted(stock)</code> sans fonction clé. Ici, <code>quantite</code><br/>
impose de comparer les stocks.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[('poires', 5), ('kiwis', 8), ('pommes', 12)]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce seraient les couples de <code>stock.items()</code>.<br/>
<code>sorted(stock, key=quantite)</code> ne trie que les clés et<br/>
renvoie une liste de noms.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q20 : Reconnaître un dictionnaire vide</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le dictionnaire <code>inscrits</code> associe à chaque atelier la liste de<br/>
ses participants. Quelle condition vaut <code>True</code> exactement<br/>
lorsque <code>inscrits</code> ne contient aucune entrée ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le nombre d'entrées d'un dictionnaire s'obtient avec <code>len</code>,<br/>
comme pour une liste : <code>len({})</code> vaut $0$. Comparer un<br/>
dictionnaire à une liste ou lire une clé absente ne permet<br/>
pas de tester qu'il est vide.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>len(inscrits) == 0</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>len</code> renvoie le nombre d'entrées<br/>
du dictionnaire ; il vaut $0$ exactement quand le<br/>
dictionnaire est vide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>inscrits == []</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un dictionnaire n'est jamais égal à une<br/>
liste, même vide. Cette condition vaut toujours<br/>
<code>False</code>, y compris pour <code>{}</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>inscrits[0] == 0</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>inscrits[0]</code> cherche la clé <code>0</code>. Sur un<br/>
dictionnaire vide, cette clé n'existe pas et Python<br/>
lève <code>KeyError</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>inscrits.values() == 0</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>values()</code> renvoie les valeurs du<br/>
dictionnaire, pas leur nombre ; la comparaison avec<br/>
$0$ vaut toujours <code>False</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q23 : Modifier un dictionnaire pendant son parcours</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi est-il dangereux de<br/>
modifier un dictionnaire<br/>
pendant qu'on l'<strong>itère</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle générale : ne<br/>
<strong>jamais</strong> modifier une<br/>
collection (dictionnaire,<br/>
ensemble, liste, etc.)<br/>
pendant son parcours. Il<br/>
vaut mieux travailler sur<br/>
une copie ou collecter les<br/>
modifications dans une<br/>
structure auxiliaire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les modifications sont perdues à la fin du parcours</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les modifications ne sont pas<br/>
perdues. Le danger est que Python lève<br/>
<code>RuntimeError</code> si la taille change, ou que<br/>
le parcours devienne imprévisible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que le dictionnaire est copié à chaque tour de boucle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune copie n'est faite. Le<br/>
parcours travaille sur le dictionnaire<br/>
lui-même, ce qui est justement le<br/>
problème.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun danger, Python applique les modifications au tour suivant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python détecte le changement de<br/>
taille et lève <code>RuntimeError</code> au lieu de<br/>
continuer.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que le parcours peut échouer ou devenir imprévisible</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ajouter ou supprimer une<br/>
clé change la taille du dictionnaire ;<br/>
Python le détecte et lève <code>RuntimeError</code><br/>
(« dictionary changed size during<br/>
iteration »). Pour modifier<br/>
en sécurité, il faut<br/>
itérer sur une <strong>copie</strong><br/>
de la liste des clés,<br/>
par exemple<br/>
<code>for k in list(d):</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations<br/>
suivantes sur les<br/>
dictionnaires, laquelle est<br/>
<strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Mémo utile : la clé d'un<br/>
dictionnaire doit être<br/>
stable dans le temps. Tout<br/>
ce qui est mutable n'est<br/>
donc pas autorisé comme<br/>
clé.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'opérateur <code>in</code> teste la présence d'une clé, pas celle d'une valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte. Sur un<br/>
dictionnaire, <code>k in d</code><br/>
cherche <code>k</code> parmi les<br/>
clés ; pour les valeurs,<br/>
il faut écrire<br/>
<code>v in d.values()</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Affecter <code>d[k] = v</code> avec une clé <code>k</code> déjà présente remplace l'ancienne valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte. Une clé est<br/>
unique : une nouvelle<br/>
affectation écrase<br/>
l'ancienne valeur, sans<br/>
créer de doublon.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une liste peut être utilisée comme clé d'un dictionnaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
fausse (donc c'est la<br/>
bonne réponse). Les<br/>
listes étant modifiables,<br/>
elles ne peuvent pas<br/>
servir de clés. Les<br/>
chaînes, les entiers et<br/>
les p-uplets d'éléments<br/>
immuables le peuvent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La méthode <code>items()</code> permet de parcourir les couples (clé, valeur)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte : la boucle<br/>
<code>for k, v in d.items():</code><br/>
parcourt chaque clé avec<br/>
sa valeur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q26 : Méthode values</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On dispose du dictionnaire suivant :<br/>
<pre><code>stock = {"stylo": 5, "cahier": 12, "gomme": 3}</code></pre><br/>
Que renvoie l'expression <code>sum(stock.values())</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois vues complémentaires sur un dictionnaire :<br/>
<code>d.keys()</code> (les clés), <code>d.values()</code> (les valeurs)<br/>
et <code>d.items()</code> (les couples). Combinées avec les<br/>
fonctions natives <code>sum</code>, <code>max</code>, <code>min</code> ou <code>len</code>,<br/>
elles permettent d'écrire des traitements concis.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La somme des longueurs des clés (16)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>values</code> agit sur les valeurs, pas sur<br/>
les clés. La longueur des chaînes utilisées<br/>
comme clés n'intervient pas ici.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur de type</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction <code>sum</code> accepte parfaitement<br/>
un itérable de nombres. La méthode <code>values</code><br/>
renvoie justement un itérable, donc<br/>
l'opération est valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$20$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>stock.values()</code> renvoie une vue<br/>
sur les valeurs <code>[5, 12, 3]</code>, et <code>sum</code> calcule<br/>
leur total : $5 + 12 + 3 = 20$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$3$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait le nombre de <strong>clés</strong>, soit<br/>
la longueur du dictionnaire (<code>len(stock)</code>).<br/>
La somme demandée porte sur les <strong>valeurs</strong>, pas<br/>
sur le nombre d'entrées.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q27 : Inverser un dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On souhaite, à partir d'un dictionnaire <code>d</code> aux<br/>
valeurs distinctes, construire un nouveau<br/>
dictionnaire <code>inv</code> où les clés et les valeurs sont<br/>
échangées. Quel code convient ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette technique ne fonctionne correctement que si<br/>
les valeurs sont uniques. Si plusieurs clés<br/>
partagent une même valeur, chaque affectation<br/>
<code>inv[v] = k</code> écrase celle déjà rangée sous cette<br/>
clé et une seule association survit. Pour un mappage<br/>
multivalué, il faudrait construire un dictionnaire<br/>
de listes.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>inv = {}
for k in d:
    inv[v] = k</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle <code>for k in d</code> ne fournit que<br/>
la clé <code>k</code> ; la variable <code>v</code> n'est définie nulle<br/>
part et Python lève <code>NameError</code>. Il faut<br/>
obtenir la valeur par <code>d[k]</code> ou par <code>items()</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>inv = {}
for v in d.values():
    inv[v] = d[v]</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle parcourt les <strong>valeurs</strong> de<br/>
<code>d</code>, et <code>d[v]</code> cherche une valeur parmi les<br/>
clés, d'où une <code>KeyError</code> dès le premier tour.<br/>
Les valeurs ne sont pas des clés de <code>d</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>inv = {}
for k, v in d.items():
    inv[v] = k</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>items()</code> fournit chaque couple<br/>
<code>(clé, valeur)</code>, dépaqueté dans <code>k</code> et <code>v</code>.<br/>
L'affectation <code>inv[v] = k</code> range le couple<br/>
inversé dans le nouveau dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>inv = {}
for k, v in d.items():
    inv[k] = v</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'affectation <code>inv[k] = v</code> recopie<br/>
chaque couple dans le même sens. On obtient une<br/>
copie de <code>d</code>, pas son inverse ; il faut<br/>
échanger les rôles avec <code>inv[v] = k</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q28 : Des couples retournés en dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On construit un dictionnaire à partir d'une liste de couples :</p>
<pre><code>couples = [("rouge", 1), ("vert", 2), ("bleu", 3)]
couleurs = {}
for c in couples:
    couleurs[c[1]] = c[0]
print(couleurs[2])</code></pre>
<p>Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Dans <code>couleurs[c[1]] = c[0]</code>, l'expression entre crochets est<br/>
la clé : chaque couple (nom, numéro) donne une entrée qui<br/>
associe le numéro au nom. On lit ensuite une valeur par sa<br/>
clé, jamais par sa position.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>vert</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>c[1]</code> est le numéro et <code>c[0]</code> le nom,<br/>
donc la boucle construit<br/>
<code>{1: 'rouge', 2: 'vert', 3: 'bleu'}</code>. La clé <code>2</code> est<br/>
associée à <code>"vert"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>bleu</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>couleurs[2]</code> ne désigne pas la troisième<br/>
entrée, comme dans une liste, mais la valeur associée<br/>
à la clé <code>2</code>, soit <code>"vert"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>2</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>2</code> est la clé cherchée, pas la valeur.<br/>
L'affectation <code>couleurs[c[1]] = c[0]</code> associe à chaque<br/>
numéro le nom de la couleur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il lève une <code>KeyError</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait le cas si les noms servaient de<br/>
clés. Ici, <code>couleurs[c[1]] = c[0]</code> prend les numéros<br/>
comme clés, et la clé <code>2</code> existe bien.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q29 : Pourquoi un dictionnaire pour appartenir</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On dispose de dix mille valeurs distinctes et l'on doit,<br/>
pour chacune des nombreuses entrées suivantes lues au<br/>
clavier, déterminer si la valeur saisie figure dans la<br/>
collection. En Python, il est nettement plus efficace<br/>
de ranger ces dix mille valeurs comme clés d'un<br/>
<strong>dictionnaire</strong> plutôt que dans une <strong>liste</strong>. Pourquoi ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>En pratique, on range les dix mille valeurs comme clés<br/>
d'un dictionnaire (par exemple <code>d[valeur] = True</code> dans<br/>
une boucle), puis chaque test s'écrit <code>saisie in d</code>,<br/>
sans parcourir la collection.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que le dictionnaire retrouve une clé directement, sans parcourir la collection</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le test <code>saisie in d</code> retrouve la clé<br/>
sans examiner les autres valeurs. Une liste, au<br/>
contraire, est parcourue séquentiellement : dans le<br/>
pire des cas, les dix mille valeurs sont examinées,<br/>
avec un coût linéaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'un dictionnaire occupe systématiquement moins de mémoire qu'une liste de même taille</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est plutôt l'inverse. Un dictionnaire est<br/>
plus coûteux en mémoire qu'une liste de même taille.<br/>
Le gain se situe sur la vitesse de recherche, pas sur<br/>
la place occupée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'un dictionnaire est automatiquement trié, ce qui rend la recherche dichotomique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un dictionnaire n'est pas trié sur ses clés,<br/>
et aucune recherche dichotomique n'y est effectuée.<br/>
L'accès rapide vient de ce que la clé est retrouvée<br/>
directement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'une liste interdit les valeurs en double et que ce contrôle ralentit chaque recherche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une liste accepte parfaitement les<br/>
doublons ; ce sont les clés d'un dictionnaire qui<br/>
sont uniques. Et aucun contrôle d'unicité<br/>
n'intervient dans une recherche.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q30 : Liste impossible comme clé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>L'instruction <code>d = {[1, 2]: "premier"}</code> provoque une<br/>
erreur <code>TypeError</code>. En revanche,<br/>
<code>d = {(1, 2): "premier"}</code> est acceptée. Pourquoi cette<br/>
différence ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle générale en Python : seuls les objets immuables<br/>
peuvent servir de clés de dictionnaire. Les types<br/>
usuels acceptés sont les entiers, les flottants, les<br/>
chaînes, les booléens et les tuples dont les éléments<br/>
sont eux-mêmes immuables. Les listes et les<br/>
dictionnaires, modifiables, ne peuvent pas être des<br/>
clés.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce qu'une liste est modifiable, alors qu'une clé doit rester fixe, comme un tuple</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : si une clé pouvait être modifiée après<br/>
son insertion, l'entrée correspondante ne serait plus<br/>
retrouvée. C'est pourquoi Python n'autorise que des<br/>
objets <strong>immuables</strong> comme clés, comme les tuples.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'une liste occupe trop de mémoire alors qu'un tuple n'en utilise pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le tuple consomme également de la mémoire,<br/>
simplement un peu moins qu'une liste. La raison du<br/>
refus n'est pas la taille mais la mutabilité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'une liste ne peut contenir que des entiers, alors qu'un tuple peut contenir tout type de valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une liste peut contenir n'importe quel<br/>
type de valeur en Python (entiers, chaînes,<br/>
objets, autres listes, etc.).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les tuples sont, en Python, les seuls objets autorisés comme clés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : beaucoup d'autres objets servent de clés en<br/>
Python (entiers, flottants, chaînes, booléens). Le<br/>
critère est l'immuabilité, pas l'appartenance à la<br/>
famille des tuples.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q31 : Représenter un p-uplet nommé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un <strong>p-uplet nommé</strong> (ou enregistrement) regroupe<br/>
des valeurs de types différents, chacune désignée<br/>
par un nom de champ, par exemple le nom et l'âge<br/>
d'une personne. Comment le représente-t-on en<br/>
Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le programme de première présente les p-uplets<br/>
nommés comme des dictionnaires : les clés jouent le<br/>
rôle des noms de champs. Une table de données est<br/>
alors une liste de tels dictionnaires, tous avec les<br/>
mêmes clés.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Par un dictionnaire dont les clés sont les noms des champs : <code>{"nom": "Dupont", "age": 17}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Chaque champ est une clé, chaque valeur est<br/>
accessible par ce nom.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Par un tuple qui alterne les noms et les valeurs des champs : <code>("nom", "Dupont", "age", 17)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un tuple n'associe pas un nom à chaque valeur ;<br/>
il faudrait retenir des positions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Par une liste qui ne contient que les noms des champs : <code>["nom", "age"]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les valeurs manquent ; une liste de noms ne<br/>
décrit pas une personne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Par une chaîne de caractères qui concatène noms et valeurs : <code>"nom=Dupont;age=17"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On ne pourrait accéder à un champ qu'en découpant<br/>
la chaîne ; le dictionnaire le fait directement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q32 : Lire un champ des données d'une photo</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Les données d'une photo sont rangées dans un<br/>
enregistrement :</p>
<pre><code>photo = {"largeur": 4000, "hauteur": 3000, "iso": 200, "date": "2026-07-14"}</code></pre>
<p>Quelle expression donne la hauteur de la photo ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un enregistrement se lit par le nom de ses champs :<br/>
<code>photo["hauteur"]</code> vaut $3000$. Les données EXIF<br/>
d'une image (dimensions, sensibilité, date de prise<br/>
de vue) se prêtent bien à cette représentation.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>photo["hauteur"]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'accès se fait par la clé, le nom du champ.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>photo[1]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Il n'y a pas de clé $1$ : l'expression lève une<br/>
<code>KeyError</code>. Un dictionnaire ne se lit pas par<br/>
position.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>photo.hauteur</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette écriture lève une <code>AttributeError</code> : un<br/>
dictionnaire n'a pas d'attribut nommé comme ses<br/>
clés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>photo("hauteur")</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les parenthèses tentent d'appeler le dictionnaire<br/>
comme une fonction : <code>TypeError</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q33 : Le meilleur élève d'une liste d'enregistrements</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<pre><code>eleves = [{"nom": "Lina", "note": 14},
          {"nom": "Noah", "note": 9},
          {"nom": "Ava", "note": 17}]
meilleur = eleves[0]
for e in eleves:
    if e["note"] &gt; meilleur["note"]:
        meilleur = e
print(meilleur["nom"])</code></pre>
<p>Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Chaque élément de la liste est un enregistrement ;<br/>
la recherche du maximum compare un champ (<code>note</code>)<br/>
et conserve l'enregistrement entier, d'où l'accès<br/>
final au champ <code>nom</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>Ava</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>meilleur</code> prend l'enregistrement de plus haute<br/>
note ; <code>Ava</code> a $17$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Lina</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>Lina</code> est seulement le point de départ ; elle<br/>
est dépassée par <code>Ava</code> au troisième tour.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>17</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le programme affiche le champ <code>nom</code> de<br/>
l'enregistrement retenu, pas sa note.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{"nom": "Ava", "note": 17}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>print</code> reçoit <code>meilleur["nom"]</code>, une chaîne, pas<br/>
l'enregistrement entier.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q34 : Une clé entière et une clé chaîne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>d = {1: "un", "1": "one"}
print(len(d), d[1])</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le type d'une clé compte : une saisie <code>input</code>, toujours une chaîne,<br/>
ne retrouve pas une entrée à clé entière sans conversion.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>2 un</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'entier <code>1</code> et la chaîne <code>"1"</code> sont deux<br/>
clés différentes. Le dictionnaire a deux entrées, et <code>d[1]</code><br/>
lit celle de la clé entière.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>1 one</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux clés ne se confondent pas, aucune valeur<br/>
n'écrase l'autre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>2 one</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>d[1]</code> sans guillemets vise la clé entière, associée<br/>
à <code>"un"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, deux clés ne pouvant avoir la même écriture</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>1</code> et <code>"1"</code> n'ont pas la même écriture ni le même<br/>
type.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q35 : Des coordonnées comme clé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour associer une couleur à chaque case d'une grille repérée par<br/>
ses coordonnées, Lina écrit <code>grille[(2, 3)] = "rouge"</code>. Pourquoi ce<br/>
choix fonctionne-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un tuple immuable fait une clé composée commode : coordonnées,<br/>
couples nom-prénom, dates.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce qu'un tuple est immuable, donc accepté comme clé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les clés doivent être immuables. Un tuple de<br/>
deux entiers désigne une case de façon unique et ne peut pas<br/>
changer.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que Python convertit le tuple en chaîne <code>"2, 3"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune conversion n'a lieu, la clé reste le tuple.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les dictionnaires n'acceptent que des tuples</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : entiers, chaînes et tuples sont tous acceptés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Cela ne fonctionne pas, une clé devant être un entier ou une chaîne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un tuple est une clé valide, contrairement à une liste.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q36 : Une clé flottante introuvable</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>d = {0.3: "trois dixièmes"}
print(0.1 + 0.2 in d)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les flottants font de mauvaises clés : leurs approximations rendent<br/>
les recherches imprévisibles. On préfère des entiers ou des<br/>
chaînes.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>False</code>, <code>0.1 + 0.2</code> n'étant pas exactement <code>0.3</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la recherche d'une clé repose sur l'égalité<br/>
exacte. Deux flottants presque égaux sont deux clés différentes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>True</code>, les deux valeurs étant égales à <code>0.3</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : en binaire, <code>0.1 + 0.2</code> n'est pas exactement <code>0.3</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, un flottant ne pouvant être une clé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un flottant est immuable, donc accepté comme clé ; il<br/>
est simplement peu fiable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>trois dixièmes</code>, la valeur associée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>in</code> renvoie un booléen, pas une valeur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q37 : Une clé écrite deux fois à la création</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>stock = {"pommes": 10, "poires": 4, "pommes": 25}
print(len(stock), stock["pommes"])</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Écrire deux fois une clé est presque toujours une faute de frappe ;<br/>
Python ne la signale pas, d'où l'intérêt de relire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>2 25</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une clé est unique ; la seconde valeur<br/>
associée à <code>"pommes"</code> remplace la première. Il reste deux clés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>3 10</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un dictionnaire ne peut pas contenir deux fois la même<br/>
clé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>2 10</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la dernière valeur écrite qui l'emporte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, une clé répétée étant interdite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python accepte l'écriture et garde la dernière valeur,<br/>
sans avertissement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q38 : L'ordre de parcours d'un dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans quel ordre <code>for cle in d:</code> parcourt-il les clés d'un<br/>
dictionnaire Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un dictionnaire se parcourt dans l'ordre d'insertion ; pour un<br/>
autre ordre, on trie explicitement les clés.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Dans l'ordre où les clés ont été ajoutées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : depuis Python 3.7, un dictionnaire conserve<br/>
l'ordre d'insertion de ses clés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Dans l'ordre alphabétique des clés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun tri n'est fait ; pour un ordre alphabétique, on<br/>
utilise <code>sorted(d)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Dans un ordre aléatoire, différent à chaque exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'ordre est stable et prévisible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Par valeurs croissantes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le parcours porte sur les clés, dans leur ordre<br/>
d'ajout.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q39 : Compter les valeurs au-dessus d'un seuil</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>notes = {"Lou": 12, "Sami": 9, "Inès": 15}
n = 0
for prenom in notes:
    if notes[prenom] &gt; 10:
        n = n + 1
print(n)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Parcourir les clés et accéder aux valeurs par <code>d[cle]</code> est le<br/>
schéma de base pour compter ou cumuler dans un dictionnaire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>2</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la boucle parcourt les clés, lit chaque valeur<br/>
avec <code>notes[prenom]</code> et compte celles qui dépassent 10.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>3</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : recompte les notes strictement supérieures à 10, il y<br/>
en a 2.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>0</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : au moins une note dépasse 10.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, <code>prenom</code> étant une clé et non une note</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>notes[prenom]</code> donne bien la note associée à la clé.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q40 : Construire un dictionnaire filtré</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
<pre><code>prix = {"stylo": 2, "cahier": 5, "gomme": 1}
pas_cher = {}
for article, p in prix.items():
    if p &lt; 3:
        pas_cher[article] = p
print(pas_cher)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Filtrer un dictionnaire, c'est en construire un nouveau en ne<br/>
recopiant que les couples qui vérifient une condition.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>{'stylo': 2, 'gomme': 1}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>items</code> fournit chaque couple clé-valeur ; les<br/>
couples dont le prix est inférieur à 3 sont recopiés dans le<br/>
nouveau dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'cahier': 5}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la condition garde les prix inférieurs à 3, pas<br/>
supérieurs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>['stylo', 'gomme']</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>pas_cher</code> est un dictionnaire, les valeurs sont<br/>
conservées avec les clés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'stylo': 2, 'cahier': 5, 'gomme': 1}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le <code>if</code> écarte le cahier.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
