feat(vocab): enhance vocabulary exercises and localization support
All checks were successful
Deploy to production / deploy (push) Successful in 2m51s
All checks were successful
Deploy to production / deploy (push) Successful in 2m51s
- Updated core patterns in BISAYA_PHASE5_DIDACTICS to include gloss translations for better understanding. - Refactored vocabulary exercise generation in update-food-care-exercises.js to improve randomization and user engagement. - Added new exercise types and improved question structures for vocabulary lessons, enhancing the learning experience. - Enhanced localization files for German, English, and Spanish to support new exercise features and improve user guidance. - Updated VocabLessonView to incorporate sequential navigation for exercises, providing a more structured learning flow.
This commit is contained in:
@@ -52,7 +52,12 @@ export const BISAYA_PHASE5_DIDACTICS = {
|
||||
'Nahe Bedeutungen in stabilere Antworten überführen.',
|
||||
'Häufige Stolperstellen transparent machen.'
|
||||
],
|
||||
corePatterns: ['Palangga taka.', 'Mingaw ko nimo.', 'Magpahuway sa.', 'Andam na ka?']
|
||||
corePatterns: [
|
||||
{ target: 'Palangga taka.', gloss: 'Ich hab dich lieb.' },
|
||||
{ target: 'Mingaw ko nimo.', gloss: 'Ich vermisse dich.' },
|
||||
{ target: 'Magpahuway sa.', gloss: 'Ruh dich aus.' },
|
||||
{ target: 'Andam na ka?', gloss: 'Bist du fertig?' }
|
||||
]
|
||||
},
|
||||
'Freies Erzählen - Mein Alltag': {
|
||||
learningGoals: [
|
||||
|
||||
@@ -652,23 +652,43 @@ async function updateFoodCareExercises() {
|
||||
totalExercisesCreated++;
|
||||
}
|
||||
} else if (lesson.title === 'Essen & Trinken') {
|
||||
// Vokabular-Übungen für "Essen & Trinken"
|
||||
for (const vocab of conversations) {
|
||||
// Multiple Choice: Muttersprache -> Bisaya
|
||||
// Vokabular: keine strikte Paarung Deutsch→Bisaya direkt gefolgt von Rückrichtung (vermeidet Verräter-Effekt).
|
||||
const n = conversations.length;
|
||||
const offset = Math.max(1, Math.floor(n / 2));
|
||||
const revIdx = (i) => (i + offset) % Math.max(n, 1);
|
||||
|
||||
const pickOtherBisaya = (correct, start) => {
|
||||
for (let t = 1; t <= n; t++) {
|
||||
const o = conversations[(start + t) % n]?.bisaya;
|
||||
if (o && o !== correct) return o;
|
||||
}
|
||||
return 'Salamat';
|
||||
};
|
||||
const pickOtherNative = (correct, start) => {
|
||||
for (let t = 1; t <= n; t++) {
|
||||
const o = conversations[(start + t) % n]?.native;
|
||||
if (o && o !== correct) return o;
|
||||
}
|
||||
return 'Danke';
|
||||
};
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
const vocab = conversations[i];
|
||||
await VocabGrammarExercise.create({
|
||||
lessonId: lesson.id,
|
||||
exerciseTypeId: 2, // multiple_choice
|
||||
exerciseTypeId: 2,
|
||||
exerciseNumber: exerciseNumber++,
|
||||
title: `Wie sagt man "${vocab.native}"?`,
|
||||
instruction: 'Wähle die richtige Übersetzung.',
|
||||
questionData: JSON.stringify({
|
||||
type: 'multiple_choice',
|
||||
answerLanguage: 'target',
|
||||
question: `Wie sagt man "${vocab.native}" auf Bisaya?`,
|
||||
options: [
|
||||
vocab.bisaya,
|
||||
conversations[(exerciseNumber - 2 + 1) % conversations.length]?.bisaya || 'Salamat',
|
||||
conversations[(exerciseNumber - 2 + 2) % conversations.length]?.bisaya || 'Maayo',
|
||||
conversations[(exerciseNumber - 2 + 3) % conversations.length]?.bisaya || 'Palihug'
|
||||
pickOtherBisaya(vocab.bisaya, i),
|
||||
pickOtherBisaya(vocab.bisaya, i + 3),
|
||||
pickOtherBisaya(vocab.bisaya, i + 6)
|
||||
]
|
||||
}),
|
||||
answerData: JSON.stringify({
|
||||
@@ -679,22 +699,25 @@ async function updateFoodCareExercises() {
|
||||
createdByUserId: course.owner_user_id || systemUser.id
|
||||
});
|
||||
totalExercisesCreated++;
|
||||
}
|
||||
|
||||
// Multiple Choice: Bisaya -> Muttersprache
|
||||
for (let i = 0; i < n; i++) {
|
||||
const vocab = conversations[revIdx(i)];
|
||||
await VocabGrammarExercise.create({
|
||||
lessonId: lesson.id,
|
||||
exerciseTypeId: 2, // multiple_choice
|
||||
exerciseTypeId: 2,
|
||||
exerciseNumber: exerciseNumber++,
|
||||
title: `Was bedeutet "${vocab.bisaya}"?`,
|
||||
instruction: 'Wähle die richtige Übersetzung.',
|
||||
questionData: JSON.stringify({
|
||||
type: 'multiple_choice',
|
||||
answerLanguage: 'native',
|
||||
question: `Was bedeutet "${vocab.bisaya}"?`,
|
||||
options: [
|
||||
vocab.native,
|
||||
conversations[(exerciseNumber - 3 + 1) % conversations.length]?.native || 'Danke',
|
||||
conversations[(exerciseNumber - 3 + 2) % conversations.length]?.native || 'Bitte',
|
||||
conversations[(exerciseNumber - 3 + 3) % conversations.length]?.native || 'Gut'
|
||||
pickOtherNative(vocab.native, i),
|
||||
pickOtherNative(vocab.native, i + 4),
|
||||
pickOtherNative(vocab.native, i + 8)
|
||||
]
|
||||
}),
|
||||
answerData: JSON.stringify({
|
||||
@@ -706,6 +729,31 @@ async function updateFoodCareExercises() {
|
||||
});
|
||||
totalExercisesCreated++;
|
||||
}
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
const vocab = conversations[i];
|
||||
await VocabGrammarExercise.create({
|
||||
lessonId: lesson.id,
|
||||
exerciseTypeId: 4,
|
||||
exerciseNumber: exerciseNumber++,
|
||||
title: `Tippe auf Bisaya: "${vocab.native}"`,
|
||||
instruction: 'Übersetze das Wort (Schreibtest).',
|
||||
questionData: JSON.stringify({
|
||||
type: 'transformation',
|
||||
text: vocab.native,
|
||||
sourceLanguage: nativeLangName,
|
||||
targetLanguage: 'Bisaya'
|
||||
}),
|
||||
answerData: JSON.stringify({
|
||||
type: 'transformation',
|
||||
correct: vocab.bisaya,
|
||||
alternatives: []
|
||||
}),
|
||||
explanation: vocab.explanation,
|
||||
createdByUserId: course.owner_user_id || systemUser.id
|
||||
});
|
||||
totalExercisesCreated++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user