namespace AIStudio.Assistants.ModelComparison;
///
/// How often the user's own vote came out on each side across a batch of runs.
///
///
/// Counted in First/Second terms, never in columns, for the same reason as
/// : the column a model stood in was drawn fresh for
/// every run. A run the user never voted on -- the batch was left before reaching it -- is left out
/// of every count, the same way an unanswered judge is left out of the judge tally.
///
public sealed record ModelComparisonBatchVoteSummary
{
public required int TotalRunCount { get; init; }
public required int ScoredRunCount { get; init; }
public required int FirstModelWins { get; init; }
public required int SecondModelWins { get; init; }
public required int Ties { get; init; }
///
/// Tallies the user's own votes across a batch, alongside its entries. Never throws: a run with
/// no vote at its index is simply left out of the count.
///
/// The runs of the batch, each with its own presentation order.
/// The user's vote for each entry, at the same index. Null means not voted on.
public static ModelComparisonBatchVoteSummary From(IReadOnlyList entries, IReadOnlyList votes)
{
var firstModelWins = 0;
var secondModelWins = 0;
var ties = 0;
for (var index = 0; index < entries.Count; index++)
{
if (index >= votes.Count || votes[index] is not { } vote)
continue;
switch (entries[index].PresentationOrder.ToModelChoice(vote))
{
case ModelComparisonModelChoice.FIRST:
firstModelWins++;
break;
case ModelComparisonModelChoice.SECOND:
secondModelWins++;
break;
case ModelComparisonModelChoice.TIE:
ties++;
break;
}
}
return new ModelComparisonBatchVoteSummary
{
TotalRunCount = entries.Count,
ScoredRunCount = firstModelWins + secondModelWins + ties,
FirstModelWins = firstModelWins,
SecondModelWins = secondModelWins,
Ties = ties,
};
}
}