\documentclass[10pt,aspectratio=169]{beamer}

% --- Thème ---
\usetheme[language=french]{Celestia}

% Avec [allowframebreaks] sur les frames de questions, Beamer ajoute
% par défaut « (1) », « (2) », « (3) »... sur chaque sous-slide. On
% supprime entièrement cette annotation : un template vide pour
% « frametitle continuation ». L'enseignant identifie visuellement la
% continuation par le contenu de la slide. (Les variantes [from second]
% et [roman] interagissent mal avec un titre contenant \textemdash{}
% sous Celestia : elles déclenchent une erreur « Missing $ inserted ».)
\setbeamertemplate{frametitle continuation}{}

\subject{Numérique et sciences informatiques}
\title{Tables de données}
\subtitle{QCM}
\author{Première}
\date{\today}

\begin{document}

\begin{frame}
    \titlepage
\end{frame}

% Q1 - Réponse en C
\begin{frame}[fragile]{Question 1 \textemdash{} Qu'est-ce qu'une table ?}
    En informatique, qu'appelle-t-on une \textbf{table de données} ?\medskip
    \begin{itemize}
        \item[A.] Un meuble pour poser un ordinateur
        \item[B.] Un type primitif de Python
        \item[\alert<2>{C.}] \alert<2>{Un tableau composé de lignes (enregistrements) et de colonnes (descripteurs ou attributs)}
        \item[D.] Une fonction Python qui renvoie un dictionnaire
    \end{itemize}
\end{frame}

% Q2 - Réponse en D
\begin{frame}[fragile]{Question 2 \textemdash{} Vocabulaire}
    Comment appelle-t-on une \textbf{colonne} dans une table
de données ?\medskip
    \begin{itemize}
        \item[A.] Une ligne
        \item[B.] Une clé primaire
        \item[C.] Un enregistrement
        \item[\alert<2>{D.}] \alert<2>{Un descripteur (ou attribut, ou champ)}
    \end{itemize}
\end{frame}

% Q3 - Réponse en B
\begin{frame}[fragile]{Question 3 \textemdash{} Liste de dictionnaires}
    Comment représente-t-on couramment une table en
Python (avec en-tête) ?\medskip
    \begin{itemize}
        \item[A.] Comme une simple chaîne de caractères
        \item[\alert<2>{B.}] \alert<2>{Comme une liste de dictionnaires, chaque dictionnaire représentant une ligne}
        \item[C.] Comme une fonction
        \item[D.] Comme un entier
    \end{itemize}
\end{frame}

% Q4 - Réponse en A
\begin{frame}[fragile]{Question 4 \textemdash{} Accéder à une cellule}
    Soit \texttt{table = [\{"nom":"Alice","age":17\}, \{"nom":"Bob","age":16\}]}.
Comment accéder à l'âge de Bob ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{\texttt{table[1]['age']}}
        \item[B.] \texttt{table['Bob']['age']}
        \item[C.] \texttt{table[2]['age']}
        \item[D.] \texttt{table.age[1]}
    \end{itemize}
\end{frame}

% Q5 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 5 \textemdash{} Parcourir une table}
    Pour afficher tous les noms d'élèves d'une table
(liste de dictionnaires avec une clé \texttt{"nom"}), quel
code utilise-t-on ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
print(table.nom)
\end{lstlisting}

        \item[B.]~\\
\begin{lstlisting}
for ligne in table:
    print(ligne["nom"])
\end{lstlisting}

        \item[C.]~\\
\begin{lstlisting}
for nom in table:
    print(nom)
\end{lstlisting}

        \item[D.]~\\
\begin{lstlisting}
print(table["nom"])
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q5 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 5 \textemdash{} Parcourir une table}
    Pour afficher tous les noms d'élèves d'une table
(liste de dictionnaires avec une clé \texttt{"nom"}), quel
code utilise-t-on ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
print(table.nom)
\end{lstlisting}

        \item[\alert{B.}]~\\
\begin{lstlisting}
for ligne in table:
    print(ligne["nom"])
\end{lstlisting}

        \item[C.]~\\
\begin{lstlisting}
for nom in table:
    print(nom)
\end{lstlisting}

        \item[D.]~\\
\begin{lstlisting}
print(table["nom"])
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q6 - Réponse en A
\begin{frame}[fragile]{Question 6 \textemdash{} Origine des tables}
    D'où peut provenir une table de données dans un
projet réel ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{D'un fichier (CSV, JSON), d'un tableur, d'une base de données, d'une API web...}
        \item[B.] Aucune des réponses précédentes
        \item[C.] Uniquement d'un fichier CSV créé à la main
        \item[D.] Uniquement d'une base de données SQL
    \end{itemize}
\end{frame}

% Q7 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 7 \textemdash{} Recherche par critère}
    Pour trouver toutes les lignes où l'âge est
strictement supérieur à 16, quel code écrit-on ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
for ligne in table:
    if ligne["age"] > 16:
        print(ligne)
\end{lstlisting}

        \item[B.]~\\
\begin{lstlisting}
[ligne for ligne in table if ligne["age"] > 16]
\end{lstlisting}

        \item[C.]~\\
\begin{lstlisting}
table.find(age > 16)
\end{lstlisting}

        \item[D.]~\\
\begin{lstlisting}
table[ligne["age"] > 16]
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q7 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 7 \textemdash{} Recherche par critère}
    Pour trouver toutes les lignes où l'âge est
strictement supérieur à 16, quel code écrit-on ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
for ligne in table:
    if ligne["age"] > 16:
        print(ligne)
\end{lstlisting}

        \item[\alert{B.}]~\\
\begin{lstlisting}
[ligne for ligne in table if ligne["age"] > 16]
\end{lstlisting}

        \item[C.]~\\
\begin{lstlisting}
table.find(age > 16)
\end{lstlisting}

        \item[D.]~\\
\begin{lstlisting}
table[ligne["age"] > 16]
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q8 - Réponse en C
\begin{frame}[fragile]{Question 8 \textemdash{} Construire depuis CSV}
    Quel est le moyen le plus simple de construire une
table (liste de dictionnaires) à partir d'un fichier
CSV avec en-tête ?\medskip
    \begin{itemize}
        \item[A.] Lire le fichier ligne par ligne et coder à la main le découpage
        \item[B.] \texttt{csv.load('data.csv')} (cette fonction existe-t-elle ?)
        \item[\alert<2>{C.}] \alert<2>{\texttt{list(csv.DictReader(open('data.csv', encoding='utf-8')))}}
        \item[D.] \texttt{json.load(open('data.csv'))}
    \end{itemize}
\end{frame}

% Q9 - Réponse en C
\begin{frame}[fragile]{Question 9 \textemdash{} Nombre de lignes}
    Comment obtenir le \textbf{nombre d'enregistrements}
(lignes) d'une table représentée comme liste de
dictionnaires ?\medskip
    \begin{itemize}
        \item[A.] \texttt{size(table)}
        \item[B.] \texttt{len(table.keys())}
        \item[\alert<2>{C.}] \alert<2>{\texttt{len(table)}}
        \item[D.] \texttt{table.count}
    \end{itemize}
\end{frame}

% Q10 - Réponse en B
\begin{frame}[fragile]{Question 10 \textemdash{} Table vide}
    Que vaut \texttt{len(table)} pour une table vide ?\medskip
    \begin{itemize}
        \item[A.] Une exception est levée
        \item[\alert<2>{B.}] \alert<2>{\texttt{0}}
        \item[C.] \texttt{-1}
        \item[D.] \texttt{None}
    \end{itemize}
\end{frame}

% Q11 - Réponse en A
\begin{frame}[fragile]{Question 11 \textemdash{} Trier par descripteur}
    Comment trier la table par âge \textbf{croissant} ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{\texttt{table.sort(key=lambda ligne: ligne['age'])}}
        \item[B.] \texttt{table.sort()}
        \item[C.] \texttt{sorted(table, by='age')}
        \item[D.] \texttt{table.sort('age')}
    \end{itemize}
\end{frame}

% Q12 - Réponse en C
\begin{frame}[fragile]{Question 12 \textemdash{} Sélectionner des colonnes}
    Comment construire une nouvelle table ne contenant
que les colonnes \texttt{nom} et \texttt{age} (sans les autres
descripteurs) ?\medskip
    \begin{itemize}
        \item[A.] \texttt{table[['nom', 'age']]}
        \item[B.] \texttt{table.select('nom', 'age')}
        \item[\alert<2>{C.}] \alert<2>{\texttt{[\{k: l[k] for k in ['nom', 'age']\} for l in table]}}
        \item[D.] \texttt{table.keep('nom', 'age')}
    \end{itemize}
\end{frame}

% Q13 - Réponse en D
\begin{frame}[fragile]{Question 13 \textemdash{} Fusion de tables}
    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} ?\medskip
    \begin{itemize}
        \item[A.] \texttt{t1.append(t2)}
        \item[B.] \texttt{fusion(t1, t2)}
        \item[C.] \texttt{t1.merge(t2)}
        \item[\alert<2>{D.}] \alert<2>{\texttt{t1 + t2}}
    \end{itemize}
\end{frame}

% Q14 - Réponse en D
\begin{frame}[fragile]{Question 14 \textemdash{} Calculer une moyenne}
    Comment calculer la \textbf{moyenne} des âges d'une
table avec un descripteur \texttt{age} (entier) ?\medskip
    \begin{itemize}
        \item[A.] \texttt{mean(table.age)}
        \item[B.] \texttt{table.average('age')}
        \item[C.] \texttt{sum(table['age']) / len(table)}
        \item[\alert<2>{D.}] \alert<2>{\texttt{sum(ligne['age'] for ligne in table) / len(table)}}
    \end{itemize}
\end{frame}

% Q15 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 15 \textemdash{} Jointure simple}
    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 ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
notes + eleves
\end{lstlisting}

        \item[B.]~\\
\begin{lstlisting}
eleves.merge(notes)
\end{lstlisting}

        \item[C.]~\\
\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}

        \item[D.]~\\
\begin{lstlisting}
for n in notes:
    print(eleves[n["id_eleve"]]["nom"])
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q15 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 15 \textemdash{} Jointure simple}
    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 ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
notes + eleves
\end{lstlisting}

        \item[B.]~\\
\begin{lstlisting}
eleves.merge(notes)
\end{lstlisting}

        \item[\alert{C.}]~\\
\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}

        \item[D.]~\\
\begin{lstlisting}
for n in notes:
    print(eleves[n["id_eleve"]]["nom"])
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q16 - Réponse en D
\begin{frame}[fragile]{Question 16 \textemdash{} Pièges de conversion}
    Après lecture d'un CSV avec \texttt{csv.DictReader}, on
veut calculer la moyenne des âges. Quel piège
faut-il éviter ?\medskip
    \begin{itemize}
        \item[A.] Le module \texttt{csv} ne gère pas les fichiers de plus de 100 lignes
        \item[B.] Toujours initialiser une variable globale
        \item[C.] Il faut payer une licence pour utiliser \texttt{csv.DictReader}
        \item[\alert<2>{D.}] \alert<2>{Oublier de convertir les valeurs en \texttt{int} (les valeurs lues sont des chaînes)}
    \end{itemize}
\end{frame}

% Q17 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 17 \textemdash{} Compter par catégorie}
    Comment compter le nombre d'élèves dans chaque
ville à partir de \texttt{table = [\{"nom":..., "ville":...\}, ...]} ?\medskip
    \begin{itemize}
        \item[A.] \texttt{set(table['ville'])}
        \item[B.]~\\
\begin{lstlisting}
c = {}
for ligne in table:
    v = ligne["ville"]
    c[v] = c.get(v, 0) + 1
\end{lstlisting}

        \item[C.] \texttt{len(table)}
        \item[D.] \texttt{table.count('ville')}
    \end{itemize}
\end{frame}

% Q17 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 17 \textemdash{} Compter par catégorie}
    Comment compter le nombre d'élèves dans chaque
ville à partir de \texttt{table = [\{"nom":..., "ville":...\}, ...]} ?\medskip
    \begin{itemize}
        \item[A.] \texttt{set(table['ville'])}
        \item[\alert{B.}]~\\
\begin{lstlisting}
c = {}
for ligne in table:
    v = ligne["ville"]
    c[v] = c.get(v, 0) + 1
\end{lstlisting}

        \item[C.] \texttt{len(table)}
        \item[D.] \texttt{table.count('ville')}
    \end{itemize}
\end{frame}

% Q18 - Réponse en A
\begin{frame}[fragile]{Question 18 \textemdash{} Tri sur deux critères}
    Comment trier la table par \textbf{âge croissant}, puis
par \textbf{nom alphabétique} en cas d'égalité ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{\texttt{table.sort(key=lambda l: (l['age'], l['nom']))}}
        \item[B.] \texttt{table.sort('age', 'nom')}
        \item[C.] \texttt{table.sort(key=lambda l: l['age'] + l['nom'])}
        \item[D.] \texttt{table.sort(by=['age', 'nom'])}
    \end{itemize}
\end{frame}

% Q19 - Réponse en A
\begin{frame}[fragile]{Question 19 \textemdash{} Exemple concret}
    Lequel des fichiers Open Data suivants se prête
naturellement à une représentation en table ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{La liste des stations Vélib' avec leurs coordonnées et capacités, au format CSV}
        \item[B.] Une carte des arrondissements de Paris au format SVG
        \item[C.] Un PDF illustré
        \item[D.] Une vidéo de présentation des transports
    \end{itemize}
\end{frame}

% Q20 - Réponse en C
\begin{frame}[fragile]{Question 20 \textemdash{} Limite des tables}
    Pour quel type de données les tables sont-elles
\textbf{mal adaptées} ?\medskip
    \begin{itemize}
        \item[A.] Une liste de produits avec prix
        \item[B.] Un classement sportif
        \item[\alert<2>{C.}] \alert<2>{Un arbre généalogique sur plusieurs générations avec des relations multiples}
        \item[D.] Une liste d'élèves avec nom, âge, ville
    \end{itemize}
\end{frame}

% Q21 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 21 \textemdash{} Trace d'accès}
    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)} ?\medskip
    \begin{itemize}
        \item[A.] 12
        \item[B.] 8
        \item[C.] 0
        \item[D.] 9
    \end{itemize}
\end{frame}

% Q21 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 21 \textemdash{} Trace d'accès}
    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)} ?\medskip
    \begin{itemize}
        \item[A.] 12
        \item[\alert{B.}] \alert{8}
        \item[C.] 0
        \item[D.] 9
    \end{itemize}
\end{frame}

% Q22 - Réponse en A
\begin{frame}[fragile,allowframebreaks]{Question 22 \textemdash{} Transformer la structure}
    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 ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
{k: [l[k] for l in table] for k in table[0]}
\end{lstlisting}

        \item[B.] \texttt{table.pivot()}
        \item[C.]~\\
\begin{lstlisting}
{k: l[k] for l in table for k in l}
\end{lstlisting}

        \item[D.] \texttt{dict(table)}
    \end{itemize}
\end{frame}

% Q22 - Réponse en A
\begin{frame}[fragile,allowframebreaks]{Question 22 \textemdash{} Transformer la structure}
    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 ?\medskip
    \begin{itemize}
        \item[\alert{A.}]~\\
\begin{lstlisting}
{k: [l[k] for l in table] for k in table[0]}
\end{lstlisting}

        \item[B.] \texttt{table.pivot()}
        \item[C.]~\\
\begin{lstlisting}
{k: l[k] for l in table for k in l}
\end{lstlisting}

        \item[D.] \texttt{dict(table)}
    \end{itemize}
\end{frame}

% Q23 - Réponse en C
\begin{frame}[fragile]{Question 23 \textemdash{} Performance d'une jointure}
    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 ?\medskip
    \begin{itemize}
        \item[A.] En supprimant la moitié des colonnes
        \item[B.] En triant les deux tables au préalable
        \item[\alert<2>{C.}] \alert<2>{En indexant une table par sa clé dans un dictionnaire (accès O(1)), ce qui ramène la jointure à O(n + m)}
        \item[D.] En utilisant des tuples au lieu de dictionnaires
    \end{itemize}
\end{frame}

% Q24 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 24 \textemdash{} Bug subtil}
    Un élève écrit
\begin{lstlisting}
for ligne in table:
    if ligne["age"] > 16:
        table.remove(ligne)
\end{lstlisting}
Quel est le problème ?\medskip
    \begin{itemize}
        \item[A.] La boucle ne compile pas
        \item[B.] Cela lève toujours une exception
        \item[C.] Modifier une liste pendant qu'on la parcourt provoque des lignes ignorées : certains éléments ne seront jamais testés
        \item[D.] La méthode \texttt{.remove} n'existe pas
    \end{itemize}
\end{frame}

% Q24 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 24 \textemdash{} Bug subtil}
    Un élève écrit
\begin{lstlisting}
for ligne in table:
    if ligne["age"] > 16:
        table.remove(ligne)
\end{lstlisting}
Quel est le problème ?\medskip
    \begin{itemize}
        \item[A.] La boucle ne compile pas
        \item[B.] Cela lève toujours une exception
        \item[\alert{C.}] \alert{Modifier une liste pendant qu'on la parcourt provoque des lignes ignorées : certains éléments ne seront jamais testés}
        \item[D.] La méthode \texttt{.remove} n'existe pas
    \end{itemize}
\end{frame}

% Q25 - Réponse en D
\begin{frame}[fragile]{Question 25 \textemdash{} Synthèse}
    Parmi les affirmations suivantes sur les tables de
données, laquelle est \textbf{fausse} ?\medskip
    \begin{itemize}
        \item[A.] Les opérations classiques sont la recherche, le tri, la sélection de lignes (filtrage), la sélection de colonnes et la fusion
        \item[B.] Une fusion permet de combiner deux tables sur la base d'un descripteur commun
        \item[C.] En Python, on représente couramment une table par une liste de dictionnaires
        \item[\alert<2>{D.}] \alert<2>{Le module \texttt{csv} produit toujours des données typées (entiers, flottants, dates)}
    \end{itemize}
\end{frame}

\begin{frame}[standout]{}
    Fin de l'évaluation
\end{frame}

\end{document}
