Génération de rapports
Fait partie de la section Logique & Flux du Journey C# de Coddy. Leçon 44 sur 66.
Défi
MoyenMaintenant que nous avons le système de notation, créons un module de rapports pour générer des rapports formatés sur les performances des étudiants. Créez une classe appelée ReportGenerator avec ces méthodes :
GenerateStudentReport(int[][] scoreGrid, int studentIndex): renvoie une chaîne formatée présentant les notes, la moyenne et la note alphabétique d’un étudiant donné.- Format : "Student #X | Average: YY.Y | Grade: Z\nAssignment scores: S1, S2, S3, ..." où S1, S2, S3, ... sont les notes numériques de chaque devoir.
- Pour les devoirs non notés (note de -1), affichez "N/A" à la place de la note.
- Renvoie "Invalid student index" pour tout index d’étudiant invalide.
GenerateClassSummary(int[][] scoreGrid): renvoie une chaîne formatée résumant les performances de la classe.- Format : "Class Summary\nTotal Students: X\nClass Average: YY.Y\nGrade Distribution: A: #, B: #, C: #, D: #, F: #"
GenerateAssignmentReport(int[][] scoreGrid, int assignmentIndex): renvoie une chaîne formatée contenant les statistiques d’un devoir donné.- Format : "Assignment #X | Average: YY.Y | Completion Rate: Z%"
- Le taux de réalisation correspond au pourcentage d’étudiants ayant une note pour ce devoir (différente de -1).
- Renvoie "Invalid assignment index" pour tout index de devoir invalide.
Essayez vous-même
using System; // Ne supprimez pas cette ligne
using System.Text;
public class ReportGenerator
{
public static string GenerateStudentReport(int[][] scoreGrid, int studentIndex)
{
// Écrivez votre code ici
}
public static string GenerateClassSummary(int[][] scoreGrid)
{
// Écrivez votre code ici
}
public static string GenerateAssignmentReport(int[][] scoreGrid, int assignmentIndex)
{
// Écrivez votre code ici
}
}
// Requis pour les tests - ne pas modifier
public class DataCollector
{
public static int[][] CreateScoreGrid(int students, int assignments)
{
int[][] scoreGrid = new int[students][];
for (int i = 0; i < students; i++)
{
scoreGrid[i] = new int[assignments];
}
return scoreGrid;
}
public static bool ValidateScore(int score)
{
return score >= 0 && score <= 100;
}
public static int[][] PopulateWithDefaultValues(int[][] scoreGrid)
{
for (int i = 0; i < scoreGrid.Length; i++)
{
for (int j = 0; j < scoreGrid[i].Length; j++)
{
scoreGrid[i][j] = -1;
}
}
return scoreGrid;
}
}
public class DataEntry
{
public static int SetStudentScore(int[][] scoreGrid, int studentIndex, int assignmentIndex, int score)
{
// Vérifier les indices hors limites
if (studentIndex < 0 || studentIndex >= scoreGrid.Length ||
assignmentIndex < 0 || assignmentIndex >= scoreGrid[studentIndex].Length)
{
return -1;
}
// Valider le score
if (!DataCollector.ValidateScore(score))
{
return -2;
}
// Définir le score
scoreGrid[studentIndex][assignmentIndex] = score;
return 0;
}
public static int UpdateAllScores(int[][] scoreGrid, int[] studentIndices, int assignmentIndex, int score)
{
int successCount = 0;
for (int i = 0; i < studentIndices.Length; i++)
{
int result = SetStudentScore(scoreGrid, studentIndices[i], assignmentIndex, score);
if (result == 0)
{
successCount++;
}
}
return successCount;
}
}
public class DataAnalyzer
{
public static double CalculateStudentAverage(int[][] scoreGrid, int studentIndex)
{
// Check if student index is valid
if (studentIndex < 0 || studentIndex >= scoreGrid.Length)
{
return -1;
}
int sum = 0;
int count = 0;
// Calculer la somme des scores valides
for (int j = 0; j < scoreGrid[studentIndex].Length; j++)
{
int score = scoreGrid[studentIndex][j];
if (score != -1) // Ignorer les devoirs non notés
{
sum += score;
count++;
}
}
// Retourner la moyenne ou 0 s'il n'y a pas de scores valides
return count > 0 ? (double)sum / count : 0;
}
public static double CalculateAssignmentAverage(int[][] scoreGrid, int assignmentIndex)
{
// Vérifier s'il y a des étudiants
if (scoreGrid.Length == 0)
{
return -1;
}
// Check if assignment index is valid
if (assignmentIndex < 0 || assignmentIndex >= scoreGrid[0].Length)
{
return -1;
}
int sum = 0;
int count = 0;
// Calculer la somme des scores valides pour le devoir
for (int i = 0; i < scoreGrid.Length; i++)
{
if (assignmentIndex < scoreGrid[i].Length)
{
int score = scoreGrid[i][assignmentIndex];
if (score != -1) // Ignorer les devoirs non notés
{
sum += score;
count++;
}
}
}
// Retourner la moyenne ou 0 s'il n'y a pas de scores valides
return count > 0 ? (double)sum / count : 0;
}
public static int[] FindHighestScore(int[][] scoreGrid)
{
int highestStudentIndex = 0;
int highestAssignmentIndex = 0;
int highestScore = -1;
// Rechercher le score le plus élevé
for (int i = 0; i < scoreGrid.Length; i++)
{
for (int j = 0; j < scoreGrid[i].Length; j++)
{
int currentScore = scoreGrid[i][j];
if (currentScore > highestScore)
{
highestScore = currentScore;
highestStudentIndex = i;
highestAssignmentIndex = j;
}
}
}
return new int[] { highestStudentIndex, highestAssignmentIndex, highestScore };
}
}
public class GradingSystem
{
public static string ConvertToLetterGrade(double score)
{
if (score < 0 || score > 100)
{
return "N/A";
}
else if (score >= 90)
{
return "A";
}
else if (score >= 80)
{
return "B";
}
else if (score >= 70)
{
return "C";
}
else if (score >= 60)
{
return "D";
}
else
{
return "F";
}
}
public static string GetStudentGrade(int[][] scoreGrid, int studentIndex)
{
double average = DataAnalyzer.CalculateStudentAverage(scoreGrid, studentIndex);
if (average == -1)
{
return "N/A";
}
return ConvertToLetterGrade(average);
}
public static int[] GetClassDistribution(int[][] scoreGrid)
{
int[] distribution = new int[5]; // [A, B, C, D, F]
for (int i = 0; i < scoreGrid.Length; i++)
{
string grade = GetStudentGrade(scoreGrid, i);
switch (grade)
{
case "A":
distribution[0]++;
break;
case "B":
distribution[1]++;
break;
case "C":
distribution[2]++;
break;
case "D":
distribution[3]++;
break;
case "F":
distribution[4]++;
break;
// N/A grades are not counted in the distribution
}
}
return distribution;
}
}Toutes les leçons de Logique & Flux
1Tableaux multidimensionnels
Bases des tableaux 2DDéclaration et initialisation en 2DAccès aux éléments d'un tableau 2DBoucles imbriquées et tableaux 2DTableaux irréguliersOpérations matricielles courantesRécapitulatif - Multidimensionnel4Techniques de contrôle de flux
Retours anticipésClauses de gardeInstructions de saut (goto)Break et ContinueAplatir les conditionnelles imbriquées2Prise de décision avancée
Conditions multiplesLogique booléenne complexeComparaison If vs SwitchInstructions Switch imbriquéesRécapitulatif - Décisions avancées5Gestion des exceptions
Bases du Try-CatchTypes d'exceptionsBlocs Catch multiplesManipulation de fichiersLe bloc FinallyUsing vs Try-FinallyExceptions personnaliséesRécapitulatif - Gestion des erreurs8Système d'analyse de données
Configuration de la collecte de donnéesLogique de saisie de données3Améliorations des boucles
Performance des bouclesItération de structures complexesChaque type de boucleRefactorisation des bouclesRécapitulatif - Boucles optimisées6Gestion des valeurs nulles
Les bases des références nullesTypes valeur nullablesPatterns de vérification de nullitéProgrammation défensiveRécapitulatif - Null SafetyEntraînez-vous par vous-même : Compilateur C# en ligne