Workshop — 3 CLI Tools ใน 1 สัปดาห์
ปิดเฟส Code Literacy ด้วยการ "สร้างของจริง 3 ชิ้น" · แต่ละชิ้นเริ่มจาก spec → plan → code → test → docs · นี่คือ "workflow ที่ใช้จริงตลอด 15 สัปดาห์ที่เหลือ"
เป้าหมายสัปดาห์นี้
- สร้าง CLI tool ที่ทำงานได้จริง 3 ตัว
- ฝึก workflow Spec→Plan→Code→Test→Docs ให้ติดเป็นนิสัย
- แต่ละ tool ต้องใช้ได้กับ real input ของตัวเอง (ไม่ใช่แค่ test case)
- มี README.md ที่ใครก็ใช้ tool ตามได้
- เปรียบเทียบ code ของคุณกับ reference implementation ในหน้านี้
🎯 3 Tools ต่างกัน แต่ใช้ Pattern เดียวกัน
ทุก CLI tool ใน 15 สัปดาห์นี้ — และในงานจริง — ใช้ "pattern" เดียวกัน:
argv / input / file/] --> validate{Valid?} validate -->|No| err[/Error msg/] validate -->|Yes| logic[Process
คำนวณ / parse / aggregate] logic --> persist[(Persist
ถ้าต้องเก็บ)] logic --> output[/Output
print / file/] persist --> output classDef io fill:#0d3f3a,stroke:#2dd4bf,color:#fff classDef logic fill:#3b2962,stroke:#8b5cf6,color:#fff classDef decision fill:#5c2618,stroke:#ff7a18,color:#fff classDef err fill:#5c1818,stroke:#ef4444,color:#fff classDef db fill:#1e3a5f,stroke:#3776ab,color:#fff class input,output io class logic logic class validate decision class err err class persist db
Tool 1 (Grade): Input→Logic→Output · Tool 2 (WC): Input(file)→Logic→Output · Tool 3 (TODO): Input(argv)→Persist→Output · เห็น pattern เดียวกันมั้ย?
🛠️ Tool 1 — Grade Calculator ตัวจริง
Spec
## Spec: Course Grade Calculator
**ปัญหา:** นักศึกษาอยากรู้ระหว่างเทอมว่า "ถ้าฉันได้คะแนน X final ฉันจะได้เกรดอะไร"
แทนที่จะเดาเอง
**Input:**
- คะแนน homework (รวมแล้ว, max 30)
- คะแนน midterm (max 30)
- คะแนน final ที่เดาว่าจะได้ (max 40)
**Output:**
- คะแนนรวม
- เกรดที่จะได้ (A/B+/B/C+/C/D+/D/F ตามเกณฑ์ภาควิชา)
- คะแนน final ขั้นต่ำเพื่อได้เกรด B (target)
**Rules:**
- ใช้เกณฑ์: 80+=A, 75+=B+, 70+=B, 65+=C+, 60+=C, 55+=D+, 50+=D, <50=F
- ถ้า input ติดลบ/เกิน max → error
**Success:**
- (hw=25, mid=24, final=32) → รวม 81 → A
- target B (70) ต้องการ final อย่างน้อยเท่าไหร่
**Non-goals:**
- ยังไม่เซฟ history
- ยังไม่รองรับวิชาที่มี weight ต่างกัน
ตัวอย่าง output
$ python grade_calc.py
คะแนน homework (max 30): 25
คะแนน midterm (max 30): 24
คะแนน final คาดการณ์ (max 40): 32
📊 คะแนนรวม: 81 / 100
🎓 เกรดที่คาดว่าได้: A
🎯 เป้าหมาย B (70+):
ต้องการ final อย่างน้อย: 21 / 40 คะแนน
(ตอนนี้คาดว่าได้ 32 → ผ่านเป้าแล้ว ✅)
🐍 Reference Implementation — ลองรันก่อนเขียนเอง
นี่คือ working version ที่ตรงตาม spec · รันดูก่อน · เปลี่ยนค่า input ดูพฤติกรรม
💡 เปรียบเทียบกับของคุณ: หลังเขียน tool เสร็จ — เอามาวางใน Python Runner ของหน้านี้ หรือใช้ Diff Viewer เทียบบรรทัดต่อบรรทัด
🛠️ Tool 2 — Word Counter ตัวจริง
Spec
## Spec: Word/Line Counter
**ปัญหา:** อาจารย์ขอให้นักศึกษาเขียนรายงาน 1000-1500 คำ — ต้องการเครื่องมือนับเร็ว ๆ
ที่ทำงานกับไฟล์ .txt ได้
**Input:**
- path ของไฟล์ .txt (argument หรือ input)
**Output:**
- จำนวนบรรทัด
- จำนวนคำ
- จำนวนตัวอักษร (รวม / ไม่รวมช่องว่าง)
- คำที่พบบ่อย 10 อันดับแรก
**Rules:**
- ภาษาไทย: ใช้ space แยกคำ (ไม่ต้องใช้ word segmenter)
- skip บรรทัดว่าง
- ตัด punctuation ออกก่อนนับ
**Success:**
- ทำงานกับไฟล์ขนาด < 100KB
- รัน < 1 วินาที
**Non-goals:**
- ยังไม่รองรับ .docx / .pdf
- ยังไม่ใช้ Thai word segmenter (PyThaiNLP)
ตัวอย่าง output
$ python wc.py report.txt
📄 report.txt
บรรทัด: 87
คำ: 1247
ตัวอักษร: 8,432 (ไม่นับช่องว่าง 7,015)
🏆 คำที่พบบ่อย:
1. ระบบ → 42
2. นักศึกษา → 38
3. ข้อมูล → 25
...
Tool นี้แนะนำ Python concept ใหม่: open(), str.split(), collections.Counter
🐍 Reference Implementation
ใน browser นี้ไม่มี file system จริง · เลยใช้ "text ตัวอย่างใน input" แทน · ของจริงใน Cursor
จะใช้ open(sys.argv[1])
💡 ลองเปลี่ยน input เป็น paragraph อื่น · หรือใส่ word ซ้ำ ๆ ดูว่า top ranking ขึ้น
🛠️ Tool 3 — TODO Manager (มี JSON persistence)
Spec
## Spec: TODO Manager CLI
**ปัญหา:** นักศึกษาอยากเก็บ TODO ของวิชาต่าง ๆ — แทนการเขียนใน Notes ของมือถือ
ที่หาไม่เจอตอนต้องการ
**Commands:**
- add <ข้อความ> → เพิ่ม TODO
- list → แสดงทั้งหมด
- done <id> → mark ว่าเสร็จ
- delete <id> → ลบ
**Persistence:**
- เซฟลง todo.json ใน folder ของโปรแกรม
- โหลด todo.json ทุกครั้งที่รัน (ถ้ามี)
**Output:**
- list แสดงเป็น:
[ ] 1. ทำการบ้านวิชา CP
[x] 2. ส่งใบงาน lab 3
[ ] 3. นัด TA Tuesday
**Rules:**
- id เพิ่มทีละ 1, ไม่ใช้ id ซ้ำแม้จะลบไปแล้ว
- list เรียงตาม id
**Success:**
- เพิ่ม + รัน list → เห็น
- มาร์ค done + รัน list → เห็น [x]
- ปิดโปรแกรม + เปิดใหม่ → ข้อมูลยังอยู่
ตัวอย่าง session
$ python todo.py add "ทำการบ้านวิชา CP"
✅ เพิ่ม TODO #1
$ python todo.py add "ส่งใบงาน lab 3"
✅ เพิ่ม TODO #2
$ python todo.py list
📋 TODO List
[ ] 1. ทำการบ้านวิชา CP
[ ] 2. ส่งใบงาน lab 3
$ python todo.py done 1
✅ มาร์ค TODO #1 เสร็จแล้ว
$ python todo.py list
📋 TODO List
[x] 1. ทำการบ้านวิชา CP
[ ] 2. ส่งใบงาน lab 3
Tool นี้แนะนำ Python concept ใหม่:
sys.argv— รับ argument จาก command linejson.load() / json.dump()— เซฟ/โหลดข้อมูล- การจัดการไฟล์ "ไม่มีก็สร้าง"
🐍 Reference Implementation (in-memory simulation)
Browser ไม่มี file system · simulation นี้เก็บใน memory แทน · ของจริงใน Cursor ใช้
json.load(open("todo.json")) · ลองพิมพ์ command หลาย ๆ ครั้ง
💡 ใน Input — แต่ละบรรทัดคือ 1 command · ลองเพิ่ม / ลบ / list ดูว่า state คงอยู่
🧪 Workshop Process — สำหรับทุก Tool
- (วันจันทร์-อังคาร) เลือก Tool — ใช้ spec ตามที่ให้ หรือดัดให้เข้ากับ "ของจริง" ของคุณ (เช่น ใช้คะแนนวิชาที่กำลังเรียน)
- ขอ AI วาง plan — function names, validation, test cases · ตอบคำถามที่ AI ถามให้ครบ
- ขอ AI เขียน code — อ่านทุกบรรทัด · ถ้าไม่เข้าใจ → ถาม
-
รัน test cases ทั้งหมด
— บันทึกใน
test-results.md - ใช้กับ "ของจริง" — Tool 1: ใส่คะแนนตัวเอง · Tool 2: ใส่ไฟล์รายงานจริง · Tool 3: ใส่ TODO จริงของสัปดาห์นี้
- เขียน README.md ที่: คำอธิบาย + วิธีติดตั้ง + วิธีใช้ + ตัวอย่าง output + known issues
- commit + push GitHub — แต่ละ tool เป็นโฟลเดอร์ใน repo เดียวกัน
- ทำ Tool ถัดไป — repeat 1-7
📁 โครงสร้าง Repo ที่แนะนำ
cp-w07-cli-tools/
├── README.md ← อธิบายภาพรวม + ลิงก์ไป tool แต่ละตัว
├── grade-calc/
│ ├── grade_calc.py
│ ├── README.md
│ ├── spec.md
│ └── test-results.md
├── word-counter/
│ ├── wc.py
│ ├── sample.txt
│ ├── README.md
│ ├── spec.md
│ └── test-results.md
└── todo-manager/
├── todo.py
├── todo.json ← สร้างอัตโนมัติเมื่อรันครั้งแรก
├── README.md
├── spec.md
└── test-results.md
📝 Template — README.md ที่ดี
# Grade Calculator
CLI tool คำนวณเกรดจากคะแนน hw + midterm + final
และบอก final ขั้นต่ำเพื่อได้ตามเป้า
## ติดตั้ง
ต้องมี Python 3.11+
## วิธีใช้
```bash
python grade_calc.py
```
แล้วกรอกคะแนนตามที่ถาม
## ตัวอย่าง
[screenshot หรือ output ตัวอย่าง]
## Known issues
- ยังไม่รองรับวิชาที่มี weight ต่างกัน
- ยังไม่ save history
## License
สำหรับใช้ในวิชา Computer Programming คณะวิศวกรรมศาสตร์ UBU
✅ "Done" Rubric — รู้ได้ยังไงว่า tool เสร็จแล้ว
"พอ" ของแต่ละคนไม่เท่ากัน · ใช้ checklist นี้ทุก tool — ถ้าได้ครบ ≥ 8/10 = ส่งได้
| เกณฑ์ | ผ่านเมื่อ |
|---|---|
| 1. มี spec.md | ผ่าน Spec Scorecard ≥ 75% (ใน W06) |
| 2. รันได้ | python tool.py รันแล้วไม่ crash |
| 3. Happy path ผ่าน | Input ปกติ → Output ตรงตาม spec |
| 4. Edge case ผ่าน | Input ผิด (empty, ติดลบ, type ผิด) → error message ชัด |
| 5. ทำงานกับ "ของจริง" | ลองใช้กับข้อมูลจริงของตัวเอง 1 ครั้ง |
| 6. test-results.md | มีตาราง test case + ผล ≥ 5 case |
| 7. README.md | install + usage + screenshot |
| 8. Code อ่านง่าย | function names ชัด · ไม่มี code ที่ใช้งานไม่ได้ |
| 9. Git commit ≥ 5 | commit ระหว่างทาง · ไม่ใช่ 1 commit ใหญ่ |
| 10. เพื่อน 1 คน "ใช้ได้" | ส่งให้เพื่อน clone → รันตาม README → ใช้ได้ |
🎯 Bonus Challenges (ทำได้ค่อยทำ)
| Bonus | Tool | ทำอะไร |
|---|---|---|
| B1 | grade_calc | เซฟ history ลง history.json + คำสั่ง --history |
| B2 | wc | รองรับหลายไฟล์ + รวมผล |
| B3 | wc | ใช้ argparse รับ flag เช่น --top 20 |
| B4 | todo | เพิ่มคำสั่ง edit <id> <new text> |
| B5 | todo | เพิ่ม tag และ filter list --tag urgent |
| B6 | todo | เพิ่ม due date + สีถ้าใกล้ |
ข้อผิดที่พบบ่อย
ส่งงานสัปดาห์นี้
- 📁 GitHub repo
cp-w07-cli-tools/มีโครงสร้างตามด้านบน - 📷 screenshot การรันแต่ละ tool
- 📋 test-results.md ของแต่ละ tool ครบทุกเคส
- 📝 README.md ของแต่ละ tool (3 ไฟล์)
Reference จาก slide เดิม
Workshop นี้รวมทักษะจาก Topic 2-7 ของ slide เดิม + วิธีการ AI-assist จาก Topic 11