作業回顧與解題:最佳實作與除錯技巧

Week 16: 作業檢視、回顧與統整

張傑帆

National Taiwan University

作業檢視、回顧與統整

目錄

Alt1

🎯 學習目標

本週我們將化身「程式偵探」,一起檢視過去的作業,從錯誤中學習、向優秀作品取經!
你將學會:

  • 辨識常見錯誤與最佳實作模式
  • 練習程式碼重構與優化
  • 掌握除錯與測試的實用技巧

一、作業常見錯誤大解析 1/2

常見繳交問題:

  • 未填寫姓名:作業檔案或表單未標註學生姓名,導致無法辨識作者。
  • 未標註學校名稱:缺少學校資訊,影響成績統計與歸檔。
  • 檔案未成功上傳:檔案遺漏、格式錯誤或雲端連結失效,導致老師無法開啟。
  • 檔名格式錯誤:未依規定命名(如缺少班級、姓名、作業編號),容易混淆。
  • 內容不完整:僅上傳部分檔案或缺少必要說明文件。
  • 未依規定格式繳交:如應繳 .py 檔卻上傳 .txt 或圖片檔。

建議:繳交前請再次確認檔案內容、命名與上傳狀態,避免影響成績。

一、作業常見錯誤大解析 2/2

常見問題:

錯誤類型 常見現象 解決建議
變數命名混亂 a, b, c 無意義命名 用有意義的名稱
邏輯判斷錯誤 if 條件順序錯、遺漏 else 條件詳加檢查
無限迴圈 while 條件寫錯,程式卡住 加入終止條件
輸入格式錯誤 忘記轉型、input未處理例外 用 try-except 處理
重複程式碼 多段類似邏輯重複 用函式封裝

二、優良作業範例分享

本週我們分別從HW5與HW6挑選優良範例,說明其設計亮點與可改進處。

【HW5】優良範例

範例一:台東女中蔡同學的學習追蹤系統

alt

# 主程式 main.py 節錄
import tkinter as tk
from study_logger import StudyLogger
from stats_plotter import StatsPlotter
# ...existing code...
def record_study():
    subject = subject_entry.get().strip()
    time_val = time_entry.get().strip()
    # ...existing code...
    msg = logger.log_study(subject, minutes)
    # ...existing code...
    update_chart()
# ...existing code...
def update_chart():
    # ...existing code...
    for subject, mins in subjects.items():
        filtered[subject] = filtered.get(subject, 0) + mins
    # ...existing code...

優點:

  • 介面美觀,功能完整(記錄、查詢、匯出、圖表)。
  • 程式結構清楚,資料儲存與繪圖分離,易於維護。
  • 有例外處理,使用者體驗佳。

可改進處:

  • 主程式與GUI邏輯仍有部分耦合,可再進一步模組化。
  • 資料檔案路徑可考慮集中管理,便於部署。

範例二:高雄中山工商趙同學的函式工具模組

def add(a, b):
    return a + b

def square(n):
    return n ** 2

def divide(a, b):
    if b == 0:
        return "錯誤:除數不能為 0"
    return a / b

def average(numbers):
    if not numbers:
        return 0
    return sum(numbers) / len(numbers)
# ...existing code...

優點:

  • 每個功能獨立成函式,易於重複使用與測試。
  • 有處理除以零、空清單等例外情境。
  • 測試區塊明確,方便驗證功能。

可改進處:

  • 若能加入型別註解與更詳細的說明,會更易於維護。
  • 可以將錯誤訊息改為丟出例外,讓呼叫端決定如何處理。

範例三:台南二中張同學的繪圖模組

def create_chart(
    data: Dict[str, Union[int, float]],
    chart_type: str = 'bar',
    # ...existing code...
):
    # ...existing code...
    if chart_type == 'bar':
        bars = ax.bar(categories, values, color=colors, edgecolor='white', linewidth=1.2, alpha=0.9)
        # ...existing code...
    elif chart_type == 'line':
        ax.plot(categories, values, marker='o', linewidth=3, markersize=8,
                color=colors[0],
                markerfacecolor='white', markeredgewidth=2)
        # ...existing code...
    # ...existing code...

優點:

  • 支援多種圖表型態(bar/line),參數彈性高。
  • 有型別註解與詳細註解,易於理解與擴充。
  • 預設顏色主題與自訂標註,視覺效果佳。

可改進處:

  • 若能將資料驗證與錯誤處理再加強,會更好。
  • 測試資料與主程式可分離,利於模組重用。

【HW6】優良範例

範例一:台東女中蔡同學的學生成績分析系統

class StudentSystem:
    def load_csv(self):
        path = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")])
        # ...existing code...
        self.df = pd.read_csv(path)
        # ...existing code...
        self.refresh_table()
        messagebox.showinfo("成功", "CSV 載入完成!")

    def calculate(self):
        if self.df is None:
            messagebox.showwarning("錯誤", "請先匯入 CSV!")
            return
        subjects = ["國文", "英文", "數學", "自然", "社會"]
        self.df[subjects] = self.df[subjects].apply(pd.to_numeric, errors="coerce").fillna(0)
        self.df["總分"] = self.df[subjects].sum(axis=1)
        self.df["平均"] = self.df["總分"] / len(subjects)
        self.df["排名"] = self.df["總分"].rank(ascending=False, method="min").astype(int)
        # ...existing code...

alt

優點:

  • 介面美觀,功能齊全(匯入、計算、圖表、儲存)。
  • 有資料驗證與例外處理,使用者體驗佳。
  • 成績計算、排名、等第分類等功能模組化,易於維護。

可改進處:

  • 若能將資料處理與UI進一步分離,會更利於擴充。
  • 可考慮增加單元測試,確保每個功能正確。

範例二:台南南科實中唐同學的進步分析與圖表

# 進步幅度與圖表分析
df['期中考_總分'] = df[[f'{s}_期中考' for s in SUBJECTS]].sum(axis=1)
df['期末考_總分'] = df[[f'{s}_期末考' for s in SUBJECTS]].sum(axis=1)
df['總分進步幅度'] = df['期末考_總分'] - df['期中考_總分']
df['期中考_排名'] = df['期中考_總分'].rank(method='min', ascending=False).astype(int)
df['期末考_排名'] = df['期末考_總分'].rank(method='min', ascending=False).astype(int)
# ...existing code...
plt.figure(figsize=(14, 7))
rects1 = plt.bar(x - width/2, df['期中考_總分'], width, label='期中考總分', color='lightgray')
rects2 = plt.bar(x + width/2, df['期末考_總分'], width, label='期末考總分', color=progress_color)
plt.axhline(pass_line, color='green', linestyle='--', linewidth=1, label=f'總分及格線 ({pass_line} 分)')
# ...existing code...

alt text

alt text

alt text

優點:

  • 進步幅度、排名、各科進步等指標計算完整。
  • 圖表豐富,能清楚呈現進步/退步、及格線、各科趨勢。
  • 程式有詳細註解,易於閱讀與學習。

可改進處:

  • 若能將資料分析與繪圖封裝成函式,主程式會更精簡。
  • 可考慮將檔案路徑、參數集中管理,提升彈性。

三、程式碼重構與優化技巧

  • 抽出重複邏輯:將重複的程式片段包裝成函式,主程式更簡潔。
  • 語意明確命名:變數、函式名稱要能一眼看懂用途。
  • 善用內建工具:如 sum, max, min, enumerate, zip 等,讓程式更精煉。
  • 逐步測試:每完成一小段就測試,錯誤容易定位。

四、除錯與測試方法

技巧 用法說明
print 調試 插入 print 觀察變數內容
逐步執行 用 IDE/Colab 的逐行執行功能
assert 驗證 自動檢查預期結果
邊界測試 測試極端或特殊輸入
try-except 捕捉例外,避免程式崩潰
單元測試 為函式撰寫測試案例,確保正確性
問AI輔助 利用 ChatGPT 等工具尋找錯誤原因

運算思維總整理

  • 模式識別:觀察並歸納常見錯誤與優良寫法,建立解題經驗。
  • 演算法設計:思考如何用更簡潔、有效率的方式解決問題。
  • 問題拆解:將大問題分割成小步驟,逐一處理,降低複雜度。
  • 抽象化:找出問題的本質,設計通用的解決方案或函式。
  • 測試與修正:透過測試驗證結果,持續修正與優化程式。

本週總結 🎉

  • 學會從錯誤中成長,欣賞同儕的優秀解法
  • 練習除錯、重構與優化技巧
  • 為期末專案打下堅實基礎!

※先想一下期末專案要做什麼吧!

-----------------------------------------

圖片放大特效

table樣式

- [學習目標](#🎯-學習目標) - [課程流程](#課程流程)

- [小練習 1:找出並修正錯誤](#小練習-1找出並修正錯誤) - [小練習 2:程式優化挑戰](#小練習-2程式優化挑戰) - [運算思維總整理](#運算思維總整理)

- [作業:本週練習](#作業本週練習)

--- # 課程流程 1. 作業檢討與常見問題解析 2. 優良作品範例分享 3. 重構與優化技巧教學 4. 除錯與測試方法實戰 5. 小練習:動手修正與優化

- **重複繳交或多次修改**:未註明最終版本,造成批改困擾。

--- # 小練習 1:找出並修正錯誤 請觀察下列程式,指出錯誤並修正,讓它能正確計算清單總和。 ```python nums = input("請輸入數字,以空白分隔:").split() total = 0 for n in nums: total += n print("總和:", total) ``` --- ## 小練習 1 解答參考 - 問題:`n` 是字串,需轉型成整數。 - 修正後: ```python nums = input("請輸入數字,以空白分隔:").split() total = 0 for n in nums: total += int(n) print("總和:", total) ``` --- # 小練習 2:程式優化挑戰 請將下列重複程式碼重構為函式,並簡化主程式: ```python a = int(input("請輸入a:")) b = int(input("請輸入b:")) print("a的平方:", a*a) print("b的平方:", b*b) ``` --- ## 小練習 2 解答參考 ```python def square(x): return x*x a = int(input("請輸入a:")) b = int(input("請輸入b:")) print("a的平方:", square(a)) print("b的平方:", square(b)) ```

--- # 作業:本週練習 1. 回顧自己過去的作業,挑選一題進行重構與優化,並寫下優化前後的差異。 2. 嘗試為自己的程式加上除錯訊息與測試案例。