69 lines
2.2 KiB
C#
69 lines
2.2 KiB
C#
using Jiaowu.Api.Domain.Academic;
|
|
|
|
namespace Jiaowu.Api.Infrastructure.Grades;
|
|
|
|
public static class GradeCalculator
|
|
{
|
|
public static bool AreWeightsValid(
|
|
decimal regularWeight,
|
|
decimal finalWeight,
|
|
IEnumerable<GradeItem> items) =>
|
|
regularWeight is >= 0 and <= 100 &&
|
|
finalWeight is >= 0 and <= 100 &&
|
|
items.All(item => item.Weight is >= 0 and <= 100) &&
|
|
regularWeight + finalWeight + items.Sum(item => item.Weight) == 100;
|
|
|
|
public static decimal? CalculateTotal(
|
|
decimal? regularScore,
|
|
decimal? finalScore,
|
|
IReadOnlyCollection<GradeItemScore> itemScores,
|
|
decimal regularWeight,
|
|
decimal finalWeight,
|
|
IReadOnlyCollection<GradeItem> items,
|
|
GradeExamStatus examStatus)
|
|
{
|
|
if (examStatus != GradeExamStatus.Normal && examStatus != GradeExamStatus.Makeup)
|
|
return null;
|
|
|
|
if (regularWeight > 0 && !regularScore.HasValue)
|
|
return null;
|
|
if (finalWeight > 0 && !finalScore.HasValue)
|
|
return null;
|
|
|
|
var itemWeightById = items.ToDictionary(item => item.Id, item => item.Weight);
|
|
foreach (var itemScore in itemScores)
|
|
{
|
|
if (itemWeightById.TryGetValue(itemScore.GradeItemId, out var weight) &&
|
|
weight > 0 && !itemScore.Score.HasValue)
|
|
return null;
|
|
}
|
|
|
|
var total = (regularScore ?? 0) * regularWeight / 100;
|
|
foreach (var itemScore in itemScores)
|
|
{
|
|
if (itemWeightById.TryGetValue(itemScore.GradeItemId, out var weight))
|
|
total += (itemScore.Score ?? 0) * weight / 100;
|
|
}
|
|
total += (finalScore ?? 0) * finalWeight / 100;
|
|
return Math.Round(total, 1, MidpointRounding.AwayFromZero);
|
|
}
|
|
|
|
public static decimal? CalculateGradePoint(decimal? totalScore)
|
|
{
|
|
if (!totalScore.HasValue) return null;
|
|
return totalScore.Value switch
|
|
{
|
|
>= 90 => 4.0m,
|
|
>= 85 => 3.7m,
|
|
>= 82 => 3.3m,
|
|
>= 78 => 3.0m,
|
|
>= 75 => 2.7m,
|
|
>= 72 => 2.3m,
|
|
>= 68 => 2.0m,
|
|
>= 64 => 1.5m,
|
|
>= 60 => 1.0m,
|
|
_ => 0m
|
|
};
|
|
}
|
|
}
|