TP 2 : Manipulation de Données Avancée (LINQ)
🌐
🔍 100%
👁️

TP 2 : Manipulation de Données Avancée (LINQ)

Module : Programmation .Net C#

Niveau : 4ème DS-2025/2026

École : Ecole Polytechnique de Sousse

Objectif

Remplacer les boucles manuelles par une programmation déclarative (LINQ). Apprendre à filtrer, trier, transformer et agréger des données de manière concise et lisible.

Activité 1 : Setup et "Records"

Pour représenter de la donnée pure (sans comportement complexe), C# 9 a introduit les Records. C'est plus léger qu'une Classe et c'est immuable (thread-safe, idéal pour la Data).

  1. Créez un nouveau projet Console : dotnet new console -n DataLab2
  2. Dans Program.cs, définissez ce record à la fin du fichier :
// Un 'record' définit le constructeur et les propriétés en une seule ligne.
// C'est l'équivalent d'une dataclass en Python.
public record Transaction(int Id, string Categorie, double Montant, DateTime Date, string Pays);

3. Écrivez cette fonction pour générer un Dataset de test (Mock Data) :

// Fonction locale pour générer des données
List<Transaction> GetFakeData()
{
    return new List<Transaction>
    {
        new(1, "Hardware", 1200.50, new DateTime(2023, 1, 15), "France"),
        new(2, "Software", 300.00, new DateTime(2023, 1, 16), "USA"),
        new(3, "Service", 150.00, new DateTime(2023, 1, 17), "France"),
        new(4, "Hardware", 899.99, new DateTime(2023, 1, 20), "Allemagne"),
        new(5, "Software", 50.00, new DateTime(2023, 1, 20), "France")
    };
}

var data = GetFakeData();

Activité 2 : Filtrage et Tri (Where, OrderBy)

Objectif : Trouver les transactions en "France" triées par montant décroissant.

// Syntaxe fluide (Method Syntax)
var frenchTransactions = data
    .Where(t => t.Pays == "France")       // Filtre
    .OrderByDescending(t => t.Montant);     // Tri

Console.WriteLine("--- Transactions France ---");
foreach (var t in frenchTransactions)
{
    Console.WriteLine(t);
}
--- Transactions France --- Transaction { Id = 1, Categorie = "Hardware", Montant = 1200.5, Date = 15/01/2023 00:00:00, Pays = "France" } Transaction { Id = 3, Categorie = "Service", Montant = 150, Date = 17/01/2023 00:00:00, Pays = "France" } Transaction { Id = 5, Categorie = "Software", Montant = 50, Date = 20/01/2023 00:00:00, Pays = "France" }

Activité 3 : Projection (Select)

Objectif : Créer une liste simplifiée contenant uniquement le nom de la catégorie et le montant formaté. Nous utilisons ici un Type Anonyme (new { ... }).

var rapport = data.Select(t => new {
    Nom = t.Categorie,
    Info = $"Montant: {t.Montant}€"
});

Console.WriteLine("\n--- Rapport Simplifié ---");
foreach (var ligne in rapport)
{
    Console.WriteLine($"{ligne.Nom} -> {ligne.Info}");
}

Activité 4 : Agrégation (Sum, Average, Max)

Objectif : Calculer des statistiques globales.

double total = data.Sum(t => t.Montant);
double moyenne = data.Average(t => t.Montant);

Console.WriteLine("\n--- Stats ---");
Console.WriteLine($"Total Ventes : {total}€");
Console.WriteLine($"Moyenne : {moyenne:F2}€");

Activité 5 : Regroupement (GroupBy)

Objectif : Grouper les transactions par Pays et calculer le total par pays.

var statsParPays = data
    .GroupBy(t => t.Pays) // La clé sera le Pays
    .Select(g => new {
        Pays = g.Key,
        Total = g.Sum(t => t.Montant),
        Nombre = g.Count()
    });

Console.WriteLine("\n--- Par Pays ---");
foreach (var stat in statsParPays)
{
    Console.WriteLine($"Pays: {stat.Pays}, Total: {stat.Total} ({stat.Nombre} ventes)");
}
--- Par Pays --- Pays: France, Total: 1400.5 (3 ventes) Pays: USA, Total: 300 (1 ventes) Pays: Allemagne, Total: 899.99 (1 ventes)

Exercice d'Application : Le Pipeline de Données

Scénario : Votre manager vous envoie une chaîne de caractères "sale" (format CSV mal fichu) et vous demande de trouver le Top 3 des produits "High-Tech" les moins chers.

Données brutes :

string rawCsv = "Laptop, 900; Souris, 25; Clavier, 45; Ecran, 150; CleUSB, 10; Webcam, 3000; Cable, 5";
// Note: "Webcam, 3000" est une erreur de saisie (aberration)

Consignes :

  1. Découpez la chaîne (Split).
  2. Nettoyez les données (Trim, Parse).
  3. Filtrez les prix aberrants (> 1000€).
  4. Triez par prix croissant.
  5. Prenez les 3 premiers.
  6. Affichez le résultat.
Synthèse LINQ :
Navigation <div class="nav-buttons"> <button class="nav-btn" onclick="navigateToChapter(2)"> ← Chapitre 2 </button> <span></span> </div>

Lab 2: Advanced Data Manipulation (LINQ)

Module: .Net C# Programming

Level: 4th Year DS-2025/2026

School: Ecole Polytechnique de Sousse

Objective

Replace manual loops with declarative programming (LINQ). Learn to filter, sort, transform, and aggregate data concisely and readably.

Activity 1: Setup and "Records"

To represent pure data (without complex behavior), C# 9 introduced Records. It's lighter than a Class and is immutable (thread-safe, ideal for Data).

  1. Create a new Console project: dotnet new console -n DataLab2
  2. In Program.cs, define this record at the end of the file:
// A 'record' defines the constructor and properties in a single line.
// It's equivalent to a dataclass in Python.
public record Transaction(int Id, string Category, double Amount, DateTime Date, string Country);

3. Write this function to generate a Test Dataset (Mock Data):

// Local function to generate data
List<Transaction> GetFakeData()
{
    return new List<Transaction>
    {
        new(1, "Hardware", 1200.50, new DateTime(2023, 1, 15), "France"),
        new(2, "Software", 300.00, new DateTime(2023, 1, 16), "USA"),
        new(3, "Service", 150.00, new DateTime(2023, 1, 17), "France"),
        new(4, "Hardware", 899.99, new DateTime(2023, 1, 20), "Germany"),
        new(5, "Software", 50.00, new DateTime(2023, 1, 20), "France")
    };
}

var data = GetFakeData();

Activity 2: Filtering and Sorting (Where, OrderBy)

Goal: Find transactions in "France" sorted by amount descending.

// Fluent Syntax (Method Syntax)
var frenchTransactions = data
    .Where(t => t.Country == "France")    // Filter
    .OrderByDescending(t => t.Amount);      // Sort

Console.WriteLine("--- France Transactions ---");
foreach (var t in frenchTransactions)
{
    Console.WriteLine(t);
}
--- France Transactions --- Transaction { Id = 1, Category = "Hardware", Amount = 1200.5, Date = 15/01/2023 00:00:00, Country = "France" } Transaction { Id = 3, Category = "Service", Amount = 150, Date = 17/01/2023 00:00:00, Country = "France" } Transaction { Id = 5, Category = "Software", Amount = 50, Date = 20/01/2023 00:00:00, Country = "France" }

Activity 3: Projection (Select)

Goal: Create a simplified list containing only the category name and the formatted amount. We use an Anonymous Type here (new { ... }).

var report = data.Select(t => new {
    Name = t.Category,
    Info = $"Amount: {t.Amount}€"
});

Console.WriteLine("\n--- Simplified Report ---");
foreach (var line in report)
{
    Console.WriteLine($"{line.Name} -> {line.Info}");
}

Activity 4: Aggregation (Sum, Average, Max)

Goal: Calculate global statistics.

double total = data.Sum(t => t.Amount);
double average = data.Average(t => t.Amount);

Console.WriteLine("\n--- Stats ---");
Console.WriteLine($"Total Sales: {total}€");
Console.WriteLine($"Average: {average:F2}€");

Activity 5: Grouping (GroupBy)

Goal: Group transactions by Country and calculate total per country.

var statsByCountry = data
    .GroupBy(t => t.Country) // The key will be the Country
    .Select(g => new {
        Country = g.Key,
        Total = g.Sum(t => t.Amount),
        Count = g.Count()
    });

Console.WriteLine("\n--- By Country ---");
foreach (var stat in statsByCountry)
{
    Console.WriteLine($"Country: {stat.Country}, Total: {stat.Total} ({stat.Count} sales)");
}

Application Exercise: The Data Pipeline

Scenario: Your manager sends you a "dirty" string (badly formatted CSV) and asks you to find the Top 3 cheapest "High-Tech" products.

Raw Data:

string rawCsv = "Laptop, 900; Mouse, 25; Keyboard, 45; Screen, 150; USBKey, 10; Webcam, 3000; Cable, 5";
// Note: "Webcam, 3000" is a data entry error (outlier)

Instructions:

  1. Split the string (Split).
  2. Clean the data (Trim, Parse).
  3. Filter out outlier prices (> 1000€).
  4. Sort by ascending price.
  5. Take the first 3.
  6. Display the result.
LINQ Summary:

🎙️ Sélectionner une voix

🎙️ Select a voice