Initial
This commit is contained in:
90
LehrerApp.Core/Services/GradingService.cs
Normal file
90
LehrerApp.Core/Services/GradingService.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using LehrerApp.Core.Models;
|
||||
|
||||
namespace LehrerApp.Core.Services;
|
||||
|
||||
public class GradingService
|
||||
{
|
||||
/// <summary>
|
||||
/// Berechnet die Note aus Punkten anhand des Notenschlüssels der Klausur.
|
||||
/// </summary>
|
||||
public string CalculateGrade(double achieved, double maximum, List<GradingKeyEntry> key)
|
||||
{
|
||||
if (maximum <= 0) return "-";
|
||||
var percent = achieved / maximum * 100.0;
|
||||
|
||||
return key
|
||||
.OrderByDescending(k => k.MinPercent)
|
||||
.FirstOrDefault(k => percent >= k.MinPercent)
|
||||
?.Grade ?? key.OrderBy(k => k.MinPercent).First().Grade;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Standardnotenschlüssel 1–6 nach NRW-Schema (anpassbar).
|
||||
/// </summary>
|
||||
public static List<GradingKeyEntry> DefaultKey1To6() =>
|
||||
[
|
||||
new() { Grade = "1", MinPercent = 87.5 },
|
||||
new() { Grade = "2", MinPercent = 75.0 },
|
||||
new() { Grade = "3", MinPercent = 62.5 },
|
||||
new() { Grade = "4", MinPercent = 50.0 },
|
||||
new() { Grade = "5", MinPercent = 25.0 },
|
||||
new() { Grade = "6", MinPercent = 0.0 },
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Standardnotenschlüssel 0–15 Punkte (Oberstufe).
|
||||
/// </summary>
|
||||
public static List<GradingKeyEntry> DefaultKey0To15() =>
|
||||
[
|
||||
new() { Grade = "15", MinPercent = 95.0 },
|
||||
new() { Grade = "14", MinPercent = 90.0 },
|
||||
new() { Grade = "13", MinPercent = 85.0 },
|
||||
new() { Grade = "12", MinPercent = 80.0 },
|
||||
new() { Grade = "11", MinPercent = 75.0 },
|
||||
new() { Grade = "10", MinPercent = 70.0 },
|
||||
new() { Grade = "9", MinPercent = 65.0 },
|
||||
new() { Grade = "8", MinPercent = 60.0 },
|
||||
new() { Grade = "7", MinPercent = 55.0 },
|
||||
new() { Grade = "6", MinPercent = 50.0 },
|
||||
new() { Grade = "5", MinPercent = 45.0 },
|
||||
new() { Grade = "4", MinPercent = 40.0 },
|
||||
new() { Grade = "3", MinPercent = 33.0 },
|
||||
new() { Grade = "2", MinPercent = 27.0 },
|
||||
new() { Grade = "1", MinPercent = 20.0 },
|
||||
new() { Grade = "0", MinPercent = 0.0 },
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Berechnet den Notendurchschnitt aus einer Liste von Notenwerten (1-6 System).
|
||||
/// </summary>
|
||||
public double AverageGrade1To6(List<string> grades)
|
||||
{
|
||||
var numeric = grades
|
||||
.Select(g => int.TryParse(g, out var n) ? (int?)n : null)
|
||||
.Where(n => n.HasValue)
|
||||
.Select(n => n!.Value)
|
||||
.ToList();
|
||||
|
||||
return numeric.Count == 0 ? 0 : numeric.Average();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Berechnet den Notendurchschnitt aus gewichteten Noten.
|
||||
/// </summary>
|
||||
public double WeightedAverage(List<(string Grade, double Weight)> grades)
|
||||
{
|
||||
var numeric = grades
|
||||
.Select(g => (
|
||||
Value: int.TryParse(g.Grade, out var n) ? (int?)n : null,
|
||||
g.Weight))
|
||||
.Where(g => g.Value.HasValue)
|
||||
.ToList();
|
||||
|
||||
if (numeric.Count == 0) return 0;
|
||||
|
||||
var totalWeight = numeric.Sum(g => g.Weight);
|
||||
var weightedSum = numeric.Sum(g => g.Value!.Value * g.Weight);
|
||||
|
||||
return totalWeight == 0 ? 0 : weightedSum / totalWeight;
|
||||
}
|
||||
}
|
||||
48
LehrerApp.Core/Services/SchoolYearService.cs
Normal file
48
LehrerApp.Core/Services/SchoolYearService.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace LehrerApp.Core.Services;
|
||||
|
||||
public class SchoolYearService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gibt das aktuelle Schuljahr zurück, z.B. "2024/25".
|
||||
/// Schuljahr beginnt am 1. August.
|
||||
/// </summary>
|
||||
public string CurrentSchoolYear()
|
||||
{
|
||||
var now = DateTime.Today;
|
||||
var startYear = now.Month >= 8 ? now.Year : now.Year - 1;
|
||||
return FormatSchoolYear(startYear);
|
||||
}
|
||||
|
||||
public string FormatSchoolYear(int startYear) =>
|
||||
$"{startYear}/{(startYear + 1) % 100:D2}";
|
||||
|
||||
/// <summary>
|
||||
/// Gibt den Beginn des Schuljahres zurück (1. August).
|
||||
/// </summary>
|
||||
public DateOnly SchoolYearStart(string schoolYear)
|
||||
{
|
||||
var year = int.Parse(schoolYear.Split('/')[0]);
|
||||
return new DateOnly(year, 8, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gibt das Ende des Schuljahres zurück (31. Juli des Folgejahres).
|
||||
/// </summary>
|
||||
public DateOnly SchoolYearEnd(string schoolYear)
|
||||
{
|
||||
var year = int.Parse(schoolYear.Split('/')[0]) + 1;
|
||||
return new DateOnly(year, 7, 31);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gibt die letzten N Schuljahre zurück (für Dropdowns).
|
||||
/// </summary>
|
||||
public List<string> RecentSchoolYears(int count = 5)
|
||||
{
|
||||
var now = DateTime.Today;
|
||||
var currentStart = now.Month >= 8 ? now.Year : now.Year - 1;
|
||||
return Enumerable.Range(0, count)
|
||||
.Select(i => FormatSchoolYear(currentStart - i))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user