Benny-Tang commited on
Commit
b8a81b4
·
verified ·
1 Parent(s): 722325d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -57
app.py CHANGED
@@ -1,82 +1,97 @@
1
- import os
2
- import random
3
  import gradio as gr
4
- from demo_questions import QUESTIONS # demo questions (60 across 6 subjects)
5
 
6
- # -----------------------------
7
- # Helper functions
8
- # -----------------------------
9
 
10
- def load_exam(subject):
11
- """Load 10 random questions from the selected subject."""
12
- all_questions = QUESTIONS.get(subject, [])
13
- if not all_questions:
14
- return [f"**Q{i+1}:** (No Question)" for i in range(10)]
15
 
16
- questions = random.sample(all_questions, min(10, len(all_questions)))
17
- outputs = [f"**Q{i+1}:** {q}" for i, q in enumerate(questions)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  return outputs
19
 
20
 
21
- def submit_exam_answers(*answers):
22
- """Process submitted answers. For now, just echo them back."""
23
- submitted = [f"Q{i+1}: {ans}" for i, ans in enumerate(answers, 1)]
24
- return "\n".join(submitted)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
 
 
 
 
26
 
27
- # -----------------------------
28
- # Gradio UI
29
- # -----------------------------
30
 
31
  with gr.Blocks() as demo:
32
- gr.Markdown("# 📘 SPM Exam Simulator")
33
 
34
- subject = gr.Dropdown(
35
- choices=list(QUESTIONS.keys()),
36
- label="Select Subject",
37
- value="BM"
38
- )
39
 
40
  load_btn = gr.Button("Load Exam")
41
 
42
- question_boxes = []
43
- answer_boxes = []
44
-
45
- with gr.Column():
46
- for i in range(10):
47
- q_box = gr.Markdown(f"**Q{i+1}:** (empty)")
48
- a_box = gr.Textbox(
49
- label=f"Answer Q{i+1}",
50
- lines=2,
51
- placeholder="Type your answer here (e.g., A/B/C/D or essay)..."
52
- )
53
- question_boxes.append(q_box)
54
- answer_boxes.append(a_box)
55
 
56
  submit_btn = gr.Button("Submit Answers")
57
- result = gr.Textbox(label="Submission Result", interactive=False, lines=15)
58
-
59
- # -----------------------------
60
- # Button bindings
61
- # -----------------------------
62
- load_btn.click(
63
- fn=load_exam,
64
- inputs=subject,
65
- outputs=question_boxes
66
- )
67
 
 
 
 
 
 
 
68
  submit_btn.click(
69
- fn=submit_exam_answers,
70
- inputs=answer_boxes,
71
- outputs=result
72
  )
73
 
74
- # -----------------------------
75
- # Launch
76
- # -----------------------------
77
-
78
  if __name__ == "__main__":
79
- demo.launch(server_name="0.0.0.0", server_port=7860, share=False, ssr_mode=True)
 
80
 
81
 
82
 
 
 
 
1
  import gradio as gr
2
+ from demo_questions import QUESTIONS
3
 
4
+ # Store student answers
5
+ student_answers = {}
 
6
 
 
 
 
 
 
7
 
8
+ def load_exam(subject, paper):
9
+ """Load selected subject & paper questions."""
10
+ if subject not in QUESTIONS or paper not in QUESTIONS[subject]:
11
+ return [gr.Markdown("⚠️ No questions available for this selection.")]
12
+
13
+ qlist = QUESTIONS[subject][paper]
14
+ student_answers.clear() # reset before new exam
15
+
16
+ outputs = []
17
+ for i, q in enumerate(qlist):
18
+ # Store internally but only show the text to student
19
+ student_answers[i] = {"id": q.get("id"), "question": q.get("text"),
20
+ "choices": q.get("choices"), "answer": q.get("answer"),
21
+ "student_answer": None}
22
+
23
+ # Display question text
24
+ outputs.append(gr.Markdown(f"**Q{i+1}:** {q['text']}"))
25
+
26
+ if q.get("choices"):
27
+ # Multiple-choice → student selects option
28
+ outputs.append(gr.Radio(choices=q["choices"], label=f"Your Answer for Q{i+1}",
29
+ interactive=True, key=f"q{i+1}"))
30
+ else:
31
+ # Subjective → free text box
32
+ outputs.append(gr.Textbox(label=f"Your Answer for Q{i+1}", interactive=True, key=f"q{i+1}"))
33
+
34
  return outputs
35
 
36
 
37
+ def submit_exam(*responses):
38
+ """Process submission, calculate score, and show results."""
39
+ score = 0
40
+ total = len(student_answers)
41
+
42
+ # Store student answers
43
+ for i, response in enumerate(responses):
44
+ student_answers[i]["student_answer"] = response
45
+
46
+ # Evaluate
47
+ review = []
48
+ for i, q in student_answers.items():
49
+ correct = q["answer"]
50
+ student = q["student_answer"]
51
+
52
+ if correct and student == correct:
53
+ score += 1
54
+ result = f"✅ Q{i+1}: Correct! (Your Answer: {student})"
55
+ elif correct:
56
+ result = f"❌ Q{i+1}: Wrong (Your Answer: {student}, Correct: {correct})"
57
+ else:
58
+ result = f"✏️ Q{i+1}: Essay submitted. (Your Answer: {student})"
59
 
60
+ review.append(result)
61
+
62
+ summary = f"## Exam Finished!\n\n**Score: {score} / {total}**\n\n" + "\n".join(review)
63
+ return summary
64
 
 
 
 
65
 
66
  with gr.Blocks() as demo:
67
+ gr.Markdown("# 🎓 SPM Exam Simulator")
68
 
69
+ with gr.Row():
70
+ subject = gr.Dropdown(choices=list(QUESTIONS.keys()), label="Select Subject")
71
+ paper = gr.Dropdown(choices=["Paper1", "Paper2"], label="Select Paper")
 
 
72
 
73
  load_btn = gr.Button("Load Exam")
74
 
75
+ exam_area = gr.Column()
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
  submit_btn = gr.Button("Submit Answers")
78
+ result_box = gr.Markdown("")
 
 
 
 
 
 
 
 
 
79
 
80
+ def render_exam(subject, paper):
81
+ return load_exam(subject, paper)
82
+
83
+ load_btn.click(render_exam, inputs=[subject, paper], outputs=exam_area)
84
+
85
+ # Capture student responses dynamically
86
  submit_btn.click(
87
+ submit_exam,
88
+ inputs=exam_area, # all answer widgets will be collected
89
+ outputs=result_box
90
  )
91
 
 
 
 
 
92
  if __name__ == "__main__":
93
+ demo.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=True)
94
+
95
 
96
 
97