dayuian commited on
Commit
a59742c
·
verified ·
1 Parent(s): e518f76

Update quiz.py

Browse files
Files changed (1) hide show
  1. quiz.py +149 -78
quiz.py CHANGED
@@ -1,81 +1,152 @@
1
- import random
2
- from vocab import get_words_from_source
3
- from sentences import get_sentence
4
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- # 生成單字選擇題
7
- def generate_fill_in_blank_exam(source, num):
8
- words_data = get_words_from_source(source)
9
- words = random.sample(words_data, num)
10
-
11
- questions = []
12
- for word_data in words:
13
- word = word_data['word']
14
- phonetic = word_data['phonetic']
15
-
16
- # 取得例句
17
- sentence_data = get_sentence(word)
18
- if not sentence_data:
19
- continue # 沒例句的跳過
20
-
21
- sentence = sentence_data[2]
22
- blank_sentence = sentence.replace(word, '______')
23
-
24
- # 生成干擾選項 (亂數抽 3 個其他單字)
25
- other_words = [w['word'] for w in words_data if w['word'] != word]
26
- distractors = random.sample(other_words, 3)
27
- options = [word] + distractors
28
- random.shuffle(options)
29
-
30
- questions.append({
31
- "sentence": blank_sentence,
32
- "options": options,
33
- "answer": word,
34
- "phonetic": phonetic
35
- })
36
-
37
- return questions
38
-
39
-
40
- # 自動對答案並計分
41
- def check_exam(user_answers, questions):
42
- correct_count = 0
43
- results = []
44
-
45
- for i, user_answer in enumerate(user_answers):
46
- correct_answer = questions[i]['answer']
47
- is_correct = (user_answer == correct_answer)
48
- results.append({
49
- "question": questions[i]['sentence'],
50
- "user_answer": user_answer,
51
- "correct_answer": correct_answer,
52
- "is_correct": is_correct
53
- })
54
- if is_correct:
55
- correct_count += 1
56
-
57
- score = f"{correct_count}/{len(questions)} 分"
58
-
59
- # 顯示結果
60
- result_html = f"<p><strong>得分:</strong> {score}</p>"
61
- for res in results:
62
- color = 'green' if res['is_correct'] else 'red'
63
- result_html += f"<p style='color:{color};'><strong>題目:</strong> {res['question']}<br>" \
64
- f"<strong>你的答案:</strong> {res['user_answer']}<br>" \
65
- f"<strong>正確答案:</strong> {res['correct_answer']}</p>"
66
-
67
- return result_html
68
-
69
- # 動態生成 Gradio Radio 元件
70
-
71
- def render_exam_interface(questions):
72
- radios = []
73
- for i, q in enumerate(questions):
74
- radios.append(
75
- gr.Radio(
76
- choices=q['options'],
77
- label=f"第 {i + 1} 題:{q['sentence']}",
78
- interactive=True
79
- )
80
  )
81
- return radios
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import random
3
+ from vocab import get_sources, get_words_from_source
4
+ from sentences import generate_sentences
5
+ from ai_sentence import MODEL_LIST
6
+ from quiz import generate_fill_in_blank_exam, check_exam, render_exam_interface
7
+
8
+ def process_sentence(mode, word, source, num, use_ai, model_name):
9
+ try:
10
+ if mode == '查詢單字':
11
+ if not word:
12
+ return "<p style='color:red;'>❌ 請輸入單字</p>", "未輸入單字"
13
+ words = [word.strip()]
14
+ elif mode == '隨機抽單字':
15
+ num = int(num)
16
+ if num <= 0:
17
+ return "<p style='color:red;'>❌ 抽取數量須大於0</p>", "數量錯誤"
18
+ words_data = get_words_from_source(source)
19
+ words = [w['word'] for w in words_data]
20
+ words = random.sample(words, num)
21
+ else:
22
+ return "<p style='color:red;'>❌ 模式錯誤</p>", "模式選擇異常"
23
+
24
+ result_display, status_log = generate_sentences(words, source, use_ai, model_name)
25
+
26
+ return result_display, status_log
27
+
28
+ except Exception as e:
29
+ return f"<p style='color:red;'>❌ 發生錯誤:{str(e)}</p>", f"錯誤:{str(e)}"
30
+
31
+ def project_description():
32
+ return """
33
+ # 📖 VocabLine 單字例句工具
34
+ 支援單字例句查詢,AI 自動生成句子。適合作為 LINE 單字推播、英文學習輔助工具。
35
+ ## 🔍 核心功能
36
+ - 查詢單字 → 獲取例句
37
+ - 抽取單字 → 批量獲取例句
38
+ - 可選 AI 生成句子(模型:GPT2 / Pythia)
39
+ ## 🧑‍💻 技術架構
40
+ - Gradio Blocks + Transformers (Hugging Face)
41
+ - SQLite 句庫管理
42
+ - 支援多單字庫擴展
43
+ ## 📚 資料來源
44
+ - 常用 3000 單字表
45
+ - 英文例句資料庫 (Tatoeba)
46
+ ## 👨‍💻 開發資訊
47
+ - 開發者:余彦志 (大宇 ian)
48
+ - 信箱:[email protected]
49
+ - GitHub:[https://github.com/dayuian](https://github.com/dayuian)
50
+ """
51
+
52
+ with gr.Blocks(css="""
53
+ #card-group { padding: 15px; border-radius: 12px; background-color: rgba(255, 255, 255, 0.05); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); margin-bottom: 15px; }
54
+ .gradio-container { max-width: 800px; margin: auto; }
55
+ """) as demo:
56
+ gr.Markdown(project_description())
57
 
58
+ with gr.Tab("單字查詢/生成例句"):
59
+ with gr.Group():
60
+ with gr.Row():
61
+ mode_radio = gr.Radio(
62
+ ["查詢單字", "隨機抽單字"],
63
+ label="選擇模式",
64
+ value="���詢單字",
65
+ interactive=True
66
+ )
67
+
68
+ with gr.Group(elem_id="card-group"):
69
+ word_input = gr.Textbox(label="輸入單字", visible=True)
70
+ num_input = gr.Slider(minimum=1, maximum=10, value=5, step=1, label="抽取單字數量")
71
+ source_dropdown = gr.Dropdown(
72
+ choices=get_sources(),
73
+ value="common3000",
74
+ label="選擇單字庫"
75
+ )
76
+
77
+ with gr.Group(elem_id="card-group"):
78
+ use_ai_checkbox = gr.Checkbox(label="使用 AI 生成句子(較慢,約 30 秒)", elem_id="use-ai-checkbox")
79
+
80
+ with gr.Row():
81
+ model_dropdown = gr.Dropdown(
82
+ choices=MODEL_LIST,
83
+ value="gpt2",
84
+ label="選擇 AI 模型",
85
+ visible=False
86
+ )
87
+ gr.Markdown("🔷 **建議使用 GPT2(表現較佳),Pythia-410m 很爛慎選!**", visible=False)
88
+
89
+ ai_warning = gr.Textbox(
90
+ value="⚠️ 使用 AI 生成句子為功能測試,每一個單字的生成過程可能需要 30 秒以上,請耐心等待。",
91
+ visible=False,
92
+ interactive=False,
93
+ label=""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  )
95
+
96
+ result_output = gr.HTML(label="結果")
97
+ status_output = gr.Textbox(label="處理狀態", interactive=False)
98
+
99
+ with gr.Row():
100
+ generate_button = gr.Button("✨ 生成句子", elem_id="generate-button")
101
+
102
+ with gr.Tab("英文小考"):
103
+ quiz_source_dropdown = gr.Dropdown(
104
+ choices=get_sources(),
105
+ value="common3000",
106
+ label="選擇單字庫"
107
+ )
108
+ quiz_num_slider = gr.Slider(minimum=1, maximum=10, value=2, step=1, label="題目數量")
109
+
110
+ quiz_generate_button = gr.Button("📄 生成試卷")
111
+ quiz_submit_button = gr.Button("✅ 提交試卷")
112
+
113
+ quiz_questions_container = gr.Column()
114
+ quiz_score_display = gr.HTML()
115
+
116
+ quiz_questions_state = gr.State([])
117
+
118
+ def display_exam(source, num):
119
+ questions = generate_fill_in_blank_exam(source, num)
120
+ quiz_questions_state.value = questions
121
+
122
+ radios = []
123
+ for i, q in enumerate(questions):
124
+ radios.append(
125
+ gr.Radio(
126
+ choices=q['options'],
127
+ label=f"第 {i + 1} 題:{q['sentence']}",
128
+ interactive=True
129
+ )
130
+ )
131
+
132
+ return radios
133
+
134
+ def submit_exam(*user_answers):
135
+ questions = quiz_questions_state.value
136
+ score_html = check_exam(user_answers, questions)
137
+ return score_html
138
+
139
+ quiz_generate_button.click(
140
+ display_exam,
141
+ inputs=[quiz_source_dropdown, quiz_num_slider],
142
+ outputs=quiz_questions_container
143
+ )
144
+
145
+ quiz_submit_button.click(
146
+ submit_exam,
147
+ inputs=quiz_questions_container,
148
+ outputs=quiz_score_display
149
+ )
150
+
151
+
152
+ demo.launch()