feat: erweitere Didaktik-Fragmente und verbessere die Übersetzungen in mehreren Sprachen
All checks were successful
Deploy to production / deploy (push) Successful in 2m6s
All checks were successful
Deploy to production / deploy (push) Successful in 2m6s
This commit is contained in:
@@ -154,6 +154,7 @@ export const BISAYA_DIDACTICS_FRAGMENTS = {
|
||||
{ target: 'Dinhi ko.', gloss: 'Ich bin hier.' },
|
||||
{ target: 'Naa ko dinhi.', gloss: 'Ich bin hier.' },
|
||||
{ target: 'Didto siya.', gloss: 'Er/sie ist dort.' },
|
||||
{ target: 'Adto ko sa merkado.', gloss: 'Ich gehe zum Markt.' },
|
||||
{ target: 'Adto ta didto.', gloss: 'Lass uns dorthin gehen.' },
|
||||
{ target: 'Padulong ko sa merkado.', gloss: 'Ich bin auf dem Weg zum Markt.' },
|
||||
{ target: 'Padulong ta didto.', gloss: 'Lass uns dorthin aufbrechen.' },
|
||||
@@ -169,6 +170,16 @@ export const BISAYA_DIDACTICS_FRAGMENTS = {
|
||||
title: 'dinhi / didto',
|
||||
text: '„dinhi“ = hier, „didto“ = dort (weg vom Sprecher).',
|
||||
example: 'Naa ko dinhi. Didto ang simbahan.'
|
||||
},
|
||||
{
|
||||
title: 'Naa + Person + Ort',
|
||||
text: 'Mit „naa“ sagst du, dass jemand an einem Ort ist. Danach steht der Ort oder das Ortswort.',
|
||||
example: 'Naa ko dinhi. Naa siya didto.'
|
||||
},
|
||||
{
|
||||
title: 'adto vs. padulong',
|
||||
text: '„adto“ ist gehen/fahren zu einem Ziel. „padulong“ betont, dass jemand bereits unterwegs in diese Richtung ist.',
|
||||
example: 'Adto ko sa merkado. Padulong ko sa merkado.'
|
||||
}
|
||||
],
|
||||
speakingPrompts: [
|
||||
|
||||
77
backend/scripts/count_corepatterns.js
Normal file
77
backend/scripts/count_corepatterns.js
Normal file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env node
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
function readFile(p) {
|
||||
return fs.readFileSync(path.resolve(p), 'utf8');
|
||||
}
|
||||
|
||||
const base = readFile('./backend/scripts/create-bisaya-course.js');
|
||||
const bisaya = readFile('./backend/scripts/bisaya-course-plan-24-43.js');
|
||||
|
||||
function extractLessons(text) {
|
||||
const lessons = new Map();
|
||||
const re = /\{[\s\S]*?num:\s*(\d+),[\s\S]*?title:\s*'([^']+)'[\s\S]*?\}/g;
|
||||
let m;
|
||||
while ((m = re.exec(text))) {
|
||||
const num = Number(m[1]);
|
||||
const title = m[2];
|
||||
if (num >= 1 && num <= 30) lessons.set(num, title);
|
||||
}
|
||||
return lessons;
|
||||
}
|
||||
|
||||
function extractCorePatternsForTitle(title, text) {
|
||||
// Try to find 'title': { ... corePatterns: [ ... ] }
|
||||
const escTitle = title.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||
const re = new RegExp("'" + escTitle + "'\\s*:\\s*\\{[\\s\\S]*?corePatterns\\s*:\\s*\\[([\\s\\S]*?)\\]", 'm');
|
||||
const m = re.exec(text);
|
||||
if (!m) return null;
|
||||
const inside = m[1];
|
||||
// Count entries: either objects { target: ... } or string entries
|
||||
const lines = inside.split(/\r?\n/).map(l => l.trim()).filter(l => l.length > 0);
|
||||
let count = 0;
|
||||
for (const ln of lines) {
|
||||
if (ln.startsWith('{') || ln.startsWith("'") || ln.startsWith('"')) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const lessons = extractLessons(base + '\n' + bisaya);
|
||||
const results = [];
|
||||
for (let i = 1; i <= 30; i++) {
|
||||
const title = lessons.get(i);
|
||||
if (!title) {
|
||||
results.push({ num: i, title: null, count: 0, note: 'title not found' });
|
||||
continue;
|
||||
}
|
||||
let count = extractCorePatternsForTitle(title, base);
|
||||
let source = 'create-bisaya-course.js';
|
||||
if (count === null) {
|
||||
count = extractCorePatternsForTitle(title, bisaya);
|
||||
source = 'bisaya-course-plan-24-43.js';
|
||||
}
|
||||
if (count === null) {
|
||||
// try relationship anchor
|
||||
const relText = bisaya;
|
||||
count = extractCorePatternsForTitle(title, relText);
|
||||
source = 'bisaya-course-plan-24-43.js';
|
||||
}
|
||||
if (count === null) {
|
||||
results.push({ num: i, title, count: 0, note: 'corePatterns not found' });
|
||||
} else {
|
||||
results.push({ num: i, title, count, source });
|
||||
}
|
||||
}
|
||||
|
||||
let total = 0;
|
||||
for (const r of results) {
|
||||
total += r.count || 0;
|
||||
}
|
||||
|
||||
console.log('Core pattern counts for lessons 1..30:');
|
||||
results.forEach(r => {
|
||||
console.log(`${r.num}. ${r.title || '<missing>'} -> ${r.count} ${r.source ? '('+r.source+')' : ''} ${r.note?'- '+r.note:''}`);
|
||||
});
|
||||
console.log('---');
|
||||
console.log('Total core patterns (1..30):', total);
|
||||
@@ -13,6 +13,7 @@ import VocabCourseLesson from '../models/community/vocab_course_lesson.js';
|
||||
import VocabGrammarExercise from '../models/community/vocab_grammar_exercise.js';
|
||||
import VocabCourse from '../models/community/vocab_course.js';
|
||||
import User from '../models/community/user.js';
|
||||
import { BISAYA_DIDACTICS_FRAGMENTS, BISAYA_PHASE1_DIDACTICS } from './bisaya-course-phase1.js';
|
||||
import { BISAYA_DIDACTICS_24_43, BISAYA_LESSONS_24_43_BY_NUMBER, BISAYA_RELATIONSHIP_ANCHOR_DIDACTICS } from './bisaya-course-plan-24-43.js';
|
||||
import { BISAYA_PHASE3_DIDACTICS, BISAYA_PHASE3_LESSONS } from './bisaya-course-phase3-extension.js';
|
||||
import { BISAYA_PHASE4_DIDACTICS, BISAYA_PHASE4_LESSONS } from './bisaya-course-phase4-extension.js';
|
||||
@@ -26,6 +27,8 @@ function withTypeName(exerciseTypeName, exercise) {
|
||||
}
|
||||
|
||||
const GENERATED_BISAYA_DIDACTICS = {
|
||||
...BISAYA_PHASE1_DIDACTICS,
|
||||
...BISAYA_DIDACTICS_FRAGMENTS,
|
||||
...BISAYA_RELATIONSHIP_ANCHOR_DIDACTICS,
|
||||
...BISAYA_DIDACTICS_24_43,
|
||||
...BISAYA_PHASE3_DIDACTICS,
|
||||
@@ -449,11 +452,23 @@ function rotateArray(values, offset) {
|
||||
|
||||
function getLessonDidactics(lesson) {
|
||||
const staticDidactics = GENERATED_BISAYA_DIDACTICS[lesson.title] || {};
|
||||
const learningGoals = Array.isArray(lesson.learningGoals) ? lesson.learningGoals : (staticDidactics.learningGoals || []);
|
||||
const corePatterns = Array.isArray(lesson.corePatterns) ? lesson.corePatterns : (staticDidactics.corePatterns || []);
|
||||
const grammarFocus = Array.isArray(lesson.grammarFocus) ? lesson.grammarFocus : (staticDidactics.grammarFocus || []);
|
||||
const speakingPrompts = Array.isArray(lesson.speakingPrompts) ? lesson.speakingPrompts : (staticDidactics.speakingPrompts || []);
|
||||
const practicalTasks = Array.isArray(lesson.practicalTasks) ? lesson.practicalTasks : (staticDidactics.practicalTasks || []);
|
||||
const learningGoals = Array.isArray(lesson.learningGoals) && lesson.learningGoals.length > 0
|
||||
? lesson.learningGoals
|
||||
: (staticDidactics.learningGoals || []);
|
||||
const corePatterns = [
|
||||
...(staticDidactics.corePatterns || []),
|
||||
...(Array.isArray(lesson.corePatterns) ? lesson.corePatterns : [])
|
||||
];
|
||||
const grammarFocus = mergeGrammarFocusForLesson(
|
||||
staticDidactics.grammarFocus || [],
|
||||
Array.isArray(lesson.grammarFocus) ? lesson.grammarFocus : []
|
||||
);
|
||||
const speakingPrompts = Array.isArray(lesson.speakingPrompts) && lesson.speakingPrompts.length > 0
|
||||
? lesson.speakingPrompts
|
||||
: (staticDidactics.speakingPrompts || []);
|
||||
const practicalTasks = Array.isArray(lesson.practicalTasks) && lesson.practicalTasks.length > 0
|
||||
? lesson.practicalTasks
|
||||
: (staticDidactics.practicalTasks || []);
|
||||
|
||||
return {
|
||||
learningGoals,
|
||||
@@ -2361,14 +2376,14 @@ const BISAYA_EXERCISES = {
|
||||
instruction: 'Fülle die Lücken mit den richtigen Bisaya-Wörtern.',
|
||||
questionData: {
|
||||
type: 'gap_fill',
|
||||
text: '{gap} ko sa merkado. (Ich gehe zum Markt.) | {gap} ta didto. (Lass uns dorthin gehen.)',
|
||||
text: '{gap} ko sa merkado. (Ich bin auf dem Weg zum Markt.) | {gap} ta didto. (Lass uns dorthin gehen.)',
|
||||
gaps: 2
|
||||
},
|
||||
answerData: {
|
||||
type: 'gap_fill',
|
||||
answers: ['Padulong', 'Padulong']
|
||||
answers: ['Padulong', 'Adto']
|
||||
},
|
||||
explanation: '\"Padulong\" beschreibt, dass man unterwegs zu einem Ziel ist.'
|
||||
explanation: '„Padulong“ betont die Richtung/Bewegung; „Adto ta didto“ ist die natürliche Aufforderung, dorthin zu gehen.'
|
||||
},
|
||||
{
|
||||
exerciseTypeId: 4, // transformation
|
||||
@@ -2386,6 +2401,86 @@ const BISAYA_EXERCISES = {
|
||||
alternatives: ['Asa dapit ang simbahan?', 'Asa man ang simbahan?']
|
||||
},
|
||||
explanation: '\"simbahan\" = Kirche, \"Asa ang ...?\" = Wo ist ...?'
|
||||
},
|
||||
{
|
||||
exerciseTypeId: 4,
|
||||
title: 'Nach der Person fragen',
|
||||
instruction: 'Übersetze ins Bisaya.',
|
||||
questionData: {
|
||||
type: 'transformation',
|
||||
text: 'Wo bist du?',
|
||||
sourceLanguage: 'Deutsch',
|
||||
targetLanguage: 'Bisaya'
|
||||
},
|
||||
answerData: {
|
||||
type: 'transformation',
|
||||
correct: 'Asa ka?',
|
||||
alternatives: ['Asa man ka?']
|
||||
},
|
||||
explanation: '„Asa ka?“ kann je nach Kontext nach Ort oder Ziel fragen.'
|
||||
},
|
||||
{
|
||||
exerciseTypeId: 4,
|
||||
title: 'Hier antworten',
|
||||
instruction: 'Übersetze ins Bisaya.',
|
||||
questionData: {
|
||||
type: 'transformation',
|
||||
text: 'Ich bin hier.',
|
||||
sourceLanguage: 'Deutsch',
|
||||
targetLanguage: 'Bisaya'
|
||||
},
|
||||
answerData: {
|
||||
type: 'transformation',
|
||||
correct: 'Naa ko dinhi.',
|
||||
alternatives: ['Dinhi ko.', 'Naa ko diri.', 'Diri ko.']
|
||||
},
|
||||
explanation: '„Naa ko dinhi“ und „Dinhi ko“ sind beide brauchbare Antworten.'
|
||||
},
|
||||
{
|
||||
exerciseTypeId: 4,
|
||||
title: 'Dort antworten',
|
||||
instruction: 'Übersetze ins Bisaya.',
|
||||
questionData: {
|
||||
type: 'transformation',
|
||||
text: 'Er ist dort.',
|
||||
sourceLanguage: 'Deutsch',
|
||||
targetLanguage: 'Bisaya'
|
||||
},
|
||||
answerData: {
|
||||
type: 'transformation',
|
||||
correct: 'Didto siya.',
|
||||
alternatives: ['Naa siya didto.', 'Siya didto.']
|
||||
},
|
||||
explanation: '„siya“ kann er oder sie bedeuten; „didto“ markiert dort.'
|
||||
},
|
||||
{
|
||||
exerciseTypeId: 3,
|
||||
title: 'Mini-Route bauen',
|
||||
instruction: 'Ordne die Sätze zu einer kurzen Route.',
|
||||
questionData: {
|
||||
type: 'sentence_building',
|
||||
question: 'Baue: Wo ist der Markt? Ich bin hier. Ich bin auf dem Weg zum Markt.',
|
||||
tokens: ['Asa ang merkado?', 'Naa ko dinhi.', 'Padulong ko sa merkado.']
|
||||
},
|
||||
answerData: {
|
||||
correct: ['Asa ang merkado? Naa ko dinhi. Padulong ko sa merkado.']
|
||||
},
|
||||
explanation: 'Die Reihenfolge verbindet Ortsfrage, Standort und Richtung.'
|
||||
},
|
||||
{
|
||||
exerciseTypeId: 10,
|
||||
title: 'Weg im Alltag',
|
||||
instruction: 'Antworte kurz mit Ort und Richtung.',
|
||||
questionData: {
|
||||
type: 'situational_response',
|
||||
question: 'Jemand fragt, wo du bist und wohin du gehst. Sage, dass du hier bist und zum Markt unterwegs bist.',
|
||||
keywords: ['naa', 'dinhi', 'padulong', 'merkado']
|
||||
},
|
||||
answerData: {
|
||||
modelAnswer: 'Naa ko dinhi. Padulong ko sa merkado.',
|
||||
keywords: ['naa', 'dinhi', 'padulong', 'merkado']
|
||||
},
|
||||
explanation: 'Die Antwort kombiniert Standort und Zielrichtung in zwei kurzen Sätzen.'
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
Reference in New Issue
Block a user