MaxBenKre commited on
Commit
5bcad58
·
1 Parent(s): f4bdbae

updated gui

Browse files
src/Start_Page.py CHANGED
@@ -9,6 +9,41 @@ from qstn.prompt_builder import LLMPrompt
9
  st.set_page_config(layout="wide")
10
  st.title("Questionnaire")
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  col1, col2 = st.columns(2)
13
 
14
  # def save_dataframe(uploaded_file):
@@ -22,39 +57,60 @@ col1, col2 = st.columns(2)
22
 
23
  # return df
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  df_population = None
26
  df_questionnaire = None
 
27
 
28
  with col1:
29
  uploaded_questionnaire = st.file_uploader("Select a questionnaire to start with")
30
  if uploaded_questionnaire is not None:
31
- # bytes_data = uploaded_questionnaire.getvalue()
32
- # st.write(bytes_data)
33
-
34
  df_questionnaire = pd.read_csv(uploaded_questionnaire)
35
- #dataframe = save_dataframe(uploaded_questionnaire)
36
-
 
 
 
 
37
  st.write(df_questionnaire)
38
 
39
  with col2:
40
  uploaded_population = st.file_uploader("Select a population to start with")
41
  if uploaded_population is not None:
42
- # bytes_data = uploaded_population.getvalue()
43
- # st.write(bytes_data)
44
-
45
  df_population = pd.read_csv(uploaded_population)
46
- #dataframe = save_dataframe(uploaded_population)
47
-
 
 
 
 
48
  st.write(df_population)
49
 
50
- disabled = True
51
-
52
- if df_population is not None and df_questionnaire is not None:
53
- disabled = False
54
 
55
  st.divider()
56
 
57
  if st.button("Confirm and Prepare Questionnaire", type="primary", disabled=disabled, use_container_width=True):
58
  questionnaires: list[LLMPrompt] = SurveyCreator.from_dataframe(df_population, df_questionnaire)
59
  st.session_state.questionnaires = questionnaires
60
- st.switch_page("pages/01_Prompt_Configuration.py")
 
9
  st.set_page_config(layout="wide")
10
  st.title("Questionnaire")
11
 
12
+ # Demo section showing expected CSV format
13
+ with st.expander("📋 View Example CSV Format", expanded=False):
14
+ demo_col1, demo_col2 = st.columns(2)
15
+
16
+ with demo_col1:
17
+ st.subheader("Questionnaire CSV Format")
18
+ st.write("**Required columns:** `questionnaire_item_id`, `question_content`, `question_stem`")
19
+ # Create example dataframe
20
+ example_questionnaire = pd.DataFrame({
21
+ 'questionnaire_item_id': [1, 2, 3],
22
+ 'question_content': ['Coffee', 'Pizza', 'Ice cream'],
23
+ 'question_stem': [
24
+ 'How do you feel about?',
25
+ 'How do you feel about?',
26
+ 'How do you feel about?'
27
+ ]
28
+ })
29
+ st.write(example_questionnaire)
30
+
31
+ with demo_col2:
32
+ st.subheader("Population CSV Format")
33
+ st.write("**Required columns:** `questionnaire_name`, `system_prompt`, `questionnaire_instruction`")
34
+ # Create example dataframe
35
+ example_population = pd.DataFrame({
36
+ 'questionnaire_name': ['Student', 'Teacher'],
37
+ 'system_prompt': ['You are a student.', 'You are a teacher.'],
38
+ 'questionnaire_instruction': [
39
+ 'Please answer the following questions.',
40
+ 'Please answer the following questions.'
41
+ ]
42
+ })
43
+ st.write(example_population)
44
+
45
+ st.divider()
46
+
47
  col1, col2 = st.columns(2)
48
 
49
  # def save_dataframe(uploaded_file):
 
57
 
58
  # return df
59
 
60
+ # Default example dataframes
61
+ default_questionnaire = pd.DataFrame({
62
+ 'questionnaire_item_id': [1, 2, 3],
63
+ 'question_content': ['Coffee', 'Pizza', 'Ice cream'],
64
+ 'question_stem': [
65
+ 'How do you feel about?',
66
+ 'How do you feel about?',
67
+ 'How do you feel about?'
68
+ ]
69
+ })
70
+
71
+ default_population = pd.DataFrame({
72
+ 'questionnaire_name': ['Student', 'Teacher'],
73
+ 'system_prompt': ['You are a student.', 'You are a teacher.'],
74
+ 'questionnaire_instruction': [
75
+ 'Please answer the following questions.',
76
+ 'Please answer the following questions.'
77
+ ]
78
+ })
79
+
80
  df_population = None
81
  df_questionnaire = None
82
+ using_defaults = False
83
 
84
  with col1:
85
  uploaded_questionnaire = st.file_uploader("Select a questionnaire to start with")
86
  if uploaded_questionnaire is not None:
 
 
 
87
  df_questionnaire = pd.read_csv(uploaded_questionnaire)
88
+ st.write(df_questionnaire)
89
+ else:
90
+ # Use default if no file uploaded
91
+ df_questionnaire = default_questionnaire
92
+ using_defaults = True
93
+ st.info("ℹ️ Using example questionnaire. Upload a file to use your own data.")
94
  st.write(df_questionnaire)
95
 
96
  with col2:
97
  uploaded_population = st.file_uploader("Select a population to start with")
98
  if uploaded_population is not None:
 
 
 
99
  df_population = pd.read_csv(uploaded_population)
100
+ st.write(df_population)
101
+ else:
102
+ # Use default if no file uploaded
103
+ df_population = default_population
104
+ using_defaults = True
105
+ st.info("ℹ️ Using example population. Upload a file to use your own data.")
106
  st.write(df_population)
107
 
108
+ # Button is always enabled now (using defaults if no files uploaded)
109
+ disabled = False
 
 
110
 
111
  st.divider()
112
 
113
  if st.button("Confirm and Prepare Questionnaire", type="primary", disabled=disabled, use_container_width=True):
114
  questionnaires: list[LLMPrompt] = SurveyCreator.from_dataframe(df_population, df_questionnaire)
115
  st.session_state.questionnaires = questionnaires
116
+ st.switch_page("pages/01_Option_Prompt.py")
src/pages/{02_Option_Prompt.py → 01_Option_Prompt.py} RENAMED
@@ -145,9 +145,9 @@ with st.container(border=True):
145
  # The submit button for the form
146
  submitted = st.button("Confirm and Generate Options", disabled=disabled, type="primary", use_container_width=True)
147
 
148
- if st.button("Remove all options", use_container_width=True, icon="❌"):
149
  st.session_state.survey_options = None
150
- st.switch_page("pages/03_Inference_Setting.py")
151
 
152
  # --- Processing and Output ---
153
  if submitted:
@@ -192,6 +192,6 @@ if submitted:
192
  )
193
 
194
  st.session_state.survey_options = survey_options
195
- st.switch_page("pages/03_Inference_Setting.py")
196
 
197
 
 
145
  # The submit button for the form
146
  submitted = st.button("Confirm and Generate Options", disabled=disabled, type="primary", use_container_width=True)
147
 
148
+ if st.button("Skip", use_container_width=True, icon="❌"):
149
  st.session_state.survey_options = None
150
+ st.switch_page("pages/02_Prompt_Configuration.py")
151
 
152
  # --- Processing and Output ---
153
  if submitted:
 
192
  )
193
 
194
  st.session_state.survey_options = survey_options
195
+ st.switch_page("pages/02_Prompt_Configuration.py")
196
 
197
 
src/pages/{01_Prompt_Configuration.py → 02_Prompt_Configuration.py} RENAMED
@@ -23,7 +23,7 @@ st.write(
23
  "This interface allows you configure how the questions are prompted to the LLM and the overall prompt structure. "
24
  "These options are applied to every questionnaire in your survey."
25
  )
26
- st.page_link("pages/02_Option_Prompt.py", label="Click here to adjust the answer options.")
27
  st.divider()
28
 
29
  @st.cache_data
@@ -104,6 +104,117 @@ if "questionnaires" in st.session_state and st.session_state.questionnaires is n
104
 
105
  with col1:
106
  st.subheader("⚙️ Configuration")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
  for field_id in field_ids:
109
  input_key = f"input_{field_id}"
@@ -120,17 +231,26 @@ if "questionnaires" in st.session_state and st.session_state.questionnaires is n
120
  placeholder_shortcut = st.session_state.placeholder_to_replace["shortcut"]
121
  placeholder_value = st.session_state.placeholder_to_replace["value"]
122
 
123
- # Replace all occurrences of the shortcut (e.g., -Q) with the placeholder
124
- if placeholder_shortcut in current_text:
125
- st.session_state[input_key] = current_text.replace(placeholder_shortcut, placeholder_value)
126
  else:
127
- # Shortcut not found, append at the end
128
- st.session_state[input_key] = current_text + f" {placeholder_value} "
 
 
 
 
129
 
130
  st.session_state.placeholder_to_replace = None
131
  st.rerun()
132
 
133
  # --- Input Widgets (No Form) ---
 
 
 
 
 
134
  question_stem_input = st.text_area(
135
  question_stem_field,
136
  key=f"input_{question_stem_field}",
@@ -160,7 +280,14 @@ if "questionnaires" in st.session_state and st.session_state.questionnaires is n
160
  button_label = description # Use the actual placeholder name
161
  button_key = f"btn_placeholder_{char_label}"
162
 
163
- if cols[i].button(button_label, key=button_key, use_container_width=True, help=f"Replaces '{shortcut}' with {placeholder_value}"):
 
 
 
 
 
 
 
164
  st.session_state.placeholder_to_replace = {
165
  "shortcut": shortcut,
166
  "value": placeholder_value
@@ -177,135 +304,165 @@ if "questionnaires" in st.session_state and st.session_state.questionnaires is n
177
 
178
  st.divider()
179
 
180
- # System prompt and main prompt section (from Basic Prompt Settings)
181
- new_system_prompt = st.text_area(
182
- label=system_prompt_field,
183
- key=f"{system_prompt_field}{current_questionnaire_id}",
184
- value=questionnaire.system_prompt,
185
- help="The system prompt the model is prompted with."
186
- )
187
-
188
- change_all_system = state.create(
189
- st.checkbox,
190
- key=change_all_system_prompts_checkbox,
191
- label="On update: change all System Prompts",
192
- help="If this is ticked, all system prompts will be changed to this.",
193
- initial_value=False
194
- )
195
-
196
- # Handle placeholder replacement for main prompt before widget is created
197
- prompt_key = f"{prompt_field}{current_questionnaire_id}"
198
- if "main_prompt_placeholder_to_replace" in st.session_state and st.session_state.main_prompt_placeholder_to_replace:
199
- current_prompt_text = st.session_state.get(prompt_key, questionnaire.prompt)
200
- placeholder_shortcut = st.session_state.main_prompt_placeholder_to_replace["shortcut"]
201
- placeholder_value = st.session_state.main_prompt_placeholder_to_replace["value"]
202
-
203
- if placeholder_shortcut in current_prompt_text:
204
- st.session_state[prompt_key] = current_prompt_text.replace(placeholder_shortcut, placeholder_value)
205
- else:
206
- st.session_state[prompt_key] = current_prompt_text + f" {placeholder_value} "
207
-
208
- st.session_state.main_prompt_placeholder_to_replace = None
209
- st.rerun()
210
-
211
- new_prompt = st.text_area(
212
- label=prompt_field,
213
- key=prompt_key,
214
- value=questionnaire.prompt,
215
- help="Instructions that are given to the model before the questions."
216
- )
217
-
218
- # Placeholder insertion buttons for main prompt
219
- st.write("**Insert Placeholder in Main Prompt:**")
220
- main_prompt_placeholders = [
221
- (placeholder.PROMPT_QUESTIONS, "-P", "P", "Prompt Questions"),
222
- (placeholder.PROMPT_OPTIONS, "-O", "O", "Prompt Options"),
223
- (placeholder.PROMPT_AUTOMATIC_OUTPUT_INSTRUCTIONS, "-A", "A", "Automatic Output"),
224
- (placeholder.JSON_TEMPLATE, "-J", "J", "JSON Template"),
225
- ]
226
 
227
- main_shortcuts_list = ", ".join([f"`{shortcut}`" for _, shortcut, _, _ in main_prompt_placeholders])
228
- st.caption(f"💡 Tip: Type shortcuts {main_shortcuts_list} in the main prompt, then click the button to replace them.")
229
-
230
- cols_main = st.columns(len(main_prompt_placeholders))
231
- for i, (placeholder_value, shortcut, char_label, description) in enumerate(main_prompt_placeholders):
232
- button_key = f"btn_main_placeholder_{char_label}"
233
- if cols_main[i].button(description, key=button_key, use_container_width=True, help=f"Replaces '{shortcut}' with {placeholder_value}"):
234
- st.session_state.main_prompt_placeholder_to_replace = {
235
- "shortcut": shortcut,
236
- "value": placeholder_value
237
- }
238
- st.rerun()
239
-
240
- change_all_questionnaire = state.create(
241
- st.checkbox,
242
- key=change_all_prompts_checkbox,
243
- label="On update: change all questionnaire instructions",
244
- help="If this is ticked, all questionnaire instructions will be changed to this.",
245
- initial_value=False
246
- )
247
 
248
  # Place the corresponding output in the second column
249
  with col2:
250
  st.subheader("📄 Live Preview")
251
-
252
  # --- The Dynamic Preview Logic ---
253
  # This block re-runs on every widget interaction.
 
 
254
  with st.container(border=True):
255
- # Update temporary questionnaire with question stem
256
- if "survey_options" in st.session_state:
257
- survey_options = st.session_state.survey_options
258
- else:
259
- survey_options = None
260
 
261
- if randomize_order_bool:
262
- st.session_state.temporary_questionnaire.prepare_prompt(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  question_stem=question_stem_input,
264
  answer_options=survey_options,
265
- randomized_item_order=randomize_order_bool,
266
  )
267
- st.session_state.base_questionnaire.prepare_prompt(
268
- question_stem=question_stem_input,
269
- answer_options=survey_options,
270
- randomized_item_order=False,
271
- )
272
-
273
- if not randomize_order_bool:
274
- st.session_state.temporary_questionnaire = st.session_state.base_questionnaire.duplicate()
275
-
276
- # Update system prompt and main prompt for preview (apply to temporary_questionnaire)
277
- st.session_state.temporary_questionnaire.system_prompt = new_system_prompt
278
- st.session_state.temporary_questionnaire.prompt = new_prompt
279
- current_system_prompt, current_prompt = st.session_state.temporary_questionnaire.get_prompt_for_questionnaire_type(QuestionnairePresentation.SEQUENTIAL)
280
- current_system_prompt = current_system_prompt.replace("\n", " \n")
281
- current_prompt = current_prompt.replace("\n", " \n")
282
- st.write(current_system_prompt)
283
- st.write(current_prompt)
284
 
285
  st.divider()
286
 
287
  if st.button("Update Prompt(s)", type="secondary", use_container_width=True):
 
 
 
 
288
  if change_all_system:
289
  for questionnaire in st.session_state.questionnaires:
290
- questionnaire.system_prompt = new_system_prompt
291
  else:
292
- st.session_state.questionnaires[current_questionnaire_id].system_prompt = new_system_prompt
293
 
294
  if change_all_questionnaire:
295
  for questionnaire in st.session_state.questionnaires:
296
- questionnaire.prompt = new_prompt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  else:
298
- st.session_state.questionnaires[current_questionnaire_id].prompt = new_prompt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  st.success("Prompt(s) updated!")
 
300
 
301
  if st.button("Confirm and Prepare Questionnaire", type="primary", use_container_width=True):
 
 
 
 
 
 
 
 
 
 
302
  for questionnaire in st.session_state.questionnaires:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  questionnaire.prepare_prompt(
304
  question_stem=question_stem_input,
305
  answer_options=survey_options,
306
  randomized_item_order=randomize_order_bool,
307
  )
308
  st.success("Changed the prompts!")
309
- st.switch_page("pages/02_Option_Prompt.py")
310
  else:
311
  st.warning("No data found. Please upload a CSV file on the 'Start Page' first.")
 
23
  "This interface allows you configure how the questions are prompted to the LLM and the overall prompt structure. "
24
  "These options are applied to every questionnaire in your survey."
25
  )
26
+ st.page_link("pages/01_Option_Prompt.py", label="Click here to adjust the answer options.")
27
  st.divider()
28
 
29
  @st.cache_data
 
104
 
105
  with col1:
106
  st.subheader("⚙️ Configuration")
107
+
108
+ # Global settings checkboxes at the top
109
+ change_all_system = state.create(
110
+ st.checkbox,
111
+ key=change_all_system_prompts_checkbox,
112
+ label="On update: change all System Prompts",
113
+ help="If this is ticked, all system prompts will be changed to this.",
114
+ initial_value=True
115
+ )
116
+
117
+ change_all_questionnaire = state.create(
118
+ st.checkbox,
119
+ key=change_all_prompts_checkbox,
120
+ label="On update: change all questionnaire instructions",
121
+ help="If this is ticked, all questionnaire instructions will be changed to this.",
122
+ initial_value=True
123
+ )
124
+
125
+ st.divider()
126
+
127
+ # System prompt and main prompt section (from Basic Prompt Settings)
128
+ system_prompt_key = f"{system_prompt_field}{current_questionnaire_id}"
129
+ prompt_key = f"{prompt_field}{current_questionnaire_id}"
130
+
131
+ # Handle placeholder replacement for both textboxes before widgets are created
132
+ if "unified_placeholder_to_replace" in st.session_state and st.session_state.unified_placeholder_to_replace:
133
+ current_system_text = st.session_state.get(system_prompt_key, questionnaire.system_prompt)
134
+ current_prompt_text = st.session_state.get(prompt_key, questionnaire.prompt)
135
+ placeholder_shortcut = st.session_state.unified_placeholder_to_replace["shortcut"]
136
+ placeholder_value = st.session_state.unified_placeholder_to_replace["value"]
137
+ target_textbox = st.session_state.unified_placeholder_to_replace.get("target", "prompt") # "system" or "prompt"
138
+
139
+ # Check if placeholder already exists in EITHER textbox
140
+ if placeholder_value in current_system_text or placeholder_value in current_prompt_text:
141
+ st.session_state.unified_placeholder_warning = f"⚠️ The placeholder `{placeholder_value}` already exists in one of the textboxes. Please remove it first if you want to insert it again."
142
+ else:
143
+ # Check for shortcut in both textboxes - replace where found
144
+ if placeholder_shortcut in current_system_text:
145
+ st.session_state[system_prompt_key] = current_system_text.replace(placeholder_shortcut, placeholder_value)
146
+ elif placeholder_shortcut in current_prompt_text:
147
+ st.session_state[prompt_key] = current_prompt_text.replace(placeholder_shortcut, placeholder_value)
148
+ else:
149
+ # No shortcut found, add to the target textbox (default based on which was clicked)
150
+ if target_textbox == "system":
151
+ st.session_state[system_prompt_key] = current_system_text + f" {placeholder_value} "
152
+ else:
153
+ st.session_state[prompt_key] = current_prompt_text + f" {placeholder_value} "
154
+
155
+ st.session_state.unified_placeholder_to_replace = None
156
+ st.rerun()
157
+
158
+ # Display warnings if they exist
159
+ if "unified_placeholder_warning" in st.session_state and st.session_state.unified_placeholder_warning:
160
+ st.warning(st.session_state.unified_placeholder_warning)
161
+ st.session_state.unified_placeholder_warning = None # Clear after displaying
162
+
163
+ new_system_prompt = st.text_area(
164
+ label=system_prompt_field,
165
+ key=system_prompt_key,
166
+ value=questionnaire.system_prompt,
167
+ help="The system prompt the model is prompted with."
168
+ )
169
+
170
+ # Display warning for main prompt if it exists
171
+ if "main_prompt_warning" in st.session_state and st.session_state.main_prompt_warning:
172
+ st.warning(st.session_state.main_prompt_warning)
173
+ st.session_state.main_prompt_warning = None # Clear after displaying
174
+
175
+ new_prompt = st.text_area(
176
+ label=prompt_field,
177
+ key=prompt_key,
178
+ value=questionnaire.prompt,
179
+ help="Instructions that are given to the model before the questions."
180
+ )
181
+
182
+ # Unified placeholder insertion buttons (work for both system prompt and main prompt)
183
+ st.write("**Insert Placeholder:**")
184
+
185
+ # Check if options were configured (needed for both main prompt and question stem sections)
186
+ options_configured = "survey_options" in st.session_state and st.session_state.survey_options is not None
187
+
188
+ unified_placeholders = [
189
+ (placeholder.PROMPT_QUESTIONS, "-P", "P", "Prompt Questions"),
190
+ (placeholder.PROMPT_OPTIONS, "-O", "O", "Prompt Options"),
191
+ (placeholder.PROMPT_AUTOMATIC_OUTPUT_INSTRUCTIONS, "-A", "A", "Automatic Output"),
192
+ (placeholder.JSON_TEMPLATE, "-J", "J", "JSON Template"),
193
+ ]
194
+
195
+ shortcuts_list = ", ".join([f"`{shortcut}`" for _, shortcut, _, _ in unified_placeholders])
196
+ st.caption(f"💡 Tip: Type shortcuts {shortcuts_list} in either the system prompt or main prompt, then click the button to replace them. The placeholder will be inserted where the shortcut is found, or in the main prompt if not found.")
197
+
198
+ cols_unified = st.columns(len(unified_placeholders))
199
+ for i, (placeholder_value, shortcut, char_label, description) in enumerate(unified_placeholders):
200
+ button_key = f"btn_unified_placeholder_{char_label}"
201
+
202
+ # Disable "Prompt Options" button if options weren't configured
203
+ is_options_button = placeholder_value == placeholder.PROMPT_OPTIONS
204
+ button_disabled = is_options_button and not options_configured
205
+ button_help = f"Replaces '{shortcut}' with {placeholder_value} in either textbox"
206
+ if button_disabled:
207
+ button_help = "⚠️ You need to configure answer options first. Go back to the Options page to set them up."
208
+
209
+ if cols_unified[i].button(description, key=button_key, use_container_width=True, disabled=button_disabled, help=button_help):
210
+ st.session_state.unified_placeholder_to_replace = {
211
+ "shortcut": shortcut,
212
+ "value": placeholder_value,
213
+ "target": "prompt" # Default to main prompt if no shortcut found
214
+ }
215
+ st.rerun()
216
+
217
+ st.divider()
218
 
219
  for field_id in field_ids:
220
  input_key = f"input_{field_id}"
 
231
  placeholder_shortcut = st.session_state.placeholder_to_replace["shortcut"]
232
  placeholder_value = st.session_state.placeholder_to_replace["value"]
233
 
234
+ # Check if placeholder already exists in the text
235
+ if placeholder_value in current_text:
236
+ st.session_state.question_stem_warning = f"⚠️ The placeholder `{placeholder_value}` already exists in the text. Please remove it first if you want to insert it again."
237
  else:
238
+ # Replace all occurrences of the shortcut (e.g., -Q) with the placeholder
239
+ if placeholder_shortcut in current_text:
240
+ st.session_state[input_key] = current_text.replace(placeholder_shortcut, placeholder_value)
241
+ else:
242
+ # Shortcut not found, append at the end
243
+ st.session_state[input_key] = current_text + f" {placeholder_value} "
244
 
245
  st.session_state.placeholder_to_replace = None
246
  st.rerun()
247
 
248
  # --- Input Widgets (No Form) ---
249
+ # Display warning for question stem if it exists
250
+ if "question_stem_warning" in st.session_state and st.session_state.question_stem_warning:
251
+ st.warning(st.session_state.question_stem_warning)
252
+ st.session_state.question_stem_warning = None # Clear after displaying
253
+
254
  question_stem_input = st.text_area(
255
  question_stem_field,
256
  key=f"input_{question_stem_field}",
 
280
  button_label = description # Use the actual placeholder name
281
  button_key = f"btn_placeholder_{char_label}"
282
 
283
+ # Disable "Prompt Options" button if options weren't configured
284
+ is_options_button = placeholder_value == placeholder.PROMPT_OPTIONS
285
+ button_disabled = is_options_button and not options_configured
286
+ button_help = f"Replaces '{shortcut}' with {placeholder_value}"
287
+ if button_disabled:
288
+ button_help = "⚠️ You need to configure answer options first. Go back to the Options page to set them up."
289
+
290
+ if cols[i].button(button_label, key=button_key, use_container_width=True, disabled=button_disabled, help=button_help):
291
  st.session_state.placeholder_to_replace = {
292
  "shortcut": shortcut,
293
  "value": placeholder_value
 
304
 
305
  st.divider()
306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
 
309
  # Place the corresponding output in the second column
310
  with col2:
311
  st.subheader("📄 Live Preview")
 
312
  # --- The Dynamic Preview Logic ---
313
  # This block re-runs on every widget interaction.
314
+ # --- The Preview Logic ---
315
+ # Preview only updates when "Update Prompt(s)" is clicked
316
  with st.container(border=True):
 
 
 
 
 
317
 
318
+
319
+ # # Update temporary questionnaire with question stem
320
+ # if "survey_options" in st.session_state:
321
+ # survey_options = st.session_state.survey_options
322
+ # else:
323
+ # survey_options = None
324
+
325
+ # if randomize_order_bool:
326
+ # st.session_state.temporary_questionnaire.prepare_prompt(
327
+ # question_stem=question_stem_input,
328
+ # answer_options=survey_options,
329
+ # randomized_item_order=randomize_order_bool,
330
+ # )
331
+ # st.session_state.base_questionnaire.prepare_prompt(
332
+ # question_stem=question_stem_input,
333
+ # answer_options=survey_options,
334
+ # randomized_item_order=False,
335
+ # )
336
+
337
+ # if not randomize_order_bool:
338
+ # st.session_state.temporary_questionnaire = st.session_state.base_questionnaire.duplicate()
339
+
340
+ # # Update system prompt and main prompt for preview (apply to temporary_questionnaire)
341
+ # st.session_state.temporary_questionnaire.system_prompt = new_system_prompt
342
+ # st.session_state.temporary_questionnaire.prompt = new_prompt
343
+ # current_system_prompt, current_prompt = st.session_state.temporary_questionnaire.get_prompt_for_questionnaire_type(QuestionnairePresentation.SEQUENTIAL)
344
+ # current_system_prompt = current_system_prompt.replace("\n", " \n")
345
+ # current_prompt = current_prompt.replace("\n", " \n")
346
+ # st.write(current_system_prompt)
347
+ # st.write(current_prompt)
348
+
349
+
350
+ # Initialize preview state if it doesn't exist
351
+ preview_key = f"preview_{current_questionnaire_id}"
352
+ if preview_key not in st.session_state:
353
+ # Create initial preview
354
+ if "survey_options" in st.session_state:
355
+ survey_options = st.session_state.survey_options
356
+ else:
357
+ survey_options = None
358
+
359
+ temp_questionnaire = st.session_state.temporary_questionnaire.duplicate()
360
+ temp_questionnaire.prepare_prompt(
361
  question_stem=question_stem_input,
362
  answer_options=survey_options,
363
+ randomized_item_order=False,
364
  )
365
+ temp_questionnaire.system_prompt = questionnaire.system_prompt
366
+ temp_questionnaire.prompt = questionnaire.prompt
367
+ current_system_prompt, current_prompt = temp_questionnaire.get_prompt_for_questionnaire_type(QuestionnairePresentation.SEQUENTIAL)
368
+ current_system_prompt = current_system_prompt.replace("\n", " \n")
369
+ current_prompt = current_prompt.replace("\n", " \n")
370
+ st.session_state[preview_key] = {
371
+ "system_prompt": current_system_prompt,
372
+ "prompt": current_prompt
373
+ }
374
+
375
+ # Display the stored preview
376
+ st.write(st.session_state[preview_key]["system_prompt"])
377
+ st.write(st.session_state[preview_key]["prompt"])
 
 
 
 
378
 
379
  st.divider()
380
 
381
  if st.button("Update Prompt(s)", type="secondary", use_container_width=True):
382
+ # Get current values from text areas (they're already in session state via the keys)
383
+ current_system_value = st.session_state.get(system_prompt_key, new_system_prompt)
384
+ current_prompt_value = st.session_state.get(prompt_key, new_prompt)
385
+
386
  if change_all_system:
387
  for questionnaire in st.session_state.questionnaires:
388
+ questionnaire.system_prompt = current_system_value
389
  else:
390
+ st.session_state.questionnaires[current_questionnaire_id].system_prompt = current_system_value
391
 
392
  if change_all_questionnaire:
393
  for questionnaire in st.session_state.questionnaires:
394
+ questionnaire.prompt = current_prompt_value
395
+ else:
396
+ st.session_state.questionnaires[current_questionnaire_id].prompt = current_prompt_value
397
+
398
+ # Update the preview when Update Prompt(s) is clicked
399
+ preview_key = f"preview_{current_questionnaire_id}"
400
+ if "survey_options" in st.session_state:
401
+ survey_options = st.session_state.survey_options
402
+ else:
403
+ survey_options = None
404
+
405
+ temp_questionnaire = st.session_state.temporary_questionnaire.duplicate()
406
+ if randomize_order_bool:
407
+ temp_questionnaire.prepare_prompt(
408
+ question_stem=question_stem_input,
409
+ answer_options=survey_options,
410
+ randomized_item_order=randomize_order_bool,
411
+ )
412
  else:
413
+ temp_questionnaire.prepare_prompt(
414
+ question_stem=question_stem_input,
415
+ answer_options=survey_options,
416
+ randomized_item_order=False,
417
+ )
418
+
419
+ temp_questionnaire.system_prompt = current_system_value
420
+ temp_questionnaire.prompt = current_prompt_value
421
+ preview_system_prompt, preview_prompt = temp_questionnaire.get_prompt_for_questionnaire_type(QuestionnairePresentation.SEQUENTIAL)
422
+ preview_system_prompt = preview_system_prompt.replace("\n", " \n")
423
+ preview_prompt = preview_prompt.replace("\n", " \n")
424
+ st.session_state[preview_key] = {
425
+ "system_prompt": preview_system_prompt,
426
+ "prompt": preview_prompt
427
+ }
428
+
429
  st.success("Prompt(s) updated!")
430
+ st.rerun()
431
 
432
  if st.button("Confirm and Prepare Questionnaire", type="primary", use_container_width=True):
433
+ # Get survey options if they exist
434
+ if "survey_options" in st.session_state:
435
+ survey_options = st.session_state.survey_options
436
+ else:
437
+ survey_options = None
438
+
439
+ # Get current system prompt and main prompt values
440
+ current_system_value = st.session_state.get(system_prompt_key, new_system_prompt)
441
+ current_prompt_value = st.session_state.get(prompt_key, new_prompt)
442
+
443
  for questionnaire in st.session_state.questionnaires:
444
+ # Update system prompt and main prompt
445
+ if change_all_system:
446
+ questionnaire.system_prompt = current_system_value
447
+ else:
448
+ # Only update if it's the current questionnaire or if we're updating all
449
+ if questionnaire == st.session_state.questionnaires[current_questionnaire_id]:
450
+ questionnaire.system_prompt = current_system_value
451
+
452
+ if change_all_questionnaire:
453
+ questionnaire.prompt = current_prompt_value
454
+ else:
455
+ # Only update if it's the current questionnaire or if we're updating all
456
+ if questionnaire == st.session_state.questionnaires[current_questionnaire_id]:
457
+ questionnaire.prompt = current_prompt_value
458
+
459
+ # Update question stem and answer options
460
  questionnaire.prepare_prompt(
461
  question_stem=question_stem_input,
462
  answer_options=survey_options,
463
  randomized_item_order=randomize_order_bool,
464
  )
465
  st.success("Changed the prompts!")
466
+ st.switch_page("pages/03_Inference_Setting.py")
467
  else:
468
  st.warning("No data found. Please upload a CSV file on the 'Start Page' first.")
src/pages/04_Final_Overview.py CHANGED
@@ -8,6 +8,7 @@ import queue
8
  import time
9
  import threading
10
  import asyncio
 
11
 
12
  import logging
13
 
@@ -147,20 +148,39 @@ with col_prompt_display:
147
  selected_method_name, selected_questionnaire_type = survey_method_options[survey_method_display]
148
 
149
  with st.container(border=True):
150
- current_system_prompt, current_prompt = questionnaires.get_prompt_for_questionnaire_type(selected_questionnaire_type)
151
- current_system_prompt = current_system_prompt.replace("\n", " \n")
152
- current_prompt = current_prompt.replace("\n", " \n")
153
- st.write(current_system_prompt)
154
- st.write(current_prompt)
155
-
156
- model_name = state.create(
157
- st.text_input,
158
- "save_file",
159
- "Save File",
160
- # initial_value="meta-llama/Llama-3.1-70B-Instruct",
161
- # placeholder="meta-llama/Llama-3.1-70B-Instruct",
162
- help="The save file to write your results to. Should be a csv file.",
163
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
 
166
  if st.button("Confirm and Run Questionnaire", type="primary", use_container_width=True):
@@ -276,14 +296,47 @@ if st.button("Confirm and Run Questionnaire", type="primary", use_container_widt
276
  except queue.Empty:
277
  st.error("Could not retrieve result from the asynchronous task.")
278
 
279
- st.success("Finished inferencing! Saving results...")
280
 
281
  responses = raw_responses(final_output)
282
 
283
  df = create_one_dataframe(responses)
284
 
285
- st.dataframe(df)
 
 
286
 
287
- df.to_csv(st.session_state.save_file, index=False)
288
 
289
- st.success(f"File saved to {st.session_state.save_file}!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  import time
9
  import threading
10
  import asyncio
11
+ import pandas as pd
12
 
13
  import logging
14
 
 
148
  selected_method_name, selected_questionnaire_type = survey_method_options[survey_method_display]
149
 
150
  with st.container(border=True):
151
+ # For single item mode, show multiple previews (up to 3 items)
152
+ if selected_questionnaire_type == QuestionnairePresentation.SINGLE_ITEM:
153
+ num_questions = len(questionnaires._questions)
154
+ num_previews = min(3, num_questions) # Show up to 3 previews
155
+
156
+ if num_previews > 1:
157
+ st.write(f"**Preview of first {num_previews} items:**")
158
+ else:
159
+ st.write("**Preview:**")
160
+
161
+ for i in range(num_previews):
162
+ if num_previews > 1:
163
+ st.write(f"**Item {i+1}:**")
164
+
165
+ current_system_prompt, current_prompt = questionnaires.get_prompt_for_questionnaire_type(
166
+ selected_questionnaire_type,
167
+ item_id=i
168
+ )
169
+ current_system_prompt = current_system_prompt.replace("\n", " \n")
170
+ current_prompt = current_prompt.replace("\n", " \n")
171
+ st.write(current_system_prompt)
172
+ st.write(current_prompt)
173
+
174
+ # Add separator between items (except for the last one)
175
+ if i < num_previews - 1:
176
+ st.divider()
177
+ else:
178
+ # For battery and sequential, show single preview as before
179
+ current_system_prompt, current_prompt = questionnaires.get_prompt_for_questionnaire_type(selected_questionnaire_type)
180
+ current_system_prompt = current_system_prompt.replace("\n", " \n")
181
+ current_prompt = current_prompt.replace("\n", " \n")
182
+ st.write(current_system_prompt)
183
+ st.write(current_prompt)
184
 
185
 
186
  if st.button("Confirm and Run Questionnaire", type="primary", use_container_width=True):
 
296
  except queue.Empty:
297
  st.error("Could not retrieve result from the asynchronous task.")
298
 
299
+ st.success("Finished inferencing!")
300
 
301
  responses = raw_responses(final_output)
302
 
303
  df = create_one_dataframe(responses)
304
 
305
+ # Store the dataframe in session state for saving later
306
+ st.session_state.results_dataframe = df
307
+ st.session_state.inference_completed = True
308
 
309
+ st.dataframe(df)
310
 
311
+ # Show save button if inference is completed
312
+ if "inference_completed" in st.session_state and st.session_state.inference_completed:
313
+ st.divider()
314
+ st.subheader("💾 Save Results")
315
+
316
+ # Text input for filename
317
+ if "save_filename" not in st.session_state:
318
+ st.session_state.save_filename = "questionnaire_results.csv"
319
+
320
+ save_filename = st.text_input(
321
+ "Save File",
322
+ value=st.session_state.save_filename,
323
+ key="save_filename_input",
324
+ help="Enter the filename for the results. Should be a CSV file (e.g., results.csv)."
325
+ )
326
+
327
+ # Ensure filename ends with .csv
328
+ if save_filename and not save_filename.endswith('.csv'):
329
+ save_filename = save_filename + '.csv'
330
+
331
+ # Convert dataframe to CSV string for download
332
+ csv = st.session_state.results_dataframe.to_csv(index=False)
333
+
334
+ st.download_button(
335
+ label="Save Results",
336
+ data=csv,
337
+ file_name=save_filename if save_filename else "questionnaire_results.csv",
338
+ mime="text/csv",
339
+ type="primary",
340
+ use_container_width=True,
341
+ help="Click to save the results to your computer. You can choose the directory and filename in the save dialog."
342
+ )
src/surveyGenGui.egg-info/PKG-INFO DELETED
@@ -1,3 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: surveyGenGui
3
- Version: 0.0.1
 
 
 
 
src/surveyGenGui.egg-info/SOURCES.txt DELETED
@@ -1,17 +0,0 @@
1
- pyproject.toml
2
- src/Start_Page.py
3
- src/__init__.py
4
- src/gui_elements/__init__.py
5
- src/gui_elements/output_manager.py
6
- src/gui_elements/paginator.py
7
- src/gui_elements/stateful_widget.py
8
- src/pages/01_Basic_Prompt_Settings.py
9
- src/pages/02_Option_Prompt.py
10
- src/pages/03_Prepare_Prompts.py
11
- src/pages/04_Inference_Setting.py
12
- src/pages/05_Final_Overview.py
13
- src/pages/__init__.py
14
- src/surveyGenGui.egg-info/PKG-INFO
15
- src/surveyGenGui.egg-info/SOURCES.txt
16
- src/surveyGenGui.egg-info/dependency_links.txt
17
- src/surveyGenGui.egg-info/top_level.txt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/surveyGenGui.egg-info/dependency_links.txt DELETED
@@ -1 +0,0 @@
1
-
 
 
src/surveyGenGui.egg-info/top_level.txt DELETED
@@ -1,4 +0,0 @@
1
- Start_Page
2
- __init__
3
- gui_elements
4
- pages