can get exact answers

This commit is contained in:
2025-10-22 13:18:18 -06:00
parent d9f7e7b3e9
commit b53948db72
10 changed files with 97 additions and 95 deletions

View File

@@ -1,22 +1,7 @@
import { z } from "zod";
import { LocalQuizQuestion, zodLocalQuizQuestion } from "./localQuizQuestion";
import { quizMarkdownUtils } from "./utils/quizMarkdownUtils";
import { zodLocalQuizQuestion } from "./localQuizQuestion";
import { IModuleItem } from "@/features/local/modules/IModuleItem";
export interface LocalQuiz extends IModuleItem {
name: string;
description: string;
password?: string;
lockAt?: string; // ISO 8601 date string
dueAt: string; // ISO 8601 date string
shuffleAnswers: boolean;
showCorrectAnswers: boolean;
oneQuestionAtATime: boolean;
localAssignmentGroupName?: string;
allowedAttempts: number;
questions: LocalQuizQuestion[];
}
export const zodLocalQuiz = z.object({
name: z.string(),
description: z.string(),
@@ -31,7 +16,4 @@ export const zodLocalQuiz = z.object({
questions: zodLocalQuizQuestion.array(),
});
export const localQuizMarkdownUtils = {
parseMarkdown: quizMarkdownUtils.parseMarkdown,
toMarkdown: quizMarkdownUtils.toMarkdown,
};
export interface LocalQuiz extends IModuleItem, z.infer<typeof zodLocalQuiz> {}

View File

@@ -1,40 +1,30 @@
import { z } from "zod";
import {
LocalQuizQuestionAnswer,
zodLocalQuizQuestionAnswer,
} from "./localQuizQuestionAnswer";
export enum QuestionType {
MULTIPLE_ANSWERS = "multiple_answers",
MULTIPLE_CHOICE = "multiple_choice",
ESSAY = "essay",
SHORT_ANSWER = "short_answer",
MATCHING = "matching",
NONE = "",
SHORT_ANSWER_WITH_ANSWERS = "short_answer=",
NUMERICAL = "numerical",
}
import { zodLocalQuizQuestionAnswer } from "./localQuizQuestionAnswer";
export const zodQuestionType = z.enum([
QuestionType.MULTIPLE_ANSWERS,
QuestionType.MULTIPLE_CHOICE,
QuestionType.ESSAY,
QuestionType.SHORT_ANSWER,
QuestionType.MATCHING,
QuestionType.NONE,
QuestionType.SHORT_ANSWER_WITH_ANSWERS,
"multiple_answers",
"multiple_choice",
"essay",
"short_answer",
"matching",
"",
"short_answer=",
"numerical",
]);
export interface LocalQuizQuestion {
text: string;
questionType: QuestionType;
points: number;
answers: LocalQuizQuestionAnswer[];
matchDistractors: string[];
correctComments?: string;
incorrectComments?: string;
neutralComments?: string;
}
export const QuestionType = {
MULTIPLE_ANSWERS: "multiple_answers",
MULTIPLE_CHOICE: "multiple_choice",
ESSAY: "essay",
SHORT_ANSWER: "short_answer",
MATCHING: "matching",
NONE: "",
SHORT_ANSWER_WITH_ANSWERS: "short_answer=",
NUMERICAL: "numerical",
} as const;
export type QuestionType = z.infer<typeof zodQuestionType>;
export const zodLocalQuizQuestion = z.object({
text: z.string(),
questionType: zodQuestionType,
@@ -45,3 +35,4 @@ export const zodLocalQuizQuestion = z.object({
incorrectComments: z.string().optional(),
neutralComments: z.string().optional(),
});
export type LocalQuizQuestion = z.infer<typeof zodLocalQuizQuestion>;

View File

@@ -1,36 +1,3 @@
type FeedbackType = "+" | "-" | "...";
const extractFeedbackContent = (
trimmedLine: string,
feedbackType: FeedbackType
): string => {
if (trimmedLine === feedbackType) return "";
const prefixLength = feedbackType === "..." ? 4 : 2; // "... " is 4 chars, "+ " and "- " are 2
return trimmedLine.substring(prefixLength);
};
const saveFeedback = (
feedbackType: FeedbackType | null,
feedbackLines: string[],
comments: {
correct?: string;
incorrect?: string;
neutral?: string;
}
): void => {
if (!feedbackType || feedbackLines.length === 0) return;
const feedbackText = feedbackLines.join("\n");
if (feedbackType === "+") {
comments.correct = feedbackText;
} else if (feedbackType === "-") {
comments.incorrect = feedbackText;
} else if (feedbackType === "...") {
comments.neutral = feedbackText;
}
};
type feedbackTypeOptions = "correct" | "incorrect" | "neutral" | "none";
export const quizFeedbackMarkdownUtils = {
@@ -78,7 +45,7 @@ export const quizFeedbackMarkdownUtils = {
.trim();
currentFeedbackType = lineFeedbackType;
comments[lineFeedbackType].push(lineWithoutIndicator);
} else {
otherLines.push(line);
}

View File

@@ -199,6 +199,8 @@ export const quizQuestionAnswerMarkdownUtils = {
return `${questionTypeIndicator}${multilineMarkdownCompatibleText}`;
} else if (question.questionType === "matching") {
return `^ ${answer.text} - ${answer.matchedText}`;
} else if (question.questionType === "numerical") {
return `= ${answer.numericAnswer}`;
} else {
const questionLetter = String.fromCharCode(97 + index);
const correctIndicator = answer.correct ? "*" : "";