Organic Slider Method?

When you change the value of a slider, is there a way to change the value of another slider?

Here’s my problem and what I want to do.

  1. the initial value of each slide I created initially.
  • When I change the value of one of the 4 sliders, I want to keep the value I changed, but change the other slider values to match the initial value (weight). (The sum of the values of all sliders is 100.
  1. (Problem I am having) When I change the value of one slider, it behaves as follows.

*The reason it looks like this is because in my code, when there is a value change, I reassign the sliders to the same columns…

2-2. when I click again, only one slider appears (this is a problem I’m having because I’m not very good with sessions…)

In fact, the organic slider issue and the session issue are probably intertwined, and I want to create a slider that works smoothly across the board.

This is an esoteric problem for me and I would really appreciate any help.

I don’t know if it will help, but I’ll post the code I’m working on as is.


    recommend_weights = []
    recommend_stock_names = []
    if 'recommend_stock_names' not in st.session_state:
        st.session_state['recommend_stock_names'] = []
    if len(recommend_stocks) > 0:
        optimal_weights = rp.get_portfolio_optimal(recommend_stocks)
        column_count = 5
        print(f"-------------------")
        print(f"optimal_weights: {optimal_weights}")

        if 'optimal_weights' not in st.session_state:
            st.session_state['optimal_weights'] = optimal_weights

        if optimal_weights != st.session_state['optimal_weights']:
            st.session_state['optimal_weights'] = optimal_weights
            st.session_state['guide_weight'] = optimal_weights

        #
        if 'guide_weight' not in st.session_state:
            st.session_state['guide_weight'] = optimal_weights

        guide_weight = st.session_state['guide_weight']

        # 비중 조절 슬라이더를 생성 UI 로직.
        col_weight_reco = st.columns(column_count)
        for idx, stock in enumerate(recommend_stocks):
            stock_name = option_info['stock_match'][stock]
            recommend_stock_names.append(stock_name)
            stock_link = f"[{stock_name}](https://rank.newsystock.com/NewsyRank/StockAnalysis/SA_Diagnosis.aspx?StockCode={stock}&Univ=KF-ALL)"

            weight_value = guide_weight[idx] if idx < len(guide_weight) else math.floor(1 / len(recommend_stocks) * 10000) / 100

            recommend_weight = col_weight_reco[idx % column_count].slider(stock_link, min_value=0.00, max_value=100.00, value=weight_value, step=1.00)
            recommend_weights.append(recommend_weight)

            if (idx + 1) % column_count == 0:
                # 5개 열이 생성되면, 새로운 열 컬럼을 생성합니다.
                col_weight_reco = st.columns(column_count)

        # st.session_state['recommend_weight'] = recommend_weights
        if recommend_weights != guide_weight:
            print(f"guide : {guide_weight}")
            print(f"recom : {recommend_weights}")

            st.session_state['guide_weight'] = recommend_weights

            # guide와 recom 다른 인덱스.(
            diff_idx = [idx for idx, (g, r) in enumerate(zip(guide_weight, recommend_weights)) if g != r]
            print(diff_idx)

            # 해당 인덱스 제외하고, 남은 비중 계산.
            remain_weight = 100 - sum([recommend_weights[idx] for idx in diff_idx])
            origin_sum = sum([optimal_weights[idx] for idx in range(len(recommend_weights)) if idx not in diff_idx])

            # 해당 인덱스는 바뀐 비중으로 적용하고, 다른 인덱스들은 optimal_weights 비중에 맞춰 비중 변경.
            for idx in range(len(recommend_weights)):
                if idx in diff_idx:
                    pass
                else:
                    recommend_weights[idx] = round(optimal_weights[idx] / origin_sum * remain_weight, 2)
            print(f"change : {recommend_weights}, sum : {sum(recommend_weights)}")
            change_weight = []
            for idx, w in enumerate(recommend_weights):
                stock = recommend_stocks[idx]
                stock_name = option_info['stock_match'][stock]
                stock_link = f"[{stock_name}](https://rank.newsystock.com/NewsyRank/StockAnalysis/SA_Diagnosis.aspx?StockCode={stock}&Univ=KF-ALL)"
                recommend_weight = col_weight_reco[idx % column_count].slider(stock_link, min_value=0.00, max_value=100.00, value=w, step=1.00)
                change_weight.append(recommend_weight)
            recommend_weights = change_weight
            st.markdown(sum(recommend_weights))

And I don’t know if it’ll help, but I’m also putting up the page.

genportview: https://genportview.streamlit.app/portfolio-manager2

I solved it with ‘st.experimental_rerun()’.

To prevent the slider from being created twice, I entered the session value in the slider’s value, put the calculated value in the session, and ran ‘st.experimental_rerun()’.

However, it adds the calculation once when reloading the page, so I added another session that doesn’t recalculate if the settings haven’t changed.

Here’s the code for the slider part


    if len(recommend_stocks) > 0:
        optimal_weights = rp.get_portfolio_optimal(recommend_stocks)
        column_count = 5
        # print(f"-------------------")
        # print(f"optimal_weights: {optimal_weights}")

        if 'optimal_weights' not in st.session_state:
            st.session_state['optimal_weights'] = optimal_weights

        if optimal_weights != st.session_state['optimal_weights']:
            st.session_state['optimal_weights'] = optimal_weights
            st.session_state['guide_weight'] = optimal_weights

        #.
        if 'guide_weight' not in st.session_state:
            st.session_state['guide_weight'] = optimal_weights

        guide_weight = st.session_state['guide_weight']

        # Create a reweighting slider in the UI logic.
        col_weight_reco = st.columns(column_count)
        for idx, stock in enumerate(recommend_stocks):
            stock_name = option_info['stock_match'][stock]
            recommend_stock_names.append(stock_name)
            stock_link = f "[{stock_name}](https://rank.newsystock.com/NewsyRank/StockAnalysis/SA_Diagnosis.aspx?StockCode={stock}&Univ=KF-ALL)"

            weight_value = st.session_state['guide_weight'][idx] if idx < len(st.session_state['guide_weight']) else math.floor(
                1 / len(recommend_stocks) * 10000) / 100

            recommend_weight = col_weight_reco[idx % column_count].slider(stock_link, min_value=0.00, max_value=100.00, value=weight_value, step=1.00)
            recommend_weights.append(recommend_weight)

            if (idx + 1) % column_count == 0:
                # if there are 5 columns, create a new column.
                col_weight_reco = st.columns(column_count)

        # st.session_state['recommend_weight'] = recommend_weights
        if recommend_weights != st.session_state['guide_weight']:
            # print(f"guide : {st.session_state['guide_weight']}")
            # print(f"recom : {recommend_weights}")

            # guide and recom different indexes.(
            diff_idx = [idx for idx, (g, r) in enumerate(zip(guide_weight, recommend_weights)) if g != r]
            # print(diff_idx)

            # Calculate remaining weight, excluding that index.
            remain_weight = 100 - sum([recommend_weights[idx] for idx in diff_idx])
            origin_sum = sum([optimal_weights[idx] for idx in range(len(recommend_weights)) if idx not in diff_idx])

            # apply that index with the changed weight, and change the weights of other indexes to match the optimal_weights weight.
            for idx in range(len(recommend_weights)):
                if idx in diff_idx:
                    pass
                else:
                    recommend_weights[idx] = round(optimal_weights[idx] / origin_sum * remain_weight, 2)
            st.session_state['guide_weight'] = recommend_weights
            # print(f"change : {recommend_weights}, sum : {sum(recommend_weights)}")

            st.experimental_rerun()

The results of the behavior can be seen on the next page.

https://genportview.com/portfolio-manager

Behavior screen

streamlit-🎨_젠포트뷰-2023-05-25-14-05-14

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