本章目標建立演算法思維的基本框架:把日常工作轉成輸入、輸出、限制、成本
學會在動手寫程式之前,先把問題說清楚
透過可執行範例與測試,養成可重現的工作流程
情境與限制情境:你必須在有限時間內整理待辦事項並排出優先順序
輸入:任務清單、優先度(數字越小越急)、截止日、預估時間
輸出:排序後的任務清單,以及可輸出的 JSON 紀錄
限制:必須保留可測試與可重現步驟,排序結果不能每次都不一樣
可重現規則本章程式碼位置:
examples/ch01/本章核心模組:
src/algo_in_life/time_log.py測試:
pytest -q tests/test_ch01_time_log.py資料:
data/synthetic/
演算法思維是什麼¶
很多人聽到「演算法」,第一個聯想是競賽題或複雜數學。但在日常工作裡,演算法思維其實更接近一種拆解問題的習慣。
你今天打開任務清單,腦中開始思考:
這幾件事哪個比較急?
哪個可以等到下午再做?
哪個其實只要 10 分鐘,拖著不做反而一直佔著心理空間?
這些判斷,本身就是在做排序與篩選。只是你平常用的是直覺,而不是明確規則。
演算法思維做的事,就是把直覺背後的邏輯說清楚——讓它可以被溝通、被驗證、也被改進。
先把問題說清楚,再動手¶
一個常見的陷阱是:問題還沒想清楚就開始寫程式,最後程式只是在放大原本的混亂。
在動手之前,值得先回答三個問題:
| 問題 | 在本章的對應 |
|---|---|
| 你手上有什麼資訊? | 任務清單:title、priority、due_date、estimate_hours |
| 你最後想得到什麼? | 排序後的任務順序,讓最應該先做的事排在最前面 |
| 過程有哪些限制? | 相同優先度時,截止日較早的任務要先排;結果必須可重現 |
這三個問題,對應的就是演算法設計裡的輸入、輸出、限制。把這三件事說清楚,後面的實作通常會清楚很多。
排序規則:優先度 → 截止日¶
本章的核心邏輯是雙鍵排序:先看優先度,相同優先度時再看截止日。
sorted(tasks, key=lambda item: (item["priority"], item["due_date"]))這行程式的意思是:用 (priority, due_date) 這個元組當排序鍵。Python 在比較元組時,會先比第一個元素,相同才比第二個——這正好符合「優先度第一、截止日第二」的規則。
舉個例子:
| 任務 | 優先度 | 截止日 |
|---|---|---|
| 整理週會紀錄 | 2 | 2026-04-18 |
| 完成專案提案 | 1 | 2026-04-20 |
排序結果:完成專案提案先(優先度 1 < 2),整理週會紀錄後——即使它的截止日更早。
這個例子說明了一件重要的事:排序規則和直覺不一定一致,正因為如此,把規則寫清楚(並且有測試固定它)才有意義。
可重現比「正確」更重要¶
「可重現」這個詞會在本書反覆出現。它的意思是:
給定相同的輸入,永遠得到相同的輸出。
為什麼這件事重要?
溝通:你可以把排序結果給同事看,大家討論的是同一份清單,而不是「你電腦上的版本」。
除錯:如果結果有問題,你知道從哪裡找起;如果每次都不一樣,你連問題在哪都不知道。
信任:一個可重現的工具,比一個「有時準、有時不準」的工具更容易被長期使用。
本章透過測試固定排序行為:
# tests/test_ch01_time_log.py
tasks = [
{"title": "B", "priority": 2, "due_date": "2026-04-20", "estimate_hours": 2},
{"title": "A", "priority": 1, "due_date": "2026-04-21", "estimate_hours": 1},
]
sorted_tasks = sort_tasks(tasks)
assert sorted_tasks[0]["title"] == "A" # 優先度 1 排第一這個測試不只是在確認「A 排在 B 前面」,更是在固定一條規則:只要優先度數字較小,就先排,不管截止日如何。日後改動排序邏輯時,測試會立刻告訴你規則有沒有被意外破壞。
演算法思維不是只有「快」¶
很多入門書一提到演算法,就很快進到速度比較(O(n)、O(log n)……)。但在日常工作裡,你真正在意的往往不是速度,而是:
可說明:決策邏輯能不能讓別人看懂?
可重現:同一批資料重做一次,結果會不會差很多?
可修改:規則要調整時,改哪裡、改多少,影響範圍清不清楚?
本書後面每一章都有這個取向:先把問題說清楚,再談怎麼解,最後用測試固定它。速度只有在資料量真的大到有感時,才會是第一個該在意的事。
實作範例¶
請參考 examples/ch01/time_log.py。請在專案根目錄執行程式,以確保路徑正確。
from examples.ch01.time_log import sort_tasks, format_tasks
tasks = [
{"title": "完成專案提案", "priority": 1, "due_date": "2026-04-20", "estimate_hours": 3},
{"title": "整理週會紀錄", "priority": 2, "due_date": "2026-04-18", "estimate_hours": 1},
]
sorted_tasks = sort_tasks(tasks)
for line in format_tasks(sorted_tasks):
print(line)
# 2026-04-20 | P1 | 完成專案提案 (3h)
# 2026-04-18 | P2 | 整理週會紀錄 (1h)也可以直接用命令列執行並輸出 JSON:
python -m examples.ch01.time_log --output sorted_tasks.json示範流程包含:
把待辦事項拆成可比較的欄位(
priority、due_date、estimate_hours)用雙鍵穩定排序決定優先順序
格式化輸出為可閱讀的字串或 JSON 檔案
透過測試固定排序規則,防止日後修改時意外破壞行為