Module : Programmation .Net C#
Niveau : 4ème DS-2025/2026
École : Ecole Polytechnique de Sousse
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.
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).
dotnet new console -n DataLab2Program.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();
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);
}
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}");
}
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}€");
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)");
}
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 :
Split).Synthèse LINQ :Navigation <div class="nav-buttons"> <button class="nav-btn" onclick="navigateToChapter(2)"> ← Chapitre 2 </button> <span></span> </div>
- Immuabilité : LINQ ne modifie jamais la liste d'origine, il crée une nouvelle séquence.
- Lazy Evaluation (Différé) : La requête ne s'exécute que lorsqu'on fait un
foreach, un.ToList()ou un calcul (Sum).
Module: .Net C# Programming
Level: 4th Year DS-2025/2026
School: Ecole Polytechnique de Sousse
Replace manual loops with declarative programming (LINQ). Learn to filter, sort, transform, and aggregate data concisely and readably.
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).
dotnet new console -n DataLab2Program.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();
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);
}
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}");
}
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}€");
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)");
}
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:
Split).LINQ Summary:
- Immutability: LINQ never modifies the original list, it creates a new sequence.
- Lazy Evaluation (Deferred): The query only executes when you perform a
foreach, a.ToList()or a calculation (Sum).