iT邦幫忙

2025 iThome 鐵人賽

DAY 18
0
Software Development

軟體開發養成計畫:以小程式實作深化開發能力系列 第 18

[Day18]程式 x 學習:用 Python 做一個單字測驗器

  • 分享至 

  • xImage
  •  

開場

呼應昨天介紹的資料交換格式,今天就要動手實作小程式啦!
背單字一直是我學生時期的惡夢(其實現在也是 ><),總覺得一背就忘,效果不彰。那如果能透過程式打造一個專屬的單字測驗小工具,是不是能讓背英文更有效率,也更有趣呢?

這次小程式的設計目標很簡單:
由電腦隨機出題 → 我們輸入答案 → 透過反覆測驗來加深記憶。

那麼就讓我們一起開始動手,寫出這個單字背誦測驗小程式吧!

單字測驗程式大綱

1.題庫管理

首先我們需要載入用JSON檔案做儲存的英文加中文單字題庫,如果 JSON 檔案不存在或空檔,則使用預設題庫 DEFAULT_WORDS,並且支援未來新增或修改單字後,將題庫寫回 JSON。

words.json題庫

[
  {"word": "apple", "meaning": "蘋果"},
  {"word": "book", "meaning": "書"},
  {"word": "cat", "meaning": "貓"}
]

程式碼:

def load_words():
    if os.path.exists(WORDS_FILE):
        try:
            with open(WORDS_FILE, "r", encoding="utf-8") as f:
                data = f.read().strip()
                if not data:
                    return DEFAULT_WORDS
                return json.loads(data)
        except json.JSONDecodeError:
            return DEFAULT_WORDS
    else:
        return DEFAULT_WORDS

def save_words(words):
    with open(WORDS_FILE, "w", encoding="utf-8") as f:
        json.dump(words, f, ensure_ascii=False, indent=2)
  • 使用 json.load() / json.loads() 讀取 JSON,將資料轉成 Python list of dicts。
  • 使用 json.dump() 將 Python 資料結構寫入 JSON,方便資料交換與永久保存。

2.分數歷史紀錄管理

記錄每次測驗的分數、題目數、答對數、正確率、測驗模式、時間,並存成 scores.json。

程式碼:

def load_scores():
    if os.path.exists(SCORES_FILE):
        with open(SCORES_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    else:
        return []

def save_score(mode, total, correct):
    scores = load_scores()
    score_entry = {
        "time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
        "mode": mode,
        "total": total,
        "correct": correct,
        "rate": f"{correct/total*100:.1f}%"
    }
    scores.append(score_entry)
    with open(SCORES_FILE, "w", encoding="utf-8") as f:
        json.dump(scores, f, ensure_ascii=False, indent=2)
  • 使用 JSON 儲存分數,結構清楚,方便日後做統計分析或整合其他平台。
  • 每次測驗完成都會呼叫 save_score(),自動更新歷史紀錄。

3.GUI 介面設計

主選單功能:

  • 選擇測驗模式:英文 → 中文 / 中文 → 英文
  • 查看歷史紀
  • 錄離開程式

測驗介面:

  • 顯示單字或中文提示
  • 使用者輸入答案
  • 支援按 Enter 提交答案
  • 顯示答對/答錯回饋

程式碼:

self.entry = tk.Entry(self.quiz_frame, font=("Arial", 14))
self.entry.pack(pady=5)
self.entry.bind("<Return>", lambda event: self.check_answer())
self.submit_btn = tk.Button(self.quiz_frame, text="提交", command=self.check_answer)
self.submit_btn.pack(pady=10)
  • 使用 Tkinter 建立簡單、直觀的 GUI。
  • bind("Return", ...) 讓使用者按 Enter 就能提交,提升使用便利性。

4.測驗流程控制

測驗邏輯清楚分層:出題 → 答題 → 檢查 → 回饋 → 下一題

程式碼:

def show_question(self):
    if self.index < len(self.words):
        item = self.words[self.index]
        if self.mode == "en2zh":
            self.question_label.config(text=item["word"])
        else:
            self.question_label.config(text=item["meaning"])
        self.entry.delete(0, tk.END)
        self.feedback.config(text="")
    else:
        self.end_quiz()

def check_answer(self):
    ans = self.entry.get().strip()
    item = self.words[self.index]
    correct = item["meaning"] if self.mode == "en2zh" else item["word"]
    ...
  • 完成測驗後呼叫 save_score(),自動更新歷史紀錄。

5.歷史紀錄顯示

利用GUI 顯示完整歷史分數,並將 JSON 內容整理成易讀文字格式。

def show_scores(self):
    scores = load_scores()
    if not scores:
        messagebox.showinfo("歷史紀錄", "目前沒有紀錄。")
        return
    top = tk.Toplevel(self.master)
    text_widget = tk.Text(top, width=60, height=20)
    text_widget.pack()
    display_text = ""
    for s in scores:
        display_text += f"{s['time']} | {s['mode']} | 題目數: {s['total']} | 答對: {s['correct']} | 正確率: {s['rate']}\n"
    text_widget.insert("1.0", display_text)
    text_widget.config(state="disabled")
  • 透過 tk.Toplevel() 彈出新視窗顯示紀錄。
  • JSON 轉文字顯示,方便使用者查看歷史紀錄。

單字測驗程式成果展示

1.主選單介面

29

2.測驗畫面

30

3.歷史紀錄呈現

31

心得

這次製作的小程式,讓我把昨天學到的 JSON 知識實際運用了一部分。雖然資料交換的功能還沒有完全發揮,但透過實作題庫操作,我還是感到滿滿的成就感。
更棒的是,我也能藉由這個單字背誦程式來增進自己的英文能力(總算不用再依賴付費 APP 了!)。未來我希望能加入更多功能與題庫,讓這個小程式真正成為一個實用又個人化的學習工具。


上一篇
[Day17]JSON、XML、YAML:資料交換三兄弟
下一篇
[Day19]從初級到進階!解鎖 Factory與 Observer模式
系列文
軟體開發養成計畫:以小程式實作深化開發能力20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言