Add variable question distractor pools

This commit is contained in:
hz
2026-07-13 10:15:05 -05:00
parent f2c59388eb
commit 93154d5925
24 changed files with 1040 additions and 247 deletions
@@ -34,13 +34,16 @@ public class QuestionAttemptStore
string userId,
string choiceId,
bool isCorrect,
bool isSkip = false)
bool isSkip = false,
IReadOnlyCollection<string>? presentedChoiceIds = null)
{
var attempt = new QuestionAttempt
{
QuestionExternalId = questionExternalId,
UserId = userId,
ChoiceId = choiceId,
PresentedChoiceIds = presentedChoiceIds?.ToList() ?? [],
TracksPresentation = presentedChoiceIds is { Count: > 0 },
IsCorrect = isCorrect,
IsSkip = isSkip,
CounterBucket = GetCounterBucket(userId),
@@ -62,49 +65,6 @@ public class QuestionAttemptStore
}
}
public async Task<Dictionary<string, int>> GetPercentagesForQuestionAsync(string questionExternalId)
{
var results = await GetPercentagesByQuestionAsync([questionExternalId]);
return results.GetValueOrDefault(questionExternalId, []);
}
public async Task<Dictionary<string, Dictionary<string, int>>> GetPercentagesByQuestionAsync(IEnumerable<string> questionExternalIds)
{
var ids = questionExternalIds.Where(id => !string.IsNullOrWhiteSpace(id)).Distinct().ToList();
if (ids.Count == 0)
return [];
var totals = await _col.Aggregate()
.Match(a => ids.Contains(a.QuestionExternalId) && !a.IsSkip)
.Group(
attempt => new { attempt.QuestionExternalId, attempt.ChoiceId },
group => new QuestionAttemptCounterTotal
{
Key = new QuestionChoiceCounterKey
{
QuestionExternalId = group.Key.QuestionExternalId,
ChoiceId = group.Key.ChoiceId
},
Count = group.Sum(_ => 1L)
})
.ToListAsync();
var output = new Dictionary<string, Dictionary<string, int>>();
foreach (var group in totals.GroupBy(total => total.Key.QuestionExternalId))
{
var total = group.Sum(item => item.Count);
if (total == 0)
continue;
output[group.Key] = group
.ToDictionary(
item => item.Key.ChoiceId,
item => (int)Math.Round(item.Count * 100.0 / total));
}
return output;
}
public Task<List<string>> GetActiveQuestionIdsAsync(DateTime sinceUtc) =>
_col.Distinct(
attempt => attempt.QuestionExternalId,