File size: 5,656 Bytes
921be27
 
 
 
 
 
d914fc2
 
921be27
 
 
 
 
 
63b16a0
921be27
 
 
 
d914fc2
 
 
 
 
 
 
 
 
 
 
 
921be27
 
d914fc2
 
88f5edb
 
 
 
d914fc2
 
 
 
88f5edb
d914fc2
 
 
c9a1fff
88f5edb
 
 
 
 
 
 
 
 
 
 
c655778
 
 
 
 
 
 
 
 
d914fc2
 
 
6b721a5
 
 
 
 
 
 
 
 
63b16a0
f3012e2
d914fc2
f3012e2
921be27
63b16a0
88f5edb
 
 
 
c655778
d914fc2
 
 
 
 
 
 
 
 
 
 
f3012e2
d914fc2
 
63b16a0
6b721a5
e53bd9f
f3012e2
 
 
928b997
63b16a0
32bf77b
fb0bb69
7628926
278c32f
d914fc2
 
 
 
63b16a0
 
664e682
63b16a0
 
 
26131db
d914fc2
278c32f
664e682
e53bd9f
 
63b16a0
 
e53bd9f
26131db
32bf77b
63b16a0
7628926
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import gradio as gr
import openai
import PyPDF2
import os
from datetime import datetime

# ✅ openai 0.28:API 金鑰設定
openai.api_key = os.getenv("OPENAI_API_KEY")

topics = ["教育哲學", "教育社會學", "教育心理學", "課程與教學", "教學原理", "班級經營", "教育測驗與評量", "青少年問題與輔導"]
difficulties = ["簡單", "中等", "困難"]

user_errors = {}
error_history = {}
reference_answers = {}

DEFAULT_PDF_PATH = "教材.pdf"

def extract_text_from_pdf():
    if not os.path.exists(DEFAULT_PDF_PATH):
        print(f"[錯誤] 教材未找到:{DEFAULT_PDF_PATH}")
        return ""
    try:
        with open(DEFAULT_PDF_PATH, "rb") as f:
            reader = PyPDF2.PdfReader(f)
            return "\n".join([page.extract_text() or "" for page in reader.pages])
    except Exception as e:
        print(f"[錯誤] PDF 載入失敗:{e}")
        return ""

pdf_text = extract_text_from_pdf()

def generate_question(topic, difficulty):
    if not pdf_text.strip():
        return "⚠️ 無法載入教材內容,請確認 PDF 是否存在。"
    
    # 修改提示以生成選擇題或填空題
    prompt = f"請根據以下教育學教材內容,設計一個屬於「{topic}」主題、「{difficulty}」難度的選擇題或填空題擇一:\n\n{pdf_text}"
    
    try:
        response = openai.ChatCompletion.create(
            model="gpt-4o-mini-2024-07-18",
            messages=[
                {"role": "system", "content": "你是一位教育專家,請根據教材內容設計題目。(不需要包含解析)"},
                {"role": "user", "content": prompt}
            ]
        )
        question = response["choices"][0]["message"]["content"]
        return question.strip()  # 返回生成的問題
    except Exception as e:
        return f"⚠️ 發生錯誤:{e}"

def save_answer(question):
    if not pdf_text.strip():
        return "⚠️ 教材內容未載入,請確認 PDF。"
    
    # 獲取參考答案
    answer_prompt = f"請根據以下問題提供正確答案:\n問題:{question}\n\n教材內容:\n{pdf_text}"
    try:
        answer_response = openai.ChatCompletion.create(
            model="gpt-4o-mini-2024-07-18",
            messages=[
                {"role": "system", "content": "你是一位教育專家,請根據教材內容提供問題的正確答案。"},
                {"role": "user", "content": answer_prompt}
            ]
        )
        correct_answer = answer_response["choices"][0]["message"]["content"]
        reference_answers[question] = correct_answer.strip()  # 儲存正確答案
    except Exception as e:
        return f"⚠️ 發生錯誤:{e}"

def save_error(question, user_input, correct_answer, feedback):
    current_date = datetime.today().strftime("%Y-%m-%d")
    error_history.setdefault(current_date, []).append({
        "題目": question,
        "回答": user_input,
        "正確答案": correct_answer,
        "AI 分析": feedback
    })

def analyze_answer(user_input, question):
    global user_errors
    if not user_input.strip():
        return "⚠️ 請輸入回答。"
    
    correct_answer = reference_answers.get(question, "無法獲取正確答案")
    
    # 獲取參考答案
    save_answer(question)  # 在分析之前儲存答案
    
    prompt = f"請根據以下教材內容,檢查學生的回答是否正確,並提供正確答案與講解:\n{pdf_text}\n\n問題:{question}\n學生回答:'{user_input}'"

    try:
        response = openai.ChatCompletion.create(
            model="gpt-4o-mini-2024-07-18",
            messages=[
                {"role": "system", "content": "你是一位教育專家,請根據教材內容分析學生回答。"},
                {"role": "user", "content": prompt}
            ]
        )
        feedback = response["choices"][0]["message"]["content"]
    except Exception as e:
        return f"⚠️ 發生錯誤:{e}"

    if "❌" in feedback or "錯" in feedback:
        user_errors[question] = user_errors.get(question, 0) + 1
        save_error(question, user_input, correct_answer, feedback)  # 儲存錯題
        # 自動輸出錯題記錄
        error_output = f"🔹 題目: {question}\n📝 回答: {user_input}\n📖 正確答案: {correct_answer}\n📖 AI 分析: {feedback}"
        return feedback, error_output
    return feedback, ""

def clear_fields():
    return "", "", ""  # 清空問題、回答和分析結果,但不清空錯題紀錄

with gr.Blocks() as demo:
    gr.Markdown("# 👨‍🏫 教師檢定智慧陪讀家教 ")

    with gr.Row():
        topic_input = gr.Dropdown(choices=topics, label="選擇複習主題")
        difficulty_input = gr.Dropdown(choices=difficulties, label="選擇難度等級")
    ask_btn = gr.Button("🎯 生成問題")
    clear_btn = gr.Button("🧹 清空")
    question_output = gr.Textbox(label="題目", lines=4)
    ask_btn.click(fn=lambda t, d: generate_question(t, d),
                  inputs=[topic_input, difficulty_input],
                  outputs=question_output)
    
    user_answer = gr.Textbox(label="你的回答", lines=3)
    analyze_btn = gr.Button("分析回答")
    analysis_result = gr.Textbox(label="分析與講解", lines=5)
    error_history_output = gr.Textbox(label="錯題紀錄", lines=5)
    
    analyze_btn.click(fn=lambda ans, q: analyze_answer(ans, q),
                      inputs=[user_answer, question_output],
                      outputs=[analysis_result, error_history_output])

    clear_btn.click(fn=clear_fields, outputs=[question_output, user_answer, analysis_result])

demo.launch()