Fra150 commited on
Commit
0fe3545
·
verified ·
1 Parent(s): c0d911e

Update app.py

Browse files

Code complete.

Files changed (1) hide show
  1. app.py +63 -168
app.py CHANGED
@@ -6,246 +6,141 @@ import gradio as gr
6
  from datasets import load_dataset, Dataset
7
  from huggingface_hub import whoami
8
 
9
- EXAM_DATASET_ID = (
10
- os.getenv("EXAM_DATASET_ID") or "nlp-course/supervised-finetuning_quiz"
11
- )
12
- EXAM_MAX_QUESTIONS = os.getenv("EXAM_MAX_QUESTIONS") or 10
13
- EXAM_PASSING_SCORE = os.getenv("EXAM_PASSING_SCORE") or 0.7
14
 
 
15
  ds = load_dataset(EXAM_DATASET_ID, split="train")
16
-
17
- # Convert dataset to a list of dicts and randomly sort
18
  quiz_data = ds.to_pandas().to_dict("records")
19
  random.shuffle(quiz_data)
 
20
 
21
- # Limit to max questions if specified
22
- if EXAM_MAX_QUESTIONS:
23
- quiz_data = quiz_data[: int(EXAM_MAX_QUESTIONS)]
24
-
25
-
26
- def on_user_logged_in(token: gr.OAuthToken | None):
27
- """
28
- If the user has a valid token, show Start button.
29
- Otherwise, keep the login button visible.
30
- """
31
  if token is not None:
32
  return [
33
- gr.update(visible=False), # login button visibility
34
- gr.update(visible=True), # start button visibility
35
- gr.update(visible=False), # next button visibility
36
- gr.update(visible=False), # submit button visibility
37
- "", # question text
38
- [], # radio choices (empty list = no choices)
39
- "Click 'Start' to begin the quiz", # status message
40
- 0, # question_idx
41
- [], # user_answers
42
- "", # final_markdown content
43
- token, # user token
44
  ]
45
  else:
46
  return [
47
- gr.update(visible=True), # login button visibility
48
- gr.update(visible=False), # start button visibility
49
- gr.update(visible=False), # next button visibility
50
- gr.update(visible=False), # submit button visibility
51
- "", # question text
52
- [], # radio choices
53
- "", # status message
54
- 0, # question_idx
55
- [], # user_answers
56
- "", # final_markdown content
57
- None, # no token
58
  ]
59
 
60
-
61
- def push_results_to_hub(user_answers, token: gr.OAuthToken | None):
62
- """
63
- Create a new dataset from user_answers and push it to the Hub.
64
- Calculates grade and checks against passing threshold.
65
- """
66
  if token is None:
67
  gr.Warning("Please log in to Hugging Face before pushing!")
68
  return
69
 
70
- # Calculate grade
71
- correct_count = sum(1 for answer in user_answers if answer["is_correct"])
72
  total_questions = len(user_answers)
73
  grade = correct_count / total_questions if total_questions > 0 else 0
74
 
75
- if grade < float(EXAM_PASSING_SCORE):
76
- gr.Warning(
77
- f"Score {grade:.1%} below passing threshold of {float(EXAM_PASSING_SCORE):.1%}"
78
- )
79
- return f"You scored {grade:.1%}. Please try again to achieve at least {float(EXAM_PASSING_SCORE):.1%}"
80
 
81
  gr.Info("Submitting answers to the Hub. Please wait...", duration=2)
82
-
83
  user_info = whoami(token=token.token)
84
  repo_id = f"{EXAM_DATASET_ID}_student_responses"
85
  submission_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
86
 
87
  new_ds = Dataset.from_list(user_answers)
88
- new_ds = new_ds.map(
89
- lambda x: {
90
- "username": user_info["name"],
91
- "datetime": submission_time,
92
- "grade": grade,
93
- }
94
- )
95
  new_ds.push_to_hub(repo_id)
96
  return f"Your responses have been submitted to the Hub! Final grade: {grade:.1%}"
97
 
98
-
99
  def handle_quiz(question_idx, user_answers, selected_answer, is_start):
100
- """
101
- Handle quiz state transitions and store answers
102
- """
103
  if not is_start and question_idx < len(quiz_data):
104
  current_q = quiz_data[question_idx]
105
- correct_reference = current_q["correct_answer"]
106
- correct_reference = f"answer_{correct_reference}".lower()
107
- is_correct = selected_answer == current_q[correct_reference]
108
- user_answers.append(
109
- {
110
- "question": current_q["question"],
111
- "selected_answer": selected_answer,
112
- "correct_answer": current_q[correct_reference],
113
- "is_correct": is_correct,
114
- "correct_reference": correct_reference,
115
- }
116
- )
117
  question_idx += 1
118
 
119
  if question_idx >= len(quiz_data):
120
- correct_count = sum(1 for answer in user_answers if answer["is_correct"])
121
  grade = correct_count / len(user_answers)
122
- results_text = (
123
- f"**Quiz Complete!**\n\n"
124
- f"Your score: {grade:.1%}\n"
125
- f"Passing score: {float(EXAM_PASSING_SCORE):.1%}\n\n"
126
- )
127
  return [
128
- "", # question_text
129
- gr.update(choices=[], visible=False), # hide radio choices
130
- f"{'✅ Passed!' if grade >= float(EXAM_PASSING_SCORE) else '❌ Did not pass'}",
131
- question_idx,
132
- user_answers,
133
- gr.update(visible=False), # start button visibility
134
- gr.update(visible=False), # next button visibility
135
- gr.update(visible=True), # submit button visibility
136
- results_text, # final results text
137
  ]
138
 
139
- # Show next question
140
  q = quiz_data[question_idx]
141
  return [
142
- f"## Question {question_idx + 1} \n### {q['question']}", # question text
143
- gr.update( # properly update radio choices
144
- choices=[q["answer_a"], q["answer_b"], q["answer_c"], q["answer_d"]],
145
- value=None,
146
- visible=True,
147
- ),
148
  "Select an answer and click 'Next' to continue.",
149
- question_idx,
150
- user_answers,
151
- gr.update(visible=False), # start button visibility
152
- gr.update(visible=True), # next button visibility
153
- gr.update(visible=False), # submit button visibility
154
- "", # clear final markdown
155
  ]
156
 
157
-
158
  def success_message(response):
159
- # response is whatever push_results_to_hub returned
160
  return f"{response}\n\n**Success!**"
161
 
162
-
163
  with gr.Blocks() as demo:
164
  demo.title = f"Dataset Quiz for {EXAM_DATASET_ID}"
165
 
166
- # State variables
167
  question_idx = gr.State(value=0)
168
  user_answers = gr.State(value=[])
169
  user_token = gr.State(value=None)
170
 
171
- with gr.Row(variant="compact"):
172
- gr.Markdown(f"## Welcome to the {EXAM_DATASET_ID} Quiz")
173
 
174
- with gr.Row(variant="compact"):
175
- gr.Markdown(
176
- "Log in first, then click 'Start' to begin. Answer each question, click 'Next', and finally click 'Submit' to publish your results to the Hugging Face Hub."
177
- )
178
 
179
- with gr.Row(variant="panel"):
180
- question_text = gr.Markdown("")
181
- radio_choices = gr.Radio(
182
- choices=[], label="Your Answer", scale=1.5, visible=False
183
- )
184
 
185
- with gr.Row(variant="compact"):
186
- status_text = gr.Markdown("")
187
- final_markdown = gr.Markdown("")
188
-
189
- with gr.Row(variant="compact"):
190
- login_btn = gr.LoginButton(visible=True)
191
- start_btn = gr.Button("Start ⏭️", visible=True)
192
- next_btn = gr.Button("Next ⏭️", visible=False)
193
- submit_btn = gr.Button("Submit ✅", visible=False)
194
-
195
- # Wire up the event handlers
196
  login_btn.click(
197
  fn=on_user_logged_in,
198
  inputs=None,
199
- outputs=[
200
- login_btn,
201
- start_btn,
202
- next_btn,
203
- submit_btn,
204
- question_text,
205
- radio_choices,
206
- status_text,
207
- question_idx,
208
- user_answers,
209
- final_markdown,
210
- user_token,
211
- ],
212
  )
213
 
214
  start_btn.click(
215
  fn=handle_quiz,
216
  inputs=[question_idx, user_answers, gr.State(""), gr.State(True)],
217
- outputs=[
218
- question_text,
219
- radio_choices,
220
- status_text,
221
- question_idx,
222
- user_answers,
223
- start_btn,
224
- next_btn,
225
- submit_btn,
226
- final_markdown,
227
- ],
228
  )
229
 
230
  next_btn.click(
231
  fn=handle_quiz,
232
  inputs=[question_idx, user_answers, radio_choices, gr.State(False)],
233
- outputs=[
234
- question_text,
235
- radio_choices,
236
- status_text,
237
- question_idx,
238
- user_answers,
239
- start_btn,
240
- next_btn,
241
- submit_btn,
242
- final_markdown,
243
- ],
244
  )
245
 
246
- submit_btn.click(fn=push_results_to_hub, inputs=[user_answers])
 
 
 
 
247
 
248
  if __name__ == "__main__":
249
- # Note: If testing locally, you'll need to run `huggingface-cli login` or set HF_TOKEN
250
- # environment variable for the login to work locally.
251
  demo.launch()
 
6
  from datasets import load_dataset, Dataset
7
  from huggingface_hub import whoami
8
 
9
+ # Dataset corretto
10
+ EXAM_DATASET_ID = "huggingface-course/chapter_1_exam"
11
+ EXAM_MAX_QUESTIONS = 10
12
+ EXAM_PASSING_SCORE = 0.7
 
13
 
14
+ # Caricamento e mescolamento delle domande
15
  ds = load_dataset(EXAM_DATASET_ID, split="train")
 
 
16
  quiz_data = ds.to_pandas().to_dict("records")
17
  random.shuffle(quiz_data)
18
+ quiz_data = quiz_data[:EXAM_MAX_QUESTIONS]
19
 
20
+ def on_user_logged_in(token):
 
 
 
 
 
 
 
 
 
21
  if token is not None:
22
  return [
23
+ gr.update(visible=False), gr.update(visible=True), gr.update(visible=False),
24
+ gr.update(visible=False), "", [],
25
+ "Click 'Start' to begin the quiz", 0, [], "", token
 
 
 
 
 
 
 
 
26
  ]
27
  else:
28
  return [
29
+ gr.update(visible=True), gr.update(visible=False), gr.update(visible=False),
30
+ gr.update(visible=False), "", [], "", 0, [], "", None
 
 
 
 
 
 
 
 
 
31
  ]
32
 
33
+ def push_results_to_hub(user_answers, token):
 
 
 
 
 
34
  if token is None:
35
  gr.Warning("Please log in to Hugging Face before pushing!")
36
  return
37
 
38
+ correct_count = sum(1 for a in user_answers if a["is_correct"])
 
39
  total_questions = len(user_answers)
40
  grade = correct_count / total_questions if total_questions > 0 else 0
41
 
42
+ if grade < EXAM_PASSING_SCORE:
43
+ gr.Warning(f"Score {grade:.1%} below passing threshold of {EXAM_PASSING_SCORE:.1%}")
44
+ return f"You scored {grade:.1%}. Please try again to achieve at least {EXAM_PASSING_SCORE:.1%}"
 
 
45
 
46
  gr.Info("Submitting answers to the Hub. Please wait...", duration=2)
 
47
  user_info = whoami(token=token.token)
48
  repo_id = f"{EXAM_DATASET_ID}_student_responses"
49
  submission_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
50
 
51
  new_ds = Dataset.from_list(user_answers)
52
+ new_ds = new_ds.map(lambda x: {
53
+ "username": user_info["name"],
54
+ "datetime": submission_time,
55
+ "grade": grade
56
+ })
 
 
57
  new_ds.push_to_hub(repo_id)
58
  return f"Your responses have been submitted to the Hub! Final grade: {grade:.1%}"
59
 
 
60
  def handle_quiz(question_idx, user_answers, selected_answer, is_start):
 
 
 
61
  if not is_start and question_idx < len(quiz_data):
62
  current_q = quiz_data[question_idx]
63
+ correct_key = f"answer_{current_q['correct_answer']}".lower()
64
+ is_correct = selected_answer == current_q[correct_key]
65
+ user_answers.append({
66
+ "question": current_q["question"],
67
+ "selected_answer": selected_answer,
68
+ "correct_answer": current_q[correct_key],
69
+ "is_correct": is_correct,
70
+ "correct_reference": correct_key
71
+ })
 
 
 
72
  question_idx += 1
73
 
74
  if question_idx >= len(quiz_data):
75
+ correct_count = sum(1 for a in user_answers if a["is_correct"])
76
  grade = correct_count / len(user_answers)
77
+ results_text = f"**Quiz Complete!**\n\nYour score: {grade:.1%}\nPassing score: {EXAM_PASSING_SCORE:.1%}\n"
 
 
 
 
78
  return [
79
+ "", gr.update(choices=[], visible=False),
80
+ f"{'✅ Passed!' if grade >= EXAM_PASSING_SCORE else '❌ Did not pass'}",
81
+ question_idx, user_answers,
82
+ gr.update(visible=False), gr.update(visible=False), gr.update(visible=True),
83
+ results_text
 
 
 
 
84
  ]
85
 
 
86
  q = quiz_data[question_idx]
87
  return [
88
+ f"## Question {question_idx + 1}\n### {q['question']}",
89
+ gr.update(choices=[q["answer_a"], q["answer_b"], q["answer_c"], q["answer_d"]], value=None, visible=True),
 
 
 
 
90
  "Select an answer and click 'Next' to continue.",
91
+ question_idx, user_answers,
92
+ gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), ""
 
 
 
 
93
  ]
94
 
 
95
  def success_message(response):
 
96
  return f"{response}\n\n**Success!**"
97
 
 
98
  with gr.Blocks() as demo:
99
  demo.title = f"Dataset Quiz for {EXAM_DATASET_ID}"
100
 
 
101
  question_idx = gr.State(value=0)
102
  user_answers = gr.State(value=[])
103
  user_token = gr.State(value=None)
104
 
105
+ gr.Markdown(f"## Welcome to the {EXAM_DATASET_ID} Quiz")
106
+ gr.Markdown("Log in first, then click 'Start' to begin. Answer each question, click 'Next', and finally click 'Submit'.")
107
 
108
+ question_text = gr.Markdown("")
109
+ radio_choices = gr.Radio(choices=[], label="Your Answer", scale=1.5, visible=False)
110
+ status_text = gr.Markdown("")
111
+ final_markdown = gr.Markdown("")
112
 
113
+ login_btn = gr.LoginButton(visible=True)
114
+ start_btn = gr.Button("Start ⏭️", visible=True)
115
+ next_btn = gr.Button("Next ⏭️", visible=False)
116
+ submit_btn = gr.Button("Submit ", visible=False)
 
117
 
 
 
 
 
 
 
 
 
 
 
 
118
  login_btn.click(
119
  fn=on_user_logged_in,
120
  inputs=None,
121
+ outputs=[login_btn, start_btn, next_btn, submit_btn, question_text, radio_choices,
122
+ status_text, question_idx, user_answers, final_markdown, user_token]
 
 
 
 
 
 
 
 
 
 
 
123
  )
124
 
125
  start_btn.click(
126
  fn=handle_quiz,
127
  inputs=[question_idx, user_answers, gr.State(""), gr.State(True)],
128
+ outputs=[question_text, radio_choices, status_text, question_idx, user_answers,
129
+ start_btn, next_btn, submit_btn, final_markdown]
 
 
 
 
 
 
 
 
 
130
  )
131
 
132
  next_btn.click(
133
  fn=handle_quiz,
134
  inputs=[question_idx, user_answers, radio_choices, gr.State(False)],
135
+ outputs=[question_text, radio_choices, status_text, question_idx, user_answers,
136
+ start_btn, next_btn, submit_btn, final_markdown]
 
 
 
 
 
 
 
 
 
137
  )
138
 
139
+ submit_btn.click(
140
+ fn=push_results_to_hub,
141
+ inputs=[user_answers, user_token],
142
+ outputs=[final_markdown]
143
+ )
144
 
145
  if __name__ == "__main__":
 
 
146
  demo.launch()