Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/ISSUE_TEMPLATE/lab-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: "Báo cáo lab"
description: "Nộp kết quả một lab (T10) kèm thời gian làm THẬT, để hiệu chỉnh các ước lượng của lộ trình."
title: "[Lab] L__ — "
body:
- type: markdown
attributes:
value: |
Một issue cho một lab. Ghi thời gian **thật**, kể cả lúc đọc đề và sửa lỗi; không tính lúc nghỉ. Con số lệch xa ước lượng ở [T10 §2](../blob/main/docs/training/T10_LABS_AND_ASSESSMENT.md#2-danh-sách-bài-lab) là thông tin quý, không phải điểm trừ.
Mentor tổng hợp mọi báo cáo bằng `node tools/docs/learning-report.mjs` (docs/training/README §8).
- type: dropdown
id: lab
attributes:
label: Lab
options: [L01, L02, L03, L04, L05, L06, L07, L08, L09, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19]
validations:
required: true
- type: input
id: hours
attributes:
label: Thời gian làm thực tế (giờ)
description: "Chỉ ghi số, dấu chấm thập phân. Ví dụ: 3.5"
placeholder: "3.5"
validations:
required: true
- type: textarea
id: reading
attributes:
label: Thời gian đọc tài liệu cho lab này (phút)
description: "Mỗi dòng một module, `🎯` nếu chỉ đọc các mục 🎯. Ví dụ: `T01 🎯: 80` hoặc `T02: 95`. Bỏ trống nếu đã đọc từ trước."
placeholder: "T01 🎯: 80"
- type: textarea
id: grader
attributes:
label: Kết quả run-lab.ps1
description: "Với L02–L06: dán phần kết quả của `.\\labs\\run-lab.ps1 -Lab L0x`."
render: text
- type: textarea
id: report
attributes:
label: Báo cáo
description: "Đã làm gì, quan sát được gì, trả lời câu phản tư của lab (T10 quy tắc 3)."
validations:
required: true
- type: input
id: pr
attributes:
label: Link PR
description: "Nếu lab có PR."
46 changes: 46 additions & 0 deletions .github/ISSUE_TEMPLATE/stage-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: "Đo đầu/cuối giai đoạn"
description: "Điểm vấn đáp trước khi học và lúc đánh giá lên cấp, cùng một bộ câu, để đo mức tiến bộ."
title: "[Đo] "
body:
- type: markdown
attributes:
value: |
Cùng **một** bộ câu hỏi, làm hai lần: **trước khi** bắt đầu giai đoạn, và **lúc đánh giá lên cấp**. Gấp tài liệu, trả lời bằng lời của mình; mentor chấm từng câu. Bộ câu của từng cấp ghi ở cột *Vấn đáp* của [T10 §4](../blob/main/docs/training/T10_LABS_AND_ASSESSMENT.md#4-đề-đánh-giá-lên-cấp).
Điểm thấp ở lần đầu là điều bình thường: đó là điểm xuất phát.
- type: dropdown
id: stage
attributes:
label: Lên cấp
options:
- "🌰 → 🌱 Fresher"
- "🌱 → 🌿 Junior"
- "🌿 → 🌳 Middle"
- "🌳 → 🏔️ Senior"
validations:
required: true
- type: dropdown
id: when
attributes:
label: Lần đo
options:
- "Trước khi học"
- "Lúc đánh giá lên cấp"
validations:
required: true
- type: textarea
id: scores
attributes:
label: Điểm từng câu
description: "Mỗi dòng một câu: `Q1: 2`. Thang 0–2: 0 = sai hoặc không biết, 1 = đúng một phần, 2 = đúng và giải thích được vì sao. Fresher dùng `C1` … `C10` cho 10 câu của C05 §6."
placeholder: |
Q1: 2
Q2: 1
validations:
required: true
- type: input
id: learner
attributes:
label: Học viên
description: "Tên hoặc mã học viên; dùng mã nếu repo công khai. Hai lần đo của cùng một người phải ghi giống nhau."
validations:
required: true
6 changes: 6 additions & 0 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ jobs:
if: ${{ !cancelled() }}
run: npm run deck

# Script tổng hợp số đo hiệu quả học (README §8) chạy trên dữ liệu mẫu fixtures/ và phải ra đúng báo cáo mẫu:
# bắt việc đổi bảng thời lượng lab (T10 §2), bộ câu lên cấp (T10 §4) hay mẫu issue mà quên script.
- name: Learning report (sample data)
if: ${{ !cancelled() }}
run: npm run learning

# Code mẫu C01–C05, U01: biên dịch C# 10 / net8.0, chạy, so output (chú thích <!-- doc-check: … -->).
- name: Setup .NET (code samples)
if: ${{ !cancelled() }}
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added (đo hiệu quả học, GĐ6)
- Hai mẫu issue (`.github/ISSUE_TEMPLATE/`): **Báo cáo lab** (lab, giờ làm thật, phút đọc từng module, kết quả `run-lab.ps1`, báo cáo, link PR) và **Đo đầu/cuối giai đoạn** (cấp, lần đo, điểm 0–2 từng câu, mã học viên). Cả hai qua schema `github-issue-forms` của SchemaStore.
- `tools/docs/learning-report.mjs`: đọc issue bằng `gh`, in giờ làm lab so với T10 §2, phút đọc so với ⏱, mức tăng điểm theo giai đoạn trên đúng bộ vấn đáp của T10 §4, cùng mục "Cần xem lại" cho issue ghi sai dạng. Tên trường đọc từ chính hai mẫu issue, ước lượng và bộ câu đọc từ chính T10.
- CI (job `docs`, bước "Learning report (sample data)", `npm run learning`): chạy script trên 16 issue giả lập ở `tools/docs/fixtures/` (có 5 trường hợp sai cài sẵn), so với báo cáo mẫu đã commit.
- training/README §8 **Đo hiệu quả học**: hai số đo, cách tổng hợp, và khi nào sửa con số của tài liệu (≥ 5 báo cáo lệch khỏi ước lượng; thời gian đọc lệch > 30% ở nhiều module; câu vẫn 0 điểm ở lần đo sau). §6 mentor: hỏi bộ vấn đáp hai lần. T10 quy tắc 3: báo cáo lab bằng mẫu issue, kèm giờ làm thật. Sửa bảng "Bắt đầu từ đâu?" còn ghi lộ trình nhanh ≈ 3,5 giờ (đã là ≈ 4 giờ từ GĐ3).

### Added (tài liệu — tra theo việc cần làm và sơ đồ, GĐ4 phần 2)
- T08 và U03 có bảng **"Tra theo việc cần làm"** ngay trên Mục lục: "bạn cần… → đọc mục nào". Bảng của T08 nối sang cả T01, T05, T07, U01, U03 và R03 (23 việc, kể cả sáu công thức của §12 vốn không hiện ở Mục lục); U03 có 10 việc.
- Bốn sơ đồ mermaid mới, ở các module chưa có sơ đồ nào: U02 §1 (chọn bề mặt UI, dạng câu hỏi lần lượt), T08 §5 (nút palette nhờ một lệnh hỏi điểm qua `ICommandLauncher`), T08 §11 (ghi nhận ở `ObjectErased`, xử lý ở `Application.Idle`), T07 §4 (vòng lặp side database cho cả lô file). Mỗi sơ đồ bám đúng bảng hay code ngay cạnh nó.
Expand Down
25 changes: 23 additions & 2 deletions docs/training/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Bộ tài liệu này dành cho người **kế thừa và phát triển tiếp*
| :--- | :--- | :--- |
| Chưa từng lập trình | [C00 — Bắt đầu từ đây](C00_START_HERE.md) | Giai đoạn 0 (6 tuần) rồi Giai đoạn 1–3: khoảng 20 tuần |
| Biết một ngôn ngữ khác, chưa biết C# | [Bài kiểm tra đầu vào](C00_START_HERE.md#6-bài-kiểm-tra-đầu-vào-bạn-nên-bắt-đầu-từ-đâu) | Thường 2 tuần cho C01–C05, rồi Giai đoạn 1–3 |
| Vững C#, mới với AutoCAD .NET | [Đồ án nhập môn](C05_ASYNC_TESTING_GIT.md#5-đồ-án-nhập-môn-planner-dãy-tủ-điện), rồi [T01](T01_AUTOCAD_NET_FOUNDATIONS.md) | Giai đoạn 1–3: 12–14 tuần ([§3](#3-lộ-trình-đào-tạo)). Cần làm được việc sớm: [lộ trình nhanh](#lộ-trình-nhanh), đọc ≈ 3,5 giờ + lab |
| Vững C#, mới với AutoCAD .NET | [Đồ án nhập môn](C05_ASYNC_TESTING_GIT.md#5-đồ-án-nhập-môn-planner-dãy-tủ-điện), rồi [T01](T01_AUTOCAD_NET_FOUNDATIONS.md) | Giai đoạn 1–3: 12–14 tuần ([§3](#3-lộ-trình-đào-tạo)). Cần làm được việc sớm: [lộ trình nhanh](#lộ-trình-nhanh), đọc ≈ 4 giờ + lab |
| Đã làm AutoCAD .NET, mới vào dự án | [T02](T02_ARCHITECTURE_DEEP_DIVE.md) → [R05 — Golden Sample](../reference/R05_GOLDEN_SAMPLE.md) → [T08](T08_RECIPES_EXTENDING.md) | Đọc theo thứ tự đó; gặp sự cố thì tra [T03](T03_PITFALLS_CASEBOOK.md) |
| Cần làm giao diện: palette, hộp thoại, xem trước | [U00 — Nhánh UI](U00_UI_START_HERE.md), sau [T01 §5 và §7](T01_AUTOCAD_NET_FOUNDATIONS.md#5-document-lock-và-hai-ngữ-cảnh-thực-thi) | Nhánh UI: 3 tuần |
| Mentor | [§6 — Dành cho mentor](#6-dành-cho-mentor) | — |
Expand Down Expand Up @@ -248,7 +248,7 @@ Nạp `bin\Debug\net48\CadCoreFramework.dll` vào AutoCAD bằng `NETLOAD` hoặ
2. **Review bằng checklist** [T09 §2](T09_SENIOR_PLAYBOOK.md#2-checklist-code-review). Yêu cầu học viên tự review PR của mình bằng checklist trước khi gửi.
3. **Ưu tiên lab "sửa backlog thật"** (L06, L08, L11, L12…). Học viên học sâu hơn khi sửa vấn đề có thật. Các mục đó đã được sửa ở PR #6, nên học viên làm trên tag `v1.0.0` rồi **đối chiếu** với lời giải đã merge ([T10 quy tắc 6](T10_LABS_AND_ASSESSMENT.md#1-quy-tắc-làm-lab)) — chấm cả lời giải lẫn chất lượng phần so sánh. Lab L02–L06 có bộ chấm chạy trên AutoCAD thật trong [`labs/`](../../labs/README.md): bảo học viên dán kết quả của `run-lab.ps1` vào báo cáo lab. Kết quả xanh mới là phần máy kiểm được; bảng quan sát, câu phản tư, ESC và đường cao su vẫn do bạn chấm.
4. **Bắt buộc tái hiện trước khi sửa.** Mọi PR sửa lỗi phải mô tả cách tái hiện, như các mục trong T03.
5. **Đánh giá lên cấp** theo [T10 §4](T10_LABS_AND_ASSESSMENT.md#4-đề-đánh-giá-lên-cấp): phần vấn đáp nặng hơn phần trắc nghiệm.
5. **Đánh giá lên cấp** theo [T10 §4](T10_LABS_AND_ASSESSMENT.md#4-đề-đánh-giá-lên-cấp): phần vấn đáp nặng hơn phần trắc nghiệm. Hỏi đúng bộ vấn đáp đó **hai lần**: một lần trước khi học viên bắt đầu giai đoạn, một lần lúc đánh giá; ghi điểm bằng mẫu issue "Đo đầu/cuối giai đoạn" ([§8](#8-đo-hiệu-quả-học)).
6. **Với học viên Giai đoạn 0:** gặp 30 phút mỗi tuần, kiểm đúng "đầu ra" của tuần ở [C00 §2](C00_START_HERE.md#2-lộ-trình-6-tuần). Bắt học viên **gõ lại** ví dụ, không copy. Bài tập C01–C04 và ViewModel của U01-E1 có test chấm sẵn trong [`exercises/`](../../exercises/README.md): test xanh là điều kiện **cần**, chưa đủ. Chọn một bài, bảo học viên giải thích từng dòng. Chấm đồ án nhập môn bằng một bộ **test ẩn** do bạn viết (các giá trị biên, nguyên văn thông điệp lỗi — [C05 §5](C05_ASYNC_TESTING_GIT.md#5-đồ-án-nhập-môn-planner-dãy-tủ-điện)), và đừng công bố lời giải.
7. **Với nhánh UI:** chấm bằng **ảnh** palette ở cả hai theme và bằng **smoke trong AutoCAD**, không chỉ đọc code. Những bước chỉ AutoCAD có giao diện mới kiểm được có danh sách ở cuối [U02](U02_UI_IN_AUTOCAD.md#trạng-thái-kiểm-chứng) và [U03](U03_DRAWING_ON_UI.md#trạng-thái-kiểm-chứng): yêu cầu học viên ghi kết quả của chúng vào mô tả PR. Lab L18 và bài tập U02-E1 (B-31…B-33) làm trên commit `632a6c1` rồi đối chiếu với PR #11, như các lab sửa backlog khác ở mục 3.

Expand Down Expand Up @@ -297,3 +297,24 @@ Nạp `bin\Debug\net48\CadCoreFramework.dll` vào AutoCAD bằng `NETLOAD` hoặ
| Bài tập chấm tự động (`exercises/`, 2026-10-15) | 14 bài, 521 test. Lời giải mẫu (giống đáp án trong tài liệu) qua cả 521 test; code khởi đầu đỏ ở cả 14 bài (513 test đỏ, 8 test xanh là các test kiểm phần đúng sẵn có, như luật cũ của `PanelSpec`). Đối chứng với lỗi cài sẵn (một bài có sẵn lời giải nên test xanh hết, lời giải mẫu in sai một chữ, file bài không có test, lớp test không có bài, lời giải không biên dịch): cả 5 đều bị bắt |
| Lab chấm trên AutoCAD (`labs/`, 2026-10-16) | 20 kiểm tra cho L02–L06, chạy trên accoreconsole của AutoCAD 2024. Lời giải mẫu đạt cả 20. Code khởi đầu đỏ ở 17 kiểm tra của L02–L05 phần 1; 3 kiểm tra framework (L05 B-17, L06) xanh trên `main` vì lỗi đã sửa ở PR #6, còn trên `v1.0.0` (qua `-FrameworkRoot`) thì đỏ, sửa xong thì xanh. Đối chứng với 16 bài làm sai mà trông hợp lý (đếm bằng `GetObject`, đếm theo `br.Name`, mở `LayerTable` `ForWrite`, đếm ModelSpace thay cho CurrentSpace, `Commit` ở TN1, `ForWrite` ở TN2, chỉ đọc thuộc tính ở TN3, `LockDocument` ở TN4, hai `Execute` nối tiếp ở TN5, không đổi màu ở TN6, không đổi UCS → WCS, bản thô có đổi hệ, prompt bên trong `Execute`, hỏi thừa một điểm, filter thiếu `` `*U* ``, không lọc lại theo tên thật): cả 16 đều bị bắt, đúng kiểm tra, đúng lý do. Bản vẽ mẫu lưu ra DWG 2018 rồi chấm lại trên chính file đó: đạt. Nhánh `[SKIP]` (máy không có bộ dynamic block mẫu) thử bằng cách tạm đổi tên file mẫu mà bộ dựng bản vẽ đi tìm. Trên AutoCAD 2024 có giao diện (2026-10-16, bản build lời giải mẫu, mở `lab-sample.dwg`): NETLOAD DLL lab được; `TRAIN_DUMP` in đúng layer và số đếm; `TRAIN_DOORS` tìm đủ 3 DOOR, 2 cái tên `*U…`; với UCS xoay 30°, `TRAIN_LINE2P` có đường cao su, vẽ đúng chỗ click; ESC ở điểm thứ hai thì không vẽ gì |
| Bộ thẻ ôn (`deck/`, 2026-10-16) | 437 thẻ sinh từ tài liệu; mọi dòng đủ 4 cột (mặt trước, mặt sau, tag, GUID), không trùng GUID. CI kiểm file khớp tài liệu: sửa một đáp án mà không sinh lại thì đỏ (đã thử). Lần chạy đầu bắt được hai khối ✅ lệch số câu/đáp án (U01 §8, T09), đã sửa. Chạy được cả trong dự án sinh từ template (file đổi tên theo tên dự án). **Chưa thử** nhập vào Anki trên máy kiểm chứng: định dạng (các dòng `#separator`, `#html`, `#deck`, `#columns`, `#tags column`, `#guid column`) theo tài liệu nhập văn bản của Anki 2.1.55 trở lên |
| Đo hiệu quả học (§8, 2026-10-16) | Hai mẫu issue qua schema `github-issue-forms` của SchemaStore (một bản sai cài sẵn bị bắt). Script tổng hợp chạy trên 16 issue giả lập: số liệu tính tay khớp (L02 trung vị 3,5 giờ lệch 17%; Junior 21,9% → 84,4%), 5 trường hợp sai cài sẵn đều vào mục "Cần xem lại". Đối chứng âm của bước CI: đổi thời lượng L02 ở T10 §2, hay đổi tên một trường của mẫu issue, thì CI đỏ. **Chưa có** số liệu từ học viên thật |

---

## 8. Đo hiệu quả học

Các con số của lộ trình là **ước lượng**: dòng ⏱ tính từ số từ (100 từ/phút), cột Thời lượng của [T10 §2](T10_LABS_AND_ASSESSMENT.md#2-danh-sách-bài-lab) lấy từ kinh nghiệm. Muốn biết lộ trình có giúp học nhanh và chắc thật không, phải đo trên học viên thật. Hai số đo, ghi bằng hai mẫu issue của repo (New issue):

| Đo gì | Mẫu issue | Cách làm | Dùng để |
| :--- | :--- | :--- | :--- |
| **Tiến bộ** của mỗi giai đoạn | Đo đầu/cuối giai đoạn | Cùng **một** bộ câu vấn đáp của [T10 §4](T10_LABS_AND_ASSESSMENT.md#4-đề-đánh-giá-lên-cấp) (Fresher: 10 câu của [C05 §6](C05_ASYNC_TESTING_GIT.md#6-đánh-giá-nhập-môn--fresher)), làm hai lần: trước khi bắt đầu giai đoạn và lúc đánh giá lên cấp. Gấp tài liệu; mentor chấm mỗi câu 0, 1 hay 2 | Mức tăng = điểm % lúc lên cấp − điểm % trước khi học |
| **Thời gian thật** | Báo cáo lab | Giờ làm lab, và phút đọc từng module cần cho lab đó | So với cột Thời lượng của T10 §2 và dòng ⏱ của module |

**Tổng hợp:** `node tools/docs/learning-report.mjs` đọc mọi issue của repo (cần GitHub CLI đã đăng nhập), rồi in ba bảng: giờ làm lab so với ước lượng, phút đọc so với ⏱, mức tăng theo giai đoạn. Cuối báo cáo là mục "Cần xem lại": issue ghi sai dạng, học viên mới có một lần đo, bộ câu thiếu hay thừa câu. Script đọc tên trường từ chính hai mẫu issue, và đọc ước lượng, bộ câu từ chính T10, nên không có số liệu nào phải chép tay. CI chạy nó trên dữ liệu mẫu ([`tools/docs/fixtures/`](../../tools/docs/fixtures/learning-report.md)) để bắt việc đổi T10 hay mẫu issue mà quên script.

**Khi nào sửa con số của tài liệu:**
- Một lab có từ 5 báo cáo trở lên mà trung vị nằm ngoài khoảng ước lượng: sửa cột Thời lượng ở T10 §2. Nếu đó là L01, L03, L04 hay L07 thì sửa cả tổng của [lộ trình nhanh](#lộ-trình-nhanh).
- Thời gian đọc lệch cùng một chiều, hơn 30%, ở nhiều module: đổi tốc độ đọc (`WORDS_PER_MINUTE` trong [`check-reading-time.mjs`](../../tools/docs/check-reading-time.mjs)). CI sẽ chỉ ra mọi dòng ⏱ cần ghi lại.
- Mức tăng thấp ở một giai đoạn: xem câu nào **vẫn** 0 điểm ở lần đo sau. Đó là chỗ tài liệu hay lab chưa dạy được; sửa tài liệu, không trách học viên.

Điểm thấp ở lần đo đầu là bình thường: đó là điểm xuất phát, không dùng để xếp hạng. Repo công khai thì ghi mã học viên thay cho tên.
Loading
Loading