Adloun

Écrire une table croisée

Exercice supplémentaire · niveau 2 · NSI (première), chapitre 6 — Traiter des données en tables · Données sales et formats mal formés

Énoncé

Écrire une table croisée : effectif par couple (classe, option). Quel contrôle simple valide le résultat ?

Corrigé


def croiser(table, lig, col):
    """Effectifs par couple de valeurs : un dictionnaire de dictionnaires.

    Postcondition : la somme de tous les effectifs vaut len(table).
    """
    res = {}
    for ligne in table:
        res.setdefault(ligne[lig], {})
        v = ligne[col]
        res[ligne[lig]][v] = res[ligne[lig]].get(v, 0) + 1
    return res

croiser(eleves, "classe", "option")
# {'1G3': {'NSI': 2}, '1G1': {'SVT': 1, 'SES': 1}, '1G2': {'NSI': 1}}

Le contrôle. La somme de toutes les cases doit valoir le nombre de lignes : chaque ligne est comptée dans une case et une seule.


assert sum(sum(d.values()) for d in croise.values()) == len(table)

Ici . C'est le même argument de partition que pour l'index multiple, et il attrape la même famille d'erreurs.

Ce que le croisement montre et qu'une colonne seule cache. Les effectifs par classe (, , ) et par option ( NSI, SVT, SES) ne disent pas que la 1G3 est entièrement en NSI. Seul le croisement le fait voir. C'est l'opération de base de toute analyse de données — et le tableau qu'on obtiendrait en terminale d'une requête GROUP BY sur deux colonnes.

Le creux du tableau. Les couples d'effectif nul n'apparaissent pas : il n'y a pas de clé 'SVT' sous '1G3'. Pour un affichage rectangulaire, il faut les ajouter à zéro — et get(v, 0) est le geste qui évite la KeyError à la lecture.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.