期末專案練習
⏱ 2個鐘頭內完成
最低門檻:能跑就好
個人語言學習小卡
一步一步把想法變成手上的 App
這是一個極簡的期末專案練習。不需要整合學期所有技術,只需要讓自己體會「我有個想法 → 變成可以給朋友看的東西」的完整過程。重點請聚焦在「落地實踐」,不追求完整性。
專案要求:學期教了不少技術,在期末專案中,不是要大家全部都用上,而是讓你選一個你 連自己都真的想用 的小工具,把它做出來。寧可一個簡單的東西完整跑起來,也不需要以為一個複雜的功能卡在半路中間而氣餒。
階段一 · 必做
本機原型
時間估算:1-2 小時
一個 HTML 檔,瀏覽器打開就能用。完成這階段就基本上達標。你已有一個能跑的小工具。
產出:一個 index.html 檔,在自己電腦能跑
階段二 · 選做加分
部署到雲端
時間估算:1–2 小時
推上 GitHub + 一鍵部署到 Zeabur,得到一個全世界都能訪問的網址。朋友打開手機就能用你做的工具。
產出:一個公開網址 + GitHub repo
完成後它長這樣
📱 your-app.zeabur.app
日語學習小卡
情境:在咖啡廳點餐
いただきます
i-ta-da-ki-ma-su
用餐前說的「我要開動了」,含感謝之意
客:「コーヒーをお願いします。いただきます!」
基本功能(最小可行版本)
每次打開或點「下一張」,AI 會幫你生成一張新的學習卡片:
- 一個你選定主題下的常用詞或片語
- 發音標記(拼音/羅馬字/注音都可)
- 中文意思 + 使用情境
- 一句例句
- 「念給我聽」按鈕(使用瀏覽器內建語音)
主題你自己決定:日語、西班牙語、文言文、學術詞彙、台灣俚語、流行用語……
階段一 · 本機原型
第一步:在自己電腦做出來
整個小卡 App 是一個檔案——index.html 裡面包含 HTML 結構、CSS 樣式、JavaScript 邏輯。你不需要 Flask、不需要 Python、不需要安裝任何東西,只需要:
-
01
申請 Gemini API key(如還沒做)
前往 aistudio.google.com → Get API key → Create API key。複製這串字到安全的地方。
-
02
新建一個資料夾,建立 index.html
檔名一定要 index.html,這是網頁的慣例。用 VS Code,Cursor 或任何文字編輯器都可以。
-
03
把下面這段範本貼進去
這是完整可運作的程式碼。你只需要修改三個地方(標示在程式碼後)。
完整範本:index.html(複製貼上即可用)
index.html約 70 行
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<title>我的日語小卡</title>
<style>
body { font-family: sans-serif; background: #faf9f7; padding: 24px;
max-width: 480px; margin: 0 auto; }
.card { background: #fff; border-radius: 14px; padding: 20px;
box-shadow: 0 1px 6px rgba(0,0,0,.06); margin-bottom: 16px; }
.word { font-size: 26px; font-weight: 500; }
.pinyin { color: #888; margin: 4px 0; font-size: 13px; }
.meaning { background: #EEEDFE; padding: 8px 12px; border-radius: 8px;
margin-top: 10px; font-size: 14px; }
.example { color: #5c5c58; font-style: italic; margin-top: 8px; font-size: 13px; }
button { background: #534AB7; color: #fff; border: none;
padding: 10px 16px; border-radius: 20px; cursor: pointer;
margin-right: 6px; font-size: 13px; }
button.sec { background: #f0efe9; color: #1a1a18; }
</style>
</head>
<body>
<h2>日語學習小卡</h2>
<div class="card" id="output">
點下方按鈕,AI 幫你出一張新卡片...
</div>
<button onclick="makeCard()">下一張 →</button>
<button class="sec" onclick="speak()">🔊 念給我聽</button>
<script>
// ── 三個你要修改的地方 ─────────────
const API_KEY = "你的_API_KEY_貼在這裡"; // ① 貼你的 Gemini API key
const LANGUAGE = "日語"; // ② 你想學的語言
const SPEECH_LANG = "ja-JP"; // ③ 發音語碼
// ─────────────────────────────
let currentWord = "";
async function makeCard() {
const prompt = `請幫我出一張${LANGUAGE}學習小卡,回應請用 JSON:
{
"word": "(一個常用詞或片語)",
"pinyin": "(發音標記)",
"meaning": "(中文意思,含使用情境,30字內)",
"example": "(一句例句)"
}
不要加 markdown 標記,直接給 JSON。`;
const res = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${API_KEY}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
contents: [{ parts: [{ text: prompt }] }]
})
}
);
const data = await res.json();
const text = data.candidates[0].content.parts[0].text;
const card = JSON.parse(text);
currentWord = card.word;
document.getElementById("output").innerHTML = `
<div class="word">${card.word}</div>
<div class="pinyin">${card.pinyin}</div>
<div class="meaning">${card.meaning}</div>
<div class="example">${card.example}</div>`;
}
function speak() {
if (!currentWord) return;
const u = new SpeechSynthesisUtterance(currentWord);
u.lang = SPEECH_LANG;
speechSynthesis.speak(u);
}
</script>
</body>
</html>
三個你需要修改的地方:
① API_KEY:貼上你的 Gemini API key
② LANGUAGE:你想學的語言("日語"、"西班牙語"、"文言文"、"台語"……)
③ SPEECH_LANG:發音語碼(日語 ja-JP、西語 es-ES、英語 en-US、中文 zh-TW)
測試:用瀏覽器打開
-
04
雙擊 index.html → 用瀏覽器打開
應該看到你的小卡介面(藍色「下一張」按鈕、灰色「念給我聽」按鈕)。
-
05
點「下一張」
等 2–3 秒,AI 會生成一張卡片,顯示詞語、發音、意思、例句。
-
06
點「念給我聽」
瀏覽器會用內建語音念出剛剛的詞——免費、不需要額外 API。
達到這裡:階段一完成。你已經有了一個能用的個人小工具。如果你不想做階段二,這個就可以當作期末作業繳交了(誤)。
注意:這版本把 API key 寫在 HTML 裡,只能 自己用,不要分享這個檔案給別人,更不要推上 GitHub。
如果你想讓朋友也能用,請繼續做階段二(用後端代理 key,才能安全部署)。
階段二 · 選做加分
第二步:讓全世界都能用你做的工具
階段一的問題:API key 寫在 HTML 裡,所以這個檔案只能你自己用。如果想分享給朋友、想推到 GitHub,必須加一個極簡的後端來「代管」API key。程式碼只多 20 行。
如何用 Flask 做後端代理,可參考這篇急速入門文章。https://ithelp.ithome.com.tw/articles/10258223
新的檔案結構
my-flashcard/4 個檔案
my-flashcard/
├── app.py ← 後端,代理 API 呼叫(30 行)
├── requirements.txt ← 套件清單(2 行)
├── .gitignore ← 告訴 git 不要追蹤敏感檔(3 行)
└── templates/
└── index.html ← 階段一那個 HTML 移到這裡
app.py:後端代理(30 行)
app.py後端代理
from flask import Flask, render_template, request, jsonify
import google.generativeai as genai
import os
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
model = genai.GenerativeModel("gemini-2.5-flash")
app = Flask(__name__)
@app.route("/")
def home():
return render_template("index.html")
@app.route("/api/card", methods=["POST"])
def card():
language = request.json.get("language", "日語")
prompt = f"""請幫我出一張{language}學習小卡,回應請用 JSON:
{{"word": "...", "pinyin": "...", "meaning": "...", "example": "..."}}
不要加 markdown 標記,直接給 JSON。"""
response = model.generate_content(prompt)
return jsonify({"text": response.text})
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app.run(host="0.0.0.0", port=port)
修改 index.html:呼叫自己的後端
把階段一的 fetch(...) 那一段替換成:
index.html · script 段落(部分)
// 不再需要 API_KEY ── 改為呼叫自己的 /api/card
const LANGUAGE = "日語";
const SPEECH_LANG = "ja-JP";
async function makeCard() {
const res = await fetch("/api/card", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ language: LANGUAGE })
});
const data = await res.json();
const card = JSON.parse(data.text);
currentWord = card.word;
document.getElementById("output").innerHTML = `...`;
}
requirements.txt 與 .gitignore
requirements.txt
flask
google-generativeai
.gitignore
.env
__pycache__/
*.pyc
venv/
本機測試(推上線前先確認能跑)
bash
$ cd my-flashcard
$ pip install -r requirements.txt
# 設定環境變數(不要寫死在程式碼)
$ export GEMINI_API_KEY="你的 key" # Mac/Linux
$ $env:GEMINI_API_KEY="你的 key" # Windows PowerShell
$ python app.py
* Running on http://0.0.0.0:5000
# 打開瀏覽器訪問 http://localhost:5000 → 跟階段一一樣可用
推到 GitHub 並一鍵部署
-
01
初始化 Git 並推上 GitHub
git init → git add . → git commit -m "初版" → 到 github.com 建 repo → git remote add origin ... → git push -u origin main。
-
02
到 zeabur.com 用 GitHub 登入
Create Project → Deploy New Service → Git → 選你的 repo。Zeabur 自動偵測這是 Python 專案。
-
03
設定環境變數
到 Variables 分頁 → 加入 GEMINI_API_KEY,貼上你的 key。這就是為什麼要用後端——Zeabur 在執行時才把 key 注入,永遠不會被推上 GitHub。
-
04
等 1–2 分鐘 build 完成 → 取得公開網址
形如 my-flashcard.zeabur.app。傳給朋友、傳給家人、用手機開都能用。
達到這裡:階段二完成。你有一個全世界都能訪問的個人小工具。這就是「idea 變成手上的 App」的完整經驗:從一個想法到一個可分享的網址。
不一定要做語言學習
同樣的架構,你可以做……
整個 App 的核心邏輯只有兩件事:給 AI 一個 prompt,把回應顯示成卡片。改改 prompt,主題就不同。以下都是相同骨架,只換內容:
📚
學術詞彙小卡
針對你的領域出 GRE / 學術詞彙
prompt 改成:「出一個語言學領域的學術詞彙」
🏛️
文言文翻譯練習
出一句現代中文,提供文言文版本
prompt 改成:「出一句現代中文+文言文對照」
🗣️
台語俚語
每天學一個有趣的台語表達
prompt 改成:「出一句日常的台語俚語+教華語對照」
🍃
每日詩詞
每次抽一首古典詩詞,附白話翻譯
prompt 改成:「抽一首唐宋詩+白話譯文+背景」
🧠
英文單字本
針對你的程度(JLPT 範圍、TOEFL 等)
prompt 改成:「出一個 GRE 高頻字+用法」
💭
每日哲學問題
每次給一個值得思考的哲學問題
prompt 改成:「出一個哲學思辨題+思考方向」
調整思路:不需要重新寫程式碼。只要改 prompt 那段字串,整個 App 就變成不同主題了。這就是 Gemini API 強大的地方:用「自然語言指令」就能定義應用功能。這也是我們一直強調的,想法更為重要!
繳交方式
怎麼交期末作業
繳交清單
必交 01
專案檔案 — 上傳 index.html(階段一)或整個資料夾 zip(階段二)
必交 02
運作截圖 — 至少 2 張,顯示 App 確實能運作(卡片內容、發音按鈕等)
必交 03
專案報告 — 你們做了什麼主題?為什麼選這個(動機)?實作過程涉及哪些技術?哪裡卡住(方法)?感想是什麼(反思與結論)?團隊分工表(如果有)
加分 01
GitHub repo 連結 階段二完成
加分 02
公開部署網址 階段二完成 例如 your-app.zeabur.app;your-app.github.io
最後的話
為什麼這個專案這樣設計
vibe coding 的核心精神不是「學會所有技術」,而是「我有一個想法,我能讓它變成現實」。這個模擬期末專案故意設計得很小,目的是讓大家能體驗到「想法到落地」的完整過程,而不是被技術細節壓垮。輝達(NVIDIA)執行長黃仁勳指出,未來全球程式設計師將由 3,000 萬人暴增至 10 億人。他認為程式設計的本質已變成「制定規格(Spec)」;只要能精確用自然語言告訴 AI 電腦要做什麼,任何人都能成為程式設計師,不需再拘泥於傳統程式語言。語言就是程式碼! AI 時代的溝通門檻降低,讓文科生、非傳統理工背景的人才,能在軟體與應用開發上發揮極大的創造力與優勢。未來的程式設計不僅限於複雜的底層架構建置,更偏向於應用程式的創意發想與邏輯定義,進而開啟大眾化的軟體開發新時代。
希望大家在實作期末專案時,能慢慢體會到這個意思。