<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Première/Fichiers CSV</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Format CSV (Comma Separated Values), séparateurs (virgule,<br/>
point-virgule, tabulation), lecture et écriture avec le<br/>
module csv, en-tête, encodage UTF-8, conversion des<br/>
types, manipulations courantes.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q01 : Que signifie CSV ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que signifie l'acronyme <strong>CSV</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le CSV est un standard très répandu pour les échanges<br/>
de données entre tableurs, bases de données et<br/>
programmes. Sa simplicité (texte brut, ligne par<br/>
ligne) en fait un format 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>Compressed Storage Vector</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : CSV n'est pas un format compressé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Computer System Variables</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport. C'est un format de<br/>
fichier de données tabulaires.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Centered Spreadsheet View</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas une vue de tableur, c'est<br/>
un format texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Comma Separated Values</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est un format texte simple<br/>
dans lequel chaque ligne est un enregistrement<br/>
et les champs sont séparés par un délimiteur<br/>
(souvent une virgule, parfois un point-virgule<br/>
ou une tabulation).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q02 : Structure d'un CSV</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la structure de base d'un fichier CSV ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Exemple typique : la première ligne nom,age,ville<br/>
définit les colonnes ; les lignes suivantes<br/>
contiennent les valeurs correspondantes.</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 XML structuré par balises</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : CSV n'a pas de balises, juste des<br/>
séparateurs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier binaire avec en-tête et indexation</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : CSV est un format <strong>texte</strong>, pas<br/>
binaire. Il s'ouvre avec n'importe quel éditeur<br/>
de texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un fichier texte, un enregistrement par ligne, champs délimités</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la première ligne contient<br/>
souvent les noms des colonnes (en-tête), puis<br/>
chaque ligne suivante représente une entrée du<br/>
jeu de données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un format de type JSON aux structures imbriquées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec JSON. CSV est plat.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q03 : Séparateur en France</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi en France utilise-t-on souvent le <strong>point-virgule</strong><br/>
; comme séparateur dans les fichiers CSV ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>D'autres séparateurs sont possibles : tabulation<br/>
(TSV), barre verticale |, etc. Le module csv de<br/>
Python permet de spécifier le délimiteur via<br/>
delimiter=";".</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que le point-virgule est plus rapide à taper</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas une raison de saisie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les fichiers seraient sinon trop volumineux</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec la taille.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'une norme ISO officielle l'impose strictement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : CSV n'est pas strictement normé. Le<br/>
choix du séparateur dépend des conventions<br/>
locales.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que la virgule sert de séparateur décimal en français, créant un conflit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : 1,5;Paris est sans ambiguïté,<br/>
mais 1,5,Paris ne l'est pas (s'agit-il d'un<br/>
ou deux champs ?). Excel et LibreOffice en<br/>
version française utilisent donc ; par défaut.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q04 : Ligne d'en-tête</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert la <strong>première ligne</strong> d'un fichier CSV ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'en-tête est une <strong>convention</strong>, pas une<br/>
obligation. Certains CSV n'en ont pas (par exemple<br/>
des exports machine sans description). Il faut alors<br/>
le savoir avant de lire le fichier.</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 contient toujours les données du premier enregistrement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : par convention, la première ligne<br/>
contient le plus souvent un <strong>en-tête</strong>, pas<br/>
des données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle indique la taille du fichier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La taille d'un fichier<br/>
se mesure en octets et<br/>
se lit dans le système<br/>
de fichiers, pas dans<br/>
son contenu. L'en-tête<br/>
d'un CSV donne les noms<br/>
des colonnes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle est obligatoirement vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : au contraire, elle contient<br/>
généralement les noms de colonnes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle contient les noms des colonnes (en-tête)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est l'usage le plus répandu.<br/>
Les programmes (et csv.DictReader) s'en<br/>
servent pour donner un nom à chaque champ.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q05 : Extension de fichier</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est l'extension habituelle d'un fichier CSV ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'extension .csv est reconnue par Excel,<br/>
LibreOffice Calc, Google Sheets et la plupart des<br/>
langages de programmation, qui peuvent<br/>
automatiquement proposer un import.</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>.txt</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : techniquement possible (CSV est du<br/>
texte), mais l'extension conventionnelle est<br/>
différente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>.json</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : JSON est un autre format de données<br/>
(hiérarchique).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>.csv</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est l'extension standard,<br/>
reconnue par les tableurs et les outils de<br/>
traitement de données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>.xlsx</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : .xlsx est le format propriétaire<br/>
d'Excel (binaire compressé), pas CSV.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q06 : Lecture sans le module csv</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Sans utiliser le module csv, comment peut-on lire<br/>
un fichier CSV simple en Python ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette approche a des limites : elle ne gère pas les<br/>
champs entre guillemets, les sauts de ligne dans<br/>
les champs, ou les caractères d'échappement. Pour<br/>
cela, mieux vaut le module csv.</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>Avec open() puis .split(',') sur chaque ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on ouvre le fichier en lecture<br/>
et on parcourt ligne par ligne, en séparant<br/>
chaque ligne par le délimiteur. Cela marche<br/>
pour les CSV simples mais échoue avec les<br/>
champs contenant le délimiteur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec open() puis .strip(',') sur chaque ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : strip(',') ne retire que les virgules<br/>
situées en début et en fin de ligne ; sur<br/>
"Alice,17", il renvoie "Alice,17" inchangé.<br/>
La ligne n'est pas découpée en champs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec readlines() seul, qui sépare déjà les champs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : readlines() découpe le fichier en<br/>
<strong>lignes</strong>, pas en champs ; il faut encore<br/>
séparer chaque ligne par le délimiteur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec open() puis .split('\n') sur chaque ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque ligne parcourue ne contient qu'un saut de ligne, à sa fin. Sur "Alice,17\n", split('\n') renvoie ['Alice,17', ''] : les champs ne sont pas séparés.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q07 : Module standard</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel module de la bibliothèque standard de Python<br/>
facilite la manipulation des fichiers CSV ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le module csv fait partie de la bibliothèque<br/>
standard (livré avec Python). Aucune installation<br/>
n'est nécessaire.</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>time</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le module time sert à mesurer une durée ou à attendre, pas à lire un fichier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>csv</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : import csv donne accès à csv.reader et csv.DictReader, qui découpent chaque ligne du fichier en champs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>math</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le module math fournit des fonctions mathématiques comme sqrt ; il ne lit aucun fichier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>random</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le module random produit des nombres au hasard ; il ne sait rien du format CSV.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q08 : Encodage recommandé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel <strong>encodage</strong> est aujourd'hui recommandé pour les<br/>
fichiers CSV ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>En Python, on précise l'encodage à l'ouverture :<br/>
open("data.csv", encoding="utf-8"). Si on omet<br/>
cet argument, Python utilise l'encodage par défaut<br/>
du système, ce qui peut poser problème entre<br/>
Windows et Linux.</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>UTF-8</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : UTF-8 supporte tous les<br/>
caractères Unicode (français, chinois, emojis...).<br/>
C'est l'encodage standard moderne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>ISO-8859-1 uniquement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Encodage ancien (Latin-1), encore courant en<br/>
Europe mais limité à 256 caractères. À éviter<br/>
pour de nouveaux projets.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>ASCII pur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ASCII ne couvre pas les caractères<br/>
accentués (é, à, ç...), inutilisables en<br/>
français.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Binaire compressé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un CSV est du texte, pas du binaire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q09 : Itération avec csv.reader</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie csv.reader(f) lorsqu'on l'utilise dans<br/>
une boucle for ligne in csv.reader(f): ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Penser à convertir les valeurs numériques avec<br/>
int() ou float() avant tout calcul. CSV est<br/>
texte : "17" + 1 ne fonctionnera 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>Un tuple immuable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est une liste mutable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un dictionnaire {nom_colonne: valeur}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est ce que renvoie csv.DictReader,<br/>
pas csv.reader.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une chaîne de caractères pour chaque ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pour avoir une chaîne, il suffirait<br/>
de boucler directement sur le fichier f.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une liste des champs de chaque ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : chaque itération produit une<br/>
liste comme ["Alice", "17", "Lyon"]. Tous les<br/>
éléments sont des chaînes (il faut convertir<br/>
si l'on veut des entiers).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q10 : Une cellule de la table chargée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le fichier notes.csv contient :<br/>
`<code>text<br/>
nom,note<br/>
Ali,12<br/>
Zoe,15<br/>
</code><br/>
On le charge dans une table :<br/>
<code>python<br/>
import csv<br/>
table = []<br/>
with open("notes.csv", encoding="utf-8") as f:<br/>
    for ligne in csv.reader(f):<br/>
        table.append(ligne)<br/>
</code><br/>
Que vaut table[2][1]` ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une table importée ainsi est un tableau doublement indexé : table[i][j] désigne la valeur de la ligne i et de la colonne j. L'en-tête compte comme une ligne, et chaque valeur reste une chaîne tant qu'on ne la convertit 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>15</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le module csv ne convertit rien, toutes les valeurs lues sont des chaînes. Il faudrait écrire int(table[2][1]) pour obtenir l'entier 15.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>'Zoe'</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : dans chaque ligne aussi, les indices commencent à 0. table[2][0] vaut 'Zoe', et table[2][1] désigne la colonne suivante, celle de la note.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>'12'</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu oublies que l'en-tête est rangé dans la table, à l'indice 0. La ligne de Ali est table[1], celle de Zoe table[2].</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>'15'</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la ligne d'en-tête occupe l'indice 0, donc table[2] vaut ['Zoe', '15'], et son élément d'indice 1 est la chaîne '15'.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q11 : Différence reader / DictReader</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence entre csv.reader et<br/>
csv.DictReader ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>DictReader est généralement préférable quand le<br/>
fichier a un en-tête : le code est plus auto-documenté<br/>
(ligne["age"] plutôt que ligne[2]).</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 fonction reader n'existe plus en Python 3</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : elle existe parfaitement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>reader produit des listes, DictReader des dictionnaires</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : DictReader consomme la<br/>
première ligne comme en-tête et permet<br/>
ensuite d'écrire ligne["nom"] au lieu de<br/>
ligne[0]. Plus lisible et robuste si l'ordre<br/>
des colonnes change.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>DictReader ignore la ligne d'en-tête du fichier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'inverse, il <strong>utilise</strong><br/>
l'en-tête pour nommer les colonnes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La classe DictReader lit nettement plus vite les fichiers</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la performance n'est pas la<br/>
différence essentielle.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q12 : Conversion de types</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Après lecture, on obtient ligne = ["Alice", "17"].<br/>
Comment obtenir un âge utilisable comme nombre ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Toujours convertir explicitement : int(),<br/>
float(), bool() selon le besoin. Penser aussi<br/>
au cas où la cellule est vide (chaîne ""), qui<br/>
provoquerait ValueError avec int().</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>age = ligne[1].number()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la méthode .number() n'existe pas<br/>
sur les chaînes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>age = list(ligne[1])</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : list("17") donne ['1', '7'], pas<br/>
un entier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>age = int(ligne[1])</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : int() convertit la chaîne<br/>
"17" en entier 17, utilisable dans des<br/>
calculs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>age = ligne[1]</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : age reste une <strong>chaîne</strong>. Faire<br/>
age + 1 lèverait TypeError.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q13 : Spécifier le séparateur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment lire un CSV utilisant le <strong>point-virgule</strong><br/>
comme séparateur avec le module csv ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour les fichiers exportés par Excel français, le<br/>
séparateur est ;. Pour les CSV anglo-saxons ou<br/>
Google Sheets, c'est ,. Pour TSV (tab-separated),<br/>
c'est '\t'.</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>csv.reader(f, delimiter=';')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on précise le délimiteur via<br/>
l'argument nommé delimiter.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>csv.reader(f).set_separator(';')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette méthode n'existe pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>csv.reader_semicolon(f)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette fonction n'existe pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>csv.reader(f) (suffisant, le module détecte tout seul)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : par défaut, le séparateur est la virgule. Le module ne devine pas le séparateur, il faut le lui indiquer.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q14 : Champs contenant le séparateur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment représente-t-on un champ contenant le<br/>
caractère séparateur (par exemple une virgule) dans<br/>
un CSV à séparateur virgule ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Et pour un guillemet à l'intérieur d'un champ<br/>
« guillemeté » ? On le double : "il dit ""bonjour""".</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>On supprime la virgule du champ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on perdrait l'information.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>On entoure le champ de guillemets doubles : "Lyon, France"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est la convention du format CSV. Le module csv gère cette syntaxe automatiquement, en lecture comme en écriture.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On change le séparateur pour ce champ uniquement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un fichier CSV utilise un séparateur<br/>
unique pour tout le fichier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On échappe la virgule avec un antislash \,</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas la convention CSV<br/>
standard (qui utilise les guillemets).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q15 : Trace de lecture</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le fichier eleves.csv contient :<br/>
`<code><br/>
nom;age<br/>
Alice;17<br/>
Bob;16<br/>
</code><br/>
Que vaut ligne au premier passage de la boucle<br/>
for ligne in csv.DictReader(open("eleves.csv"), delimiter=";")` ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour récupérer toutes les lignes d'un coup :<br/>
lignes = list(csv.DictReader(...)).</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>{'nom': 'Alice', 'age': '17'}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : DictReader saute l'en-tête<br/>
et associe chaque valeur à son nom de colonne.<br/>
Noter que '17' reste une chaîne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>{'Alice': '17', 'Bob': '16'}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ne reçoit qu'une ligne à chaque<br/>
itération, pas tout le fichier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>['Alice', '17']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait le retour de csv.reader,<br/>
pas de csv.DictReader.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>['nom', 'age']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : DictReader consomme la première<br/>
ligne comme en-tête, elle n'apparaît pas dans<br/>
la boucle.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q16 : Filtrer les données</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment afficher seulement les élèves de plus de<br/>
16 ans à partir d'un CSV nom,age lu via<br/>
csv.DictReader ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Toujours convertir avant de comparer numériquement : toutes les valeurs lues par csv.DictReader sont des chaînes.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
for ligne in lecteur:<br/>
    if int(ligne[1]) &gt; 16:<br/>
        print(ligne[0])<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : csv.DictReader produit des<br/>
<strong>dictionnaires</strong> dont les clés sont les<br/>
en-têtes ("nom", "age"), pas des listes :<br/>
ligne[1] lève KeyError: 1. L'accès par<br/>
indice vaut pour csv.reader.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
for ligne in lecteur:<br/>
    if int(ligne["age"] &gt; 16):<br/>
        print(ligne["nom"])<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la parenthèse est mal placée. Python évalue d'abord ligne["age"] &gt; 16, qui compare une chaîne et un entier et lève TypeError, avant même d'appeler int.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
for ligne in lecteur:<br/>
    if int(ligne["age"]) &gt; 16:<br/>
        print(ligne["nom"])<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on convertit l'âge en entier<br/>
(sinon "17" &gt; 16 est invalide en Python 3),<br/>
on filtre, on affiche le nom.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
for ligne in lecteur:<br/>
    if ligne["age"] &gt; 16:<br/>
        print(ligne["nom"])<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ligne["age"] est une <strong>chaîne</strong><br/>
("17"). En Python 3, comparer une chaîne et<br/>
un entier lève TypeError.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q17 : Une virgule dans un fichier tabulé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le fichier texte tabulé contacts.txt sépare ses champs par une tabulation. Sa première ligne contient Dupont, Jean, une tabulation, puis 17.<br/>
`<code>python<br/>
import csv<br/>
with open("contacts.txt", encoding="utf-8") as f:<br/>
    for ligne in csv.reader(f, delimiter="\t"):<br/>
        print(ligne)<br/>
</code>`<br/>
Qu'affiche ce programme pour la première ligne ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un fichier texte tabulé s'importe comme un fichier CSV, en indiquant delimiter="\t". Choisir un séparateur absent des données évite de couper un champ par erreur.</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>['Dupont', ' Jean', '17']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu fais couper le lecteur à la fois sur la virgule et sur la tabulation. Avec delimiter="\t", seule la tabulation sépare les champs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>['Dupont, Jean\t17']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu supposes que la tabulation n'est pas reconnue, mais "\t" désigne justement ce caractère. Passé comme délimiteur, il découpe la ligne en deux champs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>['Dupont, Jean', '17']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : seul le délimiteur indiqué, la tabulation "\t", sépare les champs. La virgule n'est qu'un caractère ordinaire du premier champ.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Rien, une virgule étant interdite dans un fichier tabulé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un champ de fichier tabulé peut contenir n'importe quel caractère, sauf la tabulation elle-même. C'est même l'intérêt de ce format quand les données contiennent des virgules.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q18 : Valeurs manquantes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un CSV avec nom,age,ville et la ligne<br/>
Alice,,Lyon, que vaut ligne["age"] après lecture<br/>
par csv.DictReader ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Donnée manquante : il faut tester la valeur avant de la convertir, par exemple avec if ligne["age"] != "":, puis écarter la ligne ou lui attribuer une valeur choisie.</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 programme lève une exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la lecture se passe sans erreur ;<br/>
c'est seulement la conversion ultérieure<br/>
(int("")) qui lèverait ValueError.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>None</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : csv.DictReader ne convertit pas<br/>
automatiquement les vides en None.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le module ne fait aucune supposition.<br/>
Une absence n'est pas un zéro.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>'' (chaîne vide)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un champ vide entre deux<br/>
séparateurs est lu comme une chaîne vide. Il<br/>
faut le tester explicitement avant toute<br/>
conversion : if ligne["age"] != "":.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q19 : Export depuis tableur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle situation correspond à un cas d'usage typique<br/>
du format CSV ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Force du CSV : universalité. Faiblesses : pas de<br/>
types (tout est texte), pas de hiérarchie, pas de<br/>
schéma standard (séparateur, encodage variables).</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>Construire une page web interactive</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le rôle du HTML/CSS/JS.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Programmer le microcontrôleur d'un objet connecté</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on programme en C, Python, etc., pas<br/>
en CSV.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Stocker une vidéo en haute définition</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : CSV est un format texte, inadapté à<br/>
la vidéo (binaire compressé).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Échanger un tableau de notes entre Pronote et un tableur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est exactement le rôle du<br/>
CSV, un format pivot universel pour les<br/>
données tabulaires, lisible par tous les<br/>
outils.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q20 : Des p-uplets construits à la lecture</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le fichier ventes.csv contient :<br/>
`<code>text<br/>
produit,quantite<br/>
stylo,4<br/>
cahier,6<br/>
</code><br/>
<code>python<br/>
import csv<br/>
table = []<br/>
with open("ventes.csv", encoding="utf-8") as f:<br/>
    for ligne in csv.DictReader(f):<br/>
        table.append((ligne["produit"], int(ligne["quantite"])))<br/>
</code><br/>
Que vaut table[1]` ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Importer une table, c'est souvent la ranger dans un tableau de p-uplets : on choisit les descripteurs utiles et on convertit les valeurs numériques au moment de la lecture, une fois pour toutes.</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>('stylo', 4)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les indices commencent à 0. La ligne du stylo est table[0] ; table[1] désigne la ligne suivante, celle du cahier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>('cahier', 6)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : DictReader utilise l'en-tête pour nommer les champs, la table ne reçoit que les deux lignes de données. table[1] est la seconde, dont la quantité a été convertie par int.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>{'produit': 'cahier', 'quantite': 6}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque ligne lue est bien un dictionnaire, mais le programme range dans la table un p-uplet construit à partir de deux de ses valeurs, et non le dictionnaire lui-même.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>('cahier', '6')</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu oublies l'appel à int, qui convertit la chaîne '6' en entier avant la construction du p-uplet.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q21 : Bug d'encodage</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un élève lit un CSV créé sous Windows et obtient<br/>
CafÃ© au lieu de Café. Quelle est la cause la<br/>
plus probable ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Indice révélateur : Ã© à la place de é est la <strong>signature classique</strong> d'une mauvaise interprétation d'UTF-8<br/>
en Latin-1. Il existe d'autres signatures<br/>
(Ã¨ au lieu de è) qui pointent vers le même<br/>
problème.</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>Le fichier UTF-8 est lu comme du Latin-1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : é en UTF-8 = 0xC3 0xA9. Lu<br/>
comme Latin-1, ces deux octets donnent Ã©.<br/>
Solution : préciser encoding="utf-8" à<br/>
l'ouverture.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La connexion internet est instable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport, on lit un fichier<br/>
local.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le fichier de données est partiellement corrompu</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le contenu est correct, c'est<br/>
l'<strong>interprétation</strong> de l'encodage qui pose<br/>
problème.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Python est trop ancien pour gérer l'UTF-8</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python 3 gère parfaitement UTF-8<br/>
depuis sa sortie.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q22 : Parsing à la main</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi ligne.split(',') est-il <strong>insuffisant</strong><br/>
pour parser correctement la ligne CSV<br/>
"Doe, John",42,"Lyon, France" ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Leçon : pour tout CSV non trivial (guillemets,<br/>
sauts de ligne dans les champs, échappements),<br/>
utiliser le module csv. Le « parsing manuel »<br/>
n'est correct que pour des cas très simples et<br/>
maîtrisé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>split ignore les guillemets et coupe à chaque virgule</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on obtient cinq champs au lieu<br/>
de trois, split(',') produisant ['\"Doe',<br/>
' John\"', '42', '\"Lyon', ' France\"']. Le<br/>
module csv gère correctement ce cas en<br/>
regroupant les champs entourés de guillemets.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La méthode split est beaucoup trop lente ici</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la performance n'est pas le<br/>
problème, la <strong>correction</strong> l'est.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>split ne fonctionne que sur des fichiers UTF-8</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : split est indépendant de l'encodage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>split modifie le fichier d'origine sur le disque</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : split ne modifie rien, il renvoie<br/>
une nouvelle liste.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q23 : Calcul d'une moyenne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le fichier notes.csv contient une colonne note<br/>
(entête en première ligne) avec des nombres entiers.<br/>
Quel code calcule correctement la <strong>moyenne</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois étapes systématiques : ouvrir, convertir<br/>
les types, calculer. Toujours penser à la<br/>
conversion en numérique avant tout calcul.</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/>
with open("notes.csv") as f:<br/>
    total = 0<br/>
    for ligne in csv.DictReader(f):<br/>
        total += ligne["note"]<br/>
    moyenne = total / len(lignes)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ligne["note"] est une <strong>chaîne</strong>.<br/>
total += "12" lève TypeError. De plus<br/>
lignes n'est pas défini.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
with open("notes.csv") as f:<br/>
    moyenne = sum(csv.reader(f)) / 2<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sum ne sait pas additionner des<br/>
listes de chaînes ; et la division par 2 est<br/>
arbitraire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
with open("notes.csv") as f:<br/>
    notes = [int(ligne["note"]) for ligne in csv.DictReader(f)]<br/>
moyenne = sum(notes) / len(notes)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on construit une liste<br/>
d'entiers (conversion explicite avec int),<br/>
puis sum / len. Code concis et correct.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
moyenne = csv.mean("notes.csv", "note")<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction csv.mean n'existe pas.<br/>
Le module csv se limite à la lecture/écriture.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q24 : Une table de dictionnaires construite à la main</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Sans utiliser DictReader, Hugo associe lui-même l'en-tête du fichier eleves.csv aux valeurs :<br/>
`<code>text<br/>
nom,classe<br/>
Ali,1A<br/>
Zoe,1B<br/>
</code><br/>
<code>python<br/>
import csv<br/>
lignes = []<br/>
with open("eleves.csv", encoding="utf-8") as f:<br/>
    for ligne in csv.reader(f):<br/>
        lignes.append(ligne)<br/>
entete = lignes[0]<br/>
table = []<br/>
for i in range(1, len(lignes)):<br/>
    d = {}<br/>
    for j in range(len(entete)):<br/>
        d[entete[j]] = lignes[i][j]<br/>
    table.append(d)<br/>
print(table[1])<br/>
</code>`<br/>
Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Associer l'en-tête aux valeurs transforme un tableau doublement indexé en table de dictionnaires : pour chaque ligne de données, la valeur de la colonne j est rangée sous la clé entete[j]. C'est le travail que fait csv.DictReader.</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>{'Ali': '1A', 'Zoe': '1B'}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu prends les valeurs de la première colonne pour des clés. Les clés viennent de entete[j], c'est-à-dire 'nom' et 'classe', et chaque ligne donne son propre dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>['Zoe', '1B']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : table ne reçoit pas les listes lues, mais le dictionnaire d construit à chaque tour de la boucle sur i.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>{'nom': 'Zoe', 'classe': '1B'}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la boucle sur i commence à 1 et saute l'en-tête. table[0] est construit à partir de la ligne de Ali, table[1] à partir de celle de Zoe, avec pour clés les noms de colonnes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>{'nom': 'Ali', 'classe': '1A'}</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu fais correspondre table[1] à lignes[1]. Comme l'en-tête n'est pas recopié dans table, les indices sont décalés d'un cran : la ligne de Ali devient table[0].</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q25 : Limite du CSV</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes sur le format CSV,<br/>
laquelle est <strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Limites du CSV : pas de typage, pas de hiérarchie, séparateur variable, encodage variable. C'est au programme qui lit le fichier de connaître ces conventions et de convertir les valeurs.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>CSV ne gère pas nativement les structures hiérarchiques (listes imbriquées, dictionnaires)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : c'est sa principale limite, un fichier CSV ne représente qu'une table à deux dimensions, lignes et colonnes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le séparateur n'est pas standardisé universellement (virgule, point-virgule, tabulation...)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : c'est une faiblesse historique du format. Selon le logiciel, on trouve une virgule, un point-virgule ou une tabulation.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>CSV impose un typage explicite des colonnes (entier, flottant, date)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Faux (donc bonne réponse) : tout est traité<br/>
comme du <strong>texte</strong> dans un CSV. Aucun type<br/>
n'est conservé. C'est au programme de lecture<br/>
de convertir explicitement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>CSV est un format texte, lisible avec n'importe quel éditeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : c'est l'un de ses grands avantages.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q26 : Additionner une colonne lue en texte</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une table lue depuis un fichier CSV contient trois lignes :<br/>
`<code>python<br/>
table = [{"nom": "Lou", "points": "12"},<br/>
         {"nom": "Sami", "points": "30"},<br/>
         {"nom": "Inès", "points": "8"}]<br/>
total = 0<br/>
for ligne in table:<br/>
    total = total + int(ligne["points"])<br/>
print(total)<br/>
</code>`<br/>
Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Tout ce qui sort d'un fichier CSV est du texte. Convertir les<br/>
nombres avec int ou float est la première étape de tout calcul.</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>50</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : chaque valeur, lue comme une chaîne, est<br/>
convertie en entier par int avant l'addition.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>12308</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans int, + collerait les chaînes, mais ici la<br/>
conversion est bien faite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : total est augmenté à chaque ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, les points étant des chaînes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est ce qui arriverait sans int. La conversion rend<br/>
l'addition possible.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q27 : Compter les lignes d'une ville</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La table contient quatre lignes dont les villes sont, dans l'ordre,<br/>
Lyon, Nantes, Lyon et Paris. Qu'affiche ce programme ?<br/>
`<code>python<br/>
retenues = []<br/>
for ligne in table:<br/>
    if ligne["ville"] == "Lyon":<br/>
        retenues.append(ligne)<br/>
print(len(retenues))<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Filtrer une table, c'est construire une nouvelle liste avec les<br/>
lignes qui vérifient une condition.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : seules les lignes dont la ville est exactement<br/>
Lyon sont ajoutées, soit deux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Lyon</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : len(retenues) est un nombre de lignes, pas une ville.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>4</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le if filtre les lignes, toutes ne sont pas retenues.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, la liste étant vide au départ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une liste vide peut recevoir des éléments avec<br/>
append, et len d'une liste vide vaut 0.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q28 : Une comparaison qui échoue</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Après lecture d'un fichier CSV, Maya écrit if ligne["age"] &gt; 15:<br/>
et obtient une erreur. Pourquoi ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Python refuse de comparer une chaîne et un nombre : l'erreur<br/>
rappelle qu'une conversion manque.</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 nombres d'un CSV sont toujours lus comme des flottants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce sont des chaînes, à convertir selon le besoin en<br/>
int ou en float.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>ligne["age"] est une chaîne, non comparable à un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la valeur lue est "17", pas 17. Il faut<br/>
écrire int(ligne["age"]) &gt; 15.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La clé age n'existe pas dans une table lue depuis un CSV</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la clé existe si la colonne figure dans l'en-tête ; le<br/>
problème est le type de la valeur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&gt; n'est pas défini sur les dictionnaires d'une table</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la comparaison porte sur une valeur du dictionnaire,<br/>
pas sur le dictionnaire lui-même.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q29 : Une moyenne malgré des cases vides</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Les notes d'une colonne ont été lues dans la liste notes,<br/>
une case vide donnant la chaîne vide :<br/>
`<code>python<br/>
notes = ["12", "", "15", "9"]<br/>
total = 0<br/>
n = 0<br/>
for note in notes:<br/>
    if note != "":<br/>
        total = total + float(note)<br/>
        n = n + 1<br/>
print(total / n)<br/>
</code>`<br/>
Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une valeur manquante dans un CSV arrive comme chaîne vide. La<br/>
tester avant conversion évite l'erreur et fausse moins la moyenne.</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>9.0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait la somme divisée par le nombre total de cases,<br/>
vides comprises ; or n ne compte que les notes présentes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, float("") échouant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est précisément ce que le test note != "" évite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>36.0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 36.0 est la somme ; le programme affiche la<br/>
moyenne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>12.0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les cases vides sont ignorées à la fois dans la<br/>
somme et dans le compte, la moyenne porte sur les notes<br/>
présentes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q30 : Trier des nombres lus en texte</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour trier une table par âge, Lina écrit :<br/>
``python<br/>
def cle(ligne):<br/>
    return int(ligne["age"])</p>
<p>table_triee = sorted(table, key=cle)<br/>
<code><br/>
Pourquoi la fonction cle convertit-elle l'âge avec int</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La fonction passée en key dit comment comparer les lignes. Pour<br/>
un tri numérique sur des données textuelles, elle convertit.</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 dictionnaires ne peuvent pas contenir de chaînes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un dictionnaire accepte n'importe quelle valeur, et les<br/>
valeurs lues sont justement des chaînes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>sorted refuse les chaînes de caractères dans une clé de tri</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sorted trie très bien des chaînes, mais dans l'ordre<br/>
des caractères, pas des nombres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Sinon le tri placerait "9" après "10", ordre alphabétique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : des chaînes se comparent caractère par<br/>
caractère, et "1" précède "9". Convertir en entier rétablit<br/>
l'ordre numérique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>int accélère le tri en allégeant les comparaisons</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la conversion ne change pas la vitesse, seulement<br/>
l'ordre obtenu.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q31 : Compter les valeurs distinctes d'une colonne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'affiche ce programme ?<br/>
`<code>python<br/>
villes = ["Lyon", "Paris", "Lyon", "Nice", "Paris"]<br/>
vues = []<br/>
for v in villes:<br/>
    if v not in vues:<br/>
        vues.append(v)<br/>
print(len(vues))<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Ce schéma, tester l'appartenance avant d'ajouter, construit la<br/>
liste des valeurs distinctes d'une colonne.</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>5</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 5 est le nombre de lignes ; les répétitions ne sont<br/>
pas ajoutées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 2 est le nombre de répétitions écartées, pas le<br/>
nombre de villes distinctes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>3</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une ville n'est ajoutée à vues que si elle n'y<br/>
figure pas déjà. La liste finale contient chaque ville une<br/>
fois.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la première ville rencontrée est toujours ajoutée.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q32 : Le mode d'ouverture d'un fichier</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que signifie le "r" dans open("eleves.csv", "r", encoding="utf-8") ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>open prend le nom du fichier, un mode, et l'encodage. Lire du<br/>
CSV commence toujours par une ouverture en mode "r".</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>Que le fichier sera relu plusieurs fois</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le nombre de lectures ne se règle pas à l'ouverture.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Que les retours à la ligne seront retirés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les retours à la ligne restent dans les lignes lues ;<br/>
c'est strip qui les retire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Que le fichier est au format CSV</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : open ne connaît pas les formats ; il lit du texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Que le fichier est ouvert en lecture seule</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : "r", pour <em>read</em>, ouvre le fichier pour le<br/>
lire. Écrire dedans demanderait "w" ou "a".</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q33 : Un retour à la ligne de trop</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>En lisant un fichier ligne par ligne avec for ligne in fichier:,<br/>
Théo découpe chaque ligne avec ligne.split(";") et constate que<br/>
la dernière valeur de chaque ligne contient un caractère de plus.<br/>
D'où vient-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Lire un fichier texte à la main demande deux gestes : strip pour<br/>
nettoyer la ligne, puis split pour la découper.</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 fichier contient une colonne vide supplémentaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une colonne en plus donnerait un champ de plus, pas un<br/>
caractère de plus dans le dernier champ.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le séparateur ; est compté dans la dernière valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : split retire les séparateurs ; le caractère en trop<br/>
est le retour à la ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Chaque ligne lue garde son retour à la ligne final</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la lecture conserve le \n final, qui reste<br/>
collé au dernier champ. ligne.strip().split(";") règle le<br/>
problème.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'encodage UTF-8 ajoute un caractère invisible à chaque ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'encodage n'ajoute rien ; le caractère est le \n<br/>
qui termine chaque ligne du fichier.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q34 : Découper une ligne de CSV</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que vaut "Lou;15;Lyon".split(";") ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>split est l'outil de base pour lire un CSV sans module : chaque<br/>
ligne devient une liste de champs, tous textuels.</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>['Lou', '15', 'Lyon']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : split découpe la chaîne à chaque ; et<br/>
renvoie une liste de chaînes, nombres compris.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>['Lou;15;Lyon']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le séparateur ; est présent, la chaîne est bien<br/>
découpée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>'Lou;15;Lyon'</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : split renvoie une liste, pas une chaîne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>['Lou', 15, 'Lyon']</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : split ne convertit rien ; le nombre reste une chaîne<br/>
entre guillemets.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q35 : La première ligne n'est pas une donnée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un programme lit un fichier CSV ligne par ligne et convertit le<br/>
deuxième champ de chaque ligne avec int. Il échoue dès la<br/>
première ligne. Quelle est la cause la plus probable ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'en-tête décrit les colonnes ; il se traite séparément, souvent<br/>
pour construire les clés des dictionnaires de la table.</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 deuxième champ n'existe pas dans la première ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un champ absent donnerait une erreur d'indice, pas une<br/>
erreur de conversion.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le fichier est vide, et int ne reçoit rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un fichier vide ne provoquerait aucune conversion,<br/>
donc aucune erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>int ne s'applique pas aux champs d'un CSV</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : int convertit très bien "17" ; il refuse "age".</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La première ligne est l'en-tête, et int("age") échoue</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'en-tête contient les noms des descripteurs,<br/>
pas des valeurs. Il faut la lire à part et ne convertir que les<br/>
lignes suivantes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Fichiers CSV — Q36 : Un fichier venu de Windows</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un fichier CSV créé sous Windows termine ses lignes par deux<br/>
caractères, \r puis \n, alors qu'un fichier créé sous Linux<br/>
n'utilise que \n. Quelle conséquence pour un programme qui lit<br/>
les lignes et les découpe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les conventions de fin de ligne diffèrent selon les systèmes. Un<br/>
programme robuste nettoie chaque ligne avant de la découper.</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>Un \r reste collé au dernier champ, sauf nettoyage par strip</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la lecture retire le \n mais garde parfois le<br/>
\r. strip élimine les deux, ce qui rend le programme<br/>
indépendant du système d'origine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Chaque ligne est lue deux fois, une par caractère de fin</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux caractères marquent une seule fin de ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le fichier ne peut pas être ouvert sous Linux sans conversion</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le fichier s'ouvre ; seule la fin de ligne diffère.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les séparateurs ; sont remplacés par des virgules</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le séparateur n'a rien à voir avec la fin de ligne.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
