Some checks failed
Automated Container Build / build-and-push (push) Failing after 7s
41 lines
1.1 KiB
TypeScript
41 lines
1.1 KiB
TypeScript
type OptionLite = { id: string; isCorrect: boolean };
|
|
type QuestionLite = {
|
|
id: string;
|
|
type: "MULTIPLE_CHOICE" | "SATA";
|
|
options: OptionLite[];
|
|
};
|
|
|
|
export function scoreQuestion(
|
|
question: QuestionLite,
|
|
selectedIds: string[]
|
|
): number {
|
|
const correctIds = question.options
|
|
.filter((o) => o.isCorrect)
|
|
.map((o) => o.id);
|
|
|
|
if (question.type === "MULTIPLE_CHOICE") {
|
|
return correctIds.includes(selectedIds[0]) ? 1 : 0;
|
|
}
|
|
|
|
// SATA: partial credit
|
|
const correctSelected = selectedIds.filter((id) =>
|
|
correctIds.includes(id)
|
|
).length;
|
|
const incorrectSelected = selectedIds.filter(
|
|
(id) => !correctIds.includes(id)
|
|
).length;
|
|
return Math.max(0, correctSelected - incorrectSelected) / correctIds.length;
|
|
}
|
|
|
|
export function scoreQuiz(
|
|
questions: QuestionLite[],
|
|
answers: Record<string, string[]>
|
|
) {
|
|
let total = 0;
|
|
const perQuestion = questions.map((q) => {
|
|
const points = scoreQuestion(q, answers[q.id] ?? []);
|
|
total += points;
|
|
return { questionId: q.id, points };
|
|
});
|
|
return { total, maxScore: questions.length, perQuestion };
|
|
}
|