capradeepgujaran commited on
Commit
e54bd0b
1 Parent(s): 14d9366

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +154 -242
app.py CHANGED
@@ -595,15 +595,28 @@ def create_quiz_interface():
595
 
596
  gr.Markdown("---") # Separator
597
 
598
- submit_btn = gr.Button(
599
- "Submit Assessment",
600
- variant="primary",
601
- size="lg"
602
- )
 
 
 
 
 
 
603
 
604
  # Results section
605
  with gr.Group(visible=False) as results_group:
606
  feedback_box = gr.Markdown("")
 
 
 
 
 
 
 
607
 
608
  # Certification Tab
609
  with gr.Tab("🎓 Step 3: Get Certified"):
@@ -615,269 +628,168 @@ def create_quiz_interface():
615
  )
616
  certificate_display = gr.Image(label="Your Certificate")
617
 
618
-
619
  def on_generate_questions(text, num_questions):
620
- success, questions = quiz_app.generate_questions(text, num_questions)
621
- if not success:
622
- return [
623
- "", # question_display
624
- gr.update(choices=[], visible=False), # current_options
625
- "", # question_counter
626
- gr.update(visible=False), # question_box
627
- [], # current_questions
628
- 0, # current_question_idx
629
- [None] * 5, # answer_state
630
- gr.update(selected=1), # tabs
631
- gr.update(visible=False) # results_group
632
- ]
633
-
634
- # Initialize first question
635
- initial_answers = [None] * len(questions)
636
- question = questions[0]
637
-
638
- return [
639
- f"""## Question 1
640
- {question.question}
641
-
642
- Please select one answer:""", # question_display
643
- gr.update(
644
- choices=question.options,
645
- value=None,
646
- visible=True,
647
- label="Select your answer for Question 1:"
648
- ), # current_options
649
- f"Question 1 of {len(questions)}", # question_counter
650
- gr.update(visible=True), # question_box
651
- questions, # current_questions
652
- 0, # current_question_idx
653
- initial_answers, # answer_state
654
- gr.update(selected=1), # tabs
655
- gr.update(visible=False) # results_group
656
- ]
657
-
658
- def navigate(direction, current_idx, questions, answers, current_answer):
659
- """
660
- Handle navigation between questions
661
- """
662
- if not questions: # No questions available
663
- return [
664
- 0, # current_question_idx
665
- answers, # answer_state
666
- "", # question_display
667
- gr.update(choices=[], value=None, visible=False), # current_options
668
- "", # question_counter
669
- gr.update(visible=False) # question_box
670
- ]
671
-
672
- # Save current answer
673
- new_answers = list(answers)
674
- if current_answer and 0 <= current_idx < len(new_answers):
675
- new_answers[current_idx] = current_answer
676
-
677
- # Calculate new index
678
- new_idx = max(0, min(len(questions) - 1, current_idx + direction))
679
-
680
- # Get current question
681
- question = questions[new_idx]
682
-
683
- return [
684
- new_idx, # current_question_idx
685
- new_answers, # answer_state
686
- f"""## Question {new_idx + 1}
687
- {question.question}
688
-
689
- Please select one answer:""", # question_display
690
- gr.update(
691
- choices=question.options,
692
- value=new_answers[new_idx] if new_idx < len(new_answers) else None,
693
- visible=True,
694
- label=f"Select your answer for Question {new_idx + 1}:"
695
- ), # current_options
696
- f"Question {new_idx + 1} of {len(questions)}", # question_counter
697
- gr.update(visible=True) # question_box
698
- ]
 
 
 
 
 
 
699
 
700
  def on_submit(questions, answers, current_idx, current_answer):
701
- # Update the current answer in the answers list
702
  final_answers = list(answers)
703
  if 0 <= current_idx < len(final_answers):
704
  final_answers[current_idx] = current_answer
705
 
706
- # Validate all answers are provided
707
  if not all(a is not None for a in final_answers[:len(questions)]):
708
- return {
709
- feedback_box: "⚠️ Please answer all questions before submitting.",
710
- results_group: gr.update(visible=True),
711
- score_display: 0,
712
- result_message: "",
713
- question_box: gr.update(visible=True),
714
- tabs: gr.update(selected=1)
715
- }
 
716
 
717
  score, passed, feedback = quiz_app.calculate_score(final_answers[:len(questions)])
718
 
719
- # Generate feedback HTML
720
  feedback_html = "# Assessment Results\n\n"
721
  for i, (q, f) in enumerate(zip(questions, feedback)):
722
  color = "green" if f.is_correct else "red"
723
  symbol = "✅" if f.is_correct else "❌"
724
- feedback_html += f"""
725
- ### Question {i+1}
726
- {q.question}
727
-
728
- <div style="color: {color}; padding: 10px; margin: 5px 0; border-left: 3px solid {color};">
729
- {symbol} Your answer: {f.selected or "No answer"}
730
- {'' if f.is_correct else f'<br>Correct answer: {f.correct_answer}'}
731
- </div>
732
- """
733
 
734
  result_msg = "🎉 Passed!" if passed else "Please try again"
735
  if not passed:
736
  feedback_html += f"""
737
- <div style="background-color: #ffe6e6; padding: 20px; margin-top: 20px; border-radius: 10px;">
738
- <h3 style="color: #cc0000;">Please Try Again</h3>
739
- <p>Your score: {score:.1f}%</p>
740
- <p>You need 80% or higher to pass and receive a certificate.</p>
741
- </div>
742
- """
743
 
744
- return {
745
- feedback_box: feedback_html,
746
- results_group: gr.update(visible=True),
747
- score_display: score,
748
- result_message: result_msg,
749
- question_box: gr.update(visible=passed),
750
- tabs: gr.update(selected=2 if passed else 1)
751
- }
752
-
753
- # Event handlers
754
- generate_btn.click(
755
- fn=on_generate_questions,
756
- inputs=[text_input, num_questions],
757
- outputs=[
758
- question_display,
759
- current_options,
760
- question_counter,
761
- question_box,
762
- current_questions,
763
- current_question_idx,
764
- answer_state,
765
- tabs,
766
- results_group
767
- ]
768
- )
769
-
770
- # Navigation event handlers
771
- def handle_prev(current_idx, questions, answers, current_answer):
772
- result = navigate(-1, current_idx, questions, answers, current_answer)
773
- return [
774
- result[current_question_idx],
775
- result[answer_state],
776
- result[question_display],
777
- result[current_options],
778
- result[question_counter],
779
- result[question_box]
780
- ]
781
-
782
- def handle_next(current_idx, questions, answers, current_answer):
783
- result = navigate(1, current_idx, questions, answers, current_answer)
784
  return [
785
- result[current_question_idx],
786
- result[answer_state],
787
- result[question_display],
788
- result[current_options],
789
- result[question_counter],
790
- result[question_box]
791
- ]
792
-
793
- prev_btn.click(
794
- fn=handle_prev,
795
- inputs=[
796
- current_question_idx,
797
- current_questions,
798
- answer_state,
799
- current_options
800
- ],
801
- outputs=[
802
- current_question_idx,
803
- answer_state,
804
- question_display,
805
- current_options,
806
- question_counter,
807
- question_box
808
- ]
809
- )
810
-
811
- next_btn.click(
812
- fn=handle_next,
813
- inputs=[
814
- current_question_idx,
815
- current_questions,
816
- answer_state,
817
- current_options
818
- ],
819
- outputs=[
820
- current_question_idx,
821
- answer_state,
822
- question_display,
823
- current_options,
824
- question_counter,
825
- question_box
826
- ]
827
- )
828
-
829
- # Update answer state when radio button changes
830
- def update_answer_state(answer, idx, current_answers):
831
- new_answers = list(current_answers)
832
- if 0 <= idx < len(new_answers):
833
- new_answers[idx] = answer
834
- return new_answers
835
-
836
- current_options.change(
837
- fn=update_answer_state,
838
- inputs=[current_options, current_question_idx, answer_state],
839
- outputs=answer_state
840
- )
841
-
842
- # Submission handler
843
- def on_submit_wrapper(questions, answers, current_idx, current_answer):
844
- result = on_submit(questions, answers, current_idx, current_answer)
845
- return [
846
- result[feedback_box],
847
- result[results_group],
848
- result[score_display],
849
- result[result_message],
850
- result[question_box],
851
- result[tabs]
852
  ]
 
853
 
854
- submit_btn.click(
855
- fn=on_submit_wrapper,
856
- inputs=[
857
- current_questions,
858
- answer_state,
859
- current_question_idx,
860
- current_options
861
- ],
862
- outputs=[
863
- feedback_box,
864
- results_group,
865
- score_display,
866
- result_message,
867
- question_box,
868
- tabs
869
- ]
870
- )
871
 
872
- # Certificate generation
873
- score_display.change(
874
- fn=quiz_app.certificate_generator.generate,
875
- inputs=[score_display, name, course_name, company_logo, participant_photo],
876
- outputs=certificate_display
877
- )
878
 
879
  return demo
880
 
881
  if __name__ == "__main__":
882
  demo = create_quiz_interface()
883
- demo.launch()
 
 
595
 
596
  gr.Markdown("---") # Separator
597
 
598
+ with gr.Row():
599
+ submit_btn = gr.Button(
600
+ "Submit Assessment",
601
+ variant="primary",
602
+ size="lg"
603
+ )
604
+ reset_btn = gr.Button(
605
+ "Reset Quiz",
606
+ variant="secondary",
607
+ size="lg"
608
+ )
609
 
610
  # Results section
611
  with gr.Group(visible=False) as results_group:
612
  feedback_box = gr.Markdown("")
613
+ with gr.Row():
614
+ view_cert_btn = gr.Button(
615
+ "View Certificate",
616
+ variant="primary",
617
+ size="lg",
618
+ visible=False
619
+ )
620
 
621
  # Certification Tab
622
  with gr.Tab("🎓 Step 3: Get Certified"):
 
628
  )
629
  certificate_display = gr.Image(label="Your Certificate")
630
 
631
+ # Helper Functions
632
  def on_generate_questions(text, num_questions):
633
+ success, questions = quiz_app.generate_questions(text, num_questions)
634
+ if not success:
635
+ return [
636
+ "",
637
+ gr.update(choices=[], visible=False),
638
+ "",
639
+ gr.update(visible=False),
640
+ [],
641
+ 0,
642
+ [None] * 5,
643
+ gr.update(selected=1),
644
+ gr.update(visible=False)
645
+ ]
646
+
647
+ initial_answers = [None] * len(questions)
648
+ question = questions[0]
649
+
650
+ return [
651
+ f"## Question 1\n{question.question}\n\nPlease select one answer:",
652
+ gr.update(
653
+ choices=question.options,
654
+ value=None,
655
+ visible=True,
656
+ label="Select your answer for Question 1:"
657
+ ),
658
+ f"Question 1 of {len(questions)}",
659
+ gr.update(visible=True),
660
+ questions,
661
+ 0,
662
+ initial_answers,
663
+ gr.update(selected=1),
664
+ gr.update(visible=False)
665
+ ]
666
+
667
+ def navigate(direction, current_idx, questions, answers, current_answer):
668
+ """Handle navigation between questions"""
669
+ if not questions:
670
+ return [
671
+ 0,
672
+ answers,
673
+ "",
674
+ gr.update(choices=[], value=None, visible=False),
675
+ "",
676
+ gr.update(visible=False)
677
+ ]
678
+
679
+ new_answers = list(answers)
680
+ if current_answer and 0 <= current_idx < len(new_answers):
681
+ new_answers[current_idx] = current_answer
682
+
683
+ new_idx = max(0, min(len(questions) - 1, current_idx + direction))
684
+ question = questions[new_idx]
685
+
686
+ return [
687
+ new_idx,
688
+ new_answers,
689
+ f"## Question {new_idx + 1}\n{question.question}\n\nPlease select one answer:",
690
+ gr.update(
691
+ choices=question.options,
692
+ value=new_answers[new_idx] if new_idx < len(new_answers) else None,
693
+ visible=True,
694
+ label=f"Select your answer for Question {new_idx + 1}:"
695
+ ),
696
+ f"Question {new_idx + 1} of {len(questions)}",
697
+ gr.update(visible=True)
698
+ ]
699
+ def handle_prev(current_idx, questions, answers, current_answer):
700
+ return navigate(-1, current_idx, questions, answers, current_answer)
701
+
702
+ def handle_next(current_idx, questions, answers, current_answer):
703
+ return navigate(1, current_idx, questions, answers, current_answer)
704
+
705
+ def update_answer_state(answer, idx, current_answers):
706
+ new_answers = list(current_answers)
707
+ if 0 <= idx < len(new_answers):
708
+ new_answers[idx] = answer
709
+ return new_answers
710
+
711
+ def reset_quiz(text, num_questions):
712
+ """Handle quiz reset"""
713
+ return on_generate_questions(text, num_questions)
714
+
715
+ def view_certificate():
716
+ """Navigate to certificate tab"""
717
+ return gr.update(selected=2)
718
 
719
  def on_submit(questions, answers, current_idx, current_answer):
 
720
  final_answers = list(answers)
721
  if 0 <= current_idx < len(final_answers):
722
  final_answers[current_idx] = current_answer
723
 
 
724
  if not all(a is not None for a in final_answers[:len(questions)]):
725
+ return [
726
+ "⚠️ Please answer all questions before submitting.",
727
+ gr.update(visible=True),
728
+ 0,
729
+ "",
730
+ gr.update(visible=True),
731
+ gr.update(selected=1),
732
+ gr.update(visible=False) # view_cert_btn visibility
733
+ ]
734
 
735
  score, passed, feedback = quiz_app.calculate_score(final_answers[:len(questions)])
736
 
 
737
  feedback_html = "# Assessment Results\n\n"
738
  for i, (q, f) in enumerate(zip(questions, feedback)):
739
  color = "green" if f.is_correct else "red"
740
  symbol = "✅" if f.is_correct else "❌"
741
+ feedback_html += f"""### Question {i+1}
742
+ {q.question}
743
+
744
+ <div style="color: {color}; padding: 10px; margin: 5px 0; border-left: 3px solid {color};">
745
+ {symbol} Your answer: {f.selected or "No answer"}
746
+ {'' if f.is_correct else f'<br>Correct answer: {f.correct_answer}'}
747
+ </div>
748
+ """
 
749
 
750
  result_msg = "🎉 Passed!" if passed else "Please try again"
751
  if not passed:
752
  feedback_html += f"""
753
+ <div style="background-color: #ffe6e6; padding: 20px; margin-top: 20px; border-radius: 10px;">
754
+ <h3 style="color: #cc0000;">Please Try Again</h3>
755
+ <p>Your score: {score:.1f}%</p>
756
+ <p>You need 80% or higher to pass and receive a certificate.</p>
757
+ </div>
758
+ """
759
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
760
  return [
761
+ feedback_html,
762
+ gr.update(visible=True),
763
+ score,
764
+ result_msg,
765
+ gr.update(visible=not passed),
766
+ gr.update(selected=1),
767
+ gr.update(visible=passed) # Show view certificate button only if passed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
768
  ]
769
+ # Event handlers
770
 
771
+ generate_btn.click(fn=on_generate_questions, inputs=[text_input, num_questions], outputs=[question_display, current_options, question_counter, question_box, current_questions, current_question_idx, answer_state, tabs, results_group, view_cert_btn]).then(fn=lambda: gr.Tabs(selected=2), outputs=tabs)
772
+
773
+ prev_btn.click(fn=handle_prev, inputs=[current_question_idx, current_questions, answer_state, current_options], outputs=[current_question_idx, answer_state, question_display, current_options, question_counter, question_box])
774
+
775
+ next_btn.click(fn=handle_next, inputs=[current_question_idx, current_questions, answer_state, current_options], outputs=[current_question_idx, answer_state, question_display, current_options, question_counter, question_box])
776
+
777
+ current_options.change(fn=update_answer_state, inputs=[current_options, current_question_idx, answer_state], outputs=answer_state)
778
+
779
+ submit_btn.click(fn=on_submit, inputs=[current_questions, answer_state, current_question_idx, current_options], outputs=[feedback_box, results_group, score_display, result_message, question_box, tabs, view_cert_btn])
780
+
781
+ reset_btn.click(fn=reset_quiz, inputs=[text_input, num_questions], outputs=[question_display, current_options, question_counter, question_box, current_questions, current_question_idx, answer_state, tabs, results_group, view_cert_btn])
782
+
783
+ view_cert_btn.click(fn=lambda: gr.Tabs(selected=3), outputs=tabs)
784
+
785
+ back_to_assessment.click(fn=lambda: gr.Tabs(selected=2), outputs=tabs)
786
+
787
+ score_display.change(fn=lambda s, n, c, l, p: quiz_app.certificate_generator.generate(s, n, c, l, p) or gr.update(value=None), inputs=[score_display, name, course_name, company_logo, participant_photo], outputs=certificate_display)
788
 
 
 
 
 
 
 
789
 
790
  return demo
791
 
792
  if __name__ == "__main__":
793
  demo = create_quiz_interface()
794
+ demo.launch()
795
+