Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -15,9 +15,11 @@ class ExamPrepApp:
|
|
| 15 |
def reset(self):
|
| 16 |
random.shuffle(self.all_topics)
|
| 17 |
self.exam_questions = self.all_topics[:NUM_EXAM_QUESTIONS]
|
| 18 |
-
self.answered = {}
|
| 19 |
-
self.answered_yes = set()
|
|
|
|
| 20 |
self.current_index = 0
|
|
|
|
| 21 |
|
| 22 |
def _parse_flashcards(self) -> List[Dict[str, str]]:
|
| 23 |
return [
|
|
@@ -376,27 +378,54 @@ Features:
|
|
| 376 |
"answer": """Range, bandwidth, interference, security."""
|
| 377 |
}
|
| 378 |
]
|
|
|
|
| 379 |
def get_current_card(self) -> Dict[str, str]:
|
| 380 |
qidx = self.exam_questions[self.current_index]
|
| 381 |
return self.flashcards[qidx]
|
| 382 |
|
| 383 |
def show_question(self):
|
| 384 |
card = self.get_current_card()
|
| 385 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 386 |
|
| 387 |
def show_answer(self):
|
| 388 |
card = self.get_current_card()
|
| 389 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
|
| 391 |
def handle_yes(self, score):
|
| 392 |
qidx = self.exam_questions[self.current_index]
|
| 393 |
self.answered_yes.add(qidx)
|
| 394 |
self.answered[qidx] = int(score)
|
|
|
|
|
|
|
|
|
|
| 395 |
return self.goto_next()
|
| 396 |
|
| 397 |
def handle_no(self, score):
|
| 398 |
qidx = self.exam_questions[self.current_index]
|
|
|
|
| 399 |
self.answered[qidx] = int(score)
|
|
|
|
|
|
|
|
|
|
| 400 |
return self.goto_next()
|
| 401 |
|
| 402 |
def goto_next(self):
|
|
@@ -404,13 +433,14 @@ Features:
|
|
| 404 |
for _ in range(n):
|
| 405 |
self.current_index = (self.current_index + 1) % n
|
| 406 |
qidx = self.exam_questions[self.current_index]
|
| 407 |
-
if qidx not in self.
|
| 408 |
return self.show_question()
|
| 409 |
return self.show_summary()
|
| 410 |
|
| 411 |
def show_summary(self):
|
| 412 |
total = sum(self.answered.get(qidx, 0) for qidx in self.exam_questions)
|
| 413 |
-
|
|
|
|
| 414 |
details = "\n\n".join([
|
| 415 |
f"**Q{i+1}: {self.flashcards[q]['question']}**\n"
|
| 416 |
f"**A:** {self.flashcards[q]['answer']}\n"
|
|
@@ -418,12 +448,23 @@ Features:
|
|
| 418 |
for i, q in enumerate(self.exam_questions)
|
| 419 |
])
|
| 420 |
status = "β
You PASSED!" if total >= PASS_POINTS else "β You did NOT pass."
|
| 421 |
-
summary =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 422 |
return ("Exam Finished!", summary, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), summary, gr.update(visible=False), self.get_pass_probability())
|
| 423 |
|
| 424 |
-
def
|
| 425 |
-
|
| 426 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 427 |
|
| 428 |
def get_pass_probability(self):
|
| 429 |
if len(self.answered) == NUM_EXAM_QUESTIONS:
|
|
@@ -463,7 +504,7 @@ with gr.Blocks(title="Network Exam Simulator", theme=gr.themes.Soft()) as demo:
|
|
| 463 |
with gr.Row():
|
| 464 |
with gr.Column(scale=3):
|
| 465 |
question = gr.Textbox(label="β Question", interactive=False, lines=3)
|
| 466 |
-
answer = gr.Textbox(label="π‘ Answer", interactive=False, visible=
|
| 467 |
with gr.Row():
|
| 468 |
show_answer_btn = gr.Button("π Show Answer", variant="primary")
|
| 469 |
yes_btn = gr.Button("β
I remember this", visible=False)
|
|
@@ -471,21 +512,32 @@ with gr.Blocks(title="Network Exam Simulator", theme=gr.themes.Soft()) as demo:
|
|
| 471 |
with gr.Row():
|
| 472 |
score_input = gr.Radio(choices=[0,1,2,3], value=0, label="How many points would you get for this question?", interactive=True, visible=False)
|
| 473 |
with gr.Column(scale=1):
|
| 474 |
-
stats = gr.Markdown(app.
|
| 475 |
prob = gr.Markdown(app.get_pass_probability())
|
| 476 |
reset_btn = gr.Button("β»οΈ Start New Exam", variant="stop")
|
| 477 |
-
|
| 478 |
show_answer_btn.click(
|
| 479 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 480 |
outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob]
|
| 481 |
)
|
| 482 |
-
def yes_submit(score): return app.handle_yes(score)
|
| 483 |
-
yes_btn.click(yes_submit, inputs=[score_input], outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob])
|
| 484 |
-
def no_submit(score): return app.handle_no(score)
|
| 485 |
-
no_btn.click(no_submit, inputs=[score_input], outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob])
|
| 486 |
-
def on_reset(): return app.reset_exam()
|
| 487 |
-
reset_btn.click(on_reset, outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob])
|
| 488 |
-
demo.load(app.show_question, outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob])
|
| 489 |
|
| 490 |
if __name__ == "__main__":
|
| 491 |
demo.launch()
|
|
|
|
| 15 |
def reset(self):
|
| 16 |
random.shuffle(self.all_topics)
|
| 17 |
self.exam_questions = self.all_topics[:NUM_EXAM_QUESTIONS]
|
| 18 |
+
self.answered = {} # qidx: score (0-3)
|
| 19 |
+
self.answered_yes = set()
|
| 20 |
+
self.answered_no = set()
|
| 21 |
self.current_index = 0
|
| 22 |
+
self.last_answer = ""
|
| 23 |
|
| 24 |
def _parse_flashcards(self) -> List[Dict[str, str]]:
|
| 25 |
return [
|
|
|
|
| 378 |
"answer": """Range, bandwidth, interference, security."""
|
| 379 |
}
|
| 380 |
]
|
| 381 |
+
|
| 382 |
def get_current_card(self) -> Dict[str, str]:
|
| 383 |
qidx = self.exam_questions[self.current_index]
|
| 384 |
return self.flashcards[qidx]
|
| 385 |
|
| 386 |
def show_question(self):
|
| 387 |
card = self.get_current_card()
|
| 388 |
+
answer_to_show = self.last_answer if self.last_answer else ""
|
| 389 |
+
return (
|
| 390 |
+
card["question"],
|
| 391 |
+
answer_to_show,
|
| 392 |
+
gr.update(visible=True),
|
| 393 |
+
gr.update(visible=False),
|
| 394 |
+
gr.update(visible=False),
|
| 395 |
+
self.get_stats(),
|
| 396 |
+
gr.update(visible=False),
|
| 397 |
+
self.get_pass_probability()
|
| 398 |
+
)
|
| 399 |
|
| 400 |
def show_answer(self):
|
| 401 |
card = self.get_current_card()
|
| 402 |
+
return (
|
| 403 |
+
card["question"],
|
| 404 |
+
card["answer"],
|
| 405 |
+
gr.update(visible=False),
|
| 406 |
+
gr.update(visible=True),
|
| 407 |
+
gr.update(visible=True),
|
| 408 |
+
self.get_stats(),
|
| 409 |
+
gr.update(visible=True),
|
| 410 |
+
self.get_pass_probability()
|
| 411 |
+
)
|
| 412 |
|
| 413 |
def handle_yes(self, score):
|
| 414 |
qidx = self.exam_questions[self.current_index]
|
| 415 |
self.answered_yes.add(qidx)
|
| 416 |
self.answered[qidx] = int(score)
|
| 417 |
+
self.last_answer = self.flashcards[qidx]["answer"]
|
| 418 |
+
if qidx in self.answered_no:
|
| 419 |
+
self.answered_no.remove(qidx)
|
| 420 |
return self.goto_next()
|
| 421 |
|
| 422 |
def handle_no(self, score):
|
| 423 |
qidx = self.exam_questions[self.current_index]
|
| 424 |
+
self.answered_no.add(qidx)
|
| 425 |
self.answered[qidx] = int(score)
|
| 426 |
+
self.last_answer = self.flashcards[qidx]["answer"]
|
| 427 |
+
if qidx in self.answered_yes:
|
| 428 |
+
self.answered_yes.remove(qidx)
|
| 429 |
return self.goto_next()
|
| 430 |
|
| 431 |
def goto_next(self):
|
|
|
|
| 433 |
for _ in range(n):
|
| 434 |
self.current_index = (self.current_index + 1) % n
|
| 435 |
qidx = self.exam_questions[self.current_index]
|
| 436 |
+
if qidx not in self.answered:
|
| 437 |
return self.show_question()
|
| 438 |
return self.show_summary()
|
| 439 |
|
| 440 |
def show_summary(self):
|
| 441 |
total = sum(self.answered.get(qidx, 0) for qidx in self.exam_questions)
|
| 442 |
+
correct = len(self.answered_yes)
|
| 443 |
+
wrong = len(self.answered_no)
|
| 444 |
details = "\n\n".join([
|
| 445 |
f"**Q{i+1}: {self.flashcards[q]['question']}**\n"
|
| 446 |
f"**A:** {self.flashcards[q]['answer']}\n"
|
|
|
|
| 448 |
for i, q in enumerate(self.exam_questions)
|
| 449 |
])
|
| 450 |
status = "β
You PASSED!" if total >= PASS_POINTS else "β You did NOT pass."
|
| 451 |
+
summary = (
|
| 452 |
+
f"**Your Score:** {total}/24\n"
|
| 453 |
+
f"**Result:** {status}\n"
|
| 454 |
+
f"β
Remembered: {correct} | β Not remembered: {wrong}\n\n"
|
| 455 |
+
f"**Full breakdown:**\n\n{details}"
|
| 456 |
+
)
|
| 457 |
return ("Exam Finished!", summary, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), summary, gr.update(visible=False), self.get_pass_probability())
|
| 458 |
|
| 459 |
+
def get_stats(self):
|
| 460 |
+
total = sum(self.answered.get(qidx, 0) for qidx in self.exam_questions)
|
| 461 |
+
correct = len(self.answered_yes)
|
| 462 |
+
wrong = len(self.answered_no)
|
| 463 |
+
return (
|
| 464 |
+
f"β
Remembered: {correct} | β Not remembered: {wrong} | "
|
| 465 |
+
f"π― Your Score: {total}/24 | "
|
| 466 |
+
f"Question {len(self.answered)+1} of {NUM_EXAM_QUESTIONS}"
|
| 467 |
+
)
|
| 468 |
|
| 469 |
def get_pass_probability(self):
|
| 470 |
if len(self.answered) == NUM_EXAM_QUESTIONS:
|
|
|
|
| 504 |
with gr.Row():
|
| 505 |
with gr.Column(scale=3):
|
| 506 |
question = gr.Textbox(label="β Question", interactive=False, lines=3)
|
| 507 |
+
answer = gr.Textbox(label="π‘ Answer (for previous question)", interactive=False, visible=True, lines=8)
|
| 508 |
with gr.Row():
|
| 509 |
show_answer_btn = gr.Button("π Show Answer", variant="primary")
|
| 510 |
yes_btn = gr.Button("β
I remember this", visible=False)
|
|
|
|
| 512 |
with gr.Row():
|
| 513 |
score_input = gr.Radio(choices=[0,1,2,3], value=0, label="How many points would you get for this question?", interactive=True, visible=False)
|
| 514 |
with gr.Column(scale=1):
|
| 515 |
+
stats = gr.Markdown(app.get_stats())
|
| 516 |
prob = gr.Markdown(app.get_pass_probability())
|
| 517 |
reset_btn = gr.Button("β»οΈ Start New Exam", variant="stop")
|
| 518 |
+
|
| 519 |
show_answer_btn.click(
|
| 520 |
+
fn=app.show_answer,
|
| 521 |
+
outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob]
|
| 522 |
+
)
|
| 523 |
+
yes_btn.click(
|
| 524 |
+
fn=app.handle_yes,
|
| 525 |
+
inputs=[score_input],
|
| 526 |
+
outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob]
|
| 527 |
+
)
|
| 528 |
+
no_btn.click(
|
| 529 |
+
fn=app.handle_no,
|
| 530 |
+
inputs=[score_input],
|
| 531 |
+
outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob]
|
| 532 |
+
)
|
| 533 |
+
reset_btn.click(
|
| 534 |
+
fn=app.reset_exam,
|
| 535 |
+
outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob]
|
| 536 |
+
)
|
| 537 |
+
demo.load(
|
| 538 |
+
fn=app.show_question,
|
| 539 |
outputs=[question, answer, show_answer_btn, yes_btn, no_btn, stats, score_input, prob]
|
| 540 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 541 |
|
| 542 |
if __name__ == "__main__":
|
| 543 |
demo.launch()
|