2025年3月27日 星期四

green judge problems

https://web.archive.org/web/20210917163453/http://www.tcgs.tc.edu.tw:1218/Problems

2025年3月11日 星期二

組字程式 III


# -*- coding: utf-8 -*-

# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import ttk
import pyttsx3
import random

# 初始化語音引擎
engine = pyttsx3.init()

# 字首、字根、字尾選項
prefixes = sorted("ante,anti,auto,ambi,apo,be,bene,bi,circ,co,com,col,con,contra,counter,de,dia,dis,en,ex,extra,hetero,homo,hyper,il,im,in,inter,intra,intro,ir,mal,mega,micro,mis,mono,multi,neo,non,ob,para,pan,per,poly,post,pre,pro,re,se,semi,sub,super,supra,sur,sym,syn,tele,trans,tri,uni".split(','))

roots = sorted("ann,audi,bio,cap,ceive,cip,cept,ced,ceed,cess,cede,circ,cyc,dem,demo,dict,divid,duc,equ,flect,flex,form,gram,graph,gress,ject,manu,mob,mot,mov,nov,ped,pict,port,pos,press,rupt,scribe,serve,sist,spec,spir,tain,tract,vid,vise,viv,volv,astro,bell,cardi,chron,corp,cred,geo,hydr,luc,phon,therm".split(','))

suffixes = sorted("er,or,an,ian,ant,ent,ar,ate,ee,eer,ese,ess,ic,ics,ician,ist,ster,al,age,ance,ence,ancy,ency,dom,hood,ism,ity,ty,logy,ment,ness,ory,ship,tion,ation,sion,ure,ture,ate,en,fy,ify,ish,ize,ise,le,able,ible,ary,ful,ical,id,ior,ive,less,like,ly,ous,proof,ward,wards,way,ways,wise,acious,tude,phobia,escence,ory,cule,ling".split(','))

# 建立主視窗
root = tk.Tk()
root.title("字根組合器")
root.geometry("550x450")

# 設定標籤
tk.Label(root, text="選擇字首:").grid(row=0, column=0, padx=10, pady=10)
tk.Label(root, text="選擇字根:").grid(row=0, column=1, padx=10, pady=10)
tk.Label(root, text="選擇字尾:").grid(row=0, column=2, padx=10, pady=10)
tk.Label(root, text="組合的單字:").grid(row=4, column=0, padx=10, pady=10)

# 建立 Combobox 下拉選單
prefix_var = tk.StringVar()
prefix_combobox = ttk.Combobox(root, textvariable=prefix_var, values=prefixes, state="readonly")
prefix_combobox.grid(row=1, column=0, padx=10, pady=10)

root_var = tk.StringVar()
root_combobox = ttk.Combobox(root, textvariable=root_var, values=roots, state="readonly")
root_combobox.grid(row=1, column=1, padx=10, pady=10)

suffix_var = tk.StringVar()
suffix_combobox = ttk.Combobox(root, textvariable=suffix_var, values=suffixes, state="readonly")
suffix_combobox.grid(row=1, column=2, padx=10, pady=10)

# 顯示組合後的單字
word_label = tk.Label(root, text="", font=("Arial", 14, "bold"), fg="blue")
word_label.grid(row=4, column=1, padx=10, pady=10)

# 更新單字的函式
def update_word():
    combined_word = f"{prefix_var.get()}{root_var.get()}{suffix_var.get()}"
    word_label.config(text=combined_word)
    engine.say(combined_word)
    engine.runAndWait()

# 隨機生成 10 個單字並朗讀
def generate_random_words():
    words = [f"{random.choice(prefixes)}{random.choice(roots)}{random.choice(suffixes)}" for _ in range(10)]
    word_label.config(text="\n".join(words))
    for word in words:
        engine.say(word)
    engine.runAndWait()

# 設定按鈕,點擊後更新顯示
combine_button = tk.Button(root, text="組合單字", command=update_word)
combine_button.grid(row=3, column=1, padx=10, pady=10)

# 設定隨機練習按鈕
auto_practice_button = tk.Button(root, text="自動練習 10 字", command=generate_random_words)
auto_practice_button.grid(row=5, column=1, padx=10, pady=10)

# 啟動主循環
root.mainloop()

組字練習 II

 import tkinter as tk


from tkinter import ttk


import pyttsx3


engine = pyttsx3.init()



# 字首、字根、字尾選項


t ='ante,contra,contro,counter,a,auto,bene,con,co,com,col,de,en,ex,extra,homo,hyper,in,im,inter,intra,intro,mal,micro,mono,multi,ob,op,para,per,poly,re,semi,sub,sup,super,supra,sur,sym,syn,tele,trans,anti,dis,ab,in,il,ir,im'

t = t.split(',')

t.sort()


prefixes =  t


t1 = 'ann,audi,bio,cap,ceive,cip,cept,ced,ceed,cess,cede,circ,cyc,dem,demo,dict,divid,duc,equ,flect,flex,form,gram,graph,gress,ject,manu,mob,mot,mov,nov,ped,pict,port,pos,press,rupt,scribe,serve,sist,spec,spir,spire,tain,tract,vid,vise,viv,volv,volute,uni,bi,tri,oct,deca,cent,kilo,mega'

t1 = t1.split(',')

t1.sort()

roots = t1


t2 = 'er,or,an,ian,ant,ent,ar,ate,ee,eer,ese,ess,ic,ician,ist,ster,al,age,ance,ence,ancy,ency,dom,hood,ic(s),ism,ity,ty,logy,ment,ness,ory,ship,tion,ation,sion,ure,ture,ate,en,fy,ify,ish,ize,ise,le,able,ible,al,ant,ent,ar,ary,ate,en,ful,ic,ical,id,ior,ish,ive,less,like,ly,ous,proof,ward,y,ly,ward(s),way(s),wise'

t2 = t2.split(',')

t2.sort()

suffixes = t2




# 建立主視窗


root = tk.Tk()


root.title("字根組合器")


root.geometry("550x250")




# 設定標籤


tk.Label(root, text="選擇字首:").grid(row=0, column=0, padx=10, pady=10)


tk.Label(root, text="選擇字根:").grid(row=0, column=1, padx=10, pady=10)


tk.Label(root, text="選擇字尾:").grid(row=0, column=2, padx=10, pady=10)


tk.Label(root, text="組合的單字:").grid(row=4, column=0, padx=10, pady=10)




# 建立 Combobox 下拉選單


prefix_var = tk.StringVar()


prefix_combobox = ttk.Combobox(root, textvariable=prefix_var, values=prefixes, state="readonly")


prefix_combobox.grid(row=1, column=0, padx=10, pady=10)




root_var = tk.StringVar()


root_combobox = ttk.Combobox(root, textvariable=root_var, values=roots, state="readonly")


root_combobox.grid(row=1, column=1, padx=10, pady=10)




suffix_var = tk.StringVar()


suffix_combobox = ttk.Combobox(root, textvariable=suffix_var, values=suffixes, state="readonly")


suffix_combobox.grid(row=1, column=2, padx=10, pady=10)




# 顯示組合後的單字


word_label = tk.Label(root, text="", font=("Arial", 14, "bold"), fg="blue")


word_label.grid(row=4, column=1, padx=10, pady=10)




# 更新單字的函式


def update_word():


    prefix = prefix_var.get()


    root_word = root_var.get()


    suffix = suffix_var.get()


    combined_word = f"{prefix}{root_word}{suffix}"


    word_label.config(text=combined_word)


    engine.say(combined_word)

    engine.runAndWait()






# 設定按鈕,點擊後更新顯示


combine_button = tk.Button(root, text="組合單字", command=update_word)


combine_button.grid(row=3, column=1, padx=10, pady=10)




# 啟動主循環


root.mainloop()

2025年3月10日 星期一

Combobox 下拉選單





import tkinter as tk

from tkinter import ttk


# 字首、字根、字尾選項

prefixes = ["pre", "un", "re", "dis"]

roots = ["dict", "form", "struct", "spect"]

suffixes = ["ion", "able", "ive", "ment"]


# 建立主視窗

root = tk.Tk()

root.title("字根組合器")

root.geometry("400x250")


# 設定標籤

tk.Label(root, text="選擇字首:").grid(row=0, column=0, padx=10, pady=10)

tk.Label(root, text="選擇字根:").grid(row=1, column=0, padx=10, pady=10)

tk.Label(root, text="選擇字尾:").grid(row=2, column=0, padx=10, pady=10)

tk.Label(root, text="組合的單字:").grid(row=4, column=0, padx=10, pady=10)


# 建立 Combobox 下拉選單

prefix_var = tk.StringVar()

prefix_combobox = ttk.Combobox(root, textvariable=prefix_var, values=prefixes, state="readonly")

prefix_combobox.grid(row=0, column=1, padx=10, pady=10)


root_var = tk.StringVar()

root_combobox = ttk.Combobox(root, textvariable=root_var, values=roots, state="readonly")

root_combobox.grid(row=1, column=1, padx=10, pady=10)


suffix_var = tk.StringVar()

suffix_combobox = ttk.Combobox(root, textvariable=suffix_var, values=suffixes, state="readonly")

suffix_combobox.grid(row=2, column=1, padx=10, pady=10)


# 顯示組合後的單字

word_label = tk.Label(root, text="", font=("Arial", 14, "bold"), fg="blue")

word_label.grid(row=4, column=1, padx=10, pady=10)


# 更新單字的函式

def update_word():

    prefix = prefix_var.get()

    root_word = root_var.get()

    suffix = suffix_var.get()

    combined_word = f"{prefix}{root_word}{suffix}"

    word_label.config(text=combined_word)


# 設定按鈕,點擊後更新顯示

combine_button = tk.Button(root, text="組合單字", command=update_word)

combine_button.grid(row=3, column=1, padx=10, pady=10)


# 啟動主循環

root.mainloop()

字首字根字尾組字練習



 import tkinter as tk

from tkinter import ttk

import pyttsx3

import requests

from bs4 import BeautifulSoup


def build_word():

    prefix = prefix_var.get()

    root = root_var.get()

    suffix = suffix_var.get()

    

    if prefix in prefixes and root in roots and suffix in suffixes:

        word = prefix + root + suffix

        meaning = f"{prefixes[prefix]} + {roots[root]} + {suffixes[suffix]}"

        chinese_meaning = f"{prefix_ch[prefix]} + {root_ch[root]} + {suffix_ch[suffix]}"

        dictionary_meaning = fetch_yahoo_definition(word)

        

        result_label.config(text=f"你的新單字: {word}\n英文解釋: {meaning}\n中文解釋: {chinese_meaning}\n字典解釋: {dictionary_meaning}")

        speak_word(word)

    else:

        result_label.config(text="無效的組合,請選擇有效的選項。")


def speak_word(word):

    engine = pyttsx3.init()

    engine.say(word)

    engine.runAndWait()


def fetch_yahoo_definition(word):

    try:

        url = f"https://tw.dictionary.search.yahoo.com/search?p={word}"

        headers = {"User-Agent": "Mozilla/5.0"}

        response = requests.get(url, headers=headers)

        soup = BeautifulSoup(response.text, "html.parser")

        

        definition = soup.find("span", class_="fz-14 lh-22").text if soup.find("span", class_="fz-14 lh-22") else "無字典解釋"

        return definition

    except:

        return "查詢失敗,請檢查網絡。"


prefixes = {

    "un": "not, opposite of",

    "re": "again, back",

    "pre": "before",

    "mis": "wrongly",

    "dis": "opposite of",

    "sub": "under, below",

    "inter": "between",

    "auto": "self",

    "trans": "across"

}


prefix_ch = {

    "un": "不,相反的",

    "re": "再,回",

    "pre": "前,預先",

    "mis": "錯誤地",

    "dis": "相反的",

    "sub": "下,次級",

    "inter": "之間",

    "auto": "自己",

    "trans": "跨,穿越"

}


roots = {

    "act": "do, perform",

    "form": "shape",

    "ject": "throw",

    "port": "carry",

    "rupt": "break",

    "scribe": "write",

    "struct": "build",

    "vis": "see",

    "dict": "say"

}


root_ch = {

    "act": "行動,執行",

    "form": "形狀,形成",

    "ject": "投擲,拋",

    "port": "運輸,攜帶",

    "rupt": "破壞,中斷",

    "scribe": "書寫,記錄",

    "struct": "建造,結構",

    "vis": "看,視覺",

    "dict": "說話,命令"

}


suffixes = {

    "er": "one who",

    "able": "capable of",

    "ion": "act, process",

    "ment": "state or quality",

    "ful": "full of",

    "less": "without",

    "ness": "state of being",

    "ity": "quality of",

    "ive": "tending to"

}


suffix_ch = {

    "er": "從事...的人",

    "able": "能夠...的",

    "ion": "行為,過程",

    "ment": "狀態,品質",

    "ful": "充滿...的",

    "less": "沒有...的",

    "ness": "狀態,性質",

    "ity": "品質,特性",

    "ive": "具有...性質的"

}


root = tk.Tk()

root.geometry("600x300")

root.title("字首字根字尾組字練習")


tk.Label(root, text="字首").grid(row=0, column=0, padx=20)

tk.Label(root, text="字根").grid(row=0, column=1, padx=20)

tk.Label(root, text="字尾").grid(row=0, column=2, padx=20)


prefix_var = tk.StringVar()

root_var = tk.StringVar()

suffix_var = tk.StringVar()


prefix_menu = ttk.Combobox(root, textvariable=prefix_var, values=list(prefixes.keys()))

prefix_menu.grid(row=1, column=0, padx=20)


root_menu = ttk.Combobox(root, textvariable=root_var, values=list(roots.keys()))

root_menu.grid(row=1, column=1, padx=20)


suffix_menu = ttk.Combobox(root, textvariable=suffix_var, values=list(suffixes.keys()))

suffix_menu.grid(row=1, column=2, padx=20)


tk.Button(root, text="組字", command=build_word).grid(row=4, column=0, columnspan=3, pady=10)


result_label = tk.Label(root, text="", wraplength=500, justify="left")

result_label.grid(row=5, column=0, columnspan=3, pady=10)


root.mainloop()

2025年3月7日 星期五

Python 讀寫 SQLite(Docker 最簡單範例)

 

Python 讀寫 SQLite(Docker 最簡單範例)

這是一個 最簡單的 Python 程式,可以在 Docker 容器中讀取與寫入 SQLite 資料庫。


1. 建立專案目錄

首先,在 Windows 命令提示字元 (cmd) 或 PowerShell 建立專案資料夾:

mkdir C:\sqlite_docker
cd C:\sqlite_docker

2. 建立 Python 讀寫 SQLite 檔案

在 C:\sqlite_docker 內建立 app.py:

import sqlite3

# 設定 SQLite 資料庫檔案
DB_FILE = "test.db"

# 連接資料庫(如果不存在則自動建立)
conn = sqlite3.connect(DB_FILE)
cursor = conn.cursor()

# 建立表格(如果不存在)
cursor.execute('''
    CREATE TABLE IF NOT EXISTS messages (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        text TEXT NOT NULL
    )
''')

# 插入測試資料
cursor.execute("INSERT INTO messages (text) VALUES (?)", ("Hello, SQLite in Docker!",))
conn.commit()

# 讀取所有資料
cursor.execute("SELECT * FROM messages")
rows = cursor.fetchall()

# 顯示結果
print("=== SQLite 資料庫內容 ===")
for row in rows:
    print(row)

# 關閉連接
conn.close()

3. 建立 Dockerfile

在 C:\sqlite_docker 內建立 Dockerfile:

# 使用 Python 3.10 作為基礎映像
FROM python:3.10

# 設定工作目錄
WORKDIR /app

# 複製當前目錄的所有檔案到容器內
COPY . .

# 安裝 SQLite3(Python 內建支援,不需要額外安裝)
# 確保資料庫文件存在
RUN touch test.db

# 執行 Python 腳本
CMD ["python", "app.py"]

4. 建立 Docker 映像檔

回到 PowerShell,進入 C:\sqlite_docker:

cd C:\sqlite_docker

執行:

docker build -t sqlite_test .

這會 建立 Docker 映像檔,名稱為 sqlite_test。


5. 運行 Docker 容器

docker run --rm -v C:\sqlite_docker:/app sqlite_test

這樣:

  • --rm:執行結束後自動刪除容器
  • -v C:\sqlite_docker:/app:將本機目錄掛載到容器,確保 SQLite 資料庫 test.db 可持久保存

預期輸出:

=== SQLite 資料庫內容 ===
(1, 'Hello, SQLite in Docker!')

這代表:

  • 成功建立 test.db
  • 寫入了一筆測試數據
  • 成功讀取數據

6. 檢查 SQLite 資料庫

如果你想檢查 test.db 內的內容,執行:

sqlite3 C:\sqlite_docker\test.db

然後在 SQLite 交互模式中輸入:

SELECT * FROM messages;

你應該會看到:

1|Hello, SQLite in Docker!

輸入 .exit 離開 SQLite。


7. 停止 & 刪除容器

因為我們用了 --rm,所以容器執行完畢後會自動刪除。 如果你想讓容器持續運行,請改用:

docker run -d -p 5000:5000 -v C:\sqlite_docker:/app sqlite_test

然後用:

docker ps

來查看運行中的容器。


🚀 總結

✅ 這個範例使用 Python 讀寫 SQLite,並執行在 Docker 容器中
✅ SQLite 資料庫 (test.db) 存放在本機 (C:\sqlite_docker),確保資料不會因容器刪除而遺失
✅ Dockerfile 非常簡單,只需 Python + SQLite 即可運行

這樣你的 Python + SQLite + Docker 最簡單範例就完成了!🚀

Flask 留言板(留言存入檔案 + Docker 版本)

 

Flask 留言板(留言存入檔案 + Docker 版本)

這個 Flask 留言板不僅能提交留言,還會 將留言儲存至檔案 (messages.txt),讓留言可以保留。


1. 建立 Flask 留言板

1.1 建立 app.py

在 C:\flask_board 目錄內,建立 app.py:

from flask import Flask, request, render_template
import os

app = Flask(__name__)

# 設定留言儲存檔案
MESSAGE_FILE = "messages.txt"

# 確保檔案存在
if not os.path.exists(MESSAGE_FILE):
    open(MESSAGE_FILE, "w").close()

# 讀取留言
def load_messages():
    messages = []
    with open(MESSAGE_FILE, "r", encoding="utf-8") as file:
        for line in file:
            parts = line.strip().split(":", 1)
            if len(parts) == 2:
                messages.append({'name': parts[0], 'message': parts[1]})
    return messages

# 儲存留言
def save_message(name, message):
    with open(MESSAGE_FILE, "a", encoding="utf-8") as file:
        file.write(f"{name}: {message}\n")

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        name = request.form.get('name')
        message = request.form.get('message')
        if name and message:
            save_message(name, message)
    messages = load_messages()
    return render_template('index.html', messages=messages)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

這個 Flask 應用做了什麼?

  1. 留言存到 messages.txt。
  2. 讀取檔案內容顯示留言。
  3. 確保留言不會因為重啟 Flask 而消失。

1.2 建立 templates/index.html

在 C:\flask_board\templates 目錄內,建立 index.html:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flask 留言板</title>
</head>
<body>
    <h1>Flask 留言板</h1>
    <form method="post">
        <label>姓名:</label>
        <input type="text" name="name" required>
        <br>
        <label>留言:</label>
        <textarea name="message" required></textarea>
        <br>
        <button type="submit">提交留言</button>
    </form>

    <h2>留言列表</h2>
    <ul>
        {% for msg in messages %}
            <li><strong>{{ msg.name }}</strong>: {{ msg.message }}</li>
        {% endfor %}
    </ul>
</body>
</html>

這個 HTML:

  • 提供表單讓使用者提交留言
  • 顯示所有留言

2. 建立 Dockerfile

在 C:\flask_board 內,建立 Dockerfile:

# 使用 Python 3.10 作為基礎映像
FROM python:3.10

# 設定工作目錄
WORKDIR /app

# 複製當前目錄的所有檔案到容器內
COPY . .

# 安裝 Flask
RUN pip install flask

# 設定留言存儲檔案(確保 messages.txt 存在)
RUN touch messages.txt

# 啟動 Flask 伺服器
CMD ["python", "app.py"]

3. 建立 Docker 映像檔

回到 PowerShell,進入 C:\flask_board:

cd C:\flask_board

執行:

docker build -t flask_board .

這會 建立 Docker 映像檔,名稱為 flask_board。


4. 運行 Flask 容器

執行:

docker run -d -p 5000:5000 -v C:\flask_board:/app flask_board

這樣:

  • -d:讓 Flask 在背景運行
  • -p 5000:5000:將本機 5000 port 對應到 Docker 內的 Flask 伺服器
  • -v C:\flask_board:/app:掛載本機資料夾到 Docker 容器,確保留言檔案持久化

5. 訪問 Flask 留言板

打開 瀏覽器,訪問:

http://localhost:5000/
  • 輸入姓名 & 留言
  • 點擊提交
  • 留言會寫入 messages.txt,並顯示在頁面上
  • 重啟容器後,留言仍然存在!

6. 如何更新 Flask 應用?

如果你修改 app.py 或 index.html,只要 重啟容器,不用重新 build:

docker restart <容器ID>

如果你 修改了 Dockerfile,則需要:

docker stop <容器ID>
docker rm <容器ID>
docker build -t flask_board .
docker run -d -p 5000:5000 -v C:\flask_board:/app flask_board

7. 停止 & 刪除容器

如果你想停止 Flask 伺服器:

docker ps          # 找到運行中的容器 ID
docker stop <容器ID>

如果要刪除容器:

docker rm <容器ID>

如果要刪除 Docker 映像:

docker rmi flask_board

這個版本的 Flask 留言板: ✅ 留言存到檔案 (messages.txt),可持久化
✅ 使用 Docker 容器運行
✅ Volume 掛載,修改內容不需要重建映像檔

這樣你的 Flask 留言板就完整了!🚀