\documentclass[a4paper,11pt]{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[francais,bloc,completemulti]{automultiplechoice}
\usepackage[french]{babel}
\usepackage{amsmath, amssymb}

\title{Tables de données}
\date{Numérique et sciences informatiques}

\begin{document}

\noindent\textbf{Tables de données} \hfill \textit{Numérique et sciences informatiques}\\[0.4em]
Nom~: \dotfill\ Prénom~: \dotfill

\bigskip

\element{premieretablesdedonnees}{
  \begin{question}{q01}
    En informatique, qu'appelle-t-on une \textbf{table de données} ?
    \begin{choices}
    \wrongchoice{Un meuble pour poser un ordinateur}
    \wrongchoice{Un type primitif de Python}
    \correctchoice{Un tableau composé de lignes (enregistrements) et de colonnes (descripteurs ou attributs)}
    \wrongchoice{Une fonction Python qui renvoie un dictionnaire}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q02}
    Comment appelle-t-on une \textbf{colonne} dans une table
de données ?
    \begin{choices}
    \wrongchoice{Une ligne}
    \wrongchoice{Une clé primaire}
    \wrongchoice{Un enregistrement}
    \correctchoice{Un descripteur (ou attribut, ou champ)}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q03}
    Comment représente-t-on couramment une table en
Python (avec en-tête) ?
    \begin{choices}
    \wrongchoice{Comme une simple chaîne de caractères}
    \correctchoice{Comme une liste de dictionnaires, chaque dictionnaire représentant une ligne}
    \wrongchoice{Comme une fonction}
    \wrongchoice{Comme un entier}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q04}
    Soit \texttt{table = [\{"nom":"Alice","age":17\}, \{"nom":"Bob","age":16\}]}.
Comment accéder à l'âge de Bob ?
    \begin{choices}
    \correctchoice{\texttt{table[1]['age']}}
    \wrongchoice{\texttt{table['Bob']['age']}}
    \wrongchoice{\texttt{table[2]['age']}}
    \wrongchoice{\texttt{table.age[1]}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q05}
    Pour afficher tous les noms d'élèves d'une table
(liste de dictionnaires avec une clé \texttt{"nom"}), quel
code utilise-t-on ?
    \begin{choices}
    \wrongchoice{\begin{lstlisting}
print(table.nom)
\end{lstlisting}
}
    \correctchoice{\begin{lstlisting}
for ligne in table:
    print(ligne["nom"])
\end{lstlisting}
}
    \wrongchoice{\begin{lstlisting}
for nom in table:
    print(nom)
\end{lstlisting}
}
    \wrongchoice{\begin{lstlisting}
print(table["nom"])
\end{lstlisting}
}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q06}
    D'où peut provenir une table de données dans un
projet réel ?
    \begin{choices}
    \correctchoice{D'un fichier (CSV, JSON), d'un tableur, d'une base de données, d'une API web...}
    \wrongchoice{Aucune des réponses précédentes}
    \wrongchoice{Uniquement d'un fichier CSV créé à la main}
    \wrongchoice{Uniquement d'une base de données SQL}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q07}
    Pour trouver toutes les lignes où l'âge est
strictement supérieur à 16, quel code écrit-on ?
    \begin{choices}
    \wrongchoice{\begin{lstlisting}
for ligne in table:
    if ligne["age"] > 16:
        print(ligne)
\end{lstlisting}
}
    \correctchoice{\begin{lstlisting}
[ligne for ligne in table if ligne["age"] > 16]
\end{lstlisting}
}
    \wrongchoice{\begin{lstlisting}
table.find(age > 16)
\end{lstlisting}
}
    \wrongchoice{\begin{lstlisting}
table[ligne["age"] > 16]
\end{lstlisting}
}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q08}
    Quel est le moyen le plus simple de construire une
table (liste de dictionnaires) à partir d'un fichier
CSV avec en-tête ?
    \begin{choices}
    \wrongchoice{Lire le fichier ligne par ligne et coder à la main le découpage}
    \wrongchoice{\texttt{csv.load('data.csv')} (cette fonction existe-t-elle ?)}
    \correctchoice{\texttt{list(csv.DictReader(open('data.csv', encoding='utf-8')))}}
    \wrongchoice{\texttt{json.load(open('data.csv'))}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q09}
    Comment obtenir le \textbf{nombre d'enregistrements}
(lignes) d'une table représentée comme liste de
dictionnaires ?
    \begin{choices}
    \wrongchoice{\texttt{size(table)}}
    \wrongchoice{\texttt{len(table.keys())}}
    \correctchoice{\texttt{len(table)}}
    \wrongchoice{\texttt{table.count}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q10}
    Que vaut \texttt{len(table)} pour une table vide ?
    \begin{choices}
    \wrongchoice{Une exception est levée}
    \correctchoice{\texttt{0}}
    \wrongchoice{\texttt{-1}}
    \wrongchoice{\texttt{None}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q11}
    Comment trier la table par âge \textbf{croissant} ?
    \begin{choices}
    \correctchoice{\texttt{table.sort(key=lambda ligne: ligne['age'])}}
    \wrongchoice{\texttt{table.sort()}}
    \wrongchoice{\texttt{sorted(table, by='age')}}
    \wrongchoice{\texttt{table.sort('age')}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q12}
    Comment construire une nouvelle table ne contenant
que les colonnes \texttt{nom} et \texttt{age} (sans les autres
descripteurs) ?
    \begin{choices}
    \wrongchoice{\texttt{table[['nom', 'age']]}}
    \wrongchoice{\texttt{table.select('nom', 'age')}}
    \correctchoice{\texttt{[\{k: l[k] for k in ['nom', 'age']\} for l in table]}}
    \wrongchoice{\texttt{table.keep('nom', 'age')}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q13}
    Soient deux tables \texttt{t1} et \texttt{t2} ayant les \textbf{mêmes
descripteurs}. Comment obtenir une nouvelle table
contenant toutes les lignes de \texttt{t1} puis celles de
\texttt{t2} ?
    \begin{choices}
    \wrongchoice{\texttt{t1.append(t2)}}
    \wrongchoice{\texttt{fusion(t1, t2)}}
    \wrongchoice{\texttt{t1.merge(t2)}}
    \correctchoice{\texttt{t1 + t2}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q14}
    Comment calculer la \textbf{moyenne} des âges d'une
table avec un descripteur \texttt{age} (entier) ?
    \begin{choices}
    \wrongchoice{\texttt{mean(table.age)}}
    \wrongchoice{\texttt{table.average('age')}}
    \wrongchoice{\texttt{sum(table['age']) / len(table)}}
    \correctchoice{\texttt{sum(ligne['age'] for ligne in table) / len(table)}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q15}
    Soient \texttt{eleves = [\{"id":1,"nom":"Alice"\},...]} et
\texttt{notes = [\{"id\_eleve":1,"matiere":"Maths","note":15\},...]}.
Pour associer chaque note au nom de l'élève, on
effectue une \textbf{jointure}. Quel pseudo-code
l'implémente correctement ?
    \begin{choices}
    \wrongchoice{\begin{lstlisting}
notes + eleves
\end{lstlisting}
}
    \wrongchoice{\begin{lstlisting}
eleves.merge(notes)
\end{lstlisting}
}
    \correctchoice{\begin{lstlisting}
for n in notes:
    for e in eleves:
        if n["id_eleve"] == e["id"]:
            print(e["nom"], n["matiere"], n["note"])
\end{lstlisting}
}
    \wrongchoice{\begin{lstlisting}
for n in notes:
    print(eleves[n["id_eleve"]]["nom"])
\end{lstlisting}
}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q16}
    Après lecture d'un CSV avec \texttt{csv.DictReader}, on
veut calculer la moyenne des âges. Quel piège
faut-il éviter ?
    \begin{choices}
    \wrongchoice{Le module \texttt{csv} ne gère pas les fichiers de plus de 100 lignes}
    \wrongchoice{Toujours initialiser une variable globale}
    \wrongchoice{Il faut payer une licence pour utiliser \texttt{csv.DictReader}}
    \correctchoice{Oublier de convertir les valeurs en \texttt{int} (les valeurs lues sont des chaînes)}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q17}
    Comment compter le nombre d'élèves dans chaque
ville à partir de \texttt{table = [\{"nom":..., "ville":...\}, ...]} ?
    \begin{choices}
    \wrongchoice{\texttt{set(table['ville'])}}
    \correctchoice{\begin{lstlisting}
c = {}
for ligne in table:
    v = ligne["ville"]
    c[v] = c.get(v, 0) + 1
\end{lstlisting}
}
    \wrongchoice{\texttt{len(table)}}
    \wrongchoice{\texttt{table.count('ville')}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q18}
    Comment trier la table par \textbf{âge croissant}, puis
par \textbf{nom alphabétique} en cas d'égalité ?
    \begin{choices}
    \correctchoice{\texttt{table.sort(key=lambda l: (l['age'], l['nom']))}}
    \wrongchoice{\texttt{table.sort('age', 'nom')}}
    \wrongchoice{\texttt{table.sort(key=lambda l: l['age'] + l['nom'])}}
    \wrongchoice{\texttt{table.sort(by=['age', 'nom'])}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q19}
    Lequel des fichiers Open Data suivants se prête
naturellement à une représentation en table ?
    \begin{choices}
    \correctchoice{La liste des stations Vélib' avec leurs coordonnées et capacités, au format CSV}
    \wrongchoice{Une carte des arrondissements de Paris au format SVG}
    \wrongchoice{Un PDF illustré}
    \wrongchoice{Une vidéo de présentation des transports}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q20}
    Pour quel type de données les tables sont-elles
\textbf{mal adaptées} ?
    \begin{choices}
    \wrongchoice{Une liste de produits avec prix}
    \wrongchoice{Un classement sportif}
    \correctchoice{Un arbre généalogique sur plusieurs générations avec des relations multiples}
    \wrongchoice{Une liste d'élèves avec nom, âge, ville}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q21}
    Soit
\begin{lstlisting}
t = [{"a":1,"b":2}, {"a":3,"b":4}, {"a":5,"b":6}]
\end{lstlisting}
Que vaut \texttt{sum(l["a"] for l in t if l["b"] >= 4)} ?
    \begin{choices}
    \wrongchoice{12}
    \correctchoice{8}
    \wrongchoice{0}
    \wrongchoice{9}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q22}
    On veut convertir une \textbf{liste de dictionnaires}
\texttt{[\{"x":1,"y":2\}, \{"x":3,"y":4\}]} en \textbf{dictionnaire
de listes} \texttt{\{"x":[1,3], "y":[2,4]\}} (représentation
"colonne par colonne"). Quel code est correct ?
    \begin{choices}
    \correctchoice{\begin{lstlisting}
{k: [l[k] for l in table] for k in table[0]}
\end{lstlisting}
}
    \wrongchoice{\texttt{table.pivot()}}
    \wrongchoice{\begin{lstlisting}
{k: l[k] for l in table for k in l}
\end{lstlisting}
}
    \wrongchoice{\texttt{dict(table)}}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q23}
    Pour une jointure entre deux tables de tailles
\texttt{n} et \texttt{m}, la version naïve à deux boucles
imbriquées a une complexité de O(n × m). Comment
l'améliorer ?
    \begin{choices}
    \wrongchoice{En supprimant la moitié des colonnes}
    \wrongchoice{En triant les deux tables au préalable}
    \correctchoice{En indexant une table par sa clé dans un dictionnaire (accès O(1)), ce qui ramène la jointure à O(n + m)}
    \wrongchoice{En utilisant des tuples au lieu de dictionnaires}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q24}
    Un élève écrit
\begin{lstlisting}
for ligne in table:
    if ligne["age"] > 16:
        table.remove(ligne)
\end{lstlisting}
Quel est le problème ?
    \begin{choices}
    \wrongchoice{La boucle ne compile pas}
    \wrongchoice{Cela lève toujours une exception}
    \correctchoice{Modifier une liste pendant qu'on la parcourt provoque des lignes ignorées : certains éléments ne seront jamais testés}
    \wrongchoice{La méthode \texttt{.remove} n'existe pas}
    \end{choices}
  \end{question}
}

\element{premieretablesdedonnees}{
  \begin{question}{q25}
    Parmi les affirmations suivantes sur les tables de
données, laquelle est \textbf{fausse} ?
    \begin{choices}
    \wrongchoice{Les opérations classiques sont la recherche, le tri, la sélection de lignes (filtrage), la sélection de colonnes et la fusion}
    \wrongchoice{Une fusion permet de combiner deux tables sur la base d'un descripteur commun}
    \wrongchoice{En Python, on représente couramment une table par une liste de dictionnaires}
    \correctchoice{Le module \texttt{csv} produit toujours des données typées (entiers, flottants, dates)}
    \end{choices}
  \end{question}
}


\onecopy{1}{
  \shufflegroup{premieretablesdedonnees}
  \insertgroup{premieretablesdedonnees}
}

\end{document}
