This may be more complicated of a solution than you’re looking for, but here is one way to accomplish this without a lot of repeated code, but creating a custom class that knows how to go down that “tree” that you’ve down if you choose yes or no. The essence of it is "display a button, if the Yes button is pressed, then keep track of that with st.session_state. This is necessary because a button doesn’t keep its state between app runs (unlike something like a text box or a checkbox).
from dataclasses import dataclass
from typing import Optional
import streamlit as st
@dataclass
class Choice:
"""
A choice for a question. A choice must have a label, and if you want to
show a different choice if yes or no is picked, you can specify that.
"""
label: str
if_true: Optional["Choice"] = None
if_false: Optional["Choice"] = None
# Create set of choices by starting at the bottom and working up
service = Choice("Call a service")
noise = Choice("Noise?", service)
oil = Choice("Oil?", noise)
vibrations = Choice("Vibrations?", oil)
warranty = Choice("Warranty?", vibrations)
broken = Choice("Pump Broken?", warranty)
# Create placeholders for the text, and the yes/no buttons
placeholder = st.empty()
col1, col2 = st.columns(2)
yes = col1.empty()
no = col2.empty()
def display_choice(choice: Optional[Choice] = None):
"""
Display a single choice, including yes and no buttons if applicable, and go to the next choice if
Yes or no is pressed
"""
yes.empty()
no.empty()
# IF there is no choice, we're done
if choice is None:
placeholder.write("No more choices")
yes.button("Start over?")
st.session_state.clear()
return
if choice.label not in st.session_state:
st.session_state[choice.label] = False
placeholder.write(choice.label)
if choice.if_true or choice.if_false:
if (
yes.button("Yes", key=choice.label + "Yes")
or st.session_state[choice.label]
):
st.session_state[choice.label] = True
display_choice(choice.if_true)
elif no.button("No", key=choice.label + "No"):
st.session_state[choice.label] = False
display_choice(choice.if_false)
# Call display_choice for the starting choice
display_choice(broken)
You are the best. Thank you so much. I like the solution without a lot of repeated code.
I tried to implement the code above to my real case and I would prefer a solution with the repeated code, because it would be optimal to add an unique image to the each question and there are several “No” answers, that are meaningfull (the image above was too simplified). Moreover I would like to style the text and the images. Could you provide a “nested” code (repeated), in order to have (at least for me) a freedom to customize the answers and to have a possibility to style the app.
All i need is an example of 4-5 nested buttons with:
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.