gladguy commited on
Commit
2daa58c
·
1 Parent(s): b5810fa

Fix NameError in navigation logic

Browse files
Files changed (1) hide show
  1. app.py +195 -130
app.py CHANGED
@@ -793,23 +793,28 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
793
  # Display student name
794
  student_name_display = gr.Markdown("")
795
 
796
- # Tabs are inside main_app so they're hidden initially
797
- with gr.Tabs(elem_id="main_tabs") as tabs:
798
- # LEARNING MODE TAB
799
- with gr.Tab("📚 Learning Mode", elem_id="tab_learning"):
800
- # Search and examples at the top
801
- with gr.Row():
802
- query_input = gr.Textbox(
803
- label="Ask an Anatomy Question",
804
- placeholder="e.g., Show me the Circle of Willis",
805
- lines=2
806
- )
807
-
808
- # Examples
809
- gr.Examples(
810
- examples=[
811
- ["Show me the Circle of Willis"],
812
- ["Brachial plexus anatomy"],
 
 
 
 
 
813
  ["Carpal bones arrangement"],
814
  ["Layers of the scalp"],
815
  ["Anatomy of the heart chambers"],
@@ -841,17 +846,17 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
841
  with gr.Column(scale=1):
842
  image_output = gr.Image(label="🖼️ Anatomy Diagram", type="pil")
843
 
844
- # VIVA MODE TAB (Defined before Book Mode to allow component access)
845
- with gr.Tab("🎯 VIVA Training Mode", elem_id="tab_viva") as viva_tab:
846
- viva_status = gr.Markdown("Click 'Start VIVA Training' from Learning Mode after studying a topic!")
847
 
848
- # Additional greeting component (initially hidden)
849
- viva_greeting = gr.Markdown("", visible=False)
850
 
851
- with gr.Column(visible=False) as viva_container:
852
- with gr.Row():
853
- with gr.Column(scale=1):
854
- viva_image = gr.Image(label="Reference Image", type="pil", interactive=False)
855
 
856
  with gr.Column(scale=2):
857
  current_question_display = gr.Markdown("### Question will appear here")
@@ -870,132 +875,115 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
870
 
871
  feedback_display = gr.Markdown("Feedback will appear here after you submit your answer")
872
 
873
- # BOOK LEARNING MODE TAB
874
- with gr.Tab("📖 Book Learning Mode", elem_id="tab_book") as book_tab:
875
- # Upload PDF
876
- pdf_upload = gr.File(label="Upload Anatomy Textbook (PDF)", file_types=[".pdf"], type="binary")
877
- upload_status = gr.Markdown()
878
 
879
- # State to hold extracted images, captions, and text
880
- book_images_state = gr.State([])
881
- page_captions_state = gr.State([])
882
- page_texts_state = gr.State([])
883
 
884
- # Dropdown to select a page after processing
885
- page_dropdown = gr.Dropdown(label="Select Page", choices=[], interactive=False)
886
 
887
- # Display selected page image
888
- selected_page_image = gr.Image(label="Selected Page", type="pil")
889
 
890
- # Analysis output
891
- analysis_output = gr.Markdown(label="Page Analysis")
892
 
893
- # Button to start VIVA from this page
894
- start_viva_book_btn = gr.Button("🎯 Start VIVA Training from this Page", variant="primary", visible=False)
895
 
896
- # Process upload
897
- def handle_book_upload(pdf_bytes):
898
- extracted_data, status_msg = process_uploaded_book(pdf_bytes)
899
- if not extracted_data:
900
- # No data extracted
901
- return [], status_msg, [], [], gr.update(choices=[], interactive=False), None, ""
902
 
903
- # Separate images, captions, and text
904
- img_list = [item[0] for item in extracted_data]
905
- caps = [item[1] for item in extracted_data]
906
- texts = [item[2] for item in extracted_data]
907
 
908
- # Update dropdown with captions and enable it
909
- dropdown_update = gr.update(choices=caps, interactive=True)
910
- return img_list, status_msg, caps, texts, dropdown_update, None, ""
911
 
912
- pdf_upload.upload(
913
- fn=handle_book_upload,
914
- inputs=[pdf_upload],
915
- outputs=[book_images_state, upload_status, page_captions_state, page_texts_state, page_dropdown, selected_page_image, analysis_output]
916
- )
917
 
918
- # When a page is selected, show image and analysis
919
- def show_page_analysis(selected_caption, images, captions, texts):
920
- if not selected_caption:
921
- return None, ""
922
- # Find index
923
- try:
924
- idx = captions.index(selected_caption)
925
- except ValueError:
926
- return None, ""
927
 
928
- img = images[idx]
929
- text = texts[idx] if idx < len(texts) else ""
930
 
931
- analysis = analyze_book_image(img, selected_caption, text)
932
 
933
- # Construct a topic string for VIVA
934
- viva_topic = f"Anatomy of {selected_caption} (from textbook)"
935
 
936
- return img, analysis, viva_topic, gr.update(visible=True)
937
-
938
- # Hidden state to store current page topic for VIVA
939
- current_book_topic = gr.State("")
940
 
941
- page_dropdown.change(
942
- fn=show_page_analysis,
943
- inputs=[page_dropdown, book_images_state, page_captions_state, page_texts_state],
944
- outputs=[selected_page_image, analysis_output, current_book_topic, start_viva_book_btn]
945
- )
946
 
947
- # Start VIVA from Book Mode - Use pre-collected name
948
- start_viva_book_btn.click(
949
- fn=lambda name, topic, image: start_viva_with_name(name, topic, image),
950
- inputs=[student_name_state, current_book_topic, selected_page_image],
951
- outputs=[
952
- viva_container, viva_status, viva_image,
953
- current_question_display, hint_display,
954
- student_answer, feedback_display, submit_answer_btn,
955
- viva_questions_state,
956
- question_audio, viva_greeting, student_name_state
957
- ]
958
- ).then(
959
- fn=lambda: gr.update(selected=1), # Switch to VIVA tab
960
- outputs=[tabs]
961
- ).then(
962
- fn=lambda: 0,
963
- outputs=[current_question_idx]
964
  )
 
 
965
 
966
- # ADMIN PANEL TAB
967
- with gr.Tab("🔐 Admin Panel", elem_id="tab_admin") as admin_tab:
968
- gr.Markdown("## Admin Panel - Student Database")
969
- gr.Markdown("Enter the admin password to view registered students.")
970
 
971
- # Password input
972
- with gr.Row():
973
- admin_password_input = gr.Textbox(
974
- label="Admin Password",
975
- placeholder="Enter admin password",
976
- type="password",
977
- scale=2
978
- )
979
- admin_login_btn = gr.Button("🔓 Login", variant="primary", scale=1)
980
 
981
- admin_status = gr.Markdown("")
982
 
983
- # Admin content (hidden until authenticated)
984
- with gr.Column(visible=False) as admin_content:
985
- gr.Markdown("### 📊 Registered Students")
986
 
987
- admin_stats = gr.Markdown("")
988
 
989
- with gr.Row():
990
- refresh_btn = gr.Button("🔄 Refresh Data", variant="secondary")
991
- logout_btn = gr.Button("🚪 Logout", variant="secondary")
992
 
993
- students_table = gr.Dataframe(
994
- headers=["ID", "Name", "Medical School", "Year", "Registration Date"],
995
- label="Students Database",
996
- interactive=False,
997
- wrap=True
998
- )
999
 
1000
  # Registration Modal Popup (shown on first load)
1001
  with gr.Column(visible=True, elem_id="registration_modal") as registration_modal:
@@ -1035,6 +1023,58 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
1035
 
1036
  # Event Handlers
1037
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1038
  # Welcome Screen Handler (now for modal)
1039
  def handle_modal_submit(name, medical_school, year):
1040
  """Handle registration modal submission."""
@@ -1099,8 +1139,11 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
1099
  student_name_state # Return student name (unchanged)
1100
  ]
1101
  ).then(
1102
- fn=lambda: gr.update(selected=1), # Switch to VIVA tab
1103
- outputs=[tabs]
 
 
 
1104
  ).then(
1105
  fn=lambda: gr.update(value="🎯 Start VIVA Training", interactive=True), # Reset button
1106
  outputs=[start_viva_btn]
@@ -1180,6 +1223,28 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
1180
  outputs=[admin_stats, students_table]
1181
  )
1182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1183
  if __name__ == "__main__":
1184
  # Check if API keys are configured
1185
  if not SERPAPI_KEY or SERPAPI_KEY == "your_serpapi_key_here":
 
793
  # Display student name
794
  student_name_display = gr.Markdown("")
795
 
796
+ # Custom Navigation Bar
797
+ with gr.Row(elem_id="nav_bar"):
798
+ nav_learning_btn = gr.Button("📚 Learning Mode", variant="primary", scale=1)
799
+ nav_viva_btn = gr.Button("🎯 VIVA Training Mode", variant="secondary", scale=1)
800
+ nav_book_btn = gr.Button("📖 Book Learning Mode", variant="secondary", scale=1)
801
+ nav_admin_btn = gr.Button("🔐 Admin Panel", variant="secondary", scale=1)
802
+
803
+ # LEARNING MODE COLUMN
804
+ with gr.Column(visible=True, elem_id="learning_col") as learning_col:
805
+ # Search and examples at the top
806
+ with gr.Row():
807
+ query_input = gr.Textbox(
808
+ label="Ask an Anatomy Question",
809
+ placeholder="e.g., Show me the Circle of Willis",
810
+ lines=2
811
+ )
812
+
813
+ # Examples
814
+ gr.Examples(
815
+ examples=[
816
+ ["Show me the Circle of Willis"],
817
+ ["Brachial plexus anatomy"],
818
  ["Carpal bones arrangement"],
819
  ["Layers of the scalp"],
820
  ["Anatomy of the heart chambers"],
 
846
  with gr.Column(scale=1):
847
  image_output = gr.Image(label="🖼️ Anatomy Diagram", type="pil")
848
 
849
+ # VIVA MODE COLUMN
850
+ with gr.Column(visible=False, elem_id="viva_col") as viva_col:
851
+ viva_status = gr.Markdown("Click 'Start VIVA Training' from Learning Mode after studying a topic!")
852
 
853
+ # Additional greeting component (initially hidden)
854
+ viva_greeting = gr.Markdown("", visible=False)
855
 
856
+ with gr.Column(visible=False) as viva_container:
857
+ with gr.Row():
858
+ with gr.Column(scale=1):
859
+ viva_image = gr.Image(label="Reference Image", type="pil", interactive=False)
860
 
861
  with gr.Column(scale=2):
862
  current_question_display = gr.Markdown("### Question will appear here")
 
875
 
876
  feedback_display = gr.Markdown("Feedback will appear here after you submit your answer")
877
 
878
+ # BOOK LEARNING MODE COLUMN
879
+ with gr.Column(visible=False, elem_id="book_col") as book_col:
880
+ # Upload PDF
881
+ pdf_upload = gr.File(label="Upload Anatomy Textbook (PDF)", file_types=[".pdf"], type="binary")
882
+ upload_status = gr.Markdown()
883
 
884
+ # State to hold extracted images, captions, and text
885
+ book_images_state = gr.State([])
886
+ page_captions_state = gr.State([])
887
+ page_texts_state = gr.State([])
888
 
889
+ # Dropdown to select a page after processing
890
+ page_dropdown = gr.Dropdown(label="Select Page", choices=[], interactive=False)
891
 
892
+ # Display selected page image
893
+ selected_page_image = gr.Image(label="Selected Page", type="pil")
894
 
895
+ # Analysis output
896
+ analysis_output = gr.Markdown(label="Page Analysis")
897
 
898
+ # Button to start VIVA from this page
899
+ start_viva_book_btn = gr.Button("🎯 Start VIVA Training from this Page", variant="primary", visible=False)
900
 
901
+ # Process upload
902
+ def handle_book_upload(pdf_bytes):
903
+ extracted_data, status_msg = process_uploaded_book(pdf_bytes)
904
+ if not extracted_data:
905
+ # No data extracted
906
+ return [], status_msg, [], [], gr.update(choices=[], interactive=False), None, ""
907
 
908
+ # Separate images, captions, and text
909
+ img_list = [item[0] for item in extracted_data]
910
+ caps = [item[1] for item in extracted_data]
911
+ texts = [item[2] for item in extracted_data]
912
 
913
+ # Update dropdown with captions and enable it
914
+ dropdown_update = gr.update(choices=caps, interactive=True)
915
+ return img_list, status_msg, caps, texts, dropdown_update, None, ""
916
 
917
+ pdf_upload.upload(
918
+ fn=handle_book_upload,
919
+ inputs=[pdf_upload],
920
+ outputs=[book_images_state, upload_status, page_captions_state, page_texts_state, page_dropdown, selected_page_image, analysis_output]
921
+ )
922
 
923
+ # When a page is selected, show image and analysis
924
+ def show_page_analysis(selected_caption, images, captions, texts):
925
+ if not selected_caption:
926
+ return None, ""
927
+ # Find index
928
+ try:
929
+ idx = captions.index(selected_caption)
930
+ except ValueError:
931
+ return None, ""
932
 
933
+ img = images[idx]
934
+ text = texts[idx] if idx < len(texts) else ""
935
 
936
+ analysis = analyze_book_image(img, selected_caption, text)
937
 
938
+ # Construct a topic string for VIVA
939
+ viva_topic = f"Anatomy of {selected_caption} (from textbook)"
940
 
941
+ return img, analysis, viva_topic, gr.update(visible=True)
 
 
 
942
 
943
+ # Hidden state to store current page topic for VIVA
944
+ current_book_topic = gr.State("")
 
 
 
945
 
946
+ page_dropdown.change(
947
+ fn=show_page_analysis,
948
+ inputs=[page_dropdown, book_images_state, page_captions_state, page_texts_state],
949
+ outputs=[selected_page_image, analysis_output, current_book_topic, start_viva_book_btn]
 
 
 
 
 
 
 
 
 
 
 
 
 
950
  )
951
+
952
+ # Start VIVA from Book Mode handler moved to end of file to resolve NameError
953
 
954
+ # ADMIN PANEL COLUMN
955
+ with gr.Column(visible=False, elem_id="admin_col") as admin_col:
956
+ gr.Markdown("## Admin Panel - Student Database")
957
+ gr.Markdown("Enter the admin password to view registered students.")
958
 
959
+ # Password input
960
+ with gr.Row():
961
+ admin_password_input = gr.Textbox(
962
+ label="Admin Password",
963
+ placeholder="Enter admin password",
964
+ type="password",
965
+ scale=2
966
+ )
967
+ admin_login_btn = gr.Button("🔓 Login", variant="primary", scale=1)
968
 
969
+ admin_status = gr.Markdown("")
970
 
971
+ # Admin content (hidden until authenticated)
972
+ with gr.Column(visible=False) as admin_content:
973
+ gr.Markdown("### 📊 Registered Students")
974
 
975
+ admin_stats = gr.Markdown("")
976
 
977
+ with gr.Row():
978
+ refresh_btn = gr.Button("🔄 Refresh Data", variant="secondary")
979
+ logout_btn = gr.Button("🚪 Logout", variant="secondary")
980
 
981
+ students_table = gr.Dataframe(
982
+ headers=["ID", "Name", "Medical School", "Year", "Registration Date"],
983
+ label="Students Database",
984
+ interactive=False,
985
+ wrap=True
986
+ )
987
 
988
  # Registration Modal Popup (shown on first load)
989
  with gr.Column(visible=True, elem_id="registration_modal") as registration_modal:
 
1023
 
1024
  # Event Handlers
1025
 
1026
+ # Navigation Logic
1027
+ def navigate(nav_target):
1028
+ """Handle navigation between views."""
1029
+ # Returns: learning_col, viva_col, book_col, admin_col
1030
+ # Also returns button variants: learning_btn, viva_btn, book_btn, admin_btn
1031
+
1032
+ if nav_target == "learning":
1033
+ return (
1034
+ gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
1035
+ gr.update(variant="primary"), gr.update(variant="secondary"), gr.update(variant="secondary"), gr.update(variant="secondary")
1036
+ )
1037
+ elif nav_target == "viva":
1038
+ return (
1039
+ gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False),
1040
+ gr.update(variant="secondary"), gr.update(variant="primary"), gr.update(variant="secondary"), gr.update(variant="secondary")
1041
+ )
1042
+ elif nav_target == "book":
1043
+ return (
1044
+ gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False),
1045
+ gr.update(variant="secondary"), gr.update(variant="secondary"), gr.update(variant="primary"), gr.update(variant="secondary")
1046
+ )
1047
+ elif nav_target == "admin":
1048
+ return (
1049
+ gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True),
1050
+ gr.update(variant="secondary"), gr.update(variant="secondary"), gr.update(variant="secondary"), gr.update(variant="primary")
1051
+ )
1052
+ return (
1053
+ gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
1054
+ gr.update(variant="primary"), gr.update(variant="secondary"), gr.update(variant="secondary"), gr.update(variant="secondary")
1055
+ )
1056
+
1057
+ # Bind Navigation Buttons
1058
+ nav_learning_btn.click(
1059
+ fn=lambda: navigate("learning"),
1060
+ outputs=[learning_col, viva_col, book_col, admin_col, nav_learning_btn, nav_viva_btn, nav_book_btn, nav_admin_btn]
1061
+ )
1062
+
1063
+ nav_viva_btn.click(
1064
+ fn=lambda: navigate("viva"),
1065
+ outputs=[learning_col, viva_col, book_col, admin_col, nav_learning_btn, nav_viva_btn, nav_book_btn, nav_admin_btn]
1066
+ )
1067
+
1068
+ nav_book_btn.click(
1069
+ fn=lambda: navigate("book"),
1070
+ outputs=[learning_col, viva_col, book_col, admin_col, nav_learning_btn, nav_viva_btn, nav_book_btn, nav_admin_btn]
1071
+ )
1072
+
1073
+ nav_admin_btn.click(
1074
+ fn=lambda: navigate("admin"),
1075
+ outputs=[learning_col, viva_col, book_col, admin_col, nav_learning_btn, nav_viva_btn, nav_book_btn, nav_admin_btn]
1076
+ )
1077
+
1078
  # Welcome Screen Handler (now for modal)
1079
  def handle_modal_submit(name, medical_school, year):
1080
  """Handle registration modal submission."""
 
1139
  student_name_state # Return student name (unchanged)
1140
  ]
1141
  ).then(
1142
+ fn=lambda: (gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)),
1143
+ outputs=[learning_col, viva_col, book_col, admin_col]
1144
+ ).then(
1145
+ fn=lambda: (gr.update(variant="secondary"), gr.update(variant="primary"), gr.update(variant="secondary"), gr.update(variant="secondary")),
1146
+ outputs=[nav_learning_btn, nav_viva_btn, nav_book_btn, nav_admin_btn]
1147
  ).then(
1148
  fn=lambda: gr.update(value="🎯 Start VIVA Training", interactive=True), # Reset button
1149
  outputs=[start_viva_btn]
 
1223
  outputs=[admin_stats, students_table]
1224
  )
1225
 
1226
+ # Start VIVA from Book Mode - Use pre-collected name (Moved here to ensure all columns are defined)
1227
+ start_viva_book_btn.click(
1228
+ fn=lambda name, topic, image: start_viva_with_name(name, topic, image),
1229
+ inputs=[student_name_state, current_book_topic, selected_page_image],
1230
+ outputs=[
1231
+ viva_container, viva_status, viva_image,
1232
+ current_question_display, hint_display,
1233
+ student_answer, feedback_display, submit_answer_btn,
1234
+ viva_questions_state,
1235
+ question_audio, viva_greeting, student_name_state
1236
+ ]
1237
+ ).then(
1238
+ fn=lambda: (gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)),
1239
+ outputs=[learning_col, viva_col, book_col, admin_col]
1240
+ ).then(
1241
+ fn=lambda: (gr.update(variant="secondary"), gr.update(variant="primary"), gr.update(variant="secondary"), gr.update(variant="secondary")),
1242
+ outputs=[nav_learning_btn, nav_viva_btn, nav_book_btn, nav_admin_btn]
1243
+ ).then(
1244
+ fn=lambda: 0,
1245
+ outputs=[current_question_idx]
1246
+ )
1247
+
1248
  if __name__ == "__main__":
1249
  # Check if API keys are configured
1250
  if not SERPAPI_KEY or SERPAPI_KEY == "your_serpapi_key_here":