Session State Logic Problem

Summary
In the following example, I have 4 checkboxes with keys A, B, C, D. The goal is to let the user select a checkbox and, based on which key he enables, it displays a data editor with a dataframe with that key and two columns of values “Low”/“High”.

Problem
The thing is, for some reason, let’s say I enable A and change the “High” value to 37, ithen ok. But when I change it to 98, it goes back to 37. It is only if I try to change again to, whatever value let’s say 51, that it changes to 51. How can I fix that?

Code snippet

import pandas as pd
import streamlit as st

if 'df' not in st.session_state:
    st.session_state['df'] = pd.DataFrame(
      index=['A', 'B', 'C', 'D'], 
      columns=['Low', 'High', 'Active'], 
      data=[[.0, 50., False], [.0, 500., False], [.1, 1.5, False], [.0, 50., False]])

st.session_state['df']['Active'].loc['A'] = st.checkbox('A')
st.session_state['df']['Active'].loc['B'] = st.checkbox('B')
st.session_state['df']['Active'].loc['C'] = st.checkbox('C')
st.session_state['df']['Active'].loc['D'] = st.checkbox('D')

active_df = st.session_state['df'][st.session_state['df']['Active'] == True].copy()
edited_df = st.data_editor(active_df[['Low', 'High']])
 
if edited_df is not None:
    for idx, row in edited_df.iterrows():
        st.session_state['df'].loc[idx, ['Low', 'High']] = row['Low'], row['High']

Random Idea
Well I’m struggling to find a logic to fix that. I thought that maybe if I call a function on the “on_change” parameter of “st.data_editor” it could work, but didn’t I need to pass “edited_df” as an argument? But this doesn’t work, so I’m completely lost lol Would appreciate any help! Thanks

Hi @Davi_Bandeira

I believe your issue may be related to st.session_state() and how it handles the data editor along with checkboxes.

To fix the issue, you’d need to ensure that the values in st.session_state['df'] are updated after the edited dataframe is created, and only when the st.data_editor has indeed been changed.

import pandas as pd
import streamlit as st

if 'df' not in st.session_state:
    st.session_state['df'] = pd.DataFrame(
      index=['A', 'B', 'C', 'D'], 
      columns=['Low', 'High', 'Active'], 
      data=[[.0, 50., False], [.0, 500., False], [.1, 1.5, False], [.0, 50., False]])

# Check if there are any updated values from data_editor and update them
if 'updated_values' in st.session_state:
    for idx, values in st.session_state['updated_values'].items():
        st.session_state['df'].loc[idx, ['Low', 'High']] = values
    del st.session_state['updated_values']  # Clear after updating

st.session_state['df']['Active'].loc['A'] = st.checkbox('A')
st.session_state['df']['Active'].loc['B'] = st.checkbox('B')
st.session_state['df']['Active'].loc['C'] = st.checkbox('C')
st.session_state['df']['Active'].loc['D'] = st.checkbox('D')

active_df = st.session_state['df'][st.session_state['df']['Active'] == True].copy()
edited_df = st.data_editor(active_df[['Low', 'High']])

if edited_df is not None:
    if 'updated_values' not in st.session_state:
        st.session_state['updated_values'] = {}
    for idx, row in edited_df.iterrows():
        st.session_state['updated_values'][idx] = (row['Low'], row['High'])

Please find a gif of the results:

Recording 2023-09-19 at 08.33.50

Hopefully this is what you’re after. If not, let me know and I can help you further! :slight_smile:

Best,
Charly

Hi @Charly_Wargnier, thanks for you answer!

Unfortunately, this doesn’t solve my problem. The problem seems to be happening everytime we try to change a value 2 times consecutively (after have enabled some checkbox).

Example:
From the beginning, we enable B and change the “Low” value to 12 and then change it to 37. It will change to 12 at first, but it won’t change it to 37, only if we try again. And this pattern keeps repeating… We try to change it and it work, then we try to change it again and it doesn’t work, and then it work, and then it don’t…

In your example this problem didn’t happened because it was only 1 change per “new selection on the checkbox”, the problem appears to be happening when we don’t change the state of the checkboxes and just start to change values in the data editor