diff --git a/weeks/week-16/README.md b/weeks/week-16/README.md index 917c52e68..ae5134c9c 100644 --- a/weeks/week-16/README.md +++ b/weeks/week-16/README.md @@ -1,35 +1,53 @@ # Week 16(115/06/08-115/06/14) -- 主題:綜合練習 +- 主題:**TDD + Git PR 加壓演練週**(期末上機考倒數第二個練習週) +- 課堂範例:[`in_class/`](./in_class/) — 6/10 計時演練、6/11 獨立演練 - 解題:本週無 `QUESTION-*.md` -- 作業:模擬考前練習與提交紀錄整理 +- 作業:依 6/10、6/11 課堂教案完成 PR,**兩天都必須附 `AI_LOG.md`** +- 備註:6/12(五)生成式 AI 論壇,本週除兩個課堂 PR 外無額外作業 --- -## 本週建議 +## 本週定位 -- 進行定時練習並記錄解題時間 -- 在 `weeks/week-16/solutions//README.md` 記錄複習進度 +Week 15 練的是「流程跑得通」,本週練的是「**有壓力也跑得完**」。三個升級: +1. **時間壓力**:目標 **60 分鐘內開出合法 PR**(期末考實際節奏)。 +2. **鷹架收斂**:6/10 只准看[精簡版檢查表](../week-15/in_class/exam-sop-checklist-lite.md);6/11 連精簡版也收走,全憑記憶跑八步驟。 +3. **提示詞自己打**:本週起課程文件**不再提供任何 AI 提示詞範例**。要問 AI 什麼、怎麼問,自己想、自己打,並在 `AI_LOG.md` 逐字記錄。 + +TDD 原則不變:**先測試(紅燈)→ 再實作(綠燈)**,commit 順序就是評分依據。 + +--- + +## 本週進度 + +| 日期 | 教案 | 題目 | 是否評分 | +|------|------|------|---------| +| 6/10 (三) | [0610-timed-drill.md](./in_class/0610-timed-drill.md) | 數字根(UVA 11332 簡化版) | 不評分,記錄是否準時開出 PR | +| 6/11 (四) | [0611-solo-drill.md](./in_class/0611-solo-drill.md) | 進位計數(UVA 10035 簡化版) | 不評分,記錄 PR 與 AI_LOG 完整度 | + +> 本週兩題均進入期末考 **B 區候選池(不公開)**。 +> B 區範圍是 6/3 ~ 6/18 的週三、週四課堂題——**缺這兩堂,B 區就少一半。** --- -## AI 使用方式 +## 期末考分數結構提醒 -1. 讀 {問題說明} 設計一版針對該問題的 python unit-test 程式,並加上繁體中文的註解放到 {指定目錄} 中 -2. 幫我寫一版 python 程式,並跑完測試,並保留測試紀錄 -3. 幫我加上繁體中文的註解說明 -4. 有更簡單、更容易記憶的方式來寫這個程式,在檔名後加上 `-easy` -5. 幫我加上繁體中文的詳細註解說明 +``` +0 ──── 60 ─── 75 ─────── 80 ─────── 95 ───── 105 +不及格 A區 ↑ B區 C區 + 舊題 保底完成 近期練習 新題(bonus) +``` -## 今天任務 +- **A 區(0–60)**:學期內已上過的 in-class 題目 +- **B 區(60–95)**:6/3 ~ 6/18 週三、週四課堂題目 +- **C 區(95–105)**:全新題(bonus) + +--- -因為 CPE 是要當場打程式設計出來,所以請手動把簡單版本程式在 `week-#/solutions/{學號}` 中打一遍你的程式,並進行測試。 +## 相關文件 -以下是送出標準 -- 參考 [GITHUB_WORKFLOW](GITHUB_WORKFLOW.md) 將程式 PR 出來 -- 內容 (2 程式、1 測試 及 LOG 資料)要包括: - - AI 教你的簡單版本,有中文註解 - - 你手打的程式 - - 測試程式 - - 你手打程式的測試 LOG 記錄 \ No newline at end of file +- [期末考 SOP 檢查表・精簡版](../week-15/in_class/exam-sop-checklist-lite.md)(6/10 唯一可看的版本) +- [AI_LOG 範本](../week-15/in_class/ai-log-template.md) +- [Week 15 流程演練週](../week-15/README.md)(本週的前置訓練) diff --git a/weeks/week-16/in_class/0610-starter/README.md b/weeks/week-16/in_class/0610-starter/README.md new file mode 100644 index 000000000..1706b7af6 --- /dev/null +++ b/weeks/week-16/in_class/0610-starter/README.md @@ -0,0 +1,22 @@ +# 6/10 Starter — 數字根 + +## 使用方式 + +```bash +cp -r weeks/week-16/in_class/0610-starter weeks/week-16/solutions/<學號>/0610 +cd weeks/week-16/solutions/<學號>/0610 +``` + +## 檔案說明 + +- `test_digit_root.py`:測試骨架,**請先補 ≥3 個 test case**(含 edge case 與例外案例) +- `digit_root.py`:實作檔(尚未建立)。測試紅燈 commit 之後再建立。 +- 完成後追加 `AI_LOG.md`(範本見 [`week-15/in_class/ai-log-template.md`](../../../week-15/in_class/ai-log-template.md)) + +## 本日規則 + +- [ ] 只准看[精簡版檢查表](../../../week-15/in_class/exam-sop-checklist-lite.md),完整版請闔上 +- [ ] AI 提示詞自己打,逐字記入 `AI_LOG.md` +- [ ] 60 分鐘內開出 PR + +詳細見 [`../0610-timed-drill.md`](../0610-timed-drill.md)。 diff --git a/weeks/week-16/in_class/0610-starter/test_digit_root.py b/weeks/week-16/in_class/0610-starter/test_digit_root.py new file mode 100644 index 000000000..f93bdc949 --- /dev/null +++ b/weeks/week-16/in_class/0610-starter/test_digit_root.py @@ -0,0 +1,34 @@ +"""數字根 — 測試骨架 + +題目:digit_root(n) 反覆把 n 的各位數字相加,直到剩一位數,回傳該一位數。 + 若 n < 1,應 raise ValueError("n must be >= 1")。 + +待辦: + 1. 自己打提示詞跟 AI 拆 test case,補齊至少 3 個 + - 至少 1 個 edge case + - 至少 1 個例外案例 + (AI 給的案例齊不齊,自己驗收——這是 AI_LOG 要寫的事) + 2. 跑 `python -m unittest` 確認全紅 + 3. commit: "test: add failing tests for digit root" + 4. 寫 digit_root.py,全綠後 commit: "feat: implement digit root" + 5. 寫 AI_LOG.md(提示詞逐字記錄) +""" + +import unittest + +# from digit_root import digit_root # 完成 digit_root.py 後解除註解 + + +class TestDigitRoot(unittest.TestCase): + def test_basic(self): + self.fail("尚未實作 — 自己打提示詞跟 AI 討論後補上") + + def test_edge_case(self): + self.fail("尚未實作") + + def test_invalid_input_raises(self): + self.fail("尚未實作") + + +if __name__ == "__main__": + unittest.main() diff --git a/weeks/week-16/in_class/0610-timed-drill.md b/weeks/week-16/in_class/0610-timed-drill.md new file mode 100644 index 000000000..a32a6ac16 --- /dev/null +++ b/weeks/week-16/in_class/0610-timed-drill.md @@ -0,0 +1,81 @@ +# 6/10 (三)|計時演練 + +> 本日題目進入期末考 **B 區候選池(不公開)**。 +> 本日只准看[精簡版檢查表](../../week-15/in_class/exam-sop-checklist-lite.md),完整版請闔上。 +> **AI 提示詞自己打**,並逐字記入 `AI_LOG.md`。 + +## 學習目標 + +- 在 **60 分鐘**內跑完「紅燈 → 綠燈 → PR + AI_LOG」全流程(期末考實際節奏) +- 第一次在沒有提示詞範例的情況下,自己設計要問 AI 什麼 +- 找出自己「不看完整版就卡住」的步驟,列入考前補強清單 + +## 本日不評分,但要記錄 + +- 是否在時限內開出合法 PR +- `AI_LOG.md` 是否逐字記錄提示詞 + +--- + +## 題目:數字根(UVA 11332 簡化版) + +寫一個函式 `digit_root(n: int) -> int`,反覆把 `n` 的各位數字相加,直到結果只剩一位數為止,回傳那個一位數。 + +- 輸入:正整數 `n`(1 ≤ n ≤ 2,000,000,000) +- 輸出:數字根(1–9 的整數) +- 例外:若 `n < 1`,丟出 `ValueError("n must be >= 1")` + +範例: + +| n | 過程 | 結果 | +|---|------|------| +| 24 | 2+4=6 | 6 | +| 199 | 1+9+9=19 → 1+9=10 → 1+0=1 | 1 | +| 9999 | 36 → 9 | 9 | +| 5 | 已是一位數 | 5 | + +> 此為 UVA 11332 的簡化版(去掉多筆測資輸入,只考核心計算)。 + +--- + +## 必備 test case(至少 3 個) + +1. **基本案例**:用上表任一個多位數 +2. **Edge case**:自己想(一位數?很大的數?) +3. **例外案例**:`n < 1` 應 `raise ValueError` + +跟 Week 15 不同:**這次不會提醒你 AI 容易漏掉哪一個。** 驗收 AI 給的測試是不是齊全,是你的工作——也是 AI_LOG「我改了什麼」該寫的內容。 + +--- + +## 課堂節奏(90 分鐘,前 60 分鐘計時) + +| 時間 | 內容 | 計時目標 | +|------|------|---------| +| 0:00–0:05 | 發題、開分支 `feature/wk16-0610-<學號>` | | +| 0:05–0:15 | **自己打提示詞**跟 AI 拆 test case | ⏱ 10 分鐘內完成拆題 | +| 0:15–0:30 | 寫 `test_digit_root.py` → 紅燈 → `test:` commit | ⏱ 30 分鐘內紅燈 commit | +| 0:30–0:50 | 寫 `digit_root.py` → 綠燈 → `feat:` commit | ⏱ 50 分鐘內綠燈 commit | +| 0:50–1:00 | 寫 `AI_LOG.md`、push、開 PR | ⏱ **60 分鐘內 PR 開出** | +| 1:00–1:30 | 對照精簡版檢查表自評;記下卡住的步驟 | | + +超時不是失敗——**記下超時的是哪一段**,那就是 6/11 和考前要練的重點。 + +--- + +## AI_LOG 要求(本週升級版) + +格式同 [Week 15 範本](../../week-15/in_class/ai-log-template.md),但「我問 AI 什麼」一欄改為: + +- **逐字貼上你實際輸入的提示詞**(可多則,照順序) +- 不接受事後摘要(「我請 AI 幫我寫測試」這種不算) + +「我改了什麼」依然是計分關鍵,0 字 = 期末考此項 0 分。 + +--- + +## starter 檔 + +```bash +cp -r weeks/week-16/in_class/0610-starter weeks/week-16/solutions/<學號>/0610 +``` diff --git a/weeks/week-16/in_class/0611-solo-drill.md b/weeks/week-16/in_class/0611-solo-drill.md new file mode 100644 index 000000000..450ed3777 --- /dev/null +++ b/weeks/week-16/in_class/0611-solo-drill.md @@ -0,0 +1,88 @@ +# 6/11 (四)|獨立演練 + +> 本日題目進入期末考 **B 區候選池(不公開)**。 +> **本日不發任何檢查表**——精簡版也收走,八個步驟全憑記憶。 +> 這刻意比期末考更嚴(6/22 當天會發精簡版)。練習比考試難,考試才會覺得簡單。 + +## 學習目標 + +- 不看任何 SOP 文件,獨立跑完「紅燈 → 綠燈 → PR + AI_LOG」 +- 第二次自己設計提示詞,這次要比 6/10 更精準(一次問到位,少來回) +- 課末用五題自我檢測,產出自己的考前補強清單 + +## 本日不評分,但要記錄 + +- PR 是否合法(分支命名、commit 順序、base/compare 方向) +- `AI_LOG.md` 是否逐字記錄提示詞 + +--- + +## 題目:進位計數(UVA 10035 簡化版) + +寫一個函式 `count_carries(a: int, b: int) -> int`,回傳直式計算 `a + b` 時發生**進位**的次數。 + +- 輸入:兩個非負整數 `a`, `b`(0 ≤ a, b < 10,000,000,000) +- 輸出:進位次數 +- 例外:若 `a` 或 `b` 為負數,丟出 `ValueError("operands must be non-negative")` + +範例: + +| a | b | 結果 | +|---|---|------| +| 123 | 456 | 0 | +| 555 | 555 | 3 | +| 123 | 594 | 1 | +| 999 | 1 | 3 | + +> 此為 UVA 10035 的簡化版(去掉多筆測資輸入與英文單複數輸出,只考核心計算)。 +> 注意 `999 + 1`:前一位的進位會再觸發下一位的進位,要算進去。 + +--- + +## 必備 test case(至少 3 個) + +1. **基本案例**:用上表任一組 +2. **Edge case**:自己想(無進位?連鎖進位?含 0?) +3. **例外案例**:負數輸入應 `raise ValueError` + +AI 給的測試齊不齊、對不對,自己驗收,寫進 AI_LOG。 + +--- + +## 課堂節奏(90 分鐘,前 60 分鐘計時) + +| 時間 | 內容 | 計時目標 | +|------|------|---------| +| 0:00–0:05 | 發題、開分支 `feature/wk16-0611-<學號>` | | +| 0:05–0:50 | 憑記憶跑完八步驟(拆題 → 紅燈 → 綠燈) | ⏱ 50 分鐘內綠燈 commit | +| 0:50–1:00 | `AI_LOG.md`、push、開 PR | ⏱ **60 分鐘內 PR 開出** | +| 1:00–1:30 | 自我檢測(下方五題)+ 整理考前補強清單 | | + +--- + +## 課末自我檢測(必做) + +PR 開出後,**不翻任何文件**,回答[精簡版檢查表](../../week-15/in_class/exam-sop-checklist-lite.md)最後的五題: + +1. 分支命名長什麼樣? +2. `test:` / `feat:` 哪個先?順序錯會怎樣? +3. 為什麼一定要先紅燈?一開始就綠代表什麼? +4. PR 描述至少要含哪三件事? +5. base / compare 各選誰?選錯會怎樣? + +答不出來的題目+今天卡住的步驟=你的**考前補強清單**,寫進 PR 描述最後一段。 +6/17、6/18(Week 17)是考前最後兩堂練習,帶著這份清單來。 + +--- + +## AI_LOG 要求 + +同 6/10:「我問 AI 什麼」**逐字貼上實際輸入的提示詞**;「我改了什麼」0 字 = 期末考此項 0 分。 + +--- + +## starter 檔 + +```bash +cp -r weeks/week-16/in_class/0611-starter weeks/week-16/solutions/<學號>/0611 +``` diff --git a/weeks/week-16/in_class/0611-starter/README.md b/weeks/week-16/in_class/0611-starter/README.md new file mode 100644 index 000000000..3de3e1354 --- /dev/null +++ b/weeks/week-16/in_class/0611-starter/README.md @@ -0,0 +1,23 @@ +# 6/11 Starter — 進位計數 + +## 使用方式 + +```bash +cp -r weeks/week-16/in_class/0611-starter weeks/week-16/solutions/<學號>/0611 +cd weeks/week-16/solutions/<學號>/0611 +``` + +## 檔案說明 + +- `test_carry_counter.py`:測試骨架,**請先補 ≥3 個 test case**(含 edge case 與例外案例) +- `carry_counter.py`:實作檔(尚未建立)。測試紅燈 commit 之後再建立。 +- 完成後追加 `AI_LOG.md`(範本見 [`week-15/in_class/ai-log-template.md`](../../../week-15/in_class/ai-log-template.md)) + +## 本日規則 + +- [ ] **不看任何檢查表**,八個步驟憑記憶 +- [ ] AI 提示詞自己打,逐字記入 `AI_LOG.md` +- [ ] 60 分鐘內開出 PR +- [ ] 課末完成五題自我檢測,補強清單寫進 PR 描述 + +詳細見 [`../0611-solo-drill.md`](../0611-solo-drill.md)。 diff --git a/weeks/week-16/in_class/0611-starter/test_carry_counter.py b/weeks/week-16/in_class/0611-starter/test_carry_counter.py new file mode 100644 index 000000000..0f3af6c5f --- /dev/null +++ b/weeks/week-16/in_class/0611-starter/test_carry_counter.py @@ -0,0 +1,33 @@ +"""進位計數 — 測試骨架 + +題目:count_carries(a, b) 回傳直式計算 a + b 時發生進位的次數。 + 若 a 或 b 為負數,應 raise ValueError("operands must be non-negative")。 + +待辦: + 1. 自己打提示詞跟 AI 拆 test case,補齊至少 3 個 + - 至少 1 個 edge case(提示一個方向:進位會不會連鎖?) + - 至少 1 個例外案例 + 2. 跑 `python -m unittest` 確認全紅 + 3. commit: "test: add failing tests for carry counter" + 4. 寫 carry_counter.py,全綠後 commit: "feat: implement carry counter" + 5. 寫 AI_LOG.md(提示詞逐字記錄) +""" + +import unittest + +# from carry_counter import count_carries # 完成 carry_counter.py 後解除註解 + + +class TestCountCarries(unittest.TestCase): + def test_basic(self): + self.fail("尚未實作 — 自己打提示詞跟 AI 討論後補上") + + def test_edge_case(self): + self.fail("尚未實作") + + def test_invalid_input_raises(self): + self.fail("尚未實作") + + +if __name__ == "__main__": + unittest.main() diff --git a/weeks/week-16/in_class/README.md b/weeks/week-16/in_class/README.md new file mode 100644 index 000000000..8d3b1256f --- /dev/null +++ b/weeks/week-16/in_class/README.md @@ -0,0 +1,53 @@ +# Week 16 課堂範例:TDD + Git PR 加壓演練 + +本週兩堂課的共同目標:**在接近期末考的壓力條件下,把 SOP 跑到不用看表也不會錯。** + +- 6/10 (三):[計時演練](./0610-timed-drill.md) — 60 分鐘完賽,只准看精簡版檢查表 +- 6/11 (四):[獨立演練](./0611-solo-drill.md) — 不給任何檢查表,全憑記憶 + +--- + +## 鷹架收斂進度表 + +| 時間點 | 可看的 SOP 文件 | AI 提示詞 | +|--------|----------------|-----------| +| Week 15(6/3、6/4) | 完整版檢查表 | 教案有提示問法 | +| **6/10(本週三)** | **只有[精簡版](../../week-15/in_class/exam-sop-checklist-lite.md)** | **自己打,逐字記入 AI_LOG** | +| **6/11(本週四)** | **不發任何檢查表** | **自己打,逐字記入 AI_LOG** | +| 6/22 期末考 | 精簡版(當天發) | 自己打,AI_LOG 計分 | + +> 6/11 刻意比期末考更嚴(連精簡版都沒有)。練習比考試難,考試才會覺得簡單。 + +--- + +## 本週新規則:提示詞自己打 + +從本週起,課程文件**不再提供 AI 提示詞範例**,理由: + +1. 期末考評的是**你**跟 AI 協作的能力,不是你貼範本的能力。 +2. `AI_LOG.md` 的「我問 AI 什麼」一欄,本週起必須**逐字貼上你實際輸入的提示詞**(不是事後摘要)。 +3. 複製課程文件舊範例、或複製同學的提示詞,在 AI_LOG 中看得出來——千篇一律的提示詞配上「我改了什麼:無」,期末考此項 **0 分**。 + +打提示詞前先想清楚三件事(這不是範本,是思考順序): + +- 你要 AI 產出**什麼**(測試?實作?解釋?) +- 題目有哪些**條件**是 AI 看不到、你必須講的(函式簽名、範圍、例外要求) +- AI 給的東西你要用**什麼標準**驗收(紅燈?範例值?例外案例有沒有?) + +--- + +## TDD 原則不變(評分依據) + +- **先 test 再 impl**:`git log --reverse` 必須先看到 `test:` 再看到 `feat:`。順序反了 = 0 流程分。 +- **必須紅燈 → 綠燈**:一開始就綠的測試證明不了任何事。 +- **必須開 PR**:fork 分支 → 課程 repo 的 `main`,不開 PR 不算完成。 + +--- + +## 相關文件 + +- [6/10 教案](./0610-timed-drill.md) +- [6/11 教案](./0611-solo-drill.md) +- [SOP 檢查表・精簡版](../../week-15/in_class/exam-sop-checklist-lite.md) +- [AI_LOG 範本](../../week-15/in_class/ai-log-template.md) +- [Week 15 完整版檢查表](../../week-15/in_class/README.md#期末考-sop-檢查表學生版完整版)(本週課堂上**不准看**,課後複習用)