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

updated the layout

Browse files
Files changed (7) hide show
  1. README.md +4 -2
  2. app.py +5 -126
  3. css/layout.py +33 -0
  4. db/schema.py +3 -3
  5. views/intro_screen.py +44 -0
  6. views/nav_buttons.py +46 -0
  7. views/questions_screen.py +142 -0
README.md CHANGED
@@ -23,5 +23,7 @@ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-
23
  ### TODO List (Human Eval)
24
  [ ] Check if user_id in database, then resume where they left off
25
  [ ] Implement save and continue later button
26
- [ ] Implement questions
27
- [ ] Back button
 
 
 
23
  ### TODO List (Human Eval)
24
  [ ] Check if user_id in database, then resume where they left off
25
  [ ] Implement save and continue later button
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
app.py CHANGED
@@ -8,6 +8,9 @@ import streamlit as st
8
  from datetime import datetime
9
  import os
10
  from dotenv import load_dotenv
 
 
 
11
 
12
  load_dotenv()
13
  VALIDATION_CODE = os.getenv("VALIDATION_CODE")
@@ -91,126 +94,6 @@ def initialization():
91
  st.session_state.survey_state = SurveyState()
92
 
93
 
94
- def validate_username(username: str) -> bool:
95
- return bool(username.strip())
96
-
97
-
98
- def validate_code(input_code: str) -> bool:
99
- """Validate the entered code against the hardcoded validation code"""
100
- return input_code.strip() == VALIDATION_CODE
101
-
102
-
103
- def username_screen():
104
- """Display the Prolific ID entry screen."""
105
- st.title("Welcome to the Feedback Survey")
106
-
107
- username_input = st.text_input("Enter your First name and press TAB:")
108
- validation_code_input = st.text_input("Enter the validation code to proceed and press ENTER:")
109
-
110
- next_button = st.button("Next")
111
- if (username_input and validation_code_input) or next_button:
112
- # Validate Prolific ID and code
113
- if validate_username(username_input) and validate_code(validation_code_input):
114
- st.session_state.username = username_input
115
-
116
- # Load previous state if exists
117
- saved_state = st.session_state.survey_state.load_state(username_input)
118
- if saved_state:
119
- st.session_state.current_index = saved_state.get('current_index', 0)
120
- st.session_state.responses = saved_state.get('responses', [])
121
- st.success("Previous progress loaded! Continuing from where you left off.")
122
- else:
123
- st.success("Prolific ID and code validated! Starting new survey.")
124
- st.rerun()
125
- else:
126
- if not validate_username(username_input):
127
- st.warning("Invalid Prolific ID. Please check and try again.")
128
- if not validate_code(validation_code_input):
129
- st.warning("Invalid validation code. Please check and try again.")
130
-
131
-
132
- def questions_screen(data):
133
- """Display the questions screen."""
134
- current_index = st.session_state.current_index
135
- config = data.iloc[current_index]
136
-
137
- # Progress bar
138
- progress = (current_index + 1) / len(data)
139
- st.progress(progress)
140
- st.write(f"Question {current_index + 1} of {len(data)}")
141
-
142
- st.subheader(f"Config ID: {config['config_id']}")
143
-
144
- # Create tabs for better organization
145
- context_tab, questions_tab = st.tabs(["Context", "Questions"])
146
-
147
- with context_tab:
148
- st.write(f"**Persona:** {config['persona']}")
149
- st.write(f"**Filters:** {config['filters']}")
150
- st.write(f"**Cities:** {config['city']}")
151
-
152
- # Expandable context
153
- with st.expander("Show Context", expanded=False):
154
- st.write(config['context'])
155
-
156
- options = [0, 1, 2, 3, 4, 5]
157
-
158
- with questions_tab:
159
- st.write(f"**Query_v:** {config['query_v']}")
160
- rating_v = st.radio("Rate this config:", options, key=f"rating_v_{current_index}")
161
-
162
- st.write(f"**Query_p0:** {config['query_p0']}")
163
- rating_p0 = st.radio("Rate this config:", options, key=f"rating_p0_{current_index}")
164
-
165
- st.write(f"**Query_p1:** {config['query_p1']}")
166
- rating_p1 = st.radio("Rate this config:", options, key=f"rating_p1_{current_index}")
167
-
168
- comment = st.text_area("Comments (Optional):")
169
- response = Response(config_id=config["config_id"],
170
- rating_v=rating_v, rating_p0=rating_p0, rating_p1=rating_p1,
171
- comment=comment, timestamp=datetime.now().isoformat())
172
- print(response)
173
- if len(st.session_state.responses) > current_index:
174
- st.session_state.responses[current_index] = response
175
- else:
176
- st.session_state.responses.append(response)
177
- navigation_buttons(data, rating_v, rating_p0, rating_p1)
178
-
179
-
180
- def navigation_buttons(data, rating_v, rating_p0, rating_p1):
181
- """Display navigation buttons."""
182
- current_index = st.session_state.current_index
183
-
184
- col1, col2, col3 = st.columns([1, 1, 2])
185
-
186
- with col1: # Back button
187
- if st.button("Back") and current_index > 0:
188
- st.session_state.current_index -= 1
189
- st.rerun()
190
-
191
- with col2: # Next button
192
- if st.button("Next"):
193
- if rating_v == 0 or rating_p0 == 0 or rating_p1 == 0:
194
- st.warning("Please provide a rating before proceeding.")
195
- else:
196
- if current_index < len(data) - 1:
197
- st.session_state.current_index += 1
198
- st.rerun()
199
- else:
200
- feedback = Feedback(
201
- id=current_index + 1,
202
- user_id=st.session_state.username,
203
- time_stamp=datetime.now().isoformat(),
204
- responses=st.session_state.responses,
205
- )
206
- try:
207
- ingest(feedback)
208
- st.session_state.completed = True
209
- st.rerun()
210
- except Exception as e:
211
- st.error(f"An error occurred while submitting feedback: {e}")
212
-
213
-
214
  def exit_screen():
215
  """Display exit screen"""
216
  st.markdown("""
@@ -253,22 +136,18 @@ def reset_survey():
253
 
254
  def ui():
255
  """Main function to control the survey flow."""
 
256
  data = pd.read_csv("data/gemini_results_subset.csv")[:3]
257
  initialization()
258
 
259
  if st.session_state.completed:
260
- # st.title("Survey Completed")
261
- # st.success("Thank you! Your survey has been submitted successfully.")
262
- # if st.button("Start New Survey"):
263
- # reset_survey()
264
- # st.rerun()
265
  exit_screen()
266
  return
267
 
268
  if st.session_state.username is None:
269
  username_screen()
270
  else:
271
- questions_screen(data)
272
 
273
 
274
  if __name__ == "__main__":
 
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")
 
94
  st.session_state.survey_state = SurveyState()
95
 
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  def exit_screen():
98
  """Display exit screen"""
99
  st.markdown("""
 
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__":
css/layout.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ def custom_css():
3
+ """Add custom CSS for layout"""
4
+ st.markdown("""
5
+ <style>
6
+ .split-container {
7
+ display: flex;
8
+ gap: 2rem;
9
+ }
10
+ .context-container {
11
+ flex: 1;
12
+ padding: 1rem;
13
+ background-color: #f8f9fa;
14
+ border-radius: 0.5rem;
15
+ }
16
+ .questions-container {
17
+ flex: 1;
18
+ padding: 1rem;
19
+ }
20
+ .stButton button {
21
+ width: 100%;
22
+ margin-bottom: 0.5rem;
23
+ }
24
+ .exit-container {
25
+ text-align: center;
26
+ padding: 2rem;
27
+ background-color: #f8f9fa;
28
+ border-radius: 1rem;
29
+ margin: 2rem auto;
30
+ max-width: 600px;
31
+ }
32
+ </style>
33
+ """, unsafe_allow_html=True)
db/schema.py CHANGED
@@ -5,9 +5,9 @@ from datetime import datetime
5
 
6
  class Response(BaseModel):
7
  config_id: str
8
- rating_v: int
9
- rating_p0: int
10
- rating_p1: int
11
  comment: Optional[str]
12
  timestamp: str
13
 
 
5
 
6
  class Response(BaseModel):
7
  config_id: str
8
+ query_v: Dict[str, int]
9
+ query_p0: Dict[str, int]
10
+ query_p1: Dict[str, int]
11
  comment: Optional[str]
12
  timestamp: str
13
 
views/intro_screen.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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")
7
+
8
+
9
+ def validate_username(username: str) -> bool:
10
+ return bool(username.strip())
11
+
12
+
13
+ def validate_code(input_code: str) -> bool:
14
+ """Validate the entered code against the hardcoded validation code"""
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.")
43
+ if not validate_code(validation_code_input):
44
+ st.warning("Invalid validation code. Please check and try again.")
views/nav_buttons.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
10
+ from dotenv import load_dotenv
11
+ 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
+
19
+ col1, col2, col3 = st.columns([1, 1, 2])
20
+
21
+ with col1: # Back button
22
+ if st.button("Back") and current_index > 0:
23
+ st.session_state.current_index -= 1
24
+ st.rerun()
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}")
views/questions_screen.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from typing import Dict
3
+
4
+ from db.schema import Feedback, Response
5
+ import streamlit as st
6
+ from datetime import datetime
7
+ import os
8
+ from dotenv import load_dotenv
9
+ from views.nav_buttons import navigation_buttons
10
+
11
+ 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"])