Outcome quiz / Troubleshooting manual app

I would like to do an app, that based on outputs lead to some conclusion.
I made a simplified flow chart, what i would like to achieve:

The Problem i have are several nested “st.buttons”. I not able to nest more than two buttons. The example of two nested buttons is here (https://discuss.streamlit.io/t/button-inside-button/12046/6)
The prefered solution would be with

placeholder.container()

The only an actual question should be visible on the screen, but here i not able as well, to do more than two nested “levels”:

import streamlit as st

#You can check .empty documentation
placeholder = st.empty()

with placeholder.container():
st.title(“Pump broken”)
btn = st.button(“Yes”)
btn1 = st.button(“No”)

#If btn is pressed or True
if btn:
#This would empty everything inside the container
placeholder.empty()

st.write('Warranty?')

c1, c2 = st.columns(2)
c1 = c1.button('Yes', key="1")
c2 = c2.button('No', key="2")

if c1:
    st.session_state['button'] = False
    st.write('Vibrations?')

Can someone code the nested example as shown on the picture above?
Is it at all possible with Streamlit?

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).

Anyway, here’s some code that should work, which you can see running at
https://playground.streamlitapp.com/?q=choice-picker :

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)

Hi blackary,

You are the best. Thank you so much. I like the solution without a lot of repeated code. :clap:

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:

grafik

wih:

placeholder = st.empty()

and

st.session_state

Thank you in advance.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.