Displaying a changing variable

Say you have a variable x that changes value in a while loop, and you want to display this variable. I tried st.write(x) but it just writes it line after line. The variable is always decreasing in value so I guess I can use a progress bar to display it, but I wonder if there are other ways to display it without it producing a new line in each iteration?
Thanks

Check out st.empty – it creates a placeholder you can update.

import streamlit as st
import time

with st.empty():
    for seconds in range(60):
        st.write(f"⏳ {seconds} seconds have passed")
        time.sleep(1)
    st.write("✔️ 1 minute over!")

Thanks. But when I used st.empty() in my cached function, the function seems to lose the caching ability as it reruns each time.

Post up a minimal example of what you are doing / trying to accomplish

import streamlit as st

@st.cache_data(show_spinner=False)
def append_list(num_iterations):
    with st.spinner('This might take awhile...'):
        mylist = []
        with st.empty():
            for i in range(num_iterations):
                st.write(f"Iteration number is {i}")
                mylist.append(i)
    return mylist

output = append_list(10000)
selection = st.selectbox('Make a selection', ['Good','Bad'])
if selection == 'Good':
    st.write('You selected Good')
else:
    st.write('You selected Bad')

In the above code, I have the iteration number displayed in place using st.empty(), and the function is cached. However, if the user toggles the selection box at the bottom, the iteration number go from a low number to max, and it’s slow, even though the function is cached and it only outputs an appended list.

I’ve tried your example and honestly to me it seems like it is working as expected. It’s hard to notice the speed difference between the first and subsequent runs because the function isn’t doing any work right now and is so blazing fast anyway – the screen updates take most of the time.

Here is a slightly reworked version of your code that makes it more obvious the cache is working:

import time

import streamlit as st


@st.cache_data(show_spinner=False)
def append_list(num_iterations):
    with st.spinner("This might take awhile..."):
        mylist = []
        count = 0
        with st.empty():
            for _ in range(num_iterations):
                for _ in range(10000):
                    count += 1
                    st.write(f"Iteration number is {count}")
                    mylist.append(count)
                time.sleep(1)

    return mylist


output = append_list(5)
selection = st.selectbox("Make a selection", ["Good", "Bad"])
if selection == "Good":
    st.write("You selected Good")
else:
    st.write("You selected Bad")

The first time you re-run it, you’ll notice the 1 second sleeps between each of the blocks of 10,000. Subsequent re-runs will not have this delay and will iterate up to 50,000 as fast as Streamlit can process the cached messages.

I was actually surprised this worked this way, I didn’t realize the messages from “st.whatever” calls got replayed from within a function decorated with cache_data. I looked into the code a bit and found that this is intended and expected – cool!

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