<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Première/Tables de données</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Représentation tabulaire des données, descripteurs<br/>
(colonnes), enregistrements (lignes), opérations courantes<br/>
(recherche, tri, sélection, fusion, jointure simple), en<br/>
Python avec listes de dictionnaires ou listes de listes.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q01 : Qu'est-ce qu'une table ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>En informatique, qu'appelle-t-on une <strong>table de données</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les tables sont la structure la plus simple et la<br/>
plus répandue pour organiser des données : tableurs,<br/>
bases relationnelles, fichiers CSV, DataFrames pandas<br/>
reposent tous sur ce modèle.</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 meuble pour poser un ordinateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Plaisanterie : on parle bien d'une structure<br/>
informatique, pas de mobilier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type primitif de Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python n'a pas de type natif "table".<br/>
On peut la simuler avec des listes ou<br/>
dictionnaires.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un tableau composé de lignes (enregistrements) et de colonnes (descripteurs ou attributs)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est la définition standard,<br/>
identique à celle d'un tableur ou d'une table<br/>
de base de données. Chaque ligne décrit une<br/>
entité (élève, livre...), chaque colonne un<br/>
attribut (nom, âge...).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fonction Python qui renvoie un dictionnaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est éventuellement un moyen de<br/>
<strong>représenter</strong> une table, pas la définition<br/>
elle-même.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q02 : Vocabulaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment appelle-t-on une <strong>colonne</strong> dans une table<br/>
de données ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Vocabulaire à maîtriser : ligne = enregistrement<br/>
= entité ; colonne = descripteur = attribut =<br/>
champ. Selon le manuel, le mot peut varier.</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 ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : confusion ligne/colonne. Une ligne<br/>
décrit une entité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une clé primaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une clé primaire est un <strong>descripteur<br/>
particulier</strong> qui identifie de manière unique<br/>
chaque ligne. Toutes les colonnes ne sont pas<br/>
des clés primaires.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un enregistrement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un enregistrement est une <strong>ligne</strong>,<br/>
pas une colonne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un descripteur (ou attribut, ou champ)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la colonne décrit une propriété<br/>
commune à toutes les entités (par exemple<br/>
"nom", "age", "ville"). Les termes<br/>
"descripteur", "attribut", "champ" sont<br/>
synonymes selon le contexte.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q03 : Liste de dictionnaires</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment représente-t-on couramment une table en<br/>
Python (avec en-tête) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Autres représentations possibles : liste de<br/>
tuples, liste de listes, dict de listes (« colonne<br/>
par colonne »). Le choix dépend de l'usage. Pour<br/>
le NSI Première, on utilise principalement la liste<br/>
de dictionnaires.</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>Comme une simple chaîne de caractères</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce ne serait pas pratique pour<br/>
manipuler les données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Comme une liste de dictionnaires, chaque dictionnaire représentant une ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : exemple<br/>
[{"nom":"Alice","age":17}, {"nom":"Bob","age":16}].<br/>
C'est ce que renvoie csv.DictReader quand on<br/>
le convertit en liste. Très lisible<br/>
(ligne["nom"]).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Comme une fonction</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une fonction décrit un calcul, pas<br/>
des données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Comme un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un entier ne stocke aucune<br/>
structure.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q04 : Accéder à une cellule</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Soit table = [{"nom":"Alice","age":17}, {"nom":"Bob","age":16}].<br/>
Comment accéder à l'âge de Bob ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma général : table[indice_ligne][descripteur].<br/>
L'ordre des accès reflète la structure : d'abord<br/>
la liste, puis le 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>table[1]['age']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : Bob est la deuxième ligne<br/>
(indice 1), et 'age' est le descripteur. On<br/>
obtient 16.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table['Bob']['age']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : table est une <strong>liste</strong>, pas un<br/>
dictionnaire indexé par nom. Cela lève<br/>
TypeError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table[2]['age']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : indice <strong>hors-borne</strong>. Avec deux<br/>
lignes, les indices valides sont 0 et 1, pas<br/>
2.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.age[1]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune méthode ni attribut .age sur<br/>
une liste.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q05 : Parcourir une table</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour afficher tous les noms d'élèves d'une table<br/>
(liste de dictionnaires avec une clé "nom"), quel<br/>
code utilise-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma classique de parcours d'une liste de<br/>
dictionnaires. À retenir.</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>python<br/>
print(table.nom)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas d'attribut .nom sur une liste.<br/>
Cela lève AttributeError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
for ligne in table:<br/>
    print(ligne["nom"])<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la boucle parcourt chaque<br/>
dictionnaire, et on accède à la valeur de la<br/>
clé "nom".</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
for nom in table:<br/>
    print(nom)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la variable nom recevrait chaque<br/>
<strong>dictionnaire</strong> entier, pas le nom seulement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
print(table["nom"])<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : table est une liste, on ne peut<br/>
pas indexer par chaîne.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q06 : Origine des tables</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>D'où peut provenir une table de données dans un<br/>
projet réel ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une compétence clé du NSI : savoir lire des<br/>
données réelles (souvent en CSV ou JSON), les<br/>
transformer en table Python, puis les manipuler.</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>D'un fichier (CSV, JSON), d'un tableur, d'une base de données, d'une API web...</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les tables sont partout en<br/>
informatique. Open Data (data.gouv.fr),<br/>
extracts SQL, exports Excel, scraping web...<br/>
autant de sources possibles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune des réponses précédentes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la deuxième proposition est<br/>
correcte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Uniquement d'un fichier CSV créé à la main</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Trop restrictif : il existe de nombreuses<br/>
autres sources.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Uniquement d'une base de données SQL</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Trop restrictif : SQL est une source<br/>
fréquente mais pas la seule.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q07 : Recherche par critère</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour trouver toutes les lignes où l'âge est<br/>
strictement supérieur à 16, quel code écrit-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Compréhension de liste : schéma Python élégant<br/>
pour filtrer, transformer et combiner. Très<br/>
utilisé sur les tables.</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>python<br/>
for ligne in table:<br/>
    if ligne["age"] &gt; 16:<br/>
        print(ligne)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cela <strong>affiche</strong> les lignes mais ne renvoie<br/>
pas une liste. Si la question est "trouver",<br/>
on attend une valeur de retour, pas un<br/>
affichage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
[ligne for ligne in table if ligne["age"] &gt; 16]<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : compréhension de liste avec<br/>
condition. Forme idiomatique en Python pour<br/>
filtrer.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
table.find(age &gt; 16)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la méthode .find() n'existe pas<br/>
sur les listes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
table[ligne["age"] &gt; 16]<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : syntaxe invalide. ligne n'est pas<br/>
défini hors d'une boucle.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q08 : Construire depuis CSV</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est le moyen le plus simple de construire une<br/>
table (liste de dictionnaires) à partir d'un fichier<br/>
CSV avec en-tête ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Idiome standard. Penser à fermer le fichier<br/>
proprement avec un with, ou utiliser cette<br/>
écriture compacte si le fichier est petit.</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>Lire le fichier ligne par ligne et coder à la main le découpage</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais fastidieux et fragile. Il existe<br/>
un outil dédié.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>csv.load('data.csv') (cette fonction existe-t-elle ?)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Non, cette fonction n'existe pas dans le<br/>
module csv.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>list(csv.DictReader(open('data.csv', encoding='utf-8')))</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : csv.DictReader produit un<br/>
itérateur de dictionnaires ; list() le<br/>
matérialise en table prête à l'emploi.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>json.load(open('data.csv'))</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : json.load lit du JSON, pas du CSV.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q09 : Nombre de lignes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment obtenir le <strong>nombre d'enregistrements</strong><br/>
(lignes) d'une table représentée comme liste de<br/>
dictionnaires ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour le nombre de <strong>colonnes</strong>, on regarde les<br/>
clés du premier dictionnaire :<br/>
len(table[0]) (en supposant la table non 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>size(table)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de fonction size en Python<br/>
standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>len(table.keys())</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : .keys() n'existe pas sur une<br/>
liste. Cela lève AttributeError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>len(table)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : len() sur la liste donne le<br/>
nombre de dictionnaires, donc de lignes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.count</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : .count est une <strong>méthode</strong> (qui<br/>
compte les occurrences d'un élément), il faut<br/>
l'appeler avec des parenthèses et un<br/>
argument.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q10 : Table vide</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que vaut len(table) pour une table vide ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Toujours penser au cas de la table vide dans les<br/>
calculs : moyenne = total / len(table) lèverait<br/>
ZeroDivisionError.</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 est levée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : len([]) renvoie 0 sans erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : [] (liste vide) contient<br/>
zéro élément.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>-1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : len n'est jamais négatif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>None</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : len renvoie toujours un entier.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q11 : Trier par descripteur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment trier la table par âge <strong>croissant</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour trier sans modifier la table d'origine :<br/>
sorted(table, key=lambda r: r['age']). Pour un<br/>
tri <strong>décroissant</strong>, ajouter reverse=True.</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>table.sort(key=lambda ligne: ligne['age'])</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : key indique sur quoi<br/>
comparer. La lambda renvoie l'âge de chaque<br/>
ligne. Tri en place de la liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.sort()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sort ne sait pas comparer deux<br/>
dictionnaires sans préciser sur quel<br/>
descripteur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>sorted(table, by='age')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sorted n'a pas d'argument by.<br/>
C'est key= qu'il faut.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.sort('age')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sort n'accepte pas une chaîne<br/>
comme premier argument positionnel. Il faut<br/>
le mot-clé key=.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q12 : Sélectionner des colonnes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment construire une nouvelle table ne contenant<br/>
que les colonnes nom et age (sans les autres<br/>
descripteurs) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette opération consiste à <strong>extraire un<br/>
sous-ensemble de colonnes</strong> d'une table. C'est<br/>
l'une des manipulations classiques de tables,<br/>
au même titre que la sélection de lignes, le<br/>
tri ou la fusion.</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>table[['nom', 'age']]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est une syntaxe <strong>pandas</strong>, pas<br/>
Python standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.select('nom', 'age')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la méthode .select n'existe pas<br/>
sur les listes (cela ressemble à du SQL).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>[{k: l[k] for k in ['nom', 'age']} for l in table]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : compréhension de liste<br/>
imbriquée avec une compréhension de<br/>
dictionnaire. Pour chaque ligne, on<br/>
reconstruit un dictionnaire ne gardant que les<br/>
clés voulues.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.keep('nom', 'age')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de méthode .keep en Python<br/>
standard.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q13 : Fusion de tables</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Soient deux tables t1 et t2 ayant les <strong>mêmes<br/>
descripteurs</strong>. Comment obtenir une nouvelle table<br/>
contenant toutes les lignes de t1 puis celles de<br/>
t2 ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour modifier t1 <strong>en place</strong> au lieu de créer<br/>
une nouvelle table : t1.extend(t2) ou<br/>
t1 += t2.</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>t1.append(t2)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Attention : append(t2) ajouterait t2<br/>
comme <strong>un seul élément</strong> (une liste de<br/>
listes), pas en fusionnant. Il faudrait<br/>
plutôt extend.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>fusion(t1, t2)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de fonction fusion en Python<br/>
standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>t1.merge(t2)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de méthode .merge sur les<br/>
listes (cela ressemble à du pandas).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>t1 + t2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la concaténation de listes<br/>
(+) crée une nouvelle liste contenant tous<br/>
les éléments. Idiome Python standard.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q14 : Calculer une moyenne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment calculer la <strong>moyenne</strong> des âges d'une<br/>
table avec un descripteur age (entier) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Penser à gérer le cas de la table <strong>vide</strong><br/>
(division par zéro) : tester if table: avant<br/>
le calcul, ou utiliser<br/>
sum(...) / len(table) if table else 0.</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>mean(table.age)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de fonction mean en standard,<br/>
et pas d'attribut .age sur une liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.average('age')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de méthode .average.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>sum(table['age']) / len(table)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : table est une <strong>liste</strong>, on ne<br/>
peut pas l'indexer par chaîne. Lève<br/>
TypeError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>sum(ligne['age'] for ligne in table) / len(table)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on extrait la valeur age<br/>
pour chaque ligne via une expression<br/>
génératrice, puis on divise par le nombre de<br/>
lignes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q15 : Jointure simple</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Soient eleves = [{"id":1,"nom":"Alice"},...] et<br/>
notes = [{"id_eleve":1,"matiere":"Maths","note":15},...].<br/>
Pour associer chaque note au nom de l'élève, on<br/>
effectue une <strong>jointure</strong>. Quel pseudo-code<br/>
l'implémente correctement ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est l'opération de <strong>fusion</strong> de deux tables sur<br/>
une clé commune. Pour gagner en performance, on<br/>
peut indexer eleves par id dans un dictionnaire<br/>
au préalable.</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>python<br/>
notes + eleves<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la concaténation ne fait aucune<br/>
mise en correspondance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
eleves.merge(notes)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de méthode .merge en Python<br/>
standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
for n in notes:<br/>
    for e in eleves:<br/>
        if n["id_eleve"] == e["id"]:<br/>
            print(e["nom"], n["matiere"], n["note"])<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on parcourt les notes et,<br/>
pour chacune, on cherche l'élève<br/>
correspondant. Complexité O(n × m).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
for n in notes:<br/>
    print(eleves[n["id_eleve"]]["nom"])<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : eleves[1] accède à l'<strong>indice 1</strong><br/>
de la liste, pas à l'élève d'id 1.<br/>
Coïncidence possible mais code incorrect en<br/>
général.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q16 : Pièges de conversion</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Après lecture d'un CSV avec csv.DictReader, on<br/>
veut calculer la moyenne des âges. Quel piège<br/>
faut-il éviter ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Piège classique chez les débutants : oublier la<br/>
conversion. Symptôme : addition qui concatène<br/>
des chaînes ou comparaison qui plante.</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 module csv ne gère pas les fichiers de plus de 100 lignes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il gère sans problème des fichiers de<br/>
plusieurs millions de lignes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toujours initialiser une variable globale</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas un piège spécifique au CSV.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il faut payer une licence pour utiliser csv.DictReader</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le module csv est gratuit et inclus<br/>
dans Python standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Oublier de convertir les valeurs en int (les valeurs lues sont des chaînes)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : csv.DictReader ne fait<br/>
aucune conversion de type. "17" + "16"<br/>
donne "1716", pas 33. Toujours convertir<br/>
avant de calculer.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q17 : Compter par catégorie</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment compter le nombre d'élèves dans chaque<br/>
ville à partir de table = [{"nom":..., "ville":...}, ...] ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Alternative plus concise avec<br/>
collections.Counter :<br/>
Counter(ligne["ville"] for ligne in table).<br/>
Mais le schéma manuel est universel.</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>set(table['ville'])</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : table est une liste, on ne peut<br/>
pas l'indexer par chaîne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
c = {}<br/>
for ligne in table:<br/>
    v = ligne["ville"]<br/>
    c[v] = c.get(v, 0) + 1<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on construit progressivement<br/>
un dictionnaire ville → effectif. La<br/>
méthode .get(v, 0) renvoie 0 si la ville<br/>
n'a pas encore été rencontrée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>len(table)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cela donne le total, pas la<br/>
répartition par ville.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.count('ville')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : count cherche un élément exact<br/>
dans la liste, pas un comptage par<br/>
catégorie.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q18 : Tri sur deux critères</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment trier la table par <strong>âge croissant</strong>, puis<br/>
par <strong>nom alphabétique</strong> en cas d'égalité ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Astuce élégante : la comparaison des tuples<br/>
Python est lexicographique, ce qui simplifie<br/>
beaucoup les tris multi-critères.</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>table.sort(key=lambda l: (l['age'], l['nom']))</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la clé est un <strong>tuple</strong>.<br/>
Python compare lexicographiquement les<br/>
tuples : d'abord par âge, puis par nom en<br/>
cas d'égalité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.sort('age', 'nom')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sort n'accepte pas plusieurs<br/>
arguments positionnels.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.sort(key=lambda l: l['age'] + l['nom'])</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ne peut pas additionner un entier<br/>
et une chaîne. Et ce ne serait pas<br/>
sémantiquement correct.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.sort(by=['age', 'nom'])</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la syntaxe pandas, pas Python<br/>
standard.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q19 : Exemple concret</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel des fichiers Open Data suivants se prête<br/>
naturellement à une représentation en table ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Open Data : data.gouv.fr, opendata.paris.fr,<br/>
INSEE... regorgent de jeux de données en CSV<br/>
directement utilisables.</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>La liste des stations Vélib' avec leurs coordonnées et capacités, au format CSV</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un cas typique. Chaque ligne<br/>
= une station, descripteurs = nom,<br/>
longitude, latitude, capacité, etc. Idéal<br/>
pour traitement en table.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une carte des arrondissements de Paris au format SVG</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : SVG est un format vectoriel, pas<br/>
tabulaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un PDF illustré</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un PDF est un format de<br/>
présentation, mal adapté à la manipulation<br/>
tabulaire (sauf après extraction).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une vidéo de présentation des transports</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un fichier multimédia ne se<br/>
structure pas en table.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q20 : Limite des tables</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour quel type de données les tables sont-elles<br/>
<strong>mal adaptées</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle générale : pour des données <strong>plates</strong>, la<br/>
table est adaptée ; pour des données <strong>hiérarchiques</strong><br/>
(comme un arbre généalogique), un format imbriqué<br/>
(JSON par exemple) est plus naturel.</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 de produits avec prix</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Données plates : table parfaitement adaptée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un classement sportif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Données plates : table adaptée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un arbre généalogique sur plusieurs générations avec des relations multiples</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les relations<br/>
parent/enfant/conjoint sont <strong>hiérarchiques</strong>.<br/>
Les tables peuvent les stocker, mais ce n'est<br/>
pas la représentation la plus naturelle pour<br/>
ce type de données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une liste d'élèves avec nom, âge, ville</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Données plates : parfaitement adaptées à<br/>
une table.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q21 : Trace d'accès</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Soit<br/>
`<code>python<br/>
t = [{"a":1,"b":2}, {"a":3,"b":4}, {"a":5,"b":6}]<br/>
</code><br/>
Que vaut sum(l["a"] for l in t if l["b"] &gt;= 4)` ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Méthode : (1) appliquer le filtre l["b"] &gt;= 4<br/>
à chaque ligne ; (2) extraire l["a"] pour les<br/>
lignes restantes ; (3) sommer.</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>12</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu as additionné les a de toutes<br/>
les lignes (1 + 3 + 5) sans filtrer.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>8</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les lignes filtrées sont<br/>
{"a":3,"b":4} (b=4 ≥ 4) et {"a":5,"b":6}<br/>
(b=6 ≥ 4). Somme des a : 3 + 5 = 8.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il y a bien des lignes qui<br/>
satisfont l["b"] &gt;= 4.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>9</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu as inclus la première ligne<br/>
(a=1) à tort. Or b=2, donc le filtre rejette.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q22 : Transformer la structure</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On veut convertir une <strong>liste de dictionnaires</strong><br/>
[{"x":1,"y":2}, {"x":3,"y":4}] en <strong>dictionnaire<br/>
de listes</strong> {"x":[1,3], "y":[2,4]} (représentation<br/>
"colonne par colonne"). Quel code est correct ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette transformation est très utile pour passer<br/>
à numpy/matplotlib, qui préfèrent souvent les<br/>
colonnes individuelles aux listes<br/>
d'enregistrements.</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/>
{k: [l[k] for l in table] for k in table[0]}<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : compréhension de<br/>
dictionnaire. Pour chaque clé du premier<br/>
dictionnaire, on construit la liste des<br/>
valeurs de cette clé sur toutes les lignes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>table.pivot()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de méthode .pivot en Python<br/>
standard (cela existe en pandas).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
{k: l[k] for l in table for k in l}<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on écrase les valeurs à chaque<br/>
itération (chaque clé n'aura que la dernière<br/>
valeur).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>dict(table)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : dict ne sait pas faire cette<br/>
transformation. Lèverait TypeError ou<br/>
produirait un résultat inattendu.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q23 : Performance d'une jointure</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour une jointure entre deux tables de tailles<br/>
n et m, la version naïve à deux boucles<br/>
imbriquées a une complexité de O(n × m). Comment<br/>
l'améliorer ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est exactement ce que font les SGBD avec leurs<br/>
<strong>index</strong> : transformer une recherche linéaire<br/>
en accès direct quasi instantané (table de<br/>
hachage ou arbre B).</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>En supprimant la moitié des colonnes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la complexité dépend du <strong>nombre de<br/>
lignes</strong>, pas du nombre de colonnes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En triant les deux tables au préalable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible (jointure par fusion) mais coûteux<br/>
en pré-traitement. Il existe plus simple<br/>
en Python.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>En indexant une table par sa clé dans un dictionnaire (accès O(1)), ce qui ramène la jointure à O(n + m)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : par exemple,<br/>
idx = {e["id"]: e for e in eleves}, puis<br/>
for n in notes: e = idx.get(n["id_eleve"]).<br/>
Beaucoup plus rapide pour de gros volumes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En utilisant des tuples au lieu de dictionnaires</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas une vraie optimisation algorithmique.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q24 : Bug subtil</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un élève écrit<br/>
`<code>python<br/>
for ligne in table:<br/>
    if ligne["age"] &gt; 16:<br/>
        table.remove(ligne)<br/>
</code>`<br/>
Quel est le problème ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : <strong>ne jamais modifier</strong> une<br/>
structure pendant qu'on la parcourt. Construire<br/>
une nouvelle liste filtrée :<br/>
table = [l for l in table if l["age"] &lt;= 16].</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 boucle ne compile pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe est valide, le code<br/>
s'exécute (mais avec un bug logique).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Cela lève toujours une exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas toujours : ça produit un résultat<br/>
incorrect, sans erreur visible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Modifier une liste pendant qu'on la parcourt provoque des lignes ignorées : certains éléments ne seront jamais testés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est un piège classique.<br/>
Quand on supprime l'élément d'indice i,<br/>
les indices suivants se décalent et le<br/>
parcours saute le suivant. Solution :<br/>
construire une nouvelle liste filtrée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La méthode .remove n'existe pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : elle existe parfaitement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Tables de données — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes sur les tables de<br/>
données, laquelle est <strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les tables de données et leurs opérations<br/>
associées (recherche, tri, fusion) sont au cœur<br/>
du traitement de données. Les maîtriser en<br/>
Python est un atout majeur pour<br/>
manipuler de gros volumes.</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 opérations classiques sont la recherche, le tri, la sélection de lignes (filtrage), la sélection de colonnes et la fusion</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : ce sont les opérations canoniques sur<br/>
les tables, prévues par le programme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une fusion permet de combiner deux tables sur la base d'un descripteur commun</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : c'est exactement le rôle de la fusion,<br/>
qui rapproche les lignes de deux tables<br/>
partageant une clé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En Python, on représente couramment une table par une liste de dictionnaires</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : c'est la représentation la plus<br/>
fréquente en NSI Première.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le module csv produit toujours des données typées (entiers, flottants, dates)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Faux (donc bonne réponse) : csv produit<br/>
uniquement des <strong>chaînes</strong>. C'est au<br/>
programme de convertir les types.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
