<?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 dict en Python : association<br/>
clé-valeur, création, accès, parcours, méthodes<br/>
keys, values, items et get. 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>L'implémentation interne d'un<br/>
dictionnaire repose sur une table<br/>
de hachage. L'accès à une valeur<br/>
par sa clé est en moyenne en<br/>
O(1). Depuis Python 3.7,<br/>
l'ordre d'insertion des paires<br/>
est conservé.</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</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 indexée par des entiers</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 associant des clés à des valeurs (par exemple un nom à un âge), permettant un accès rapide par clé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>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 simple chaîne de caractères</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/>
d = {"alice": 17, "bob": 16}.<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 d = ()</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 d = []</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 d = {}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On utilise des accolades. Une<br/>
forme alternative consiste à<br/>
écrire d = dict().</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec la syntaxe d = dict[]</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é "nom" dans le<br/>
dictionnaire d = {"nom": "Alice"} ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour éviter une KeyError, on<br/>
peut utiliser<br/>
d.get("nom", default), qui<br/>
renvoie la valeur par défaut<br/>
indiquée (ou None par défaut)<br/>
si la clé n'est pas présente.</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 d(nom)</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 d.nom</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 d["nom"]</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 KeyError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec d-&gt;nom</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/>
"age": 17 à un dictionnaire d<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 d.append("age", 17)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode append 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 d.put("age", 17)</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 d.add("age": 17)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode add est définie<br/>
pour les ensembles (set),<br/>
mais pas pour les<br/>
dictionnaires.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec d["age"] = 17</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<br/>
paires</strong> clé-valeur d'un<br/>
dictionnaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'égalité len(d) == 0 revient<br/>
à dire que le dictionnaire est<br/>
vide. Comme pour les listes, le<br/>
test if d: 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 d.length</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'attribut length n'existe<br/>
pas pour les dictionnaires<br/>
en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec len(d)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction native len<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 d.size()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode size n'existe<br/>
pas pour les dictionnaires<br/>
en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec count(d)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction count 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/>
for x in d:, où d est un<br/>
dictionnaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un idiome très courant :</p>
<p>`<code>python<br/>
for cle, valeur in d.items():<br/>
    print(cle, valeur)<br/>
</code>`</p>
<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/>
for k, v in d.items():.</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/>
for x in d.keys():. Pour<br/>
parcourir les valeurs, on<br/>
écrit for v in d.values():.<br/>
Pour parcourir les paires<br/>
clé-valeur, on utilise<br/>
for k, v in d.items():.</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 d.values().</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/>
"nom" existe dans le<br/>
dictionnaire d ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour tester la présence parmi<br/>
les <strong>valeurs</strong>, on écrit<br/>
valeur in d.values(). 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 d["nom"]</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/>
KeyError si la clé est<br/>
absente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec d.has("nom")</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode has n'existe pas<br/>
en Python 3. Une méthode<br/>
has_key existait en Python<br/>
2, mais elle a été supprimée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec d.contains("nom")</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode contains n'existe<br/>
pas pour les dictionnaires en<br/>
Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec "nom" in d</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'opérateur in 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 : Supprimer une entrée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment <strong>supprime-t-on</strong> la clé<br/>
"age" d'un dictionnaire d ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Distinction importante : mettre<br/>
la valeur à None revient à<br/>
dire « la clé existe, mais<br/>
avec une valeur nulle » ;<br/>
l'opération del supprime<br/>
réellement la clé du<br/>
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="0" format="html">
    <text><![CDATA[<p>Avec d.delete("age")</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode delete n'existe<br/>
pas pour les dictionnaires<br/>
en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec d["age"] = None</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette opération met la<br/>
valeur à None, mais la<br/>
clé reste présente dans le<br/>
dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec d.remove("age")</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode remove est<br/>
définie pour les listes,<br/>
mais pas pour les<br/>
dictionnaires.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec del d["age"]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On utilise le mot-clé del.<br/>
Si la clé n'existe pas,<br/>
Python lève une exception<br/>
KeyError. Pour éviter<br/>
l'erreur, on peut utiliser<br/>
d.pop("age", None), qui<br/>
renvoie en plus la valeur<br/>
retirée.</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/>
mémoïsation (entrée vers<br/>
résultat), configuration<br/>
(option vers 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 (la clé) à un ensemble d'informations (la valeur), comme un nom à un âge ou un code postal à une ville</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 des 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 : Trace simple</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que produit ce code ?</p>
<p>`<code>python<br/>
d = {"a": 1, "b": 2}<br/>
d["c"] = 3<br/>
print(len(d))<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Vérifier la longueur d'un<br/>
dictionnaire est utile pour<br/>
s'assurer qu'on n'a pas écrasé<br/>
par mégarde une entrée<br/>
existante en utilisant la<br/>
même 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>Il déclenche une erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le code est parfaitement<br/>
valide. Aucune erreur n'est<br/>
levée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche "a", "b", "c"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction len renvoie<br/>
un entier, pas la liste des<br/>
clés. Pour obtenir les<br/>
clés, on utiliserait<br/>
list(d.keys()).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il affiche 3</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le dictionnaire contenait<br/>
deux paires au départ. On<br/>
en ajoute une troisième<br/>
("c": 3), donc len(d)<br/>
renvoie 3.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche 2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette réponse ignore l'ajout<br/>
de la nouvelle clé "c".</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 mots ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Ce motif est si fréquent que<br/>
Python propose la classe<br/>
collections.Counter, qui<br/>
automatise le comptage. Par<br/>
exemple,<br/>
Counter(["a", "b", "a"])<br/>
renvoie Counter({"a": 2,<br/>
"b": 1}).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
c = {}<br/>
for m in mots:<br/>
    c[m] = c.get(m, 0) + 1<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un motif classique.<br/>
L'appel c.get(m, 0)<br/>
renvoie 0 si la clé m<br/>
n'est pas encore présente.<br/>
Une alternative plus<br/>
concise consiste à utiliser<br/>
Counter(mots) du module<br/>
collections.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
c = sum(mots)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction sum ne<br/>
fonctionne pas avec une<br/>
liste de chaînes de<br/>
caractères. Elle attend<br/>
des nombres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
c = dict(mots)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette construction ne<br/>
fonctionne que si mots<br/>
contient des paires<br/>
clé-valeur, et non des<br/>
chaînes simples.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
c = mots.count()<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode count sur une<br/>
liste compte les occurrences<br/>
d'un seul élément précis,<br/>
et non de tous les éléments<br/>
en une fois.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q12 : Méthode get avec valeur par défaut</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait d.get("x", 0) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sans valeur par défaut,<br/>
d.get("x") renvoie None si<br/>
la clé est absente. Avec une<br/>
valeur par défaut, elle renvoie<br/>
cette valeur. Très pratique<br/>
dans les motifs<br/>
d'accumulation.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle renvoie la valeur associée à "x" si la clé existe, et 0 sinon (sans lever d'erreur)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette méthode est très<br/>
utile pour éviter une<br/>
exception KeyError. Le<br/>
second paramètre est la<br/>
valeur par défaut, à<br/>
renvoyer en l'absence de<br/>
la clé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle renvoie toujours la valeur 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode renvoie 0<br/>
uniquement quand la clé<br/>
"x" n'est pas présente.<br/>
Sinon, elle renvoie la<br/>
valeur associée à la clé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle supprime la clé "x" du dictionnaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode get se contente<br/>
de lire ; elle ne modifie<br/>
pas le dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle déclenche une erreur si la clé n'existe pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est précisément l'intérêt<br/>
de get que de <strong>ne pas</strong><br/>
déclencher d'erreur en<br/>
l'absence de la clé.</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 d.items() ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois vues complémentaires sont<br/>
disponibles : keys() pour les<br/>
clés, values() pour les<br/>
valeurs, et items() 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 les clés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description correspond<br/>
plutôt à d.keys(). La<br/>
méthode items 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/>
d.values(). La méthode<br/>
items 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/>
len(d).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une vue itérable sur les paires (clé, valeur) du dictionnaire</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/>
for k, v in d.items():.</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 str (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 tuple, à 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 list (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/>
d[[1, 2]] = 5 provoque<br/>
une TypeError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le type int (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/>
(table de hachage interne),<br/>
mais offre une recherche<br/>
très rapide. La liste, plus<br/>
compacte, est lente pour la<br/>
recherche par 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="100" format="html">
    <text><![CDATA[<p>Pour la rapidité d'accès : un accès en O(1) avec un dictionnaire, contre O(n) avec une liste utilisée pour une recherche linéaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sur de gros volumes de<br/>
données, la différence est<br/>
considérable. Pour un<br/>
million d'éléments, on<br/>
parle d'environ 1 µs<br/>
avec un dictionnaire,<br/>
contre plusieurs<br/>
millisecondes avec une<br/>
liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les listes ne supportent pas les nombres</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 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 différence notable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Il existe au contraire<br/>
une différence majeure<br/>
de performance, comme<br/>
expliqué dans la bonne<br/>
réponse.</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<br/>
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[<p>`<code>python<br/>
{"chat": "cat", "chien": "dog"}<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On utilise un dictionnaire,<br/>
ce qui permet un accès<br/>
immédiat :<br/>
traduction["chat"]<br/>
renvoie "cat".</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
("chat", "cat")<br/>
</code>`</p>]]></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[<p>`<code>python<br/>
["chat", "cat", "chien", "dog"]<br/>
</code>`</p>]]></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[<p>`<code>python<br/>
chat = "cat"; chien = "dog"<br/>
</code>`</p>]]></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 : Modification d'une valeur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>`<code>python<br/>
d = {"a": 1, "b": 2}<br/>
d["a"] = d["a"] + 10<br/>
print(d)<br/>
</code>`<br/>
Que produit ce code ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une forme abrégée<br/>
idiomatique consiste à<br/>
écrire d["a"] += 10,<br/>
plus concise et plus<br/>
lisible.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il affiche {"a": 11, "b": 2}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La valeur initiale de<br/>
d["a"] est 1, à<br/>
laquelle on ajoute 10.<br/>
La nouvelle valeur est<br/>
donc 11.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il déclenche une erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le code est parfaitement<br/>
valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche {"a": 1, "b": 2}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette réponse ignore la<br/>
modification de d["a"],<br/>
qui passe de 1 à 11.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il affiche {"a": 10, "b": 2}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On ajoute 10 à la<br/>
valeur précédente, on ne<br/>
remplace pas la valeur<br/>
par 10.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q18 : Le type defaultdict</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fournit l'instruction<br/>
from collections import<br/>
defaultdict ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le module collections<br/>
regroupe plusieurs outils<br/>
très utiles : defaultdict,<br/>
Counter, OrderedDict,<br/>
namedtuple, et d'autres<br/>
encore.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle importe une simple variable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation est<br/>
imprécise. Il s'agit en<br/>
réalité d'un type<br/>
spécialisé, comme<br/>
expliqué dans la bonne<br/>
réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle crée un dictionnaire vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le dictionnaire vide se<br/>
crée avec {} ou<br/>
dict(). La classe<br/>
defaultdict apporte<br/>
une fonctionnalité<br/>
supplémentaire : la<br/>
création automatique de<br/>
valeurs par défaut.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle importe un fichier annexe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette instruction concerne<br/>
un type Python, et non<br/>
un fichier sur le<br/>
disque.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle importe un type de dictionnaire qui crée automatiquement une valeur par défaut lorsqu'on accède à une clé inexistante (utile pour les comptages ou les regroupements)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Par exemple, en écrivant<br/>
c = defaultdict(int),<br/>
on peut directement<br/>
incrémenter<br/>
c[mot] += 1 sans<br/>
tester d'abord la<br/>
présence de la clé.<br/>
C'est très pratique.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q19 : Ordre des entrées</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Depuis Python 3.7, dans quel<br/>
ordre les entrées d'un<br/>
dictionnaire sont-elles<br/>
parcourues ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour un parcours <strong>trié par<br/>
clé</strong>, on écrit<br/>
for k in sorted(d):. Pour<br/>
un parcours <strong>trié par<br/>
valeur</strong>, on écrit<br/>
for k in sorted(d, key=d.get):.</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>Dans un ordre aléatoire à chaque exécution</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'ordre est en réalité<br/>
déterministe depuis<br/>
Python 3.7 : les<br/>
entrées sont parcourues<br/>
dans l'ordre où elles<br/>
ont été insérées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Dans l'ordre d'insertion des paires</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un changement<br/>
subtil mais important.<br/>
Avant Python 3.7,<br/>
l'ordre n'était pas<br/>
garanti, ce qui pouvait<br/>
surprendre.</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>Aucun tri automatique sur<br/>
les clés n'est effectué.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Par taille croissante des valeurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucun tri automatique<br/>
n'est effectué sur les<br/>
valeurs.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q20 : Cas du dictionnaire vide</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que vaut bool({}) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Convention dite « truthy /<br/>
falsy » : sont <strong>faux</strong><br/>
False, 0, 0.0, "",<br/>
[], {}, (), et<br/>
None. Tous les autres<br/>
objets sont considérés<br/>
comme <strong>vrais</strong> dans un<br/>
contexte booléen.</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 exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le code est parfaitement<br/>
valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>False</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est la convention<br/>
Python : les structures<br/>
vides sont fausses.<br/>
C'est utile pour<br/>
tester rapidement avec<br/>
if d:, qui se lit<br/>
« si le dictionnaire<br/>
n'est pas vide ».</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La valeur 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fonction bool<br/>
renvoie un booléen, pas<br/>
un entier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>True</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un dictionnaire vide est<br/>
considéré comme faux en<br/>
Python, au même titre que<br/>
[], "", 0 et<br/>
None.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q21 : Hachage et collisions</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi l'accès à un<br/>
dictionnaire est-il en<br/>
moyenne en O(1), mais<br/>
au pire en O(n) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette garantie est<br/>
probabiliste, et non<br/>
déterministe. Pour des<br/>
situations adversariales<br/>
(sécurité), Python<br/>
randomise le hachage des<br/>
chaînes via la variable<br/>
d'environnement<br/>
PYTHONHASHSEED.</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>Aucune raison particulière</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette différence<br/>
s'explique au contraire<br/>
par le fonctionnement<br/>
interne de la table de<br/>
hachage, comme expliqué<br/>
dans la bonne réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les clés sont triées en interne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les clés ne sont pas<br/>
triées dans une table<br/>
de hachage. C'est<br/>
précisément ce qui<br/>
permet l'accès en O(1)<br/>
en moyenne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que la table de hachage peut subir des collisions (deux clés qui se retrouvent au même emplacement). Au pire (toutes les clés au même emplacement), on retombe sur une recherche linéaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce phénomène reste<br/>
néanmoins rare en<br/>
pratique. Python utilise<br/>
des stratégies internes<br/>
(adressage ouvert,<br/>
redimensionnement) qui<br/>
maintiennent les<br/>
collisions à un niveau<br/>
acceptable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les dictionnaires sont mal conçus en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
incorrecte. Les<br/>
dictionnaires Python<br/>
sont au contraire<br/>
réputés pour leur<br/>
excellente performance.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q22 : La méthode setdefault</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait d.setdefault("k",<br/>
0) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette méthode est utile<br/>
mais elle est souvent<br/>
remplacée par<br/>
defaultdict, plus<br/>
expressif. Elle reste<br/>
pratique surtout quand la<br/>
valeur par défaut est<br/>
coûteuse à calculer.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle écrase systématiquement la valeur de la clé "k" avec 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode n'écrase pas<br/>
la valeur existante.<br/>
Elle ne définit la<br/>
valeur par défaut que si<br/>
la clé n'est pas déjà<br/>
présente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La méthode setdefault n'existe pas en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette méthode existe<br/>
bel et bien, et fait<br/>
partie de l'interface<br/>
standard des<br/>
dictionnaires.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle déclenche systématiquement une erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La méthode setdefault<br/>
ne lève pas d'erreur ;<br/>
c'est précisément son<br/>
intérêt par rapport à<br/>
un accès direct.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Si la clé "k" existe, elle renvoie sa valeur. Sinon, elle l'ajoute avec la valeur 0 et renvoie 0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette méthode combine<br/>
deux opérations en une<br/>
seule : elle est utile<br/>
pour initialiser une<br/>
clé à la première<br/>
rencontre.</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>Le code s'exécute plus rapidement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucune amélioration de<br/>
performance n'est<br/>
obtenue par cette<br/>
modification ; c'est<br/>
au contraire une source<br/>
potentielle de bugs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Cette modification est interdite par la loi</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette interprétation<br/>
littérale n'a aucun sens<br/>
en programmation.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune conséquence particulière</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette modification a au<br/>
contraire des<br/>
conséquences sérieuses,<br/>
comme expliqué dans la<br/>
bonne réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Cela peut lever une exception RuntimeError indiquant que la taille du dictionnaire a changé pendant l'itération, ou produire des comportements imprévisibles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Python détecte la<br/>
modification et lève une<br/>
erreur. 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/>
for k in list(d):.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q24 : Compréhension de dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel code crée le dictionnaire<br/>
{1: 1, 2: 4, 3: 9, ...,<br/>
10: 100} (le carré de<br/>
chaque entier) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Quatre formes de<br/>
compréhension existent en<br/>
Python : [...] pour les<br/>
listes, {x for ...} pour<br/>
les ensembles,<br/>
{k: v for ...} pour les<br/>
dictionnaires, et<br/>
(... for ...) pour les<br/>
générateurs.</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>{i: i  2 for i in range(1, 11)}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est une <strong>compréhension<br/>
de dictionnaire</strong>. Sa<br/>
syntaxe est<br/>
{cle: valeur for ... in<br/>
...}. Cette construction<br/>
est concise et<br/>
idiomatique en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>{i  2 for i in range(1, 11)}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe crée un<br/>
<strong>ensemble</strong>, et non un<br/>
dictionnaire, car il<br/>
n'y a pas de paires<br/>
clé-valeur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[i: i  2 for i in range(1, 11)]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe est<br/>
invalide en Python. Les<br/>
crochets ne permettent<br/>
pas de définir une<br/>
compréhension avec des<br/>
paires clé-valeur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>dict(i, i  2 for i in range(1, 11))</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette syntaxe est<br/>
invalide. La fonction<br/>
dict ne s'utilise pas<br/>
de cette manière.</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>La méthode d.get(k, default) renvoie default si la clé est absente, sans lever d'erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte. C'est<br/>
précisément l'intérêt<br/>
de cette méthode par<br/>
rapport à un accès<br/>
direct.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'accès par clé est en O(1) en moyenne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte. C'est la<br/>
conséquence directe de<br/>
l'implémentation par<br/>
table de hachage.</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 mutables,<br/>
elles ne peuvent pas<br/>
servir de clés. Seuls<br/>
les objets immuables<br/>
(entier, chaîne,<br/>
flottant, tuple,<br/>
ensemble figé) peuvent<br/>
être utilisés comme<br/>
clés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Depuis Python 3.7, l'ordre d'insertion des paires est conservé lors du parcours</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
correcte. C'est une<br/>
garantie introduite à<br/>
partir de Python 3.7.</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 :</p>
<p>`<code>python<br/>
stock = {"stylo": 5, "cahier": 12, "gomme": 3}<br/>
</code></p>
<p>Que renvoie l'expression sum(stock.values())` ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois vues complémentaires sur un dictionnaire :<br/>
d.keys() (les clés), d.values() (les valeurs)<br/>
et d.items() (les couples). Combinées avec les<br/>
fonctions natives sum, max, min ou len,<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 : values 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 sum accepte parfaitement<br/>
un itérable de nombres. La méthode values<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 : stock.values() renvoie une vue<br/>
sur les valeurs [5, 12, 3], et sum 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 (len(stock)).<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 d aux<br/>
valeurs distinctes, obtenir un nouveau dictionnaire<br/>
où les clés et les valeurs sont échangées. Quelle<br/>
compréhension 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, la conversion<br/>
« écrasera » les doublons et ne conservera qu'une<br/>
des associations possibles. 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[<p>{v: k for k in d}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans appeler d.items(), la variable<br/>
v n'est pas définie. Cette syntaxe ne<br/>
fonctionne qu'avec for k in d, où k est<br/>
une clé, pas un couple.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>{d[k]: k for k in d.values()}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle parcourt les <strong>valeurs</strong> de<br/>
d, pas ses clés. L'expression d[k] est donc<br/>
incorrecte (les valeurs ne sont pas des clés<br/>
du dictionnaire).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>{v: k for k, v in d.items()}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la méthode items() renvoie une<br/>
séquence de couples (clé, valeur). Le<br/>
déballage for k, v in d.items() permet ensuite<br/>
d'écrire le couple inversé v: k dans le<br/>
nouveau dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>{k: v for v, k in d.items()}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on a inversé l'ordre des variables<br/>
dans le déballage, mais on a oublié de<br/>
réécrire la paire v: k à gauche. Le résultat<br/>
ne sera pas inversé : on retrouve le<br/>
dictionnaire d'origine.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Dictionnaires — Q28 : Construction depuis une liste de couples</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie l'expression<br/>
dict([("rouge", 1), ("vert", 2), ("bleu", 3)]) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois façons usuelles de créer un dictionnaire :<br/>
littéral {"a": 1, "b": 2}, fonction<br/>
dict(a=1, b=2) (clés en chaînes implicites) et<br/>
dict(zip(cles, valeurs)) (depuis deux listes<br/>
parallèles). La forme « liste de couples » est très<br/>
utile lors de la lecture de fichiers structuré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>{'rouge': 1, 'vert': 2, 'bleu': 3}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la fonction dict accepte un<br/>
itérable de couples (clé, valeur) et construit<br/>
le dictionnaire correspondant. C'est une façon<br/>
courante de bâtir un dictionnaire à partir de<br/>
données structurées (par exemple le résultat<br/>
d'un zip sur deux listes).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>{'rouge', 'vert', 'bleu'}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait un <strong>ensemble</strong> (set).<br/>
dict produit un dictionnaire avec des clés<br/>
<strong>et</strong> des valeurs ; il ne se limite pas aux<br/>
clés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur de syntaxe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction dict est native en Python<br/>
et accepte plusieurs formes d'appel. La<br/>
construction depuis une liste de couples est<br/>
parfaitement valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>[('rouge', 1), ('vert', 2), ('bleu', 3)]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait la liste d'origine inchangée.<br/>
La fonction native dict transforme cette liste<br/>
en un véritable dictionnaire.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
