elemes/docs/04-lesson-evaluation.md

50 lines
2.7 KiB
Markdown
Raw Normal View History

---
title: Lesson Evaluation
order: 4
category: evaluation
---
2026-05-14 16:33:45 +07:00
# 04. Lesson Evaluation
The LMS determines the type of lesson and how to evaluate it based on specific markers found in the Markdown content.
## Markdown Markers
| Mode | Marker | Evaluation Logic |
|------|--------|------------------|
| **C / Python** | `---INITIAL_CODE---` / `---INITIAL_PYTHON---` | Standard stdout matching against `---EXPECTED_OUTPUT---` and presence of `---KEY_TEXT---`. |
| **Circuit** | `---INITIAL_CIRCUIT---` | Node voltage matching against `---EXPECTED_CIRCUIT_OUTPUT---` and `---KEY_TEXT_CIRCUIT---`. |
| **Arduino (Velxio)** | `---INITIAL_CODE_ARDUINO---` | Serial output sequence matching, lenient graph wiring comparison, and `---KEY_TEXT---`. |
feat(quiz): taksonomi key quiz per jenis + MCQ berbobot (partial credit) Fitur B — setiap jenis soal kini punya key sendiri sehingga model penilaiannya eksplisit, tidak ditebak dari isi konten: - ---QUIZ_MCQ--- pilihan ganda biner (tepat satu [x]; larang [N]) - ---QUIZ_WEIGHTED--- pilihan ganda berbobot ([N] >= 1, minimal satu [ ], bobot tertinggi unik = kunci; poin parsial) - ---FLASHCARD--- kartu hafalan tanpa penilaian (larang opsi) - legacy ---QUIZ_FLASHCARD--- / ---INITIAL_QUIZ--- tetap dibaca tanpa perubahan perilaku (regex opsi legacy sengaja tidak berubah — baris '- [10]' di konten lama BUKAN opsi); dihapus dari docs/template - ::diagnostic tetap kategori di dalam QUIZ_MCQ & tetap masuk skor resmi Model skor: rata-rata persentase per jenis yang ada, Math.round, lulus >= 75. statusString: "X/Y" bila hanya MCQ/legacy, "P/100" bila ada weighted, "completed" bila hanya flashcard (auto-lulus). Satu sesi/ attempt untuk semua jenis; soal flat urut dokumen. Parser (backend & frontend mirror, ekstraksi multi-blok per key urut dokumen via loop marker-start paling awal; id q-N deterministik): - lesson_service.py: regex [ xX]?[0-9]* utk key baru, _iter_option_lines kind-aware, _validate_quiz_options per kind, _parse_flashcards(kind, id_offset), _extract_quiz_sections + guard loop maju (marker end hilang tidak lagi infinite loop), get_lesson_quiz_total -> 100 bila ada weighted (round-trip CSV "P/100") - parseFlashcards.ts / index.ts / detectActiveTabs.ts / extractSections.ts: mirror perilaku; heading soal <h3> kini fence-aware (fix fixture stale) Payload attempt baru: quiz_type, earned_points, question_max_points — opsional di validasi backend supaya klien lama tetap diterima; poin di-recompute dari konten saat resume/review. UI: QuizTab skor via statusString + alert berbasis percent, badge weighted (✓ 10 / 🟡 7/10 / ✗ 0) di review, preview guru badge bobot + "Berbobot (total N)", laporan guru badge MCQ/Bobot + tooltip, CSV progress 2 kolom baru per lesson (_quiz_mcq, _quiz_weighted), template editor konten QUIZ_MCQ/Quiz Bobot/Flashcard. Tooling & docs: scripts/convert_quiz_keys.py (konversi legacy -> key baru per run jenis, idempoten, verifikasi parse identik; examples/ content dikonversi), scanner mendukung semua key, docs/07 ditulis ulang, docs/15 direvisi ke desain final, README/documentation/docs 02/04/09 diperbarui. Tes: backend 444 lulus (+33: validasi ketat per key, urutan dokumen, multi-blok, zero regression, field selalu di-emit), frontend 249 lulus (+13 parser key baru, +11 model skor), parity fixture diregenerasi, svelte-check 0 error, vite build OK.
2026-10-25 20:16:56 +07:00
| **Quiz** | `---QUIZ_MCQ---` / `---QUIZ_WEIGHTED---` / `---FLASHCARD---` | Skor resmi = rata-rata persentase per jenis quiz (weighted pakai poin bobot); lulus bila ≥ 75. |
2026-05-14 19:04:24 +07:00
| **Slide** | `---slide-start---` | Tidak ada (hanya presentasi konten). |
2026-05-14 16:33:45 +07:00
## Evaluators (`lib/services/`)
The evaluation logic is isolated into specific service files:
### General & C/Python (`evaluators.ts`, `exercise.ts`)
- `export function checkKeyText(code: string, keyText: string): boolean`
Checks if all lines in the `keyText` are present in the provided `code`.
- `export function processLanguageEvaluation(...)`
Coordinates the compilation request and output verification for C and Python.
### Circuit Evaluation (`evaluators.ts`, `exercise.ts`)
- `export function evaluateCircuitSubmission(...)`
Handles the flow of extracting the circuit state.
- `export function validateNodes(actualVoltages: Record<string, number>, expectedNodes: Record<string, NodeResult>): boolean`
Validates if the actual node voltages match the expected voltages within a specified tolerance.
### Arduino/Velxio Evaluation (`velxio-evaluator.ts`, `velxio-bridge.ts`)
- `class VelxioBridge` (`velxio-bridge.ts`)
Manages the `window.postMessage` protocol between the LMS and the Velxio iframe.
- Commands: `elemes:load_code`, `elemes:load_circuit`, `elemes:get_source_code`, `elemes:get_serial_log`, `elemes:get_wires`.
- Events: `velxio:ready`, `velxio:compile_result`.
- `export function evaluateVelxioSubmission(...)`
Orchestrates the 3-part Arduino evaluation:
1. **Key Text**: Checks the retrieved source code.
2. **Serial Output**: Uses `matchSerialSubsequence(actual, expected)` to ensure expected log lines appear in the correct order.
3. **Wiring**: Performs a lenient graph comparison (expected edges must exist; extra edges are allowed; ground pins are normalized).
### Flowchart Evaluation (`flowchart-evaluator.ts`)
- `export function evaluateFlowchartSubmission(...)`
Parses flowchart JSON data and verifies structural correctness against the expected model.