Toya0421 commited on
Commit
70c9ef9
·
verified ·
1 Parent(s): 0d155b7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -29
app.py CHANGED
@@ -6,22 +6,42 @@ import random
6
  API_KEY = "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"
7
  BASE_URL = "https://openrouter.ai/api/v1"
8
 
9
- # --- Lexile難易度別教材 ---
10
  texts = {
11
- 300: "Tom has a red ball. He plays with it in the park. The sun is bright.",
12
- 600: "A young boy found a lost puppy near the river. He decided to take care of it.",
13
- 850: "Sarah enjoyed reading stories about ancient civilizations and their discoveries.",
14
- 1050: "The scientist developed a new hypothesis about the evolution of animal behavior.",
15
- 1250: "Philosophers have long debated the intricate relationship between free will and determinism."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  }
17
 
18
  levels = [300, 600, 850, 1050, 1250]
19
 
20
  # --- OpenAIクライアント設定 ---
21
- client = OpenAI(
22
- base_url=BASE_URL,
23
- api_key=API_KEY
24
- )
25
 
26
  # --- AIに問題生成を依頼 ---
27
  def generate_question(text):
@@ -35,7 +55,6 @@ def generate_question(text):
35
  B. <option>
36
  C. <option>
37
  D. <option>
38
- Correct: <A/B/C/D>
39
 
40
  Passage:
41
  {text}
@@ -47,7 +66,27 @@ def generate_question(text):
47
  max_tokens=400,
48
  temperature=0.7,
49
  )
50
- return response.choices[0].message.content.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  # --- 適応型テストの進行 ---
53
  def adaptive_test(prev_level, prev_correct):
@@ -60,28 +99,39 @@ def adaptive_test(prev_level, prev_correct):
60
  new_level = prev_level
61
  return new_level
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  # --- テスト開始 ---
64
  def start_test():
65
  level = 850 # 中間レベルから開始
66
- text = texts[level]
67
- question = generate_question(text)
68
- return f"Lexile: {level}L", text, question, level, None, ""
 
69
 
70
  # --- 回答を処理して次へ ---
71
- def next_step(prev_level, user_answer, question_text):
72
- # 正解の抽出
73
- correct_option = None
74
- for line in question_text.splitlines():
75
- if line.lower().startswith("correct:"):
76
- correct_option = line.split(":")[1].strip().upper()
77
- break
78
 
79
  correct = (user_answer == correct_option)
80
 
81
  # レベルを更新
82
  new_level = adaptive_test(prev_level, correct)
83
- new_text = texts[new_level]
84
- new_question = generate_question(new_text)
85
 
86
  feedback = "✅ Correct!" if correct else "❌ Incorrect."
87
  if new_level == prev_level:
@@ -89,17 +139,17 @@ def next_step(prev_level, user_answer, question_text):
89
  else:
90
  feedback += f"\n➡️ Moving to next level: **{new_level}L**"
91
 
92
- # 回答欄をリセットするために "" を返す
93
  return (
94
  feedback,
95
  f"Lexile: {new_level}L",
96
  new_text,
97
  new_question,
98
  new_level,
99
- None, # user_answerをリセット
100
  ""
101
  )
102
 
 
103
  # --- Gradio UI ---
104
  with gr.Blocks() as demo:
105
  gr.Markdown("# 📘 Adaptive Reading Level Test (Lexile-based)")
@@ -115,19 +165,35 @@ with gr.Blocks() as demo:
115
 
116
  feedback_display = gr.Markdown()
117
  hidden_level = gr.Number(visible=False)
 
118
 
119
  # --- Start Test ---
120
  start_btn.click(
121
  fn=start_test,
122
  inputs=[],
123
- outputs=[level_display, text_display, question_display, hidden_level, user_answer, feedback_display]
 
 
 
 
 
 
 
124
  )
125
 
126
  # --- Submit & Move to Next ---
127
  submit_btn.click(
128
  fn=next_step,
129
- inputs=[hidden_level, user_answer, question_display],
130
- outputs=[feedback_display, level_display, text_display, question_display, hidden_level, user_answer, feedback_display]
 
 
 
 
 
 
 
 
131
  )
132
 
133
  demo.launch()
 
6
  API_KEY = "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"
7
  BASE_URL = "https://openrouter.ai/api/v1"
8
 
9
+ # --- Lexile難易度別教材(各3文) ---
10
  texts = {
11
+ 300: [
12
+ "Tom has a red ball. He plays with it in the park. The sun is bright.",
13
+ "A dog runs after a stick. The boy laughs as the dog brings it back.",
14
+ "The girl eats an apple under the tree while the wind blows softly."
15
+ ],
16
+ 600: [
17
+ "A young boy found a lost puppy near the river. He decided to take care of it.",
18
+ "Mary saw a rainbow after the rain stopped and felt happy.",
19
+ "The teacher asked the students to write a short story about friendship."
20
+ ],
21
+ 850: [
22
+ "Sarah enjoyed reading stories about ancient civilizations and their discoveries.",
23
+ "During the festival, people decorated the streets with lights and music.",
24
+ "James wanted to learn how airplanes could stay in the sky for so long."
25
+ ],
26
+ 1050: [
27
+ "The scientist developed a new hypothesis about the evolution of animal behavior.",
28
+ "Farmers began to adopt sustainable methods to protect soil health.",
29
+ "A historian analyzed old letters to understand social changes during the war."
30
+ ],
31
+ 1250: [
32
+ "Philosophers have long debated the intricate relationship between free will and determinism.",
33
+ "Modern architecture often reflects both functionality and aesthetic simplicity.",
34
+ "Researchers in neuroscience continue to explore how memory is formed and stored."
35
+ ]
36
  }
37
 
38
  levels = [300, 600, 850, 1050, 1250]
39
 
40
  # --- OpenAIクライアント設定 ---
41
+ client = OpenAI(base_url=BASE_URL, api_key=API_KEY)
42
+
43
+ # --- 出題済みテキストを管理するセット ---
44
+ used_texts = set()
45
 
46
  # --- AIに問題生成を依頼 ---
47
  def generate_question(text):
 
55
  B. <option>
56
  C. <option>
57
  D. <option>
 
58
 
59
  Passage:
60
  {text}
 
66
  max_tokens=400,
67
  temperature=0.7,
68
  )
69
+ raw_output = response.choices[0].message.content.strip()
70
+
71
+ # --- 正解の抽出 ---
72
+ correct_option = None
73
+ for line in raw_output.splitlines():
74
+ if line.lower().startswith("correct:"):
75
+ correct_option = line.split(":")[1].strip().upper()
76
+ break
77
+
78
+ # --- アスタリスク除去(*印があっても削除) ---
79
+ cleaned_lines = []
80
+ for line in raw_output.splitlines():
81
+ if "*" in line:
82
+ line = line.replace("*", "").strip()
83
+ # Correct行は表示しない
84
+ if not line.lower().startswith("correct:"):
85
+ cleaned_lines.append(line)
86
+
87
+ cleaned_output = "\n".join(cleaned_lines)
88
+ return cleaned_output, correct_option
89
+
90
 
91
  # --- 適応型テストの進行 ---
92
  def adaptive_test(prev_level, prev_correct):
 
99
  new_level = prev_level
100
  return new_level
101
 
102
+
103
+ # --- 未使用の文章を取得 ---
104
+ def get_unused_text(level):
105
+ available = [t for t in texts[level] if (level, t) not in used_texts]
106
+ if not available:
107
+ # すべて使った場合はリセット
108
+ used_texts.clear()
109
+ available = texts[level]
110
+ chosen = random.choice(available)
111
+ used_texts.add((level, chosen))
112
+ return chosen
113
+
114
+
115
  # --- テスト開始 ---
116
  def start_test():
117
  level = 850 # 中間レベルから開始
118
+ text = get_unused_text(level)
119
+ question, correct = generate_question(text)
120
+ return f"Lexile: {level}L", text, question, level, correct, ""
121
+
122
 
123
  # --- 回答を処理して次へ ---
124
+ def next_step(prev_level, user_answer, question_text, correct_option):
125
+ if correct_option is None:
126
+ feedback = "⚠️ No correct answer found in the generated question."
127
+ return feedback, f"Lexile: {prev_level}L", "", "", prev_level, None, ""
 
 
 
128
 
129
  correct = (user_answer == correct_option)
130
 
131
  # レベルを更新
132
  new_level = adaptive_test(prev_level, correct)
133
+ new_text = get_unused_text(new_level)
134
+ new_question, new_correct = generate_question(new_text)
135
 
136
  feedback = "✅ Correct!" if correct else "❌ Incorrect."
137
  if new_level == prev_level:
 
139
  else:
140
  feedback += f"\n➡️ Moving to next level: **{new_level}L**"
141
 
 
142
  return (
143
  feedback,
144
  f"Lexile: {new_level}L",
145
  new_text,
146
  new_question,
147
  new_level,
148
+ new_correct,
149
  ""
150
  )
151
 
152
+
153
  # --- Gradio UI ---
154
  with gr.Blocks() as demo:
155
  gr.Markdown("# 📘 Adaptive Reading Level Test (Lexile-based)")
 
165
 
166
  feedback_display = gr.Markdown()
167
  hidden_level = gr.Number(visible=False)
168
+ hidden_correct = gr.Textbox(visible=False)
169
 
170
  # --- Start Test ---
171
  start_btn.click(
172
  fn=start_test,
173
  inputs=[],
174
+ outputs=[
175
+ level_display,
176
+ text_display,
177
+ question_display,
178
+ hidden_level,
179
+ hidden_correct,
180
+ feedback_display,
181
+ ],
182
  )
183
 
184
  # --- Submit & Move to Next ---
185
  submit_btn.click(
186
  fn=next_step,
187
+ inputs=[hidden_level, user_answer, question_display, hidden_correct],
188
+ outputs=[
189
+ feedback_display,
190
+ level_display,
191
+ text_display,
192
+ question_display,
193
+ hidden_level,
194
+ hidden_correct,
195
+ feedback_display,
196
+ ],
197
  )
198
 
199
  demo.launch()