Enhance exercise generation for family conversations and feelings & affection
- Updated multiple choice exercises to include randomized wrong options for improved engagement and challenge. - Added new exercise types for reading aloud and speaking from memory, enhancing interactive learning experiences. - Improved gap fill exercises with clearer instructions and multiple variants for better user understanding. - Enhanced the vocabulary service to support new exercise types, ensuring robust answer checking and feedback mechanisms. - Updated localization files to include new instructions and messages related to the new exercise types.
This commit is contained in:
@@ -1421,6 +1421,15 @@ export default class VocabService {
|
||||
? answerData.answers.join(', ')
|
||||
: answerData.answers;
|
||||
}
|
||||
// Für Reading Aloud: Extrahiere den erwarteten Text
|
||||
else if (questionData.type === 'reading_aloud') {
|
||||
correctAnswer = questionData.text || answerData.expectedText || '';
|
||||
}
|
||||
// Für Speaking From Memory: Extrahiere erwarteten Text oder Schlüsselwörter
|
||||
else if (questionData.type === 'speaking_from_memory') {
|
||||
correctAnswer = questionData.expectedText || questionData.text || '';
|
||||
alternatives = questionData.keywords || [];
|
||||
}
|
||||
// Fallback: Versuche correct oder correctAnswer
|
||||
else {
|
||||
correctAnswer = Array.isArray(answerData.correct)
|
||||
@@ -1438,6 +1447,11 @@ export default class VocabService {
|
||||
};
|
||||
}
|
||||
|
||||
async _getExerciseTypeIdByName(typeName) {
|
||||
const type = await VocabGrammarExerciseType.findOne({ where: { name: typeName } });
|
||||
return type ? type.id : null;
|
||||
}
|
||||
|
||||
_checkAnswer(answerData, questionData, userAnswer, exerciseTypeId) {
|
||||
// Vereinfachte Antwortprüfung - kann je nach Übungstyp erweitert werden
|
||||
if (!answerData || userAnswer === undefined || userAnswer === null) return false;
|
||||
@@ -1476,6 +1490,32 @@ export default class VocabService {
|
||||
}
|
||||
}
|
||||
|
||||
// Für Reading Aloud: userAnswer ist der erkannte Text (String)
|
||||
// Vergleiche mit dem erwarteten Text aus questionData.text
|
||||
if (parsedQuestionData.type === 'reading_aloud' || parsedQuestionData.type === 'speaking_from_memory') {
|
||||
const normalize = (str) => String(str || '').trim().toLowerCase().replace(/[.,!?;:]/g, '');
|
||||
const expectedText = parsedQuestionData.text || parsedQuestionData.expectedText || '';
|
||||
const normalizedExpected = normalize(expectedText);
|
||||
const normalizedUser = normalize(userAnswer);
|
||||
|
||||
// Für reading_aloud: Exakter Vergleich oder Levenshtein-Distanz
|
||||
if (parsedQuestionData.type === 'reading_aloud') {
|
||||
// Exakter Vergleich (kann später mit Levenshtein erweitert werden)
|
||||
return normalizedUser === normalizedExpected;
|
||||
}
|
||||
|
||||
// Für speaking_from_memory: Flexibler Vergleich (Schlüsselwörter)
|
||||
if (parsedQuestionData.type === 'speaking_from_memory') {
|
||||
const keywords = parsedQuestionData.keywords || [];
|
||||
if (keywords.length === 0) {
|
||||
// Fallback: Exakter Vergleich
|
||||
return normalizedUser === normalizedExpected;
|
||||
}
|
||||
// Prüfe ob alle Schlüsselwörter vorhanden sind
|
||||
return keywords.every(keyword => normalizedUser.includes(normalize(keyword)));
|
||||
}
|
||||
}
|
||||
|
||||
// Für andere Typen: einfacher String-Vergleich (kann später erweitert werden)
|
||||
const normalize = (str) => String(str || '').trim().toLowerCase();
|
||||
const correctAnswers = parsedAnswerData.correct || parsedAnswerData.correctAnswer || [];
|
||||
|
||||
Reference in New Issue
Block a user