Adapt dynamic question difficulty to learner Elo
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
using QuestionsApi.Models;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace QuestionsApi.Services;
|
||||
|
||||
public static class DynamicBlueprintResolver
|
||||
{
|
||||
private static readonly JsonSerializerOptions Json = new(JsonSerializerDefaults.Web);
|
||||
|
||||
public static List<DynamicQuestionBlueprint> ResolveAll(IEnumerable<DynamicQuestionBlueprint> source)
|
||||
{
|
||||
var all = source.ToList();
|
||||
var resolved = new List<DynamicQuestionBlueprint>();
|
||||
foreach (var blueprint in all.OrderBy(value => value.Version))
|
||||
{
|
||||
if (blueprint.BaseBlueprintVersion <= 0)
|
||||
{
|
||||
resolved.Add(blueprint);
|
||||
continue;
|
||||
}
|
||||
var baseBlueprint = resolved.FirstOrDefault(value =>
|
||||
value.ExternalId == blueprint.ExternalId
|
||||
&& value.Version == blueprint.BaseBlueprintVersion)
|
||||
?? throw new InvalidDataException(
|
||||
$"{blueprint.ExternalId} v{blueprint.Version} base version {blueprint.BaseBlueprintVersion} not found");
|
||||
var materialized = Clone(baseBlueprint);
|
||||
materialized.Id = null;
|
||||
materialized.Version = blueprint.Version;
|
||||
materialized.BaseBlueprintVersion = blueprint.BaseBlueprintVersion;
|
||||
materialized.QualityStandardVersion = blueprint.QualityStandardVersion;
|
||||
materialized.IsPublished = blueprint.IsPublished;
|
||||
materialized.CaseFamilies = blueprint.CaseFamilies.Select(overlay =>
|
||||
{
|
||||
var baseFamily = baseBlueprint.CaseFamilies.FirstOrDefault(value => value.Id == overlay.BaseFamilyId)
|
||||
?? throw new InvalidDataException(
|
||||
$"{blueprint.ExternalId} v{blueprint.Version} base family {overlay.BaseFamilyId} not found");
|
||||
var family = Clone(baseFamily);
|
||||
family.Id = overlay.Id;
|
||||
family.BaseFamilyId = overlay.BaseFamilyId;
|
||||
family.DifficultyTier = overlay.DifficultyTier;
|
||||
family.NominalElo = overlay.NominalElo;
|
||||
if (!string.IsNullOrWhiteSpace(family.LeadIn)
|
||||
&& family.StemTemplate.EndsWith(family.LeadIn, StringComparison.Ordinal))
|
||||
family.StemTemplate = family.StemTemplate[..^family.LeadIn.Length].TrimEnd();
|
||||
if (!string.IsNullOrWhiteSpace(overlay.StemTemplate))
|
||||
family.StemTemplate = $"{family.StemTemplate} {overlay.StemTemplate}".Trim();
|
||||
if (!string.IsNullOrWhiteSpace(overlay.LeadIn))
|
||||
family.LeadIn = overlay.LeadIn;
|
||||
if (overlay.Distractors.Count > 0)
|
||||
family.Distractors = overlay.Distractors;
|
||||
return family;
|
||||
}).ToList();
|
||||
resolved.Add(materialized);
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
private static T Clone<T>(T value) =>
|
||||
JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(value, Json), Json)
|
||||
?? throw new InvalidOperationException("Blueprint clone failed.");
|
||||
}
|
||||
Reference in New Issue
Block a user