feat(vocabService): enhance answer validation for multiple choice exercises
- Improved answer validation logic by expanding multiple choice answer data based on lesson context. - Added methods to extract indices of correct answers and normalize question prompts for better accuracy. - Refactored existing answer checking to accommodate new data handling, ensuring robust evaluation of user responses.
This commit is contained in:
@@ -1702,8 +1702,18 @@ export default class VocabService {
|
||||
throw err;
|
||||
}
|
||||
|
||||
// Überprüfe Antwort (vereinfachte Logik - kann je nach Übungstyp erweitert werden)
|
||||
const isCorrect = this._checkAnswer(exercise.answerData, exercise.questionData, userAnswer, exercise.exerciseTypeId);
|
||||
const originalAnswerData = typeof exercise.answerData === 'string'
|
||||
? JSON.parse(exercise.answerData)
|
||||
: exercise.answerData;
|
||||
const questionData = typeof exercise.questionData === 'string'
|
||||
? JSON.parse(exercise.questionData)
|
||||
: exercise.questionData;
|
||||
const effectiveAnswerData = exercise.exerciseTypeId === 2
|
||||
? await this._expandMultipleChoiceAnswerData(exercise, originalAnswerData, questionData)
|
||||
: originalAnswerData;
|
||||
|
||||
// Überprüfe Antwort
|
||||
const isCorrect = this._checkAnswer(effectiveAnswerData, questionData, userAnswer, exercise.exerciseTypeId);
|
||||
|
||||
// Speichere Fortschritt
|
||||
const [progress, created] = await VocabGrammarExerciseProgress.findOrCreate({
|
||||
@@ -1736,12 +1746,7 @@ export default class VocabService {
|
||||
}
|
||||
|
||||
// Extrahiere richtige Antwort und Alternativen
|
||||
const answerData = typeof exercise.answerData === 'string'
|
||||
? JSON.parse(exercise.answerData)
|
||||
: exercise.answerData;
|
||||
const questionData = typeof exercise.questionData === 'string'
|
||||
? JSON.parse(exercise.questionData)
|
||||
: exercise.questionData;
|
||||
const answerData = effectiveAnswerData;
|
||||
|
||||
let correctAnswer = null;
|
||||
let alternatives = [];
|
||||
@@ -1817,6 +1822,86 @@ export default class VocabService {
|
||||
return type ? type.id : null;
|
||||
}
|
||||
|
||||
_extractMultipleChoiceIndices(answerData) {
|
||||
if (!answerData) return [];
|
||||
if (answerData.correctAnswer !== undefined) {
|
||||
return Array.isArray(answerData.correctAnswer)
|
||||
? answerData.correctAnswer.map(idx => Number(idx)).filter(Number.isInteger)
|
||||
: [Number(answerData.correctAnswer)].filter(Number.isInteger);
|
||||
}
|
||||
if (answerData.correct !== undefined) {
|
||||
return Array.isArray(answerData.correct)
|
||||
? answerData.correct.map(idx => Number(idx)).filter(Number.isInteger)
|
||||
: [Number(answerData.correct)].filter(Number.isInteger);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
_getMultipleChoicePrompt(questionData) {
|
||||
return this._normalizeTextAnswer(
|
||||
questionData?.question || questionData?.text || questionData?.prompt || ''
|
||||
);
|
||||
}
|
||||
|
||||
async _expandMultipleChoiceAnswerData(exercise, answerData, questionData) {
|
||||
const options = Array.isArray(questionData?.options) ? questionData.options : [];
|
||||
const baseIndices = this._extractMultipleChoiceIndices(answerData);
|
||||
if (!options.length || !baseIndices.length || !exercise?.lessonId) {
|
||||
return answerData;
|
||||
}
|
||||
|
||||
const prompt = this._getMultipleChoicePrompt(questionData);
|
||||
if (!prompt) {
|
||||
return answerData;
|
||||
}
|
||||
|
||||
const optionIndexMap = new Map();
|
||||
options.forEach((option, index) => {
|
||||
const normalizedOption = this._normalizeTextAnswer(option);
|
||||
if (!normalizedOption) return;
|
||||
const existing = optionIndexMap.get(normalizedOption) || [];
|
||||
existing.push(index);
|
||||
optionIndexMap.set(normalizedOption, existing);
|
||||
});
|
||||
|
||||
const lessonExercises = await VocabGrammarExercise.findAll({
|
||||
where: {
|
||||
lessonId: exercise.lessonId,
|
||||
exerciseTypeId: 2
|
||||
},
|
||||
attributes: ['id', 'questionData', 'answerData']
|
||||
});
|
||||
|
||||
const expandedIndices = new Set(baseIndices);
|
||||
lessonExercises.forEach((candidate) => {
|
||||
const candidateQuestionData = typeof candidate.questionData === 'string'
|
||||
? JSON.parse(candidate.questionData)
|
||||
: candidate.questionData;
|
||||
const candidatePrompt = this._getMultipleChoicePrompt(candidateQuestionData);
|
||||
if (candidatePrompt !== prompt) {
|
||||
return;
|
||||
}
|
||||
|
||||
const candidateAnswerData = typeof candidate.answerData === 'string'
|
||||
? JSON.parse(candidate.answerData)
|
||||
: candidate.answerData;
|
||||
const candidateOptions = Array.isArray(candidateQuestionData?.options) ? candidateQuestionData.options : [];
|
||||
const candidateIndices = this._extractMultipleChoiceIndices(candidateAnswerData);
|
||||
|
||||
candidateIndices.forEach((candidateIndex) => {
|
||||
const candidateOption = candidateOptions[candidateIndex];
|
||||
const normalizedOption = this._normalizeTextAnswer(candidateOption);
|
||||
const matchingIndices = optionIndexMap.get(normalizedOption) || [];
|
||||
matchingIndices.forEach((matchingIndex) => expandedIndices.add(matchingIndex));
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
...answerData,
|
||||
correctAnswer: Array.from(expandedIndices).sort((a, b) => a - b)
|
||||
};
|
||||
}
|
||||
|
||||
_checkAnswer(answerData, questionData, userAnswer, exerciseTypeId) {
|
||||
// Vereinfachte Antwortprüfung - kann je nach Übungstyp erweitert werden
|
||||
if (!answerData || userAnswer === undefined || userAnswer === null) return false;
|
||||
|
||||
Reference in New Issue
Block a user