Chapitre 12 : Recherche, tri et fusion de tables.

Introduction :

La recherche dans une table consiste à localiser des données spécifiques en fonction de critères, souvent via des clés ou des indices.

La fusion de tables combine deux tables sur une ou plusieurs colonnes communes, permettant de regrouper les informations provenant de plusieurs sources de données en une seule table pour une analyse plus complète.

Avant de commencer :

Pour les exercices qui suivent, on récupérera la liste des élèves du chapitre précédent : eleves.csv.

On pourra utiliser ce code :

import os
os.chdir("U:\\NSI\\chapitre11") # a modifier si necessaire
import csv


def import_depuis_csv(nom_fichier):
    liste=[]
    with open(nom_fichier, 'r',encoding='utf-8',newline='') as fichier:
        reader=csv.reader(fichier)
        for ligne in reader:
                    liste.append(ligne)
    return liste

liste=import_depuis_csv("eleves.csv")

1. Recherche :

Dans ce chapitre, rechercher un élément dans une table revient à renvoyer un booléen suivant la présence ou non de cet élément dans la table.

2. Exercice:

  1. Créer une fonction recherche_prenom(liste,prenom) qui renvoie un booléen en fonction de la présence ou non d'un élève ayant ce prénom.
  2. Créer une fonction recherche_nom(liste,nom) qui renvoie un booléen en fonction de la présence ou non d'un élève ayant ce nom.
  3. Créer une fonction recherche_specialite(liste,specialite) qui renvoie un booléen en fonction de la présence ou non d'un élève faisant cette spécialité.

3. Exercice:

  1. Créer une fonction affiche_les_noms(liste) qui affiche les noms des élèves dans l'ordre de la table.
  2. Créer une fonction affiche_les_noms_prenoms(liste) qui affiche les noms et prénoms des élèves dans l'ordre de la table.
  3. Créer la fonction ajout_eleve(liste, nom, prenom, sexe, classe, specialite1, specialite2, specialite3) qui ajoute un élève seulement si sexe est dans ("M","F"), classe est comprise entre 1g01 et 1g12, et que la specialite existe déjà dans la table.
  4. Créer la fonction supprime_eleve(liste,nom,prenom,classe) qui supprime un élève si le nom, prénom et la classe correspondent.
  5. Créer la fonction liste_classes(liste) qui retourne une liste d'objets de type string correspondant aux classes présentes dans la liste. Chaque classe n'apparaitra qu'une seule fois.
  6. Créer la fonction liste_noms(liste) qui renvoie une liste composée uniquement des noms de familles triés par ordre alphabétique. Nous pourrons utiliser la fonction tri_par_selection(liste) afin de trier la liste. Chaque nom de famille n'apparaitra qu"une fois.
  7. Créer la fonction affiche_eleves_par_prenom(liste,prenom) qui affiche les informations du ou des élèves dont le prénom est donné.
  8. Créer une fonction nb_classes(liste) qui renvoie le nombre de classe différentes du groupe.
  9. Créer une fonction nb_spe_math(liste) qui renvoie le nombre de personne faisant la spécialité mathématiques.
  10. Créer une fonction contient_string(liste,chaine) qui renvoie le nombre d'élements qui sont des strings et qui contiennent cette chaine. On pourra les afficher à chaque fois qu'on en trouve.

4. Exercice:

Y a-t-il deux élèves ayant les mêmes noms et prénoms? Si oui lesquels?

Programmer une fonction cherche_doublons(liste) qui renvoie une liste de tuples de deux integers correspondant aux indices dans la liste où ils sont présents.

Par exemple, si la fonction renvoie [(1,40),(3,799)] cela signifie que liste[1] et liste[40] comportent les mêmes noms-prénoms et de même pour liste[3] et liste[799].

5. Exercice:

Programmer la fonction pourcentage(liste,specialite) qui prend en paramètres la liste des élèves et un string specialite et qui renvoie sous la forme d'un integer le pourcentage d'élèves suivant la spécialité.

Par exemple, si le pourcentage est à peu près de 92,38%, le programme renverra 92.

6. Tri :

On peut effectuer plusieurs tris en fonction des différentes colonnes.

7. Exercice:

Nous continuons avec la même liste.

En modifiant l'algorithme de tri par selection afin qu'il ne prenne pas en compte la première sous-liste puisque ce sont les entêtes, faire les questions suivantes :

  1. Créer une fonction tri_par_prenom(liste) qui trie la liste des élèves de NSI en fonction de leurs prénoms.

    Elle renvoie une liste de listes ne contenant que les élèves qui font NSI.

    On pourra compléter le code suivant :

    def tri_par_prenom(liste):
        # On place les élèves de NSI dans une liste liste_NSI
        liste_NSI=[]
        for eleve in liste[1:]: # On ne prend pas les entêtes
            if "NSI" in eleve[4:]:
                liste_NSI.append(eleve)
    
        #On trie liste_NSI suivant les prénoms :
        N=len(liste_NSI)
        for k in range(N-1):
            imin = k
            for i in range(imin, N):
                if ............................... : #On compare les prénoms
                    imin=i
            liste_NSI[k], liste_NSI[imin] = liste_NSI[imin], liste_NSI[k]
        return liste_NSI
    
  2. Créer une fonction tri_par_nom(liste) qui trie la liste des élèves de NSI en fonction de leurs noms.
  3. Créer une fonction tri_par_classe_puis_prenom(liste) qui trie la liste des élèves de NSI en fonction de leurs classes puis de leurs prénoms.

8. Fusion:

On peut fusionner deux tables en une seule.

On peut y distinguer plusieurs cas :

9. Exercice:

Dans cet exercice, nous partons du principe que nous avons une table avec une première colonne ayant pour attribut l'identifiant.

Est considéré comme un doublon deux lignes ayant la même valeur dans l'identifiant.

  1. Créer une fonction fusion_avec_doublon(table1,table2) qui retourne la fusion de deux tables en laissant les doublons.

    On pourra tester notre code sur les deux tables suivantes:

    table1 = [
        [1, "Dupont", "Alice", "15/03/2007", "Anglais", "Espagnol"],
        [2, "Martin", "Lucas", "22/07/2006", "Allemand", "Italien"],
        [3, "Dubois", "Emma", "10/11/2008", "Espagnol", "Allemand"],
        [4, "Thomas", "Louis", "05/09/2007", "Italien", "Anglais"],
        [5, "Richard", "Chloé", "20/04/2006", "Anglais", "Espagnol"],
        [6, "Durand", "Adam", "12/06/2008", "Allemand", "Italien"],
        [32, "St-Pierre", "Eliott", "14/12/2008", "Italien", "Allemand"],
        [7, "Petit", "Léa", "25/08/2007", "Espagnol", "Anglais"],
        [8, "Leroy", "Manon", "30/01/2006", "Italien", "Allemand"],
        [9, "Moreau", "Hugo", "03/10/2008", "Anglais", "Espagnol"],
        [10, "Lefevre", "Inès", "18/07/2006", "Allemand", "Italien"],
        [11, "Garcia", "Noah", "09/05/2007", "Espagnol", "Anglais"],
        [12, "Roux", "Camille", "14/12/2008", "Italien", "Allemand"],
        [13, "Fournier", "Eva", "27/02/2006", "Anglais", "Espagnol"],
        [14, "Girard", "Théo", "08/06/2008", "Allemand", "Italien"],
        [15, "Caron", "Louise", "19/09/2007", "Espagnol", "Anglais"],
        [16, "Andre", "Mathis", "02/11/2006", "Italien", "Allemand"],
        [17, "Lecomte", "Jade", "11/04/2007", "Anglais", "Espagnol"],
        [18, "Meyer", "Arthur", "24/08/2008", "Allemand", "Italien"],
        [19, "Blanc", "Sarah", "01/03/2006", "Espagnol", "Anglais"],
        [20, "Laurent", "Nathan", "07/07/2007", "Italien", "Allemand"],
        [27, "Lavoie", "Liam", "25/08/2006", "Espagnol", "Anglais"],
        [28, "Bouchard", "Jules", "30/01/2007", "Italien", "Allemand"],
        [29, "Morin", "Charlotte", "03/10/2008", "Anglais", "Espagnol"],
        [30, "Lévesque", "Mason", "18/07/2006", "Allemand", "Italien"]
    ]
    
    table2 = [
        [16, "Andre", "Mathis", "02/11/2006", "Italien", "Allemand"],
        [17, "Lecomte", "Jade", "11/04/2007", "Anglais", "Espagnol"],
        [18, "Meyer", "Arthur", "24/08/2008", "Allemand", "Italien"],
        [19, "Blanc", "Sarah", "01/03/2006", "Espagnol", "Anglais"],
        [20, "Laurent", "Nathan", "07/07/2007", "Italien", "Allemand"],
        [21, "Gagnon", "Léo", "15/03/2006", "Anglais", "Espagnol"],
        [22, "Roy", "Lola", "22/07/2007", "Allemand", "Italien"],
        [23, "Tremblay", "Oscar", "10/11/2008", "Espagnol", "Allemand"],
        [24, "Gauthier", "Zoé", "05/09/2006", "Italien", "Anglais"],
        [25, "Fortin", "Mia", "20/04/2007", "Anglais", "Espagnol"],
        [26, "Pelletier", "Éthan", "12/06/2008", "Allemand", "Italien"],
        [27, "Lavoie", "Liam", "25/08/2006", "Espagnol", "Anglais"],
        [28, "Bouchard", "Jules", "30/01/2007", "Italien", "Allemand"],
        [29, "Morin", "Charlotte", "03/10/2008", "Anglais", "Espagnol"],
        [30, "Lévesque", "Mason", "18/07/2006", "Allemand", "Italien"],
        [31, "Bergeron", "Lou", "09/05/2007", "Espagnol", "Anglais"],
        [32, "St-Pierre", "Eliott", "14/12/2008", "Italien", "Allemand"],
        [33, "Bélanger", "Zachary", "27/02/2006", "Anglais", "Espagnol"],
        [34, "Leblanc", "Rosie", "08/06/2008", "Allemand", "Italien"],
        [35, "Giroux", "Léon", "19/09/2007", "Espagnol", "Anglais"],
        [36, "Carrière", "Mila", "02/11/2006", "Italien", "Allemand"],
        [37, "Desjardins", "Maxime", "11/04/2007", "Anglais", "Espagnol"],
        [38, "Lefebvre", "Nolan", "24/08/2008", "Allemand", "Italien"],
        [39, "Perron", "Noémie", "01/03/2006", "Espagnol", "Anglais"],
        [40, "Dufour", "Charlie", "07/07/2007", "Italien", "Allemand"]
    ]
  2. Créer une fonction fusion_sans_doublon(table1,table2) qui retourne la fusion de deux tables en supprimant les doublons.

    On pourra tester notre code sur les deux tables suivantes:

    table1 = [
        [1, "Dupont", "Alice", "15/03/2007", "Anglais", "Espagnol"],
        [2, "Martin", "Lucas", "22/07/2006", "Allemand", "Italien"],
        [3, "Dubois", "Emma", "10/11/2008", "Espagnol", "Allemand"],
        [4, "Thomas", "Louis", "05/09/2007", "Italien", "Anglais"],
        [5, "Richard", "Chloé", "20/04/2006", "Anglais", "Espagnol"],
        [6, "Durand", "Adam", "12/06/2008", "Allemand", "Italien"],
        [32, "St-Pierre", "Eliott", "14/12/2008", "Italien", "Allemand"],
        [7, "Petit", "Léa", "25/08/2007", "Espagnol", "Anglais"],
        [8, "Leroy", "Manon", "30/01/2006", "Italien", "Allemand"],
        [9, "Moreau", "Hugo", "03/10/2008", "Anglais", "Espagnol"],
        [10, "Lefevre", "Inès", "18/07/2006", "Allemand", "Italien"],
        [11, "Garcia", "Noah", "09/05/2007", "Espagnol", "Anglais"],
        [12, "Roux", "Camille", "14/12/2008", "Italien", "Allemand"],
        [13, "Fournier", "Eva", "27/02/2006", "Anglais", "Espagnol"],
        [14, "Girard", "Théo", "08/06/2008", "Allemand", "Italien"],
        [15, "Caron", "Louise", "19/09/2007", "Espagnol", "Anglais"],
        [16, "Andre", "Mathis", "02/11/2006", "Italien", "Allemand"],
        [17, "Lecomte", "Jade", "11/04/2007", "Anglais", "Espagnol"],
        [18, "Meyer", "Arthur", "24/08/2008", "Allemand", "Italien"],
        [19, "Blanc", "Sarah", "01/03/2006", "Espagnol", "Anglais"],
        [20, "Laurent", "Nathan", "07/07/2007", "Italien", "Allemand"],
        [27, "Lavoie", "Liam", "25/08/2006", "Espagnol", "Anglais"],
        [28, "Bouchard", "Jules", "30/01/2007", "Italien", "Allemand"],
        [29, "Morin", "Charlotte", "03/10/2008", "Anglais", "Espagnol"],
        [30, "Lévesque", "Mason", "18/07/2006", "Allemand", "Italien"]
    ]
    
    table2 = [
        [16, "Andre", "Mathis", "02/11/2006", "Italien", "Allemand"],
        [17, "Lecomte", "Jade", "11/04/2007", "Anglais", "Espagnol"],
        [18, "Meyer", "Arthur", "24/08/2008", "Allemand", "Italien"],
        [19, "Blanc", "Sarah", "01/03/2006", "Espagnol", "Anglais"],
        [20, "Laurent", "Nathan", "07/07/2007", "Italien", "Allemand"],
        [21, "Gagnon", "Léo", "15/03/2006", "Anglais", "Espagnol"],
        [22, "Roy", "Lola", "22/07/2007", "Allemand", "Italien"],
        [23, "Tremblay", "Oscar", "10/11/2008", "Espagnol", "Allemand"],
        [24, "Gauthier", "Zoé", "05/09/2006", "Italien", "Anglais"],
        [25, "Fortin", "Mia", "20/04/2007", "Anglais", "Espagnol"],
        [26, "Pelletier", "Éthan", "12/06/2008", "Allemand", "Italien"],
        [27, "Lavoie", "Liam", "25/08/2006", "Espagnol", "Anglais"],
        [28, "Bouchard", "Jules", "30/01/2007", "Italien", "Allemand"],
        [29, "Morin", "Charlotte", "03/10/2008", "Anglais", "Espagnol"],
        [30, "Lévesque", "Mason", "18/07/2006", "Allemand", "Italien"],
        [31, "Bergeron", "Lou", "09/05/2007", "Espagnol", "Anglais"],
        [32, "St-Pierre", "Eliott", "14/12/2008", "Italien", "Allemand"],
        [33, "Bélanger", "Zachary", "27/02/2006", "Anglais", "Espagnol"],
        [34, "Leblanc", "Rosie", "08/06/2008", "Allemand", "Italien"],
        [35, "Giroux", "Léon", "19/09/2007", "Espagnol", "Anglais"],
        [36, "Carrière", "Mila", "02/11/2006", "Italien", "Allemand"],
        [37, "Desjardins", "Maxime", "11/04/2007", "Anglais", "Espagnol"],
        [38, "Lefebvre", "Nolan", "24/08/2008", "Allemand", "Italien"],
        [39, "Perron", "Noémie", "01/03/2006", "Espagnol", "Anglais"],
        [40, "Dufour", "Charlie", "07/07/2007", "Italien", "Allemand"]
    ]
  3. Créer une fonction fusion_colonnes_incompletes(table1,table2,nom_fichier) qui :

    • prend en argument deux tables table1 et table2;
    • prend aussi en argument un string nom_fichier correspondant au nom du futur fichier au format csv généré;
    • fusionne les lignes en se fiant aux identifiants (première colonne). S'il manque des informations dans une ligne, il est possible de les trouver dans l'autre table.
    • sauvegarde la table issue de cette fusion dans un fichier csv dont le nom est passé en argument;
    • retourne la table issue de cette fusion.

    On pourra tester notre code sur les deux tables suivantes :

    table1=[
        [1, '', 'Hugo', '23/02/2008', 'Espagnol', 'Anglais'],
        [2, 'Lecomte', '', '', 'Anglais', 'Espagnol'],
        [3, 'Fournier', '', '', '', 'Anglais'],
        [4, 'Roux', '', '', '', ''],
        [5, 'Garcia', 'Eva', '', '', 'Anglais'],
        [6, '', 'Lucas', '', '', ''    ],
        [7, 'Petit', 'Manon', '26/09/2006', 'Allemand', 'Anglais'],
        [8, 'Garcia', 'Sarah', '', 'Anglais', ''],
        [9, '', 'Eva', '04/12/2006', '', 'Espagnol'],
        [10, 'Girard', '', '03/07/2007', 'Espagnol', 'Allemand'],
        [11, 'Girard', '', '', 'Allemand', 'Anglais'],
        [12, 'Martin', '', '18/01/2008', 'Espagnol', ''],
        [13, 'Durand', 'Sarah', '06/03/2007', '', 'Anglais'],
        [14, 'Andre', 'Eva', '04/09/2007', 'Espagnol', 'Allemand'],
        [15, 'Leroy', '', '', 'Anglais', ''],
        [16, '', '', '10/08/2006', 'Espagnol', 'Anglais'],
        [17, 'Petit', 'Léa', '16/12/2007', '', 'Allemand'],
        [18, 'Meyer', 'Louise', '14/04/2007', '', 'Anglais'],
        [19, 'Roux', '', '04/06/2008', '', 'Espagnol'],
        [20, 'Durand', '', '', 'Allemand', ''],
        [21, 'Durand', 'Adam', '15/09/2006', 'Anglais', 'Allemand'],
        [22, 'Lefevre', 'Manon', '02/11/2007', 'Espagnol', ''],
        [23, '', 'Alice', '23/05/2007', 'Anglais', 'Allemand'],
        [24, '', 'Noah', '23/06/2007', '', 'Espagnol'],
        [25, '', 'Théo', '22/03/2006', 'Espagnol', ''],
        [26, '', 'Nathan', '04/07/2007', 'Anglais', 'Allemand'],
        [27, 'Durand', 'Camille', '19/03/2008', '', ''],
        [28, '', '', '04/10/2008', '', ''],
        [29, 'Moreau', '', '06/08/2008', '', ''],
        [30, 'Dupont', '', '03/12/2008', '', 'Anglais'],
        [31, 'Wopiti','Jean-Louis', '03/11/2006','Anglais','Italien']
    ]
    
    
    table2=[
        [15, 'Leroy', 'Louis', '25/02/2007', '', ''],
        [23, 'Laurent', 'Alice', '23/05/2007', 'Anglais', 'Allemand'],
        [17, 'Petit', 'Léa', '', 'Anglais', ''],
        [27, 'Durand', 'Camille', '', 'Allemand', ''],
        [22, 'Lefevre', '', '', 'Espagnol', ''],
        [2, 'Lecomte', '', '', 'Anglais', ''],
        [1, 'Garcia', 'Hugo', '23/02/2008', 'Espagnol', ''],
        [9, 'Petit', 'Eva', '', 'Allemand', 'Espagnol'],
        [14, 'Andre', '', '04/09/2007', '', 'Allemand'],
        [13, '', '', '', '', 'Anglais'],
        [25, 'Lefevre', 'Théo', '22/03/2006', 'Espagnol', ''],
        [21, '', 'Adam', '15/09/2006', 'Anglais', 'Allemand'],
        [20, 'Durand', '', '13/03/2008', 'Allemand', 'Anglais'],
        [16, '', 'Noah', '10/08/2006', '', ''],
        [8, '', '', '19/09/2007', 'Anglais', 'Espagnol'],
        [19, 'Roux', 'Chloé', '04/06/2008', 'Anglais', 'Espagnol'],
        [4, 'Roux', '', '13/11/2006', '', ''],
        [10, 'Girard', '', '', 'Espagnol', 'Allemand'],
        [12, '', '', '18/01/2008', '', ''],
        [18, 'Meyer', 'Louise', '', 'Espagnol', 'Anglais'],
        [26, 'Durand', 'Nathan', '04/07/2007', '', 'Allemand'],
        [11, 'Girard', 'Louis', '', 'Allemand', 'Anglais'],
        [3, 'Fournier', 'Camille', '17/11/2007', 'Allemand', 'Anglais'],
        [28, 'Andre', 'Louis', '04/10/2008', 'Espagnol', ''],
        [7, 'Petit', '', '26/09/2006', 'Allemand', ''],
        [6, 'Moreau', 'Lucas', '28/04/2008', '', 'Anglais'],
        [30, 'Dupont', 'Hugo', '03/12/2008', 'Allemand', 'Anglais'],
        [5, '', 'Eva', '19/04/2006', 'Allemand', ''],
        [24, 'Andre', '', '23/06/2007', 'Allemand', 'Espagnol'],
        [29, 'Moreau', 'Camille', '06/08/2008', 'Espagnol', '']
    ]