哈囉,同學們!歡迎來到「Vibe Coding 與軟體工程初探課程」!
在這四週的課程中,我們將一起:
準備好了嗎?讓我們一起開始這趟全新的 AI 程式設計之旅吧!
我們已經學過 Python 的基本功了,對吧?讓我們快速回憶一下:
my_name = "小明"
, age = 13
)。str
, 數字 int
, float
, 布林值 bool
)。+ - * /
, 比較大小 > < ==
)。if...elif...else
條件判斷, for
和 while
迴圈)。下列哪一行 Python 程式碼可以正確「建立一個名為 student_score 的變數,並設定值為 100」?
執行下列哪一行程式後,變數 x 的型態會是布林值 (Boolean)?
下列哪一個運算子可以用來「判斷兩個變數是否相等」?
如果你想讓程式「根據不同條件分別執行不同區塊」,應該用哪一個語法?
歡迎來到 AI 語言模型的世界!這些聰明的 AI 能理解和生成文字,甚至程式碼!
這週我們將認識幾位赫赫有名的 AI 大師:
以及我們之後專案會用到的 Cursor (一個整合了 AI 功能的程式編輯器)。
我們前兩週會主要以 ChatGPT 的互動模式為範例,學習如何與 AI 協作。
我們會在第三週詳細學習如何使用 Cursor!
無論你使用 ChatGPT、Gemini、Claude 還是 Cursor 裡的 AI,要讓它們真正幫上忙,我們得學會怎麼「好好跟它們說話」。
我們給 AI 的指令或問題,就叫做 Prompt。
Prompt 範例1 (比較模糊):
「寫個判斷偶數的 Python。」
Prompt 範例2 (比較清楚):
「請幫我寫一個 Python 函式,名稱叫做 is_even
。這個函式接受一個整數作為參數,如果該整數是偶數,函式應該回傳 True,否則回傳 False。」
寫程式不只是讓電腦看得懂,更重要的是讓人 (包括未來的你、你的同學、還有 AI) 也能看得懂!
x = 10
, a = "小明"
, func1()
item_count = 10
, student_name = "小明"
, calculate_average_score()
我們將繼續以 ChatGPT 的互動模式為參考,深入探索 Python 的進階資料結構,學習如何處理程式中的錯誤,並思考如何運用 AI 輔助除錯!
Python 提供了多種強大的內建資料結構。這週,我們將思考如何透過向 ChatGPT 這樣的 AI 提問,來幫助我們更深入地理解和應用它們!
不同的資料結構有不同的特性,適用於不同的場景。
資料結構 | 特性 | 適用場景 |
---|---|---|
List | 有序、可變、允許重複 | 儲存一連串需要修改或排序的資料 |
Tuple | 有序、不可變、允許重複 | 儲存不應被修改的資料,如座標 |
Dictionary | 無序(3.7+ 有序)、鍵值對、鍵唯一 | 需要快速透過鍵查找值的場景 |
Set | 無序、元素唯一 | 去重、檢查成員資格 |
小測驗:如果要儲存一個班級所有學生的學號(不重複),用哪種資料結構最合適?
一種簡潔的方式來建立列表。例如,快速產生一個包含平方數的列表:
squares = [x**2 for x in range(10)]
# squares 會是 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
🤔 思考與提問: 如果你想用列表推導式從一個字串中選出所有母音,你會怎麼問 ChatGPT (或類似 AI) 來獲得提示或程式碼?
下列哪一個列表推導式可以正確產生所有大於 10 且為偶數的數字,範圍從 0 到 20?
類似地,用簡潔的方式建立字典:
square_dict = {x: x**2 for x in range(5)}
# square_dict 會是 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
🤔 思考與提問: 如果你想將兩個列表 (一個包含鍵,一個包含值) 合併成一個字典,你會如何向 AI 提問以獲得使用字典推導式的方案?
以下哪一行程式碼可以將兩個列表 keys = ['a', 'b', 'c']
和 values = [1, 2, 3]
合併成 {'a': 1, 'b': 2, 'c': 3}
?
map(function, iterable)
:將函式應用到序列中的每個元素。filter(function, iterable)
:根據函式過濾序列中的元素。sorted(iterable, key=None, reverse=False)
:對序列進行排序。🤔 思考與提問: 你會如何問 AI,請它示範如何使用 filter
過濾出一個數字列表中所有大於10的偶數?
有一個分數列表 scores = [58, 92, 75, 43, 86]
,要找出所有及格(60分以上)且分數從高到低排序,下列哪一行程式碼最合適?
假設你有一份學生成績資料 (例如,一個包含學生姓名和分數的字典列表)。
針對以下任務,思考你會如何向 ChatGPT (或類似 AI) 提問,以獲得解題思路或程式碼片段:
試著寫下你的 Prompt,並看 AI 會給你什麼樣的幫助。
程式出錯是家常便飯!學會處理「錯誤」和「異常」能讓你的程式更強壯。思考一下,AI 如何在這方面提供協助?
這是一種程式設計的思維方式,目標是讓程式碼在面對未預期的輸入或情況時,依然能夠保持穩定和可預測的行為。
主要原則:
assert age > 0, "年齡必須是正數"
)良好的錯誤處理是防禦性程式設計的重要一環!
複習一下常見的錯誤:
SyntaxError
, NameError
, TypeError
, ValueError
🤔 思考與提問: 當你遇到一個 TypeError
,但不太確定原因時,你會怎麼把錯誤訊息和相關程式碼提供給 ChatGPT,請它幫忙分析?
IndexError
, KeyError
, FileNotFoundError
, ZeroDivisionError
, AttributeError
當程式出現錯誤時,仔細閱讀錯誤訊息是除錯的第一步!它通常會告訴你錯誤的類型和發生的位置。
try-except
捕捉錯誤我們可以使用 try
和 except
區塊來「捕捉」可能發生的錯誤,並優雅地處理它們。
try:
num_str = input("請輸入一個數字:")
num = int(num_str)
result = 10 / num
print(f"結果是 {result}")
except ValueError:
print("輸入的不是有效數字!")
# ... 其他 except 區塊 ...
else:
print("計算順利完成!")
finally:
print("程式區塊執行結束。")
🤔 思考與提問: 如果你不確定一段程式碼可能會拋出哪些具體的錯誤類型,你會如何請 ChatGPT 幫你分析並建議 except
區塊的寫法?
有時候,我們希望在特定條件下主動引發一個錯誤,可以使用 raise
關鍵字。
def process_data(data):
if not data:
raise ValueError("輸入的資料不能是空的!")
# ... 處理資料 ...
print("資料處理完成。")
思考在什麼情境下,主動 raise
一個錯誤會比單純 print
錯誤訊息更好?
當內建的錯誤不夠用時,我們可以建立自己的錯誤類型,讓程式碼的意圖更清晰。
class InvalidURLError(Exception):
"""當 URL 格式不正確時引發的自訂錯誤"""
pass
def fetch_website(url):
if not url.startswith("http"):
raise InvalidURLError(f"無效的 URL:'{url}',必須以 http 開頭")
print(f"正在嘗試抓取 {url}...")
try:
fetch_website("www.google.com")
except InvalidURLError as e:
print(f"錯誤:{e}")
活動: 在您的筆記中,為成績設定函式建立一個 InvalidGradeError
,當成績不在 0-100 範圍內時引發此錯誤。
老師會提供一段可能產生錯誤的程式碼。
你的任務是,思考你會如何向 ChatGPT (或類似 AI) 提問,來幫助你:
try-except
結構來捕捉這些潛在的錯誤。else
或 finally
子句。試著寫下你的 Prompt,並預想 AI 可能會提供哪些有用的建議。
即使有了錯誤處理,程式還是可能會有 bug (臭蟲)!像 ChatGPT 這樣的 AI 可以成為你強大的除錯夥伴,幫助你更快找到並解決問題。
Prompt 範例:「我的 Python 程式出現了這個錯誤訊息 [貼上錯誤訊息]。這是相關的程式碼:[貼上程式碼]。我希望它能 [描述預期行為],但它卻 [描述實際行為]。請問可能是什麼問題?可以幫我看看程式碼哪裡有問題嗎?」
有時候程式可以執行,但結果不如預期,這就是邏輯錯誤。你可以:
與其一次丟出複雜問題,不如分步驟引導 AI,逐步建構出最終答案。
範例:請 AI 幫你寫一個線上課程報名系統
活動:在您的筆記中,練習使用多步驟提示,引導 AI 產生一個密碼驗證函式(例如,長度至少8碼,包含數字和字母)。
老師會提供幾個帶有隱晦 bug 的 Python 程式片段。
你的任務是,思考你會如何運用與 ChatGPT (或類似 AI) 互動的技巧來:
和同學分享你的「提問策略」和 AI 可能給你的「啟發」。
assert
TDD 的核心精神是「先寫測試,再寫功能」。 assert
是我們實踐這個精神最簡單的工具。
assert
語句會在條件為 False
時,引發 AssertionError
,直接中斷程式。
def calculate_discount(price, discount_rate):
# 我們斷言折扣率必須在 0 和 1 之間
assert 0 <= discount_rate <= 1, "折扣率必須在 0 和 1 之間"
return price * (1 - discount_rate)
# 這會正常運作
print(calculate_discount(100, 0.2))
# 這會引發 AssertionError
print(calculate_discount(100, 1.5))
文件字串 (Docstring) 是說明函式、模組或類別用途的「內建說明書」。它不僅是給人看的,更是 AI 理解你程式碼意圖的關鍵!
def calculate_total_price(items, tax_rate):
"""計算包含稅金的總價格。
Args:
items (list): 一個包含商品價格 (數字) 的列表。
tax_rate (float): 稅率,例如 0.05 代表 5%。
Returns:
float: 四捨五入到小數點後兩位的總金額。
如果輸入無效則返回 -1。
"""
if not isinstance(items, list) or not items:
return -1
subtotal = sum(items)
total = subtotal * (1 + tax_rate)
return round(total, 2)
# 你可以這樣查看說明書
help(calculate_total_price)
AI 協作提示:寫好清晰的 Docstring 後,你可以請 AI:「根據這個函式的 Docstring,為它產生三個測試案例,包含一個邊界情況。」AI 能提供更高品質的協助!
PEP 8 是 Python 的官方風格指南。遵循它能讓你的程式碼更具可讀性、更專業,也更容易與他人協作。
def calculate(x,y):
result=x*y
return result
def calculate(x, y):
result = x * y
return result
Linting 工具:像 flake8
或 pylint
這樣的工具可以自動檢查你的程式碼是否符合 PEP 8 規範。
AI 協作提示:將一段程式碼貼給 AI,並請它「根據 PEP 8 風格指南重構這段程式碼」。
讓我們綜合運用所學,設計一個小型專案。這能幫助我們理解各個知識點如何協同工作。
add_to_cart()
。calculate_total()
。remove_from_cart()
,需處理商品不存在的情況。AI 協作提示:卡關時可以問 AI:「我該用哪種資料結構來設計購物車比較好?」或「請幫我寫一個從列表中移除指定商品的函式。」
這一週我們從 Python 的基礎上,加入了軟體工程的重要概念與 AI 協作技巧:
try...except
捕捉錯誤,更能定義自訂例外 (Custom Exception) 處理特定狀況。assert
為功能撰寫基本驗證。我們將正式進入 Cursor 的世界!學習它的強大功能,如何將程式碼組織得更有條理 (模組化與函式設計),探索 Python 豐富的函式庫,並開始規劃我們的期末專案!
tkinter
函式庫,打造你的第一個圖形介面 App。這週,我們將從理論走向實踐,把 AI 變成你手中最強大的開發工具!
我們將透過三個「小挑戰」,把 Cursor 從一個新工具,變成你最得力的程式設計夥伴!
老師會提供一個有 3-4 個中文函式描述的 Python 檔案,你的目標是在每個註解下方,使用 Cursor 的「生成程式碼」(快捷鍵 Ctrl+K) 功能,讓 AI 自動完成這些函式。
# 函式一:計算一個圓形的面積,需要傳入半徑
# 函式二:檢查一個字串是否為有效台灣手機號碼 (09開頭,共10碼)
# 函式三:將一個句子中的所有英文單字轉為大寫
老師會提供一段邏輯混雜的程式碼(例如:一段程式碼包辦了讀取、計算、判斷、輸出的所有工作)。
你的目標是練習使用 Cursor 的「編輯/聊天」(快捷鍵 Ctrl+L),選取特定區塊,並下達指令如:「將這段計算平均的邏輯,提取成一個名為 calculate_average
的新函式」,體驗一鍵重構的魔法。
老師會提供一段含有隱晦邏輯錯誤的程式碼(例如:迴圈範圍少算一次)。
你的目標是執行程式、觀察到錯誤的結果,然後練習向 Cursor 的 AI 清晰地描述問題:「我的程式沒有報錯,但計算結果不對,這是我的程式碼,你能幫我看看邏輯問題嗎?」
什麼是 GUI?就是我們每天都在用的圖形化介面!現在,我們要用 Python 的內建函式庫 tkinter
,讓程式擁有視窗、按鈕和輸入框!
我們的第一個 AI 協作任務:在 Cursor 中,問 AI:
「請用 tkinter 幫我建立一個標題是『我的第一個 App』的空白視窗。」
讓我們打造一個有輸入框和按鈕的視窗。當使用者在輸入框填入名字 (例如 "小明") 並按下按鈕後,一個標籤的文字會從 "你好,世界!" 變成 "你好,小明!"。這將是我們的第一個完整 GUI 互動練習!
技能已備!現在我們要啟動一個更大型、更有趣的專案。從下面三個選項中,選擇一個你最想挑戰的!
打造一個可以載入圖片,並在圖片上方和下方加上文字,製作出有趣迷因圖的工具。
Pillow
函式庫。一個簡單的點擊賺分遊戲。瘋狂點擊主角來賺取金幣,然後用金幣購買升級項目,讓每次點擊能賺更多金幣!
製作一個可以呈現多張圖片與對應文字的看圖說故事工具。使用者可以透過「上一頁」、「下一頁」按鈕來瀏覽你創作的漫畫或故事。
tkinter
函式庫,並打造了第一個 GUI 互動應用。下週,我們將全力投入專案開發,學習如何測試和優化我們的 App,並準備一場精彩的成果發表會,向大家展示你的作品!
這是本週最主要的動手時間!我們將採用「先求有,再求好」的策略,分三階段完成你的 App!
完成所有 GUI 元件的排版。此刻,按鈕可能還沒有功能,但整個 App 的「外觀」和「版面」已經成形。
AI 協作提示:如果不確定如何排版,可以問 AI:「請用 tkinter 的 grid
方法,幫我設計一個兩行兩列的佈局。」
實現最核心的功能。例如,迷因產生器要能成功把文字畫到圖片上;點擊遊戲要能正確計分。
AI 協作提示:卡關時,練習具體提問!選取你的程式碼,問 AI:「我希望點擊這個按鈕後,圖片會換掉,但我這段程式碼沒反應,問題在哪?」
優化使用者體驗,例如調整字體大小、顏色,或加入一些友善的提示訊息,讓你的 App 變得更漂亮、更好用。
AI 協作提示:問 AI「如何更改 tkinter 按鈕的背景顏色?」或「如何讓標籤的字體變大一點?」
專業的軟體不只看功能,更看重品質。現在我們要學習如何找出自己程式中的瑕疵,讓它更穩定!
試著做一些「不正常操作」。例如,在迷因產生器中不選擇任何圖片就按下「產生」按鈕。看看你的 App 會不會崩潰 (Crash)?
如果程式崩潰了,告訴 AI:
「如何在我點擊按鈕時,先檢查使用者是否已經選擇了圖片?如果沒有,就跳出一個錯誤提示視窗。」
AI 會引導你使用 tkinter.messagebox
來優雅地處理錯誤。
對於你的專案,問 AI:
「我做了一個[你的專案名稱],請幫我設想幾個使用者可能會不小心讓它出錯的『極端測試情況』(Edge Cases)。」
看看 AI 提出的建議,你是否都有考慮到?試著根據 AI 的建議來加強你的程式。
當你的專案功能大致完成後,選取所有程式碼,然後對 AI 下達指令:
「請幫我審查這份程式碼,在複雜的地方加上註解,並確保它符合 PEP 8 風格指南。」
這是一個非常專業的開發習慣,可以讓你的程式碼變得更整潔、更易於他人閱讀!
恭喜你完成了專案!現在,是時候向大家展示你的學習成果,分享這段旅程中的創作與心得了!
你以為你的 App 只能在自己電腦上跑嗎?AI 還能幫我們做一件更酷的事:把它變成一個真正的網站!
即使我們只學了 Python 和 tkinter
,完全不懂網頁三劍客 (HTML, CSS, JavaScript),我們依然可以讓 AI 幫我們完成這個魔法般的轉換。
選取你專案中所有的 tkinter
程式碼,然後對 Cursor 的 AI 說:
「請將這個 tkinter 應用程式,改寫成一個單一 HTML 檔案的網頁應用程式。請使用 Tailwind CSS 來美化外觀,並將所有的 Python 邏輯轉換成 JavaScript。」
AI 就會為你生成一個完整的網頁,讓任何人只要有瀏覽器就能使用你的作品!這也是你們可以在成果發表會上展示的超酷亮點!
這就是 AI 將我們上一週的三個專案範例,從 Python (tkinter
) 桌面應用程式轉換成網頁版的成果!
你可以點擊下方的連結,直接在瀏覽器中體驗這些由 AI 生成的網頁應用程式。
每位同學上台分享時,可以包含以下幾點:
回顧這四週,我們一起:
程式設計的世界廣闊無垠,AI 的發展也日新月異。希望這次課程能為大家打開一扇窗,鼓勵大家在未來:
Happy Coding! 祝大家程式設計愉快!