capradeepgujaran commited on
Commit
4690b28
·
verified ·
1 Parent(s): 6f91d37

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +150 -190
app.py CHANGED
@@ -558,7 +558,7 @@ def create_quiz_interface():
558
  # State management
559
  current_questions = gr.State([])
560
  current_question_idx = gr.State(0)
561
- answer_state = gr.State([None] * 5) # Store all answers
562
 
563
  # Header
564
  gr.Markdown("""
@@ -568,7 +568,7 @@ def create_quiz_interface():
568
 
569
  with gr.Tabs() as tabs:
570
  # Profile Setup Tab
571
- with gr.Tab(id=1,label="📋 Step 1: Profile Setup"):
572
  with gr.Row():
573
  name = gr.Textbox(label="Full Name", placeholder="Enter your full name")
574
  email = gr.Textbox(label="Email", placeholder="Enter your email")
@@ -594,257 +594,217 @@ def create_quiz_interface():
594
  generate_btn = gr.Button("Generate Assessment", variant="primary", size="lg")
595
 
596
  # Assessment Tab
597
- with gr.Tab(id=2,label="📝 Step 2: Take Assessment") as assessment_tab:
598
- with gr.Column(visible=True) as question_box:
599
- # Question section
600
- with gr.Group():
601
- # Question display
602
- question_display = gr.Markdown("", label="Current Question")
603
-
604
- # Single radio group for current question
605
  current_options = gr.Radio(
606
  choices=[],
607
  label="Select your answer:",
608
  visible=False
609
  )
610
 
611
- # Navigation
612
  with gr.Row():
613
  prev_btn = gr.Button("← Previous", variant="secondary", size="sm")
614
  question_counter = gr.Markdown("Question 1")
615
  next_btn = gr.Button("Next →", variant="secondary", size="sm")
616
 
617
- gr.Markdown("---") # Separator
618
-
 
 
 
 
 
 
 
619
  with gr.Row():
620
- submit_btn = gr.Button(
621
- "Submit Assessment",
622
- variant="primary",
623
- size="lg"
624
- )
625
  reset_btn = gr.Button(
626
  "Reset Quiz",
627
  variant="secondary",
628
- size="lg"
 
 
 
 
 
 
 
629
  )
630
-
631
- # Results section
632
- with gr.Group(visible=False) as results_group:
633
- feedback_box = gr.Markdown("")
634
- with gr.Row():
635
- view_cert_btn = gr.Button(
636
- "View Certificate",
637
- variant="primary",
638
- size="lg",
639
- visible=False
640
- )
641
- back_to_assessment = gr.Button( # Add this button definition
642
- "Back to Assessment",
643
- variant="secondary",
644
- size="lg",
645
- visible=True
646
- )
647
 
648
  # Certification Tab
649
- with gr.Tab(id=3,label="🎓 Step 3: Get Certified"):
650
- score_display = gr.Number(label="Your Score")
651
- result_message = gr.Markdown("")
652
- course_name = gr.Textbox(
653
- label="Certification Title",
654
- value="Professional Assessment Certification"
655
- )
656
- certificate_display = gr.Image(label="Your Certificate")
657
-
658
  # Helper Functions
659
  def on_generate_questions(text, num_questions):
660
  """Generate quiz questions and setup initial state"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
661
  success, questions = quiz_app.generate_questions(text, num_questions)
662
- if not success:
663
  return [
664
- "", # question_display
665
- gr.update(choices=[], visible=False), # current_options
666
- "", # question_counter
667
- gr.update(visible=False), # question_box
668
- [], # current_questions
669
- 0, # current_question_idx
670
- [None] * 5, # answer_state
671
- gr.Tabs(selected=2), # tabs
672
- gr.update(visible=False), # results_group
673
- gr.update(visible=False) # view_cert_btn - added this
674
  ]
675
 
676
- # Setup initial state with first question
677
- initial_answers = [None] * len(questions)
678
  question = questions[0]
679
- question_html = f"""## Question 1
680
- {question.question}
681
-
682
- Please select one answer:"""
683
 
684
  return [
685
- question_html, # question_display
 
686
  gr.update(
687
  choices=question.options,
688
  value=None,
689
  visible=True,
690
- label="Select your answer for Question 1:"
691
- ), # current_options
692
- f"Question 1 of {len(questions)}", # question_counter
693
- gr.update(visible=True), # question_box
694
- questions, # current_questions
695
- 0, # current_question_idx
696
- initial_answers, # answer_state
697
- gr.Tabs(selected=2), # tabs
698
- gr.update(visible=False), # results_group
699
- gr.update(visible=False) # view_cert_btn - added this
700
  ]
 
701
  def navigate(direction, current_idx, questions, answers, current_answer):
702
  """Handle navigation between questions"""
703
  if not questions:
704
- return [
705
- 0,
706
- answers,
707
- "",
708
- gr.update(choices=[], value=None, visible=False),
709
- "",
710
- gr.update(visible=False)
711
- ]
712
 
 
713
  new_answers = list(answers)
714
- if current_answer and 0 <= current_idx < len(new_answers):
715
  new_answers[current_idx] = current_answer
716
 
 
717
  new_idx = max(0, min(len(questions) - 1, current_idx + direction))
718
  question = questions[new_idx]
719
 
 
 
 
 
720
  return [
721
  new_idx,
722
  new_answers,
723
- f"## Question {new_idx + 1}\n{question.question}\n\nPlease select one answer:",
724
  gr.update(
725
  choices=question.options,
726
  value=new_answers[new_idx] if new_idx < len(new_answers) else None,
727
  visible=True,
728
- label=f"Select your answer for Question {new_idx + 1}:"
729
  ),
730
  f"Question {new_idx + 1} of {len(questions)}",
731
  gr.update(visible=True)
732
- ]
733
- def handle_prev(current_idx, questions, answers, current_answer):
734
- return navigate(-1, current_idx, questions, answers, current_answer)
735
-
736
- def handle_next(current_idx, questions, answers, current_answer):
737
- return navigate(1, current_idx, questions, answers, current_answer)
738
-
739
- def update_answer_state(answer, idx, current_answers):
740
- new_answers = list(current_answers)
741
- if 0 <= idx < len(new_answers):
742
- new_answers[idx] = answer
743
- return new_answers
744
-
745
- def reset_quiz(text, num_questions):
746
- """Handle quiz reset"""
747
- return on_generate_questions(text, num_questions)
748
-
749
- def view_certificate():
750
- """Navigate to certificate tab"""
751
- return gr.Tabs(selected=2)
752
-
753
- def on_submit(questions, answers, current_idx, current_answer):
754
- """Handle quiz submission with updated styling and logic"""
755
- final_answers = list(answers)
756
- if 0 <= current_idx < len(final_answers):
757
- final_answers[current_idx] = current_answer
758
-
759
- if not all(a is not None for a in final_answers[:len(questions)]):
760
- return [
761
- "⚠️ Please answer all questions before submitting.",
762
- gr.update(visible=True),
763
- 0,
764
- "",
765
- gr.update(visible=True),
766
- gr.update(visible=True),
767
- gr.update(visible=False),
768
- gr.update(visible=False),
769
- gr.update(visible=False)
770
- ]
771
-
772
- score, passed, feedback = quiz_app.calculate_score(final_answers[:len(questions)])
773
-
774
- # Updated feedback HTML with proper font styling
775
- feedback_html = """
776
- <div style="font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;">
777
- <h1 style="font-size: 24px; font-weight: 600; margin-bottom: 20px;">Assessment Results</h1>
778
- """
779
-
780
- for i, (q, f) in enumerate(zip(questions, feedback)):
781
- color = "green" if f.is_correct else "red"
782
- symbol = "✅" if f.is_correct else "❌"
783
-
784
- feedback_html += f"""
785
- <div style="margin-bottom: 24px;">
786
- <h3 style="font-size: 18px; font-weight: 500; margin-bottom: 12px;">Question {i+1}</h3>
787
- <p style="font-size: 16px; margin-bottom: 12px;">{q.question}</p>
788
- <div style="color: {color}; padding: 12px; margin: 8px 0; border-left: 3px solid {color}; background-color: {'#f8fff8' if f.is_correct else '#fff8f8'}; font-size: 15px;">
789
- {symbol} Your answer: {f.selected or "No answer"}
790
- {'' if f.is_correct else f'<br><span style="font-weight: 500;">Correct answer:</span> {f.correct_answer}'}
791
- </div>
792
- </div>
793
- """
794
-
795
- # Add summary box with score
796
- if passed:
797
- feedback_html += f"""
798
- <div style="background-color: #e6ffe6; padding: 20px; margin: 20px 0; border-radius: 10px; border: 1px solid #ccffcc;">
799
- <h3 style="color: #008000; margin: 0 0 12px 0; font-size: 20px;">🎉 Congratulations!</h3>
800
- <p style="margin: 0; font-size: 16px;">You passed with a score of {score:.1f}%</p>
801
- </div>
802
- """
803
- else:
804
- feedback_html += f"""
805
- <div style="background-color: #ffe6e6; padding: 20px; margin: 20px 0; border-radius: 10px; border: 1px solid #ffcccc;">
806
- <h3 style="color: #cc0000; margin: 0 0 12px 0; font-size: 20px;">Please Try Again</h3>
807
- <p style="margin: 0; font-size: 16px;">Your score: {score:.1f}% (80% required to pass)</p>
808
- </div>
809
- """
810
-
811
- feedback_html += "</div>"
812
-
813
- return [
814
- feedback_html, # feedback_box
815
- gr.update(visible=True), # results_group
816
- score, # score_display
817
- "🎉 Passed!" if passed else "Please try again", # result_message
818
- gr.update(visible=False), # question_box
819
- gr.update(visible=True), # reset_btn
820
- gr.update(visible=passed), # view_cert_btn
821
- gr.update(visible=not passed), # back_to_assessment
822
- gr.update(visible=False) # profile_tab
823
  ]
824
-
825
- # Event handlers
826
-
827
- 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)
828
 
829
- 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])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
830
 
831
- 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])
 
 
 
 
832
 
833
- current_options.change(fn=update_answer_state, inputs=[current_options, current_question_idx, answer_state], outputs=answer_state)
 
 
 
 
834
 
835
- 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])
836
-
837
- 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])
 
 
 
 
 
 
 
 
 
 
 
 
838
 
839
- view_cert_btn.click(fn=lambda: gr.Tabs(selected=3), outputs=tabs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
840
 
841
- back_to_assessment.click(fn=lambda: gr.Tabs(selected=2), outputs=tabs)
 
 
 
842
 
843
- 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)
844
-
 
 
 
845
 
846
  return demo
847
-
848
  if __name__ == "__main__":
849
  demo = create_quiz_interface()
850
  demo.launch()
 
558
  # State management
559
  current_questions = gr.State([])
560
  current_question_idx = gr.State(0)
561
+ answer_state = gr.State([None] * 5)
562
 
563
  # Header
564
  gr.Markdown("""
 
568
 
569
  with gr.Tabs() as tabs:
570
  # Profile Setup Tab
571
+ with gr.Tab(id=1, label="📋 Step 1: Profile Setup"):
572
  with gr.Row():
573
  name = gr.Textbox(label="Full Name", placeholder="Enter your full name")
574
  email = gr.Textbox(label="Email", placeholder="Enter your email")
 
594
  generate_btn = gr.Button("Generate Assessment", variant="primary", size="lg")
595
 
596
  # Assessment Tab
597
+ with gr.Tab(id=2, label="📝 Step 2: Take Assessment") as assessment_tab:
598
+ with gr.Column() as main_container:
599
+ # Questions Section
600
+ with gr.Column(visible=True) as question_box:
601
+ question_display = gr.Markdown("")
 
 
 
602
  current_options = gr.Radio(
603
  choices=[],
604
  label="Select your answer:",
605
  visible=False
606
  )
607
 
 
608
  with gr.Row():
609
  prev_btn = gr.Button("← Previous", variant="secondary", size="sm")
610
  question_counter = gr.Markdown("Question 1")
611
  next_btn = gr.Button("Next →", variant="secondary", size="sm")
612
 
613
+ submit_btn = gr.Button(
614
+ "Submit Assessment",
615
+ variant="primary",
616
+ size="lg"
617
+ )
618
+
619
+ # Results Section
620
+ with gr.Column(visible=False) as results_group:
621
+ feedback_box = gr.Markdown("")
622
  with gr.Row():
 
 
 
 
 
623
  reset_btn = gr.Button(
624
  "Reset Quiz",
625
  variant="secondary",
626
+ size="lg",
627
+ visible=False
628
+ )
629
+ view_cert_btn = gr.Button(
630
+ "View Certificate",
631
+ variant="primary",
632
+ size="lg",
633
+ visible=False
634
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
635
 
636
  # Certification Tab
637
+ with gr.Tab(id=3, label="🎓 Step 3: Get Certified"):
638
+ with gr.Column():
639
+ score_display = gr.Number(label="Your Score", visible=False)
640
+ course_name = gr.Textbox(
641
+ label="Certification Title",
642
+ value="Professional Assessment Certification"
643
+ )
644
+ certificate_display = gr.Image(label="Your Certificate")
645
+
646
  # Helper Functions
647
  def on_generate_questions(text, num_questions):
648
  """Generate quiz questions and setup initial state"""
649
+ if not text.strip():
650
+ return [
651
+ gr.Markdown("⚠️ Please enter some text content to generate questions."),
652
+ gr.update(visible=False),
653
+ gr.update(choices=[], visible=False),
654
+ "",
655
+ [],
656
+ 0,
657
+ [None] * 5,
658
+ gr.Tabs(selected=1),
659
+ gr.update(visible=False),
660
+ gr.update(visible=False)
661
+ ]
662
+
663
  success, questions = quiz_app.generate_questions(text, num_questions)
664
+ if not success or not questions:
665
  return [
666
+ gr.Markdown("❌ Failed to generate questions. Please try again."),
667
+ gr.update(visible=False),
668
+ gr.update(choices=[], visible=False),
669
+ "",
670
+ [],
671
+ 0,
672
+ [None] * 5,
673
+ gr.Tabs(selected=1),
674
+ gr.update(visible=False),
675
+ gr.update(visible=False)
676
  ]
677
 
678
+ # Setup initial question
 
679
  question = questions[0]
680
+ question_html = f"""### Question 1
681
+ {question.question}"""
 
 
682
 
683
  return [
684
+ gr.Markdown(question_html),
685
+ gr.update(visible=True),
686
  gr.update(
687
  choices=question.options,
688
  value=None,
689
  visible=True,
690
+ label="Select your answer:"
691
+ ),
692
+ f"Question 1 of {len(questions)}",
693
+ questions,
694
+ 0,
695
+ [None] * len(questions),
696
+ gr.Tabs(selected=2),
697
+ gr.update(visible=False),
698
+ gr.update(visible=False)
 
699
  ]
700
+
701
  def navigate(direction, current_idx, questions, answers, current_answer):
702
  """Handle navigation between questions"""
703
  if not questions:
704
+ return [0, answers, "", gr.update(choices=[], visible=False), "", gr.update(visible=False)]
 
 
 
 
 
 
 
705
 
706
+ # Update current answer in state
707
  new_answers = list(answers)
708
+ if current_answer is not None and 0 <= current_idx < len(new_answers):
709
  new_answers[current_idx] = current_answer
710
 
711
+ # Calculate new index
712
  new_idx = max(0, min(len(questions) - 1, current_idx + direction))
713
  question = questions[new_idx]
714
 
715
+ # Format question display
716
+ question_html = f"""### Question {new_idx + 1}
717
+ {question.question}"""
718
+
719
  return [
720
  new_idx,
721
  new_answers,
722
+ gr.Markdown(question_html),
723
  gr.update(
724
  choices=question.options,
725
  value=new_answers[new_idx] if new_idx < len(new_answers) else None,
726
  visible=True,
727
+ label=f"Select your answer:"
728
  ),
729
  f"Question {new_idx + 1} of {len(questions)}",
730
  gr.update(visible=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
731
  ]
 
 
 
 
732
 
733
+ # Event Handlers
734
+ generate_btn.click(
735
+ fn=on_generate_questions,
736
+ inputs=[text_input, num_questions],
737
+ outputs=[
738
+ question_display,
739
+ question_box,
740
+ current_options,
741
+ question_counter,
742
+ current_questions,
743
+ current_question_idx,
744
+ answer_state,
745
+ tabs,
746
+ results_group,
747
+ view_cert_btn
748
+ ]
749
+ )
750
 
751
+ prev_btn.click(
752
+ fn=lambda *args: navigate(-1, *args),
753
+ inputs=[current_question_idx, current_questions, answer_state, current_options],
754
+ outputs=[current_question_idx, answer_state, question_display, current_options, question_counter, question_box]
755
+ )
756
 
757
+ next_btn.click(
758
+ fn=lambda *args: navigate(1, *args),
759
+ inputs=[current_question_idx, current_questions, answer_state, current_options],
760
+ outputs=[current_question_idx, answer_state, question_display, current_options, question_counter, question_box]
761
+ )
762
 
763
+ submit_btn.click(
764
+ fn=on_submit,
765
+ inputs=[current_questions, answer_state, current_question_idx, current_options],
766
+ outputs=[
767
+ feedback_box,
768
+ results_group,
769
+ score_display,
770
+ result_message,
771
+ question_box,
772
+ reset_btn,
773
+ view_cert_btn,
774
+ back_to_assessment,
775
+ tabs
776
+ ]
777
+ )
778
 
779
+ reset_btn.click(
780
+ fn=on_generate_questions,
781
+ inputs=[text_input, num_questions],
782
+ outputs=[
783
+ question_display,
784
+ question_box,
785
+ current_options,
786
+ question_counter,
787
+ current_questions,
788
+ current_question_idx,
789
+ answer_state,
790
+ tabs,
791
+ results_group,
792
+ view_cert_btn
793
+ ]
794
+ )
795
 
796
+ view_cert_btn.click(
797
+ fn=lambda: gr.Tabs(selected=3),
798
+ outputs=tabs
799
+ )
800
 
801
+ score_display.change(
802
+ fn=lambda s, n, c, l, p: quiz_app.certificate_generator.generate(s, n, c, l, p) or gr.update(value=None),
803
+ inputs=[score_display, name, course_name, company_logo, participant_photo],
804
+ outputs=certificate_display
805
+ )
806
 
807
  return demo
 
808
  if __name__ == "__main__":
809
  demo = create_quiz_interface()
810
  demo.launch()