File size: 6,428 Bytes
448ed98 5bcad58 448ed98 5bcad58 448ed98 5bcad58 448ed98 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
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")
|