qstn_gui / src /pages /01_Option_Prompt.py
MaxBenKre
updated gui
5bcad58
import streamlit as st
from qstn.prompt_builder import LLMPrompt, generate_likert_options
from qstn.utilities.prompt_templates import (
LIST_OPTIONS_DEFAULT,
SCALE_OPTIONS_DEFAULT,
)
from gui_elements.stateful_widget import StatefulWidgets
st.set_page_config(layout="wide")
st.title("Likert Scale Options Generator")
st.write(
"This interface allows you to configure and generate Likert scale answer options by adjusting the parameters below."
)
st.divider()
if "questionnaires" not in st.session_state:
st.error("You need to first upload a questionnaire and the population you want to survey.")
st.stop()
disabled = True
else:
disabled = False
#if 'answer_texts_input' not in st.session_state:
#st.session_state.answer_texts_input = "Strongly Disagree\nDisagree\nNeutral\nAgree\nStrongly Agree"
state = StatefulWidgets()
# Use a form to batch all inputs together
with st.container(border=True):
# --- Main Configuration ---
st.subheader("Main Configuration")
col1, col2, col3 = st.columns(3)
with col1:
n_options = state.create(
st.number_input,
"n_options",
"Number of Options (n)",
initial_value=5,
min_value=2,
step=1,
help="The total number of choices in the scale.",
)
with col2:
idx_type = state.create(
st.selectbox,
"idx_type",
"Index Type",
initial_value="integer",
options=["integer", "char_low", "char_up"],
help="The type of index to use for the options.",
)
with col3:
start_idx = state.create(
st.number_input,
"start_idx",
"Starting Index",
initial_value=1,
step=1,
help="The number to start counting from (e.g., 1).",
)
# --- Order and Structure Options ---
st.subheader("Ordering and Structure")
col1, col2, col3, col4 = st.columns(4)
with col1:
only_from_to_scale = state.create(
st.checkbox,
"only_from_to_scale",
"From-To Scale Only",
initial_value=False,
help="If checked, only the first and last answer labels are display e.g. 1 Strongly Disagree to 5 Strongly agree.",
)
with col2:
random_order = state.create(
st.checkbox,
"random_order",
"Random Order",
initial_value=False,
help="Randomize the order of options.",
)
with col3:
reversed_order = state.create(
st.checkbox,
"reversed_order",
"Reversed Order",
initial_value=False,
help="Reverse the order of options.",
)
with col4:
even_order = state.create(
st.checkbox,
"even_order",
"Even Order",
initial_value=False,
help="If there is an uneven number of answer texts, the middle section is automatically removed.",
)
# --- Answer Texts Input ---
st.subheader("Answer Texts")
answer_texts = state.create(
st.text_area,
"answer_texts",
"Enter Answer Texts (one per line)",
initial_value="Strongly Disagree\nDisagree\nNeutral\nAgree\nStrongly Agree",
height=150,
help="Enter the labels for each answer option.",
)
# --- Advanced Configuration ---
with st.expander("Advanced Configuration"):
options_separator = state.create(
st.text_input,
"options_separator",
"Options Separator",
initial_value=", ",
help="The character(s) used to separate options in the final string.",
)
list_prompt_template = state.create(
st.text_area,
"list_prompt_template",
"List Prompt Template",
initial_value=LIST_OPTIONS_DEFAULT,
height=100,
help="Write how the options should be presented to the model.",
)
scale_prompt_template = state.create(
st.text_area,
"scale_prompt_template",
"Scale Prompt Template",
initial_value=SCALE_OPTIONS_DEFAULT,
height=100,
help="Write how the options should be presented to the model.",
)
# The submit button for the form
submitted = st.button("Confirm and Generate Options", disabled=disabled, type="primary", use_container_width=True)
if st.button("Skip", use_container_width=True, icon="❌"):
st.session_state.survey_options = None
st.switch_page("pages/02_Prompt_Configuration.py")
# --- Processing and Output ---
if submitted:
#print("Session state answer texts "+ st.session_state.answer_texts_input)
#print(answer_texts_input)
# Convert the raw text area string into a list of strings.
answer_texts_list = [
text.strip() for text in answer_texts.split("\n") if text.strip()
]
# --- Input Validation ---
validation_ok = True
if only_from_to_scale and len(answer_texts_list) != 2:
st.error(
f"Error: When 'From-To Scale Only' is selected, you must provide exactly 2 answer texts. You provided {len(answer_texts_list)}."
)
validation_ok = False
if not only_from_to_scale and len(answer_texts_list) != n_options:
st.error(
f"Error: The number of answer texts ({len(answer_texts_list)}) must match the 'Number of Options' ({n_options})."
)
validation_ok = False
if reversed_order and random_order:
st.error(f"Error: Reversed Order and Random Order cannot both be true.")
validation_ok = False
if validation_ok:
survey_options = generate_likert_options(
n=n_options,
answer_texts=answer_texts_list,
only_from_to_scale=only_from_to_scale,
random_order=random_order,
reversed_order=reversed_order,
even_order=even_order,
start_idx=start_idx,
list_prompt_template=list_prompt_template,
scale_prompt_template=scale_prompt_template,
options_separator=options_separator,
idx_type=idx_type,
)
st.session_state.survey_options = survey_options
st.switch_page("pages/02_Prompt_Configuration.py")