Exam generation rework, batch user tables, fastapi endpoint switch

This commit is contained in:
Carlos-Mesquita
2024-11-04 23:29:14 +00:00
parent a2bc997e8f
commit 15c9c4d4bd
148 changed files with 11348 additions and 3901 deletions

View File

@@ -0,0 +1,84 @@
import { AlertItem } from "../Shared/Alert";
import { ParsedQuestion } from "./parsing";
export const validateQuestionText = (
parsedQuestions: ParsedQuestion[],
setAlerts: React.Dispatch<React.SetStateAction<AlertItem[]>>
): boolean => {
const unmodifiedQuestions = parsedQuestions.filter(q => q.questionText === "New question");
if (unmodifiedQuestions.length > 0) {
setAlerts(prev => {
const filteredAlerts = prev.filter(alert => !alert.tag?.startsWith('unmodified-question'));
return [...filteredAlerts, ...unmodifiedQuestions.map(q => ({
variant: "error" as const,
tag: `unmodified-question-${q.id}`,
description: `Question ${q.id} is unmodified`
}))];
});
return false;
}
setAlerts(prev => prev.filter(alert => !alert.tag?.startsWith('unmodified-question')));
return true;
};
export const validateEmptySolutions = (
solutions: Array<{ id: string; solution: string[] }>,
setAlerts: React.Dispatch<React.SetStateAction<AlertItem[]>>
): boolean => {
const questionsWithEmptySolutions = solutions.flatMap(solution =>
solution.solution.map((sol, index) => ({
questionId: solution.id,
solutionIndex: index,
isEmpty: !sol.trim()
})).filter(({ isEmpty }) => isEmpty)
);
if (questionsWithEmptySolutions.length > 0) {
setAlerts(prev => {
const filteredAlerts = prev.filter(alert => !alert.tag?.startsWith('empty-solution'));
return [...filteredAlerts, ...questionsWithEmptySolutions.map(({ questionId, solutionIndex }) => ({
variant: "error" as const,
tag: `empty-solution-${questionId}-${solutionIndex}`,
description: `Solution ${solutionIndex + 1} for question ${questionId} cannot be empty`
}))];
});
return false;
}
setAlerts(prev => prev.filter(alert => !alert.tag?.startsWith('empty-solution')));
return true;
};
export const validateWordCount = (
solutions: Array<{ id: string; solution: string[] }>,
maxWords: number,
setAlerts: React.Dispatch<React.SetStateAction<AlertItem[]>>
): boolean => {
let isValid = true;
solutions.forEach((solution) => {
solution.solution.forEach((value, solutionIndex) => {
const wordCount = value.trim().split(/\s+/).length;
if (wordCount > maxWords) {
isValid = false;
setAlerts(prev => {
const filteredAlerts = prev.filter(alert =>
alert.tag !== `solution-error-${solution.id}-${solutionIndex}`
);
return [...filteredAlerts, {
variant: "error",
tag: `solution-error-${solution.id}-${solutionIndex}`,
description: `Solution ${solutionIndex + 1} for question ${solution.id} exceeds maximum of ${maxWords} words (current: ${wordCount} words)`
}];
});
} else {
setAlerts(prev =>
prev.filter(alert =>
alert.tag !== `solution-error-${solution.id}-${solutionIndex}`
)
);
}
});
});
return isValid;
};