6

I am new to Streamlit. I want to make a multiple-choice user input (checkboxes). But I want to select a maximum of 3 options out of 4 options.

I have tried with the dropdown feature of multiselect.

import streamlit as st
option = st.multiselect('Select three known variables:', ['initial velocity (u)', 'final velocity (v)', 'acceleration (a)', 'time (t)'])  

It works. But I think it won't be user-friendly for my case. Also, here I couldn't limit the selections to 3 out of 4. The user can select all 4 options here. But I want the code such that if the 4th one is selected, the previous selection (3rd option) will be automatically un-selected. I prefer the looks of the checkboxes such as the radio buttons:

import streamlit as st
option = st.radio('Select three known variables:', ['initial velocity (u)', 'final velocity (v)', 'acceleration (a)', 'time (t)'])  

But using radio, I can't select multiple options. How can I edit it such that I can display it as checkboxes and only 3 options can be selected?

raf
  • 225
  • 1
  • 3
  • 13
  • 1
    It seems that the limiting checkbox options is not possible yet...There's an open feature request for this in their Github repo - [link](https://github.com/streamlit/streamlit/issues/926) – Ewelina Luczak Mar 21 '21 at 21:36

3 Answers3

5

This is visually closest to what you want, because they are actually checkboxes, not the radiobuttons. But you can't limit selected options, so all of them can be checked.

st.write('Select three known variables:')
option_1 = st.checkbox('initial velocity (u)')
option_2 = st.checkbox('final velocity (v)')
option_3 = st.checkbox('acceleration (a)')
option_4 = st.checkbox('time (t)')

enter image description here

As a workaround, you can use radiobuttons in a following way since they allow to check one combination only:

option = st.radio('Select three known variables:',
                  ['initial velocity (u), final velocity (v), acceleration (a)',
                   'initial velocity (u), final velocity (v), time (t)',
                   'initial velocity (u), acceleration (a), time (t)',
                   'final velocity (v),acceleration (a), time (t)'])

enter image description here

Ewelina Luczak
  • 379
  • 4
  • 13
  • Thank you for answering. I was also thinking about this grouping technique with `radio`. But in my main program, the number of total options is 5. And I want to select any 3 from them. So, I would need to provide a total of 10 combinations that don't look good for my purpose. – raf Mar 22 '21 at 07:51
  • 1
    `checkbox` can't limit selections. But is it possible to apply conditional statements such that if the user selects the 4th one, the previous selection (3rd option) will be automatically un-selected? – raf Mar 22 '21 at 07:54
2

I haven't found any streamlit function that fulfills my need properly. So, I am using the function streamlit.checkbox as anilewe suggested and adding some extra conditional statements such that the user must select any 3 checkboxes. Here's my code:

import streamlit as st
st.write('Select three known variables:')
option_s = st.checkbox('displacement (s)')
option_u = st.checkbox('initial velocity (u)')
option_v = st.checkbox('final velocity (v)')
option_a = st.checkbox('acceleration (a)')
option_t = st.checkbox('time (t)')
known_variables = option_s + option_u + option_v + option_a + option_t

if known_variables <3:
    st.write('You have to select minimum 3 variables.')
elif known_variables == 3:
   st.write('Now put the values of your selected variables in SI units.')
else:
    st.write('You can select maximum 3 variables.')

Update: Creating a dictionary can be more automatic & useful; also helpful in case of changing the method from st.checkbox to something else:

import streamlit as st
st.write('Select three known variables:')
opts = [ ('s', 'displacement'), ('u', 'initial velocity'), ('v', 'final velocity'), ('a', 'acceleration'), ('t', 'time') ]
known_variables = {symbol: st.checkbox(f"{name} ({symbol})") for symbol, name in opts}    

if sum(known_variables.values()) < 3:
    st.write('You have to select minimum 3 variables.')
elif sum(known_variables.values()) == 3:
    st.write('Now put the values of your selected variables in SI units.')
else:
    st.write('You can select maximum 3 variables.')

Still, I am wishing to get a function that looks like checkbox or radio buttons but with a built-in feature to limit specific numbers of selections. In a word, I think my desired function can be called "multiselect-radio". Thus I won't have put the additional conditions on limiting selection by myself.

raf
  • 225
  • 1
  • 3
  • 13
1

Consider using st.multiselect with argument max_selections=3.

import streamlit as st

st.multiselect(
    "Select three known variables:",
    ["initial velocity (u)", "final velocity (v)", "acceleration (a)", "time (t)"],
    max_selections=3,
)

enter image description here

You might also want to check for additional conditions, and then use combination of st.error(“please fix this problem”) and st.stop() to inform user about it.

Elijas Dapšauskas
  • 909
  • 10
  • 25
  • Nice. Seems like this argument `max_selections` didn't exist when I asked the question! – raf Aug 26 '23 at 05:26
  • 1
    Also i dont see anyone mentioning st.error and st.stop, they would allow using just the checkboxes (you could check if exactly three are checked with “if sum(a+b+c+d)==3”, where “a=st.checkbox()”. If it’s not three, use st.error and then st.stop – Elijas Dapšauskas Aug 27 '23 at 07:15