三十天前,我只是一位單純想挑戰自己、想透過程式實作磨練邏輯的學習者。如今,這段旅程來到了最後一篇。
我決定用一個「能記錄生活的工具」作為結尾 —— 一個簡單的 Python 日曆記事小程式。
它不只是程式,更像是這30天挑戰的象徵:用程式整理時間,用學習記錄成長。
接下來是實作流程 + 對應程式碼:
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import calendar, datetime, json, os
class CalendarApp:
def __init__(self, root):
self.root = root
self.root.title("記事日曆")
self.root.geometry("600x500")
self.today = datetime.date.today()
self.current_year = self.today.year
self.current_month = self.today.month
self.events = self.load_events()
self.create_widgets()
self.update_calendar()
def load_events(self):
if os.path.exists("events.json"):
with open("events.json", "r", encoding="utf-8") as f:
return json.load(f)
return {}
def save_events(self):
with open("events.json", "w", encoding="utf-8") as f:
json.dump(self.events, f, ensure_ascii=False, indent=2)
def create_widgets(self):
header = tk.Frame(self.root)
header.pack(pady=10)
tk.Button(header, text="< 上個月", command=self.prev_month).pack(side=tk.LEFT, padx=10)
self.title_label = tk.Label(header, text="", font=("Arial", 16))
self.title_label.pack(side=tk.LEFT)
tk.Button(header, text="下個月 >", command=self.next_month).pack(side=tk.LEFT, padx=10)
self.calendar_frame = tk.Frame(self.root)
self.calendar_frame.pack()
self.event_list = tk.Listbox(self.root, height=8)
self.event_list.pack(fill="x", padx=10, pady=10)
tk.Button(self.root, text="新增 / 編輯記事", command=self.add_event).pack(pady=5)
def update_calendar(self):
for widget in self.calendar_frame.winfo_children():
widget.destroy()
self.title_label.config(text=f"{self.current_year} 年 {self.current_month} 月")
cal = calendar.monthcalendar(self.current_year, self.current_month)
for week in cal:
row = tk.Frame(self.calendar_frame)
row.pack()
for day in week:
if day == 0:
tk.Label(row, text=" ", width=6, height=2).pack(side=tk.LEFT)
else:
btn = tk.Button(row, text=str(day), width=6, height=2,
command=lambda d=day: self.show_events(d))
btn.pack(side=tk.LEFT, padx=1, pady=1)
def show_events(self, day):
date_str = f"{self.current_year}-{self.current_month:02d}-{day:02d}"
self.event_list.delete(0, tk.END)
if date_str in self.events:
for item in self.events[date_str]:
self.event_list.insert(tk.END, f"• {item}")
else:
self.event_list.insert(tk.END, "(無記事)")
self.selected_date = date_str
def add_event(self):
if not hasattr(self, 'selected_date'):
messagebox.showinfo("提示", "請先選擇日期")
return
new_event = simpledialog.askstring("新增 / 編輯記事", f"為 {self.selected_date} 新增記事:")
if new_event:
self.events.setdefault(self.selected_date, []).append(new_event)
self.save_events()
self.show_events(int(self.selected_date.split("-")[2]))
def prev_month(self):
if self.current_month == 1:
self.current_month = 12
self.current_year -= 1
else:
self.current_month -= 1
self.update_calendar()
def next_month(self):
if self.current_month == 12:
self.current_month = 1
self.current_year += 1
else:
self.current_month += 1
self.update_calendar()
使用 ttk.Style() 變更主題,例如:
style = ttk.Style()
style.theme_use('clam')
style.configure('TButton', background='#4e73df', foreground='white', font=('Arial', 10))
today_str = self.today.strftime("%Y-%m-%d")
if today_str in self.events:
messagebox.showinfo("今日提醒", f"今日有 {len(self.events[today_str])} 項記事!")
if __name__ == "__main__":
root = tk.Tk()
app = CalendarApp(root)
root.mainloop()
回顧這30天的主題歷程,我這一個月的學習內容,主要分為四個類別:基礎篇、應用篇、工具篇、趨勢篇
這類的學習中,是這階段奠定了我整個鐵人賽的根基,從軟體開發流程出發,學會如何選擇合適的工具、理解開發模型,並逐步透過簡單的 Python 小專案強化邏輯與語法,也開始接觸 GUI 介面,從文字邏輯跨入互動式應用。
在這階段,我不再只是寫程式,而是開始理解「程式如何組成一個完整的系統」。
從設計模式(MVC、Factory、Observer)到 JSON / API 串接,逐步打開對軟體架構的視野,掌握資料交換與邏輯分層;同時透過遊戲與工具開發,強化實作能力。
這部分的重點是「讓程式更穩、更完整」。
寫出功能之外,還開始考慮「版本控管、效能優化、錯誤處理」等軟體品質問題。
從單純寫功能到能進行專案維護與版本控管,慢慢邁入「軟體工程思維」的層次。
在最後階段,除了完成程式外,也開始思考「程式的未來」。
AI 與軟體測試、自動化開發、智能應用的結合,是每個新時代工程師都該關注的議題。理解 AI 如何輔助開發流程,並開始思考「人與程式的共創關係」—— 讓技術真正走進生活。
鐵人賽的這三十天,說長不長,說短不短,卻是我自開始學習軟體開發以來,最專注於設計自己小程式的一段時光。今天回顧整個過程,會有種看著自己一步步成長的感覺。原本只是想開發幾個簡單程式作為練習,沒想到隨著練習的深入,我累積了更多心得:除了實作程式外,我還學會了各種開發工具與技巧,並透過摸索與思考,對軟體開發這個領域有了更多認識——這是平常課堂中難以學到的寶貴經驗。每一個小程式,不只是練習,更是我成長的痕跡。
這三十天讓我深刻感受到,只要持續動手、持續反思,就能一步步提升程式能力與專案思維。而這次 IT 鐵人賽的結束,並不是學習的終點,反而成了督促自己每日進步的契機。相信每一位參與的朋友也都付出了努力,也期待未來能繼續與賽友們一起奮鬥、一起成長。下一屆鐵人賽,我們再見囉!
三十天,從第一行 print() 到完整的 GUI 工具,
我用程式紀錄了挑戰、紀錄了生活,也紀錄了自己成長的軌跡。
如果說鐵人賽是一場馬拉松,那我最大的收穫,不是作品本身,而是——
「我真的堅持下來了」。
這不是結束,而是我下一段學習旅程的起點。