Ashmi Banerjee commited on
Commit
0759822
·
1 Parent(s): 90cb4f4

updated with resuming surveys:

Browse files
Files changed (8) hide show
  1. README.md +2 -1
  2. app.py +56 -92
  3. db/crud.py +37 -15
  4. db/setup.py +5 -1
  5. views/continue_survey.py +57 -0
  6. views/intro_screen.py +18 -12
  7. views/nav_buttons.py +25 -20
  8. views/questions_screen.py +142 -125
README.md CHANGED
@@ -26,4 +26,5 @@ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-
26
  [ ] Implement questions with proper buttons (with text)
27
  [ ] Back button
28
  [ ] Dataset linking
29
- [ ] prettify the context field with new lines and highlighting popularity etc. keywords in bold
 
 
26
  [ ] Implement questions with proper buttons (with text)
27
  [ ] Back button
28
  [ ] Dataset linking
29
+ [ ] prettify the context field with new lines and highlighting popularity etc. keywords in bold
30
+ [ ] Doing it for two models
app.py CHANGED
@@ -2,83 +2,44 @@ import json
2
  from typing import Dict
3
 
4
  from db.schema import Feedback, Response
5
- from db.crud import ingest, read
6
  import pandas as pd
7
  import streamlit as st
8
  from datetime import datetime
9
  import os
10
  from dotenv import load_dotenv
11
- from views.intro_screen import username_screen
12
- from views.questions_screen import new_questions_screen
 
13
  from css.layout import custom_css
14
 
15
  load_dotenv()
16
  VALIDATION_CODE = os.getenv("VALIDATION_CODE")
17
 
18
 
19
- class SurveyState:
20
- """Class to handle survey state management"""
21
-
22
- def __init__(self):
23
- pass
24
-
25
- def save_state(self, prolific_id: str, current_state: Dict) -> None:
26
- """Save current state to Firebase"""
27
- try:
28
- # Saving to Firebase via the ingest function
29
- feedback = Feedback(user_id=prolific_id, time_stamp=datetime.now().isoformat(),
30
- responses=current_state["responses"])
31
- ingest(feedback) # Ingest feedback to Firebase
32
- st.success("Your progress has been saved! You can continue later.")
33
- except Exception as e:
34
- st.error(f"Error saving state to Firebase: {e}")
35
-
36
- def load_state(self, prolific_id: str) -> Dict:
37
- """Load state for a specific user from Firebase"""
38
- try:
39
- # Retrieve the state from Firebase for the given Prolific ID
40
- state = self.get_state_from_firebase(prolific_id)
41
- if state:
42
- return state
43
- except Exception as e:
44
- st.error(f"Error loading state from Firebase: {e}")
45
- return {}
46
-
47
- class SurveyState:
48
- """Class to handle survey state management"""
49
-
50
- def __init__(self):
51
- pass
52
-
53
- @staticmethod
54
- def save_state(self, username: str, current_state: Dict) -> None:
55
- """Save current state to Firebase"""
56
- try:
57
- # Saving to Firebase via the ingest function
58
- feedback = Feedback(user_id=username, time_stamp=datetime.now().isoformat(),
59
- responses=current_state["responses"])
60
- ingest(feedback) # Ingest feedback to Firebase
61
- st.success("Your progress has been saved! You can continue later.")
62
- except Exception as e:
63
- st.error(f"Error saving state to Firebase: {e}")
64
-
65
- def load_state(self, username: str) -> Dict:
66
- """Load state for a specific user from Firebase"""
67
- try:
68
- # Retrieve the state from Firebase for the given Prolific ID
69
- state = self.get_state_from_firebase(username)
70
- if state:
71
- return state
72
- except Exception as e:
73
- st.error(f"Error loading state from Firebase: {e}")
74
- return {}
75
-
76
- def get_state_from_firebase(self, username: str) -> Dict:
77
- # Placeholder method to simulate getting state from Firebase
78
- # In practice, you will query Firebase to get the current state
79
- data = read(username)
80
- return {}
81
-
82
 
83
  def initialization():
84
  """Initialize session state variables."""
@@ -90,8 +51,14 @@ def initialization():
90
  st.session_state.responses = []
91
  if "completed" not in st.session_state:
92
  st.session_state.completed = False
93
- if "survey_state" not in st.session_state:
94
- st.session_state.survey_state = SurveyState()
 
 
 
 
 
 
95
 
96
 
97
  def exit_screen():
@@ -109,45 +76,42 @@ def exit_screen():
109
  st.rerun()
110
 
111
 
112
- def submit_survey():
113
- """Submit the complete survey"""
114
- try:
115
- feedback = Feedback(
116
- id=st.session_state.current_index,
117
- user_id=st.session_state.username,
118
- time_stamp=datetime.now().isoformat(),
119
- responses=st.session_state.responses,
120
- )
121
- print(feedback)
122
- ingest(feedback)
123
- st.session_state.completed = True
124
- st.rerun()
125
- except Exception as e:
126
- st.error(f"An error occurred while submitting feedback: {e}")
127
-
128
-
129
  def reset_survey():
130
  """Reset the survey state to start over."""
131
- st.session_state.username = None
132
- st.session_state.current_index = 0
133
  st.session_state.responses = []
134
- st.session_state.completed = False
 
135
 
136
 
137
  def ui():
138
  """Main function to control the survey flow."""
139
  custom_css()
140
- data = pd.read_csv("data/gemini_results_subset.csv")[:3]
141
  initialization()
142
 
143
- if st.session_state.completed:
144
  exit_screen()
145
  return
146
 
147
  if st.session_state.username is None:
148
- username_screen()
149
  else:
150
- new_questions_screen(data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
 
153
  if __name__ == "__main__":
 
2
  from typing import Dict
3
 
4
  from db.schema import Feedback, Response
5
+ from db.crud import ingest, read, save_feedback
6
  import pandas as pd
7
  import streamlit as st
8
  from datetime import datetime
9
  import os
10
  from dotenv import load_dotenv
11
+ from views.intro_screen import welcome_screen
12
+ from views.questions_screen import questions_screen, survey_completed
13
+ from views.continue_survey import continue_survey_screen
14
  from css.layout import custom_css
15
 
16
  load_dotenv()
17
  VALIDATION_CODE = os.getenv("VALIDATION_CODE")
18
 
19
 
20
+ # class SurveyState:
21
+ # """Class to handle survey state management"""
22
+ #
23
+ # def __init__(self):
24
+ # pass
25
+ #
26
+ # def save_state(self, username: str, current_state: Dict) -> None:
27
+ # """Save current state to Firebase"""
28
+ # try:
29
+ # """Handles feedback submission to the database."""
30
+ # feedback = Feedback(
31
+ # id=st.session_state.current_index + 1,
32
+ # user_id=st.session_state.username,
33
+ # time_stamp=datetime.now().isoformat(),
34
+ # responses=st.session_state.responses,
35
+ # )
36
+ # save_feedback(feedback)
37
+ # st.success("Your progress has been saved! You can continue later.")
38
+ # st.session_state.completed = True
39
+ # st.rerun()
40
+ # except Exception as e:
41
+ # st.error(f"An error occurred while submitting feedback: {e}")
42
+ #
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  def initialization():
45
  """Initialize session state variables."""
 
51
  st.session_state.responses = []
52
  if "completed" not in st.session_state:
53
  st.session_state.completed = False
54
+ if "show_questions" not in st.session_state:
55
+ st.session_state.show_questions = False
56
+ if "survey_continued" not in st.session_state:
57
+ st.session_state.survey_continued = None
58
+ if "start_new_survey" not in st.session_state:
59
+ st.session_state.start_new_survey = False
60
+ # if "survey_state" not in st.session_state:
61
+ # st.session_state.survey_state = SurveyState()
62
 
63
 
64
  def exit_screen():
 
76
  st.rerun()
77
 
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  def reset_survey():
80
  """Reset the survey state to start over."""
 
 
81
  st.session_state.responses = []
82
+ st.session_state.completed = True #TODO: Change to False?
83
+ st.session_state.start_new_survey = True
84
 
85
 
86
  def ui():
87
  """Main function to control the survey flow."""
88
  custom_css()
89
+ data = pd.read_csv("data/gemini_results_subset.csv")[:5]
90
  initialization()
91
 
92
+ if st.session_state.completed and not st.session_state.start_new_survey:
93
  exit_screen()
94
  return
95
 
96
  if st.session_state.username is None:
97
+ welcome_screen()
98
  else:
99
+ # Check if user progress exists in Firebase
100
+ saved_state = read(st.session_state.username)
101
+ if saved_state:
102
+ # If there's saved progress and the survey has not been continued, show continue screen
103
+ if "survey_continued" not in st.session_state or not st.session_state.survey_continued:
104
+ continue_survey_screen(data)
105
+ else:
106
+ if st.session_state.current_index >= len(data):
107
+ # If all questions have been answered, show the exit screen
108
+ print("survey completed")
109
+ survey_completed()
110
+ # Otherwise, show questions from where they left off
111
+ questions_screen(data)
112
+ else:
113
+ # If no saved progress (new user), start with the questions screen
114
+ questions_screen(data)
115
 
116
 
117
  if __name__ == "__main__":
db/crud.py CHANGED
@@ -8,32 +8,44 @@ from db.setup import db_setup
8
  def ingest(data: Feedback):
9
  ref = db_setup() # Ensure Firebase is initialized
10
  print(f"Attempting to ingest feedback data from user '{data.user_id}'...")
11
- # Check if the user_id already exists in the feedback data
12
- # user_id_str = str(data.user_id)
13
- # existing_feedback = ref.child('feedback').order_by_child('user_id').equal_to(user_id_str).get()
14
- #
15
- #
16
- # # TODO: This should probably change. If the same user has multiple feedbacks, we should allow it. -> change to update
17
- # if existing_feedback:
18
- # print(f"Feedback from user '{data.user_id}' already exists. Ingestion aborted.")
19
- # else:
20
- # # feedback_data = data.dict() # Convert Pydantic model to a dictionary
21
  feedback_data = data.model_dump()
22
  feedback_data["time_stamp"] = feedback_data['time_stamp'].isoformat()
23
  ref.child('feedback').push(feedback_data)
24
  print(f"Feedback data from user '{data.user_id}' pushed to Firebase!")
25
 
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  # Read operation (Fetch feedback data from Firebase)
28
  def read(user_id: str):
 
29
  ref = db_setup()
30
  feedback_ref = ref.child('feedback').order_by_child('user_id').equal_to(user_id).get()
31
 
32
  if feedback_ref:
33
- return feedback_ref
34
- else:
35
- print("Feedback not found!")
36
- return None
37
 
38
 
39
  # Update operation (Update feedback data in Firebase)
@@ -64,6 +76,17 @@ def delete(feedback_id: int):
64
  print("Feedback not found to delete!")
65
 
66
 
 
 
 
 
 
 
 
 
 
 
 
67
  def test():
68
  # Create a feedback object
69
  # feedback = Feedback(
@@ -101,4 +124,3 @@ def test():
101
  #
102
  # # Delete (Remove)
103
  # delete(1)
104
-
 
8
  def ingest(data: Feedback):
9
  ref = db_setup() # Ensure Firebase is initialized
10
  print(f"Attempting to ingest feedback data from user '{data.user_id}'...")
 
 
 
 
 
 
 
 
 
 
11
  feedback_data = data.model_dump()
12
  feedback_data["time_stamp"] = feedback_data['time_stamp'].isoformat()
13
  ref.child('feedback').push(feedback_data)
14
  print(f"Feedback data from user '{data.user_id}' pushed to Firebase!")
15
 
16
 
17
+ def save_feedback(data: Feedback):
18
+ ref = db_setup() # Ensure Firebase is initialized
19
+ print(f"Processing feedback for user '{data.user_id}'...")
20
+
21
+ # Convert Pydantic model to dictionary
22
+ feedback_data = data.model_dump()
23
+ feedback_data["time_stamp"] = feedback_data["time_stamp"].isoformat()
24
+
25
+ # Check if the user already has feedback
26
+ existing_feedback = ref.child("feedback").order_by_child("user_id").equal_to(data.user_id).get()
27
+
28
+ if existing_feedback:
29
+ # Update existing feedback
30
+ for key in existing_feedback:
31
+ ref.child("feedback").child(key).update(feedback_data)
32
+ print(f"Feedback updated for user '{data.user_id}'!")
33
+ else:
34
+ # Insert new feedback
35
+ ref.child("feedback").push(feedback_data)
36
+ print(f"(Ingestion) New feedback added for user '{data.user_id}'!")
37
+
38
+
39
  # Read operation (Fetch feedback data from Firebase)
40
  def read(user_id: str):
41
+ """Fetch feedback data for a specific user from Firebase."""
42
  ref = db_setup()
43
  feedback_ref = ref.child('feedback').order_by_child('user_id').equal_to(user_id).get()
44
 
45
  if feedback_ref:
46
+ for key, value in feedback_ref.items():
47
+ return value # Return the first found entry
48
+ return None # No progress found
 
49
 
50
 
51
  # Update operation (Update feedback data in Firebase)
 
76
  print("Feedback not found to delete!")
77
 
78
 
79
+ def reset_feedback_in_db(user_id: str):
80
+ """Deletes previous feedback for a user, resetting progress in Firebase."""
81
+ ref = db_setup()
82
+ feedback_ref = ref.child('feedback').order_by_child('user_id').equal_to(user_id).get()
83
+
84
+ if feedback_ref:
85
+ for key in feedback_ref:
86
+ ref.child('feedback').child(key).delete()
87
+ print(f"Feedback data for user '{user_id}' reset in Firebase.")
88
+
89
+
90
  def test():
91
  # Create a feedback object
92
  # feedback = Feedback(
 
124
  #
125
  # # Delete (Remove)
126
  # delete(1)
 
db/setup.py CHANGED
@@ -34,6 +34,10 @@ def initialize_firebase():
34
 
35
 
36
  def db_setup():
37
- initialize_firebase()
 
 
 
 
38
  ref = db.reference('/')
39
  return ref
 
34
 
35
 
36
  def db_setup():
37
+ try:
38
+ initialize_firebase()
39
+ except Exception as e:
40
+ print(f"Error initializing Firebase: {e}")
41
+ firebase_admin.get_app()
42
  ref = db.reference('/')
43
  return ref
views/continue_survey.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from db.crud import read, reset_feedback_in_db
3
+ from views.questions_screen import questions_screen
4
+
5
+
6
+ def continue_survey_screen(data):
7
+ """Screen for existing users to continue or restart their survey."""
8
+ st.title("Resume Your Survey")
9
+
10
+ st.write("Welcome back! Would you like to continue from where you left off or restart the survey?")
11
+
12
+ # Fetch user progress from Firebase
13
+ saved_state = read(st.session_state.username)
14
+
15
+ col1, col2 = st.columns(2)
16
+
17
+ with col1:
18
+ if st.button("Continue"):
19
+ if saved_state:
20
+ # Set session state values based on saved progress
21
+ st.session_state.current_index = saved_state.get("current_index", 0)
22
+ st.session_state.responses = saved_state.get("responses", [])
23
+
24
+ # Find the last answered config_id in responses
25
+ last_config_id = None
26
+ if st.session_state.responses:
27
+ last_config_id = st.session_state.responses[-1].get("config_id")
28
+
29
+ # Set the index to the matching config_id
30
+ if last_config_id is not None:
31
+ matching_index = data[data["config_id"] == last_config_id].index
32
+ if not matching_index.empty:
33
+ st.session_state.current_index = matching_index[0]+1
34
+
35
+ st.success("Resuming your survey!")
36
+ # Set survey_continued flag to True only when there's saved progress
37
+ st.session_state.survey_continued = True
38
+ print(st.session_state.current_index)
39
+ st.rerun()
40
+ # questions_screen(data)
41
+
42
+ else:
43
+ st.warning("No previous progress found. Starting a new survey.")
44
+ st.session_state.current_index = 0
45
+ st.session_state.responses = []
46
+
47
+ with col2:
48
+ if st.button("Restart"):
49
+ st.session_state.current_index = 0
50
+ st.session_state.responses = []
51
+ st.success("Survey restarted!")
52
+
53
+ # Reset Firebase data for the user
54
+ reset_feedback_in_db(st.session_state.username)
55
+
56
+ st.rerun()
57
+
views/intro_screen.py CHANGED
@@ -1,6 +1,8 @@
1
  import streamlit as st
2
  import os
3
  from dotenv import load_dotenv
 
 
4
 
5
  load_dotenv()
6
  VALIDATION_CODE = os.getenv("VALIDATION_CODE")
@@ -15,28 +17,32 @@ def validate_code(input_code: str) -> bool:
15
  return input_code.strip() == VALIDATION_CODE
16
 
17
 
18
- def username_screen():
19
- """Display the Prolific ID entry screen."""
20
  st.title("Welcome to the Feedback Survey")
21
 
22
  username_input = st.text_input("Enter your First name and press TAB:")
23
  validation_code_input = st.text_input("Enter the validation code to proceed and press ENTER:")
24
 
25
  next_button = st.button("Next")
 
26
  if (username_input and validation_code_input) or next_button:
27
- # Validate Prolific ID and code
28
  if validate_username(username_input) and validate_code(validation_code_input):
29
  st.session_state.username = username_input
30
 
31
- # Load previous state if exists
32
- saved_state = st.session_state.survey_state.load_state(username_input)
33
- if saved_state:
34
- st.session_state.current_index = saved_state.get('current_index', 0)
35
- st.session_state.responses = saved_state.get('responses', [])
36
- st.success("Previous progress loaded! Continuing from where you left off.")
37
- else:
38
- st.success("Prolific ID and code validated! Starting new survey.")
39
- st.rerun()
 
 
 
 
40
  else:
41
  if not validate_username(username_input):
42
  st.warning("Invalid Prolific ID. Please check and try again.")
 
1
  import streamlit as st
2
  import os
3
  from dotenv import load_dotenv
4
+ from views.continue_survey import continue_survey_screen
5
+ from db.crud import read
6
 
7
  load_dotenv()
8
  VALIDATION_CODE = os.getenv("VALIDATION_CODE")
 
17
  return input_code.strip() == VALIDATION_CODE
18
 
19
 
20
+ def welcome_screen():
21
+ """Display the welcome screen and direct users accordingly."""
22
  st.title("Welcome to the Feedback Survey")
23
 
24
  username_input = st.text_input("Enter your First name and press TAB:")
25
  validation_code_input = st.text_input("Enter the validation code to proceed and press ENTER:")
26
 
27
  next_button = st.button("Next")
28
+
29
  if (username_input and validation_code_input) or next_button:
 
30
  if validate_username(username_input) and validate_code(validation_code_input):
31
  st.session_state.username = username_input
32
 
33
+ # # Check if user progress exists in Firebase
34
+ # saved_state = read(username_input)
35
+ #
36
+ # if saved_state:
37
+ # # Show continue survey screen for returning users
38
+ # st.success("Previous progress found.")
39
+ # continue_survey_screen()
40
+ # else:
41
+ # # Start fresh for new users
42
+ # st.success("Starting a new survey.")
43
+ # st.session_state.current_index = 0
44
+ # st.session_state.responses = []
45
+ # st.rerun()
46
  else:
47
  if not validate_username(username_input):
48
  st.warning("Invalid Prolific ID. Please check and try again.")
views/nav_buttons.py CHANGED
@@ -1,9 +1,5 @@
1
- import json
2
- from typing import Dict
3
-
4
- from db.schema import Feedback, Response
5
- from db.crud import ingest, read
6
- import pandas as pd
7
  import streamlit as st
8
  from datetime import datetime
9
  import os
@@ -12,7 +8,23 @@ load_dotenv()
12
  VALIDATION_CODE = os.getenv("VALIDATION_CODE")
13
 
14
 
15
- def navigation_buttons(data, rating_v, rating_p0, rating_p1):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  """Display navigation buttons."""
17
  current_index = st.session_state.current_index
18
 
@@ -25,22 +37,15 @@ def navigation_buttons(data, rating_v, rating_p0, rating_p1):
25
 
26
  with col2: # Next button
27
  if st.button("Next"):
28
- if rating_v == 0 or rating_p0 == 0 or rating_p1 == 0:
29
  st.warning("Please provide a rating before proceeding.")
30
  else:
31
  if current_index < len(data) - 1:
32
  st.session_state.current_index += 1
33
  st.rerun()
34
  else:
35
- feedback = Feedback(
36
- id=current_index + 1,
37
- user_id=st.session_state.username,
38
- time_stamp=datetime.now().isoformat(),
39
- responses=st.session_state.responses,
40
- )
41
- try:
42
- ingest(feedback)
43
- st.session_state.completed = True
44
- st.rerun()
45
- except Exception as e:
46
- st.error(f"An error occurred while submitting feedback: {e}")
 
1
+ from db.schema import Feedback
2
+ from db.crud import save_feedback, read
 
 
 
 
3
  import streamlit as st
4
  from datetime import datetime
5
  import os
 
8
  VALIDATION_CODE = os.getenv("VALIDATION_CODE")
9
 
10
 
11
+ def submit_feedback(current_index):
12
+ """Handles feedback submission to the database."""
13
+ feedback = Feedback(
14
+ id=current_index + 1,
15
+ user_id=st.session_state.username,
16
+ time_stamp=datetime.now().isoformat(),
17
+ responses=st.session_state.responses,
18
+ )
19
+ try:
20
+ save_feedback(feedback)
21
+ st.session_state.completed = True
22
+ st.rerun()
23
+ except Exception as e:
24
+ st.error(f"An error occurred while submitting feedback: {e}")
25
+
26
+
27
+ def navigation_buttons(data, ratings_v, ratings_p0, ratings_p1):
28
  """Display navigation buttons."""
29
  current_index = st.session_state.current_index
30
 
 
37
 
38
  with col2: # Next button
39
  if st.button("Next"):
40
+ if any(rating == 0 for rating in [ratings_v, ratings_p0, ratings_p1]):
41
  st.warning("Please provide a rating before proceeding.")
42
  else:
43
  if current_index < len(data) - 1:
44
  st.session_state.current_index += 1
45
  st.rerun()
46
  else:
47
+ submit_feedback(current_index)
48
+
49
+ with col3: # Save & Resume Later button
50
+ if st.button("Exit & Resume Later"):
51
+ submit_feedback(current_index)
 
 
 
 
 
 
 
views/questions_screen.py CHANGED
@@ -12,131 +12,148 @@ load_dotenv()
12
  VALIDATION_CODE = os.getenv("VALIDATION_CODE")
13
 
14
 
15
- def new_questions_screen(data):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  """Display the questions screen with split layout"""
17
  current_index = st.session_state.current_index
18
- config = data.iloc[current_index]
19
-
20
- # Progress bar
21
- progress = (current_index + 1) / len(data)
22
- st.progress(progress)
23
- st.write(f"Question {current_index + 1} of {len(data)}")
24
- st.subheader(f"Config ID: {config['config_id']}")
25
-
26
- # Context information
27
- st.markdown("### Context Information")
28
-
29
- with st.expander("Persona", expanded=True):
30
- st.write(config['persona'])
31
-
32
- with st.expander("Filters & Cities", expanded=True):
33
- st.write("**Filters:**", config['filters'])
34
- st.write("**Cities:**", config['city'])
35
-
36
- with st.expander("Full Context", expanded=False):
37
- st.write(config['context'])
38
-
39
- # Split layout for questions and ratings
40
- col11, col12, col13, col14 = st.columns([1, 1, 1, 1]) # Sub-columns for query ratings
41
- options = [0, 1, 2, 3, 4, 5]
42
-
43
- # Query_v and its ratings
44
- st.markdown("### Query_v")
45
- st.write(config['query_v'])
46
- col_v_1, col_v_2, col_v_3 = st.columns(3)
47
- with col_v_1:
48
- clarity_rating = st.radio("Clarity:", options, key=f"rating_v_clarity_{current_index}")
49
-
50
- with col_v_2:
51
- relevance_rating = st.radio("Relevance:", options, key=f"rating_v_relevance_{current_index}")
52
-
53
- with col_v_3:
54
- coverage_rating = st.radio("Coverage:", options, key=f"rating_v_coverage_{current_index}")
55
-
56
- query_v_ratings = {
57
- "clarity": clarity_rating,
58
- "relevance": relevance_rating,
59
- "coverage": coverage_rating,
60
- }
61
-
62
- # Query_p0 and its ratings
63
- st.markdown("### Query_p0")
64
- st.write(config['query_p0'])
65
- col_p0_1, col_p0_2, col_p0_3, col_p0_4 = st.columns(4)
66
-
67
- with col_p0_1:
68
- clarity_rating = st.radio("Clarity:", options, key=f"rating_p0_clarity_{current_index}")
69
-
70
- with col_p0_2:
71
- relevance_rating = st.radio("Relevance:", options, key=f"rating_p0_relevance_{current_index}")
72
-
73
- with col_p0_3:
74
- coverage_rating = st.radio("Coverage:", options, key=f"rating_p0_coverage_{current_index}")
75
-
76
- with col_p0_4:
77
- persona_alignment_rating = st.radio(
78
- "Persona Alignment:", options=[0, 1, 2, 3, 4], # These are the values
79
- format_func=lambda x: ["N/A", "Not Aligned", "Partially Aligned", "Aligned", "Unclear"][x],
80
- key=f"rating_p0_persona_alignment_{current_index}"
81
- )
82
-
83
- # Collecting the ratings for query_p0
84
- query_p0_ratings = {
85
- "clarity": clarity_rating,
86
- "relevance": relevance_rating,
87
- "coverage": coverage_rating,
88
- "persona_alignment": persona_alignment_rating
89
- }
90
-
91
- # Query_p1 and its ratings
92
- st.markdown("### Query_p1")
93
- st.write(config['query_p1'])
94
- # Split the layout into 4 columns for query_p1 ratings
95
- col_p1_1, col_p1_2, col_p1_3, col_p1_4 = st.columns(4)
96
-
97
- with col_p1_1:
98
- clarity_rating_p1 = st.radio("Clarity:", options, key=f"rating_p1_clarity_{current_index}")
99
-
100
- with col_p1_2:
101
- relevance_rating_p1 = st.radio("Relevance:", options, key=f"rating_p1_relevance_{current_index}")
102
-
103
- with col_p1_3:
104
- coverage_rating_p1 = st.radio("Coverage:", options, key=f"rating_p1_coverage_{current_index}")
105
-
106
- with col_p1_4:
107
- persona_alignment_rating_p1 = st.radio(
108
- "Persona Alignment:", options=[0, 1, 2, 3, 4], # These are the values
109
- format_func=lambda x: ["N/A", "Not Aligned", "Partially Aligned", "Aligned", "Unclear"][x],
110
- key=f"rating_p1_persona_alignment_{current_index}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  )
112
-
113
- # Collecting the ratings for query_p1
114
- query_p1_ratings = {
115
- "clarity": clarity_rating_p1,
116
- "relevance": relevance_rating_p1,
117
- "coverage": coverage_rating_p1,
118
- "persona_alignment": persona_alignment_rating_p1
119
- }
120
-
121
- # Additional comments
122
- comment = st.text_area("Additional Comments (Optional):")
123
-
124
- # Collecting the response data
125
- response = Response(
126
- config_id=config["config_id"],
127
- query_v=query_v_ratings, # Use the ratings dictionary for query_v
128
- query_p0=query_p0_ratings, # Use the ratings dictionary for query_p0
129
- query_p1=query_p1_ratings, # Use the ratings dictionary for query_p1
130
- comment=comment,
131
- timestamp=datetime.now().isoformat()
132
- )
133
-
134
- # Storing the response
135
- print(response)
136
- if len(st.session_state.responses) > current_index:
137
- st.session_state.responses[current_index] = response
138
- else:
139
- st.session_state.responses.append(response)
140
-
141
- # Navigation buttons
142
- navigation_buttons(data, query_v_ratings["clarity"], query_p0_ratings["clarity"], query_p1_ratings["clarity"])
 
12
  VALIDATION_CODE = os.getenv("VALIDATION_CODE")
13
 
14
 
15
+ def survey_completed():
16
+ """Display the survey completion message."""
17
+ st.markdown("""
18
+ <div class='exit-container'>
19
+ <h1>You have already completed the survey! Thank you for participating!</h1>
20
+ <p>Your responses have been saved successfully.</p>
21
+ <p>You can safely close this window or start a new survey.</p>
22
+ </div>
23
+ """, unsafe_allow_html=True)
24
+ st.session_state.show_questions = False
25
+ st.session_state.completed = True
26
+ st.session_state.start_new_survey = True
27
+ # st.rerun()
28
+
29
+
30
+ def questions_screen(data):
31
+ # TODO: refactor to avoid code duplication
32
  """Display the questions screen with split layout"""
33
  current_index = st.session_state.current_index
34
+ try:
35
+ config = data.iloc[current_index]
36
+
37
+ # Progress bar
38
+ progress = (current_index + 1) / len(data)
39
+ st.progress(progress)
40
+ st.write(f"Question {current_index + 1} of {len(data)}")
41
+ st.subheader(f"Config ID: {config['config_id']}")
42
+
43
+ # Context information
44
+ st.markdown("### Context Information")
45
+
46
+ with st.expander("Persona", expanded=True):
47
+ st.write(config['persona'])
48
+
49
+ with st.expander("Filters & Cities", expanded=True):
50
+ st.write("**Filters:**", config['filters'])
51
+ st.write("**Cities:**", config['city'])
52
+
53
+ with st.expander("Full Context", expanded=False):
54
+ st.write(config['context'])
55
+
56
+ # Split layout for questions and ratings
57
+ col11, col12, col13, col14 = st.columns([1, 1, 1, 1]) # Sub-columns for query ratings
58
+ options = [0, 1, 2, 3, 4, 5]
59
+
60
+ # Query_v and its ratings
61
+ st.markdown("### Query_v")
62
+ st.write(config['query_v'])
63
+ col_v_1, col_v_2, col_v_3 = st.columns(3)
64
+ with col_v_1:
65
+ clarity_rating = st.radio("Clarity:", options, key=f"rating_v_clarity_{current_index}")
66
+
67
+ with col_v_2:
68
+ relevance_rating = st.radio("Relevance:", options, key=f"rating_v_relevance_{current_index}")
69
+
70
+ with col_v_3:
71
+ coverage_rating = st.radio("Coverage:", options, key=f"rating_v_coverage_{current_index}")
72
+
73
+ query_v_ratings = {
74
+ "clarity": clarity_rating,
75
+ "relevance": relevance_rating,
76
+ "coverage": coverage_rating,
77
+ }
78
+
79
+ # Query_p0 and its ratings
80
+ st.markdown("### Query_p0")
81
+ st.write(config['query_p0'])
82
+ col_p0_1, col_p0_2, col_p0_3, col_p0_4 = st.columns(4)
83
+
84
+ with col_p0_1:
85
+ clarity_rating = st.radio("Clarity:", options, key=f"rating_p0_clarity_{current_index}")
86
+
87
+ with col_p0_2:
88
+ relevance_rating = st.radio("Relevance:", options, key=f"rating_p0_relevance_{current_index}")
89
+
90
+ with col_p0_3:
91
+ coverage_rating = st.radio("Coverage:", options, key=f"rating_p0_coverage_{current_index}")
92
+
93
+ with col_p0_4:
94
+ persona_alignment_rating = st.radio(
95
+ "Persona Alignment:", options=[0, 1, 2, 3, 4], # These are the values
96
+ format_func=lambda x: ["N/A", "Not Aligned", "Partially Aligned", "Aligned", "Unclear"][x],
97
+ key=f"rating_p0_persona_alignment_{current_index}"
98
+ )
99
+
100
+ # Collecting the ratings for query_p0
101
+ query_p0_ratings = {
102
+ "clarity": clarity_rating,
103
+ "relevance": relevance_rating,
104
+ "coverage": coverage_rating,
105
+ "persona_alignment": persona_alignment_rating
106
+ }
107
+
108
+ # Query_p1 and its ratings
109
+ st.markdown("### Query_p1")
110
+ st.write(config['query_p1'])
111
+ # Split the layout into 4 columns for query_p1 ratings
112
+ col_p1_1, col_p1_2, col_p1_3, col_p1_4 = st.columns(4)
113
+
114
+ with col_p1_1:
115
+ clarity_rating_p1 = st.radio("Clarity:", options, key=f"rating_p1_clarity_{current_index}")
116
+
117
+ with col_p1_2:
118
+ relevance_rating_p1 = st.radio("Relevance:", options, key=f"rating_p1_relevance_{current_index}")
119
+
120
+ with col_p1_3:
121
+ coverage_rating_p1 = st.radio("Coverage:", options, key=f"rating_p1_coverage_{current_index}")
122
+
123
+ with col_p1_4:
124
+ persona_alignment_rating_p1 = st.radio(
125
+ "Persona Alignment:", options=[0, 1, 2, 3, 4], # These are the values
126
+ format_func=lambda x: ["N/A", "Not Aligned", "Partially Aligned", "Aligned", "Unclear"][x],
127
+ key=f"rating_p1_persona_alignment_{current_index}"
128
+ )
129
+
130
+ # Collecting the ratings for query_p1
131
+ query_p1_ratings = {
132
+ "clarity": clarity_rating_p1,
133
+ "relevance": relevance_rating_p1,
134
+ "coverage": coverage_rating_p1,
135
+ "persona_alignment": persona_alignment_rating_p1
136
+ }
137
+
138
+ # Additional comments
139
+ comment = st.text_area("Additional Comments (Optional):")
140
+
141
+ # Collecting the response data
142
+ response = Response(
143
+ config_id=config["config_id"],
144
+ query_v=query_v_ratings, # Use the ratings dictionary for query_v
145
+ query_p0=query_p0_ratings, # Use the ratings dictionary for query_p0
146
+ query_p1=query_p1_ratings, # Use the ratings dictionary for query_p1
147
+ comment=comment,
148
+ timestamp=datetime.now().isoformat()
149
  )
150
+ if len(st.session_state.responses) > current_index:
151
+ st.session_state.responses[current_index] = response
152
+ else:
153
+ st.session_state.responses.append(response)
154
+
155
+ # Navigation buttons
156
+ navigation_buttons(data, query_v_ratings["clarity"], query_p0_ratings["clarity"], query_p1_ratings["clarity"])
157
+ except IndexError:
158
+ print("Survey completed!")
159
+ # st.stop()