2026年2月3日 星期二

2026 年第 5 周記事

今年開始的生日快樂假月底是期限, 我周五請了假早上洗高雄的浴廁, 下午回鄉下載爸回診拿藥. 離過年還有兩周, 我上周就開始大掃除了, 先整理客廳前面的小書桌, 丟掉一整箱的舊文件與雜誌, 本周繼續清小書桌旁的四層櫃, 庫房, 但最費力的還是門前路旁蓮霧樹下堆積的枯葉, 我用小推車來回清了二, 三十趟才清完 :




由於小舅說要用枯葉當堆肥, 裝了好幾包放在樹下兩三年了也未曾拿來用, 路旁的鐵門因為被擋住從此無法打開, 以前媽都是在此洗衣服, 我清庫房時找到許多要清洗的袋子, 想說小圳水量豐沛也很清澈, 無奈沒打不開只好從大門繞出去, 於是決定清理這些枯葉與淤積的泥土, 恢復舊觀. 

清庫房時找到媽以前留下的一口大砂鍋, 周日將菜園的高麗菜全採收, 做了一鍋滷高麗菜封, 菁菁聞訊馬上說要, 剛好周日晚上要回高雄家, 就裝了兩大盒給她 :




下周大掃除目標是祖堂, 書房以及舊雞舍庫房, 還有更換舊豬舍廁所的馬桶座. 

2026年1月31日 星期六

樹莓派學習筆記 : 如何用 VNC 從樹莓派傳送檔案到 PC

今天整理鄉下老家客廳門口的櫃子, 打算把放在上面的 Pi 3 移到酒櫥那邊放, 關機前看到下載資料夾下有以前下載的 Anydesk 32 bit 版, 因 Anydesk 似乎不再維護 32 位元的版本, 所以想將此檔案抓回筆電中保存, 我以前都使用 WinSCP 連線來互傳檔案, 其實這可以用 VNC Cloud 桌面的 File Transfer 功能來達成. 

首先按桌面右上方的 VNC 按鈕, 再按 VNC Server 視窗右上角的三條槓按鈕, 點選彈出選單的 File Transfer 選項 :




在 Transfer Files 視窗中, 按左下角的 Send files 鈕, 於彈出視窗點選要抓取的檔案後, 按 OK 即將該檔案傳送到 PC (預設試桌面) :



Gemini CLI 學習筆記 : Python 專案開發的標準工作流程

在前一篇測試中, 我們使用 uv 工具建立 Python 專案後, 手動編輯描語境檔 GEMINI.md, 然後啟動 Gemini CLI, 它會自動讀取 GEMINI.md, 確認它所擬定的執行計畫後, 要求它開始撰寫程式. 本篇旨在摘要整理使用 Gemini CLI 開發 Python 專案時的 SOP.

本系列全部測試文章索引參考 :


後續的測試都會使用 uv 工具來建立 Python 專案結構, 關於 uv 參考 :

在 Windows 下使用 Gemini CLI 進行 Vibe Coding 的工作流程如下 :
  1. 生成語境檔 : 使用 Gemini 或其他 AI 生成 GEMINI.md 內容
    提示詞模板 : "我要用 Gemini CLI 開發一個 Python 專案 (使用 uv 工具), 目標是 {}, 技術堆疊是 {}, 請以繁體中文幫我撰寫 GEMINI.md 語境檔." 
  2. 開啟終端機 : 開啟 PowerShell 視窗
  3. 建立地基 : uv init <專案名稱> (建立資料夾與環境)
  4. 進入專案 : cd <專案名稱>
  5. 建立語境檔 :
    • 直接在 PowerShell 輸入 notepad GEMINI.md
    • 系統會問 "找不到檔案, 是否建立?", 選 "是" 
    • 貼上內容後存檔關閉記事本 (notepad 預設存檔格式 UTF-8)
  6. 啟動 AI : 輸入 gemini 進入 Gemini CLI
  7. 載入與確認 (Prompt 優化) :
    輸入 "請讀取當前目錄下的 GEMINI.md, 根據該文件規範, 你了解這個專案的目標與限制了嗎? 請先列出你的實作計畫 (Step-by-step plan), 不需要先寫程式碼"
    (說明:明確指出要讀取的檔案, 並強調 "根據該文件" 以確保 AI 不會忽略它)
  8. 執行專案 : 
    輸入 "計畫沒問題, 請開始執行第一步 (或是 Go ahead)"

如下圖所示 : 




uv init 建立的專案架構中的 pyproject.toml 是給 Python 執行環境看的專案描述檔, 此流程中我們先用 uv init 把地基打好, 然後再用 gemini 把 Gemin CLI 叫進來幹活. 

2026年1月30日 星期五

Gemini CLI 學習筆記 : 郵遞區號查詢小幫手專案 (三)

在前兩篇的查詢 6 碼郵遞區號的測試中, 我們只利用提示詞與 Gemini CLI 對話便能讓其生成程式碼, 透過 API 正確取得給定地址的郵遞區號. 本篇則要改用語境檔 GEMINI.md 來達成, 它是寫程式用的 PRD (專案需求文件檔), 關於語境檔 GEMINI.md 參考 :


以下測試使用 uv 工具來管理專案與 Python 版本, 關於 uv 參考 : 


本系列全部測試文章索引參考 :



首先開啟 PS 視窗, 用 uv init 建立一個名為 postal-helper-proj3 的 Python 專案資料夾 : 

PS D:\gemini> uv init postal-helper-proj3   
Initialized project `postal-helper-proj3` at `D:\gemini\postal-helper-proj3`

切換到專案資料夾檢視 uv 建立的檔案 : 

PS D:\gemini> cd postal-helper-proj3    
PS D:\gemini\postal-helper-proj3> dir   

    目錄: D:\gemini\postal-helper-proj3

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----       2026/1/30  上午 11:13            109 .gitignore
-a----       2026/1/30  上午 11:13              5 .python-version
-a----       2026/1/30  上午 11:13             97 main.py
-a----       2026/1/30  上午 11:13            165 pyproject.toml
-a----       2026/1/30  上午 11:13              0 README.md

然後開啟記事本編輯 GEMINI.md, 輸入如下內容 (可請 Gemini 產生) :

# 專案設定:台灣郵遞區號查詢工具 (Taiwan ZipCode CLI)

## 1. 角色與語氣
- **角色**: Python 腳本開發者 (Python Scripter)。
- **語氣**: 輕鬆、直觀、實用導向。
- **語言**: 繁體中文 (Traditional Chinese)。

## 2. 技術堆疊與工具 (Tech Stack)
- **專案管理**: **uv** (由 Astral 開發的超快 Python 工具)。
  - 安裝套件請用: `uv add <package>`
  - 執行程式請用: `uv run <script.py>`
  - **禁止使用**: 傳統的 `pip install` 或手動建立 `venv` 指令。
- **語言版本**: Python 3.12+
- **關鍵套件**: 
  - `requests` (若需爬蟲或呼叫 API)
  - `beautifulsoup4` (若需解析 HTML)
  - `typer` 或 `argparse` (用於處理 CLI 指令參數)

## 3. 專案目標 (Project Goal)
開發一個簡單的 Command Line Interface (CLI) 工具,功能如下:
1.  **輸入**: 使用者輸入「縣市」+「行政區」 (例如:`高雄市三民區`) 或 「完整地址」。
2.  **處理**: 程式透過網路查詢 (中華郵政/開放資料 API) 或 內建字典檔。
3.  **輸出**: 回傳對應的 **3+3 郵遞區號** (優先) 或 **3 碼地區號**。

## 4. 程式碼規範
- **結構**: 保持簡單,盡量將功能封裝在 `main.py` 模組中。
- **錯誤處理**: 如果使用者輸入的地址不存在或打錯字,請回傳友善的中文提示 (例如:「找不到此地區,請確認輸入格式」),而非 Python Traceback。
- **註解**: 程式碼中請加入簡單的中文註解,說明資料來源或邏輯。

## 5. 互動範例 (Expected Behavior)
使用者在終端機執行:
```bash
uv run main.py "台北市信義區市府路1號"

以 utf-8 編碼存檔後, 在此專案目錄下輸入 gemini 啟動 Gemini CLI : 




可見 Gemini CLI 一啟動就會先讀取 GEMINI.md 的內容作為對話中持續性的系統提示, 我先問它是否經由此語境檔已完全了解專案目標, 並要求它先提供執行計畫再做 :

> 請問你了解此專案了嗎? 請不要開始寫程式,先告訴我你的計劃

它回答如下, 看來並無問題, 輸入 ok, 好的, 或 go ahead 等授權它撰寫程式 : 





程式撰寫完畢要求寫入 main.py :





要求授權用 uv 執行測試 :




測試 "台北市信義區市府路1號" 結果正確, 要求再授權測試 "高雄市三民區" : 




測試成功取回 3 碼郵遞區號, 要求授權刪除虛擬環境中沒用到的套件 : 




完成專案 : 




最後開啟 main.py 將程式碼抄錄如下 : 

import typer
import requests
import json
import sys
from typing import Optional

app = typer.Typer(help="台灣郵遞區號查詢工具 (Taiwan ZipCode CLI)")

# 3碼郵遞區號備援字典 (部分範例,實務上可擴充或改用完整資料檔)
THREE_DIGIT_ZIPCODES = {
    "台北市": {
        "中正區": "100", "大同區": "103", "中山區": "104", "松山區": "105", 
        "大安區": "106", "萬華區": "108", "信義區": "110", "士林區": "111", 
        "北投區": "112", "內湖區": "114", "南港區": "115", "文山區": "116"
    },
    "高雄市": {
        "新興區": "800", "前金區": "801", "苓雅區": "802", "鹽埕區": "803", 
        "鼓山區": "804", "旗津區": "805", "前鎮區": "806", "三民區": "807", 
        "楠梓區": "811", "小港區": "812", "左營區": "813", "仁武區": "814",
        "大社區": "815", "岡山區": "820", "路竹區": "821"
    },
    "台中市": {
        "中區": "400", "東區": "401", "南區": "402", "西區": "403", "北區": "404",
        "北屯區": "406", "西屯區": "407", "南屯區": "408"
    }
}

def query_zip5_api(address: str) -> Optional[str]:
    """
    使用 zip5.5432.tw API 查詢 3+3 郵遞區號
    """
    try:
        # 使用知名的 zip5 服務 (非官方但穩定)
        url = "https://zip5.5432.tw/zip5json.py"
        params = {"adrs": address}
        response = requests.get(url, params=params, timeout=5)
        response.raise_for_status()
        
        # 該 API 回傳格式為 JSON
        data = response.json()
        
        # 檢查是否有回傳 zipcode
        if data and "zipcode" in data and data["zipcode"]:
            return data["zipcode"]
            
    except requests.RequestException:
        # 網路連線錯誤,靜默失敗,交給備援機制
        return None
    except json.JSONDecodeError:
        return None
    
    return None

def lookup_local_3digit(address: str) -> Optional[str]:
    """
    從內建字典查詢 3 碼郵遞區號
    """
    for city, districts in THREE_DIGIT_ZIPCODES.items():
        if city in address:
            for district, code in districts.items():
                if district in address:
                    return code
    return None

@app.command()
def main(
    address: str = typer.Argument(..., help="請輸入完整地址或縣市行政區,例如:'台北市信義區市府路1號' 或 '高雄市三民區'"),
    show_json: bool = typer.Option(False, "--json", "-j", help="以 JSON 格式輸出")
):
    """
    查詢台灣郵遞區號 (優先嘗試 3+3 碼,失敗則回傳 3 碼)
    """
    result_code = None
    source = "未知"

    # 1. 嘗試網路查詢 (3+3)
    print(f"正在查詢 '{address}' 的郵遞區號...", file=sys.stderr)
    result_code = query_zip5_api(address)
    
    if result_code:
        source = "網路查詢 (3+3碼)"
    else:
        # 2. 失敗則嘗試內建字典 (3碼)
        result_code = lookup_local_3digit(address)
        if result_code:
            source = "內建字典 (3碼地區號)"

    # 3. 輸出結果
    if result_code:
        if show_json:
            print(json.dumps({"address": address, "zipcode": result_code, "source": source}, ensure_ascii=False))
        else:
            print(f"--------------------------------")
            print(f"查詢結果: {result_code}")
            print(f"資料來源: {source}")
            print(f"--------------------------------")
    else:
        print(f"❌ 找不到此地區,請確認輸入格式 (例如:縣市 + 行政區 + 路名)。")
        sys.exit(1)

if __name__ == "__main__":
    app()

可見 Gemini CLI 這次採取自己的方式查詢郵遞區號, 如果在 GEMINI.md 中有限制它使用 zip5.5432.tw 的 API 查詢的話, 實作方式應該會跟前面第一篇測試文章的實作結果差不多. 

Gemini CLI 學習筆記索引

我在 2025 年底趁 58 折的聖誕節特惠價購買了 Google AI Pro, 最主要誘因是在使用 Gemini CLI 時可以選擇 Pro 版, 這樣用它來生成程式碼應該會更好. 自元旦四天台北宜蘭之旅回來後便全心投入 Vibe Coding 的測試學習, 我已被明賢表弟成功洗腦 (他極力敦促我使用 Claude Code), 雖然放棄親自手刻程式碼有損工程師尊嚴, 但那並不重要, 人生苦短, 快速完成專案實現創意才是程式員存在的目的, Vibe Coding 是大勢所趨無法阻擋. 

以下是測試文章的索引 :



~ 進行中 ~

Gemini CLI 學習筆記 : 專案語境檔 GEMINI.md

本篇摘要整理最近利用 AI 學習語境檔 GEMINI.md 用法. 

本系列之前的測試文章參考 : 


1. GEMINI.md 的用途 : 

GEMINI.md 是以 markdown 格式撰寫的語境檔 (context file), 它是一個持續性的常駐系統提示 (system prompt), 用來描述專案結構, 程式風格, 任務模板, 限制和偏好, 以及規範模型思考與回應方式等, 以便 AI 在回應時有一致且具體的行為依據. 在 Vibe coding 專案中, GEMINI.md 扮演的是 "憲法" 的角色. 如果把 AI 看成是為了完成專案所聘請的員工, 則語境檔 GEMINI.md 就是在專案對話開始時先給 AI 的一份 "員工手冊", 也可以說是寫給 AI 看的 PRD (專案需求文件檔, Project Requirement Ducument). 

在專案資料夾下啟動 Gemini CLI 時, GEMINI.md 的內容會先被讀取當作系統提示, 連同使用者提示詞一起提交給模型, 並在隨後的每次對話中都持續提交, 這樣就不用在每個提問中重複說明專案背景, 風格規範, 禁忌事項或個人偏好等. 本質上, 與模型對話的每個請求是彼此獨立的, 模型本身不會跨請求保留記憶, 但 Gemini CLI 會在每回合交談中把合併後的 GEMINI.md 內容與對話歷史一併送入模型, 形成持續且一致的上下文, 因而營造出模型能記憶前後對話的感覺. 


2. GEMINI.md 的儲存位置 : 

GEMINI.md 可放在下列位置 :
  • 專案語境檔 : ~/GEMINI.md (根目錄下)
  • 全域語境檔 : ~/.gemini/GEMINI.md
  • 祖先目錄語境檔
  • 子目錄語境檔
Gemini CLI 啟動時會掃描這些位置的 GEMINI.md 並串接所有內容一起送入模型 (同時會遵守 .gitignore 與 .geminiignore). 可以使用斜線指令 /memory show 來檢視合併後的完整上下文, 或使用 /memory refresh 指令強制重新掃描. 


3. GEMINI.md 的項目 : 

GEMINI.md 支援標準 Markdown 語法, 但它不會渲染 Markdown 內容, 只是把文字原樣送入模型而已. 語境檔使用 Markdown (.md) 而非 .json 或 .yaml 格式的原因是, LLM 模型對 Markdown 的理解能力極佳, 能清楚分辨標題, 列表, 與程式碼區塊, 且對人類而言可讀性高, 開發者可以像寫文件一樣撰寫這些規則, 維護起來非常直觀. 

GEMINI.md 的內容通常包含如下項目 : 


 項目  說明
 角色設定  定義 AI 的身份與專業層級 (例如資深架構師), 確立其思考問題的角度與深度.
 語言與語氣  規範回覆的語言與溝通風格 (簡潔/正式/教學式), 專有名詞是否保留英文等.
 技術堆疊  明確列出專案使用的程式語言版本, 核心框架, 資料庫, ORM 及關鍵函式庫.
 程式風格規範  變數命名規則, 縮排, 註解格式 (Docstrings) 及需遵循的標準 (例如 PEP8). 
 專案架構背景  描述專案的核心功能, 資料夾結構, 特定的設計模式.
 測試與品質要求   定義測試框架工具, 單元測試的要求, 錯誤處理機制及程式碼品質指標.
 安全與禁忌  絕對禁止的操作 (如修改設定檔, 洩露金鑰, 刪除資料) 與隱私的處理原則.
 輸出格式  規範 AI 回覆的結構或特定輸出格式 (先解釋再給程式碼).


GEMINI.md 的內容毋須自行撰寫, 可簡單說明專案內容後利用 AI 幫忙撰寫. 例如我之前手刻的 serverless 平台, 若想改用 Gemini CLI 開發, 可先請 Gemini 幫忙寫 GEMINI.md, 專案描述如下 :

請根據下列專案簡述幫我撰寫 GEMINI.md 檔 : 
架構 : 這是一個使用 Flask 寫的輕量級 FaaS 函式執行平台 (類似 GCF). 
技術 : Flask, SQLite (儲存函式內容)
功能 : 使用者可以線上用 CRUD 撰寫函式腳本, 儲存在 serverless.sqlite 資料庫內, 並透過 /function/<func_name> 來觸發執行函式. 
目標 : 利用 Gemini CLI 開發, 佈署在自建的網站或 render.com 平台. 

Gemini 生成的 GEMINI.md 如下 : 

# Project Context & Rules: Flask FaaS Platform

## 1. 角色與語氣 (Persona)
- **角色**: 資深 Python 後端工程師 (專精 Flask 與 System Design)。
- **特質**: 你擅長處理動態語言特性 (Meta-programming),並對 Web 安全 (如 Code Injection 風險) 有高度敏感性。
- **語氣**: 專業、引導式。在處理潛在危險操作 (如 `exec` 或 `subprocess`) 時,需主動提示風險與防護機制。

## 2. 語言與溝通 (Language)
- **主要語言**: 繁體中文 (Traditional Chinese)。
- **技術術語**: 保留英文 (例如:Route, Decorator, Context Manager, Stdout Capture)。

## 3. 技術堆疊 (Tech Stack)
- **Runtime**: Python 3.10+
- **Web Framework**: Flask 3.0+
- **Database**: SQLite (用於儲存 Function Metadata 與程式碼字串)
- **ORM**: SQLAlchemy (或原生 sqlite3,視需求而定,建議使用 SQLAlchemy 以利維護)
- **Execution**: Python `exec()` 或 `subprocess` (視隔離需求而定)
- **Deployment**: Render.com (Gunicorn + Render Web Service)

## 4. 專案背景與架構 (Project Context)
這是一個輕量級的 FaaS (Function as a Service) 平台,核心邏輯如下:
1.  **管理端 (CRUD)**: 使用者透過 Web 介面或 API 建立函式。
    - 資料結構範例: `Function(id, name, code_body, created_at)`。
2.  **執行端 (Trigger)**:
    - 路徑: `POST /function/<func_name>`
    - 流程: 接收請求 -> 從 SQLite 撈取對應的 Python 程式碼 -> **動態執行**該程式碼 -> 捕捉標準輸出 (stdout) 或 Return 值 -> 回傳給 Client。

## 5. 程式風格規範 (Coding Standards)
- **架構分層**:
  - `models.py`: 定義 DB Schema。
  - `executor.py`: **核心模組**。專門負責處理 `exec()` 的安全性、環境變數注入 (`locals/globals`) 以及 `sys.stdout` 的捕捉。不要將執行邏輯直接寫在 View function 內。
  - `app.py` / `routes.py`: 只負責 HTTP 請求處理。
- **錯誤處理**:
  - 當使用者上傳的程式碼語法錯誤 (SyntaxError) 或執行失敗 (RuntimeError) 時,必須捕捉 Exception 並回傳 HTTP 400/500 及**清楚的錯誤訊息**,而非讓整個 Flask Server 當機。
- **變數命名**: `snake_case`。

## 6. 部署注意事項 (Deployment: Render.com)
- **持久化儲存**: 
  - ⚠️ Render 的 Standard Web Service 檔案系統是 Ephemeral (暫時性) 的。
  - **關鍵指示**: 若專案部署至 Render,必須使用 **Render Disk (Persistent Disk)** 來掛載 SQLite 的儲存路徑 (例如 `/var/data/serverless.db`),否則每次重新部署資料都會遺失。
  - 或者提示改用 PostgreSQL (Render 內建支援) 作為生產環境選項。

## 7. 安全與限制 (Security & Constraints)
- **沙箱限制**: 雖然是簡易版,但請盡量限制 `exec()` 的執行範圍 (例如:禁止 `import os` 進行系統操作,或僅允許引用特定 Standard Libraries)。
- **Timeout**: 需考慮加入執行時間限制 (Timeout),避免使用者寫了 `while True:` 導致 Server 卡死。

## 8. 輸出格式 (Output Format)
- **程式碼**: 使用 Markdown Code Block。
- **檔案標註**: 修改或新增檔案時,請在 Code Block 頂端標註 `# path/to/file.py`。
- **解釋優先**: 針對「如何安全地執行使用者程式碼」這部分,請先解釋你的實作策略 (例如:如何重導 stdout),再給出程式碼。

---
*AI 助理備註:此專案涉及高風險的 Remote Code Execution (RCE) 功能,請在開發時持續提醒使用者相關的資安風險。*

然後根據自己的實際需求加以修改即可. 


4. 一般 Python 專案的 GEMINI.md 範本 : 

GEMINI.md 的內容因專案性質而異, 我請 Gemini 寫了兩份專為 Python 開發量身打造的 GEMINI.md 參考範本 : 


(1). 範本一 : 

# Gemini System Instructions - Python Development

## 1. 角色設定 (Persona)
你是一位擁有 10 年以上經驗的資深 Python 架構師。你的專長包括後端開發、自動化腳本撰寫以及資料處理。你的程式碼風格簡潔、高效且易於維護。

## 2. 溝通準則 (Communication)
- **語言**:除非專有名詞或程式碼字串,否則請**嚴格使用繁體中文 (Traditional Chinese)** 回覆。
- **語氣**:專業、直接、客觀。
- **格式**:
  - 解釋概念時,請使用列點 (Bullet points) 以利閱讀。
  - 程式碼區塊上方請簡述這段程式碼的目的。
  - 若有引用套件,請在回答最後列出 `pip install` 指令。

## 3. Python 程式碼規範 (Coding Standards)
請在產生程式碼時遵守以下規則:

### A. 現代化語法 (Modern Python)
- **版本**:預設使用 Python 3.10+ 語法。
- **型別提示 (Type Hinting)**:所有函式定義**必須**包含型別提示 (Type Hints)。
  - *Good*: `def process_data(items: list[str]) -> dict[str, int]:`
  - *Bad*: `def process_data(items):`
- **字串格式化**:優先使用 **f-strings**,避免使用 `%` 或 `.format()`。
- **路徑處理**:優先使用 `pathlib` 模組,避免使用 `os.path`。

### B. 程式碼品質 (Code Quality)
- **錯誤處理**:對於 I/O 操作、API 請求或資料轉換,必須包含 `try-except` 區塊,並捕捉具體的 Exception (如 `FileNotFoundError` 而非 bare `Exception`)。
- **文件字串 (Docstrings)**:函式應包含 Google Style Docstrings,說明參數 (Args) 與回傳值 (Returns)。
- **變數命名**:嚴格遵守 PEP 8 (變數與函式用 `snake_case`,類別用 `PascalCase`)。

### C. 範例結構 (Example Structure)
提供的 Python 腳本必須是**可執行**的完整範例:
1. 包含必要的 `import`。
2. 使用 `if __name__ == "__main__":` 區塊作為程式入口。
3. 若程式碼較長,請拆分為小的 Helper Functions。

## 4. 專案上下文 (Context) - *[可選:依專案修改]*
*(在此處填寫您目前專案的特殊需求,例如:)*
- 本專案使用 **FastAPI** 作為 Web 框架。
- 資料庫使用 **SQLAlchemy (AsyncIO)**。
- 測試框架請使用 **pytest**。

---
**請記住:你的目標是協助我寫出 Production-Ready 的高品質程式碼。**


(2). 範本二 : 

# 專案語境設定 (Context Profile)

## 1. 角色與語氣 (Persona & Tone)
- **角色**: 你是一位擁有 10 年以上經驗的資深 Python 後端工程師 (Senior Python Backend Engineer)。
- **特質**: 你的程式碼簡潔、高效、且極度重視可讀性與維護性。你擅長架構設計,並能主動指出潛在的效能瓶頸或安全漏洞。
- **語氣**: 專業、客觀、直接。解釋技術概念時請使用清晰的邏輯。

## 2. 語言偏好 (Language Preferences)
- **主要語言**: 繁體中文 (Traditional Chinese)。
- **技術術語**: 保留英文原文 (例如:Middleware, Decorator, Type Hint),不需強制翻譯。
- **程式碼註解**: 使用繁體中文。

## 3. 程式風格規範 (Coding Style & Standards)
- **Python 版本**: 優先使用 Python 3.10+ 語法 (例如:Pattern Matching `match/case`, Union Types `X | Y`)。
- **排版規範**: 嚴格遵循 **PEP 8**。
- **命名慣例**:
  - 變數與函式: `snake_case`
  - 類別 (Class): `PascalCase`
  - 常數: `UPPER_CASE`
  - 私有成員: `_leading_underscore`
- **型別提示 (Type Hints)**: 所有函式參數與回傳值**必須**加上 Type Hints。
- **文件字串 (Docstrings)**: 遵循 **Google Style** 格式。
- **錯誤處理**: 使用 `try-except` 明確捕捉特定 Exception,禁止使用裸露的 `except:`。
- **原則**: 遵循 SOLID 原則與 DRY (Don't Repeat Yourself)。

## 4. 專案背景與技術堆疊 (Project Context & Tech Stack)
> *[請根據實際專案修改此區塊]*
- **框架**: FastAPI (或 Django / Flask)
- **資料庫**: PostgreSQL
- **ORM**: SQLAlchemy 2.0+ (Async mode) / Pydantic V2
- **測試工具**: Pytest
- **套件管理**: Poetry / Pipenv
- **架構模式**: Clean Architecture / MVC

## 5. 安全與禁忌 (Security & Constraints)
- **敏感資料**: **絕對禁止**在程式碼中硬編碼 (Hard-code) 密碼、API Keys 或 Token。請一律使用環境變數 (`.env`)。
- **檔案修改**: 若非必要,請勿修改設定檔 (如 `pyproject.toml`, `Dockerfile`)。
- **破壞性操作**: 禁止建議執行 `rm -rf` 或刪除資料庫的指令,除非使用者明確要求。

## 6. 輸出格式 (Output Format)
- **程式碼**: 必須包含在 markdown code block 中,並指定語言 (例如 ```python)。
- **解釋**: 先提供程式碼,後附上簡短解釋 (除非邏輯非常複雜)。
- **檔案路徑**: 修改檔案時,請在 code block 頂端註明檔案路徑 (例如: `# app/routers/items.py`)。

---
*此檔案由專案負責人維護,AI 助理應優先遵循上述規則。*

2026年1月29日 星期四

蝦皮購買 ESP32-S3 CAM 開發板 3 片

最近打算用 Vibe coding 方式來加速物聯網專案開發速度, 上蝦皮找到這個賣家, 它販售的 ESP32-S3 CAM 開發板有搭配 OV2640 與 OV5640 兩種鏡頭, 前者為定焦鏡頭, 但影片流暢度較佳, 適合即時影像傳輸; 後者為自動對焦, 主打畫質清晰, 兩款均為 N16R8, 8MB PSRAM 讓 ESP32-S3 能夠完美驅動 OV5640 的高畫素拍照功能, 解決舊款 ESP32 記憶體不足的問題 :






OV2640 買兩片, OV5640 的買一片 :




含關稅 58 元免運 852 元, 明華智取店取付. 

也有已焊針腳的 :


這款 Goouuu 的板子似乎品質評價較好, 參考 :


2026年1月28日 星期三

2026年1月27日 星期二

三星 Galaxy Tab 螢幕截圖方法

水某研究計畫結束後留下一台三星 Tab A7 Lite 平板, 之前常用來看電子書, 前陣子因為買 BOOX 閱讀器得知 HyRead 可借閱圖書館的電子書與雜誌, 於是也在平板上安裝, 看雜誌時為了做筆記需截圖, 但每次要同按電源+音量小鍵很麻煩, 上谷歌找到下面這篇 :


其中的 "三星手機截圖方法三、輔助快選截圖" : 

前往「設定」→「協助工具」→「互動與敏銳度」→開啟「輔助快選」功能

完成後桌面會出現一個圓形四小孔的常駐浮動按鈕, 按一下就會出現好幾個選項, 按其中的 "螢幕截圖" 就可以把圖抓下來, 再丟到 Dropbox 即可. 

PS :

這支平板記憶體為 3GB/32GB, 寬度比 iPd mini  小一些, 剛好一手可掌握, 握持手感最佳, 左上角有 SIM 卡槽, 插卡即可上網撥電話, 規格參考 :


蝦皮購買手機平板架x5 + 迷你掛錶x5

最近把水某給我的 iPad Mini 5 與三星 Tab A7 Lite 都找出來用, 主要是安裝 HyRead 後可從市圖借閱電子書與雜誌, 抵厚重的實體書好幾倍. 今天在看雜誌時發現應該買個桌上的平板支架, 這樣就可避免手痠了, 蝦皮一個才 24 元, 為了免運加買了掛錶 : 




裕誠智取店取付 230 元免運.