SungyongAn
@SungyongAn

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

st.text_inputはst.writeの中に組み込むことは可能?

出力した問題の後ろに解答欄を設置したい

現状では以下のような表記になっています
スクリーンショット 2024-11-26 11.20.57.png

希望としては出題された式の「=」の後ろに回答入力欄を設置したいのですが、下記のようにダメ元で問題を出力する時にst.text_inputを組み込んでみましたがエラーとなりました。

for idx, question in enumerate(st.session_state.questions, 1):
        st.write(f'<p style="font-size: 20px;">問{idx}) {question} {st.text_input")}</p>', unsafe_allow_html=True)

ネット上で検索を行ってみましたが知識不足も否めず、そもそも可能なのかどうかも判断がつかない状態です。
ご教授のほどよろしくお願いします。

以下は現在のコードになります。
※元のコードは他の計算問題もあ流溜め足し算と問題、正解の出力関連の部分のみ抜粋しております。情報に不足があれば指摘頂ければと思います。

from fractions import Fraction
import requests
import streamlit as st


if 'questions' not in st.session_state:
    st.session_state.questions = []
if 'answers' not in st.session_state:
    st.session_state.answers = []
if 'show_answers' not in st.session_state:
    st.session_state.show_answers = False


st.title('算数の勉強部屋')
st.write('')

st.sidebar.write("注意:半角小文字の数字を入力してください。")
a = st.sidebar.text_input("問題数", value='5')
b = st.sidebar.text_input("桁数", value='2')


# 足し算
if st.sidebar.button(" + (足し算)"):
    try:
        num_questions = int(a)
        num_digits = int(b)
    except ValueError:
        st.sidebar.error("問題数と桁数には整数を入力してください。")
    else:
        st.session_state.questions = []
        st.session_state.answers = []
        st.session_state.show_answers = False

        for i in range(num_questions):
            url = 'http://127.0.0.1:8000/page_add'
            response = requests.post(url, json={"num_times": 2, "num_range": num_digits})
            if response.status_code == 200:
                data = response.json()
                question_list = data["question_list"]
                answer = data["answer"]
                question = f"{question_list[0]} + {question_list[1]} = "
                st.session_state.questions.append(question)
                st.session_state.answers.append(int(answer))
            else:
                st.error(f"{response.status_code}エラーが発生しました。詳細は以下を参照ください")
                st.json(response.json())
                break

# 各計算問題の出力
if st.session_state.questions:
    answer_list = []
    st.write("### 問題一覧")
    for idx, question in enumerate(st.session_state.questions, 1):
        st.write(f'<p style="font-size: 20px;">問{idx}) {question}</p>', unsafe_allow_html=True)
        answer_list.append(st.text_input(f"回答{idx}"))

    if st.button('正解表示'):
        st.session_state.show_answers = True

    if st.session_state.show_answers:
        st.write("### 正解一覧")
        for idx, answer in enumerate(st.session_state.answers, 1):
            st.write(f'<p style="font-size: 20px;">問{idx}){answer}</p>', unsafe_allow_html=True)
            list_idx = idx - 1
            if int(answer_list[list_idx]) == int(answer):
                st.write("○")
            else:
                st.write("×")
0

1Answer

以下のようにst.emptyを利用するのはいかがでしょうか。

output = st.empty()
output.write("問1) 16+19=")
ans = st.text_input()
output.write(f"問1) 16+19= {ans}")

1Like

Comments

  1. @SungyongAn

    Questioner

    @gaugau1106
    アドバイスありがとうございます。
    今回の作っているWebアプリでは問題数を複数同時に出力することもありますので、st.empty()では難しいと考えております。
    また、試しに提案頂いたコードの起動確認を行いましたが、3行目でエラーとなってしまいうようです。
    エラー内容
    TypeError: TextWidgetsMixin.text_input() missing 1 required positional argument: 'label'
    自分の理解不足で活用できていない可能性もあるかと思いますので、選択肢の一つとして色々と試していきたいと思います。
    ありがとうございました。

  2. すみません、共有したコードは引数が足りていなかったようです。
    上記修正し、共有いただいたコードに反映して試してみましたところ、所望の動作になっているように見えるのでお試しください。

    for idx, question in enumerate(st.session_state.questions, 1):
        output = st.empty()
        output.write(f'<p style="font-size: 20px;">問{idx}) {question}</p>', unsafe_allow_html=True)
        ans = st.text_input(f"回答{idx}")
        answer_list.append(ans)
        output.write(f'<p style="font-size: 20px;">問{idx}) {question}={ans}</p>', unsafe_allow_html=True)
    
  3. @SungyongAn

    Questioner

    @gaugau1106
    改めてのアドバイスありがとうございます。
    自分の文章の書き方が悪かったようで意図がうまく伝えられてなかったようです。
    すいません。
    頂いたコードだと以下の表記になるのですが、
    スクリーンショット 2024-11-27 13.22.05.png
    スクリーンショット 2024-11-27 13.22.05

    今回の希望としては
    問1) 42 + 58 = [ここに入力欄を配置]
    という形になります。
    表現がわかりにくくて申し訳ありませんでした。
    ただ、今回頂いたコードで一つ理解度が深まりました。
    ありがとうございます。

  4. @SungyongAn

    Questioner

    @gaugau1106
    まだ不完全ですが自分の考えを形にできそうな情報があったためお伝えしておきます。
    この形からもうちょと整えられないか考えて行きたいと思います。

    参考元:https://discuss.streamlit.io/t/horizontally-align-st-text-input-and-st-form-submit-button-in-st-form-in-the-same-line/48588/2

    if st.session_state.questions:
        answer_list = []
        st.write("### 問題一覧")
        col1, col2 = st.columns(2)
        for idx, question in enumerate(st.session_state.questions, 1):
            with col1:
                st.write(f'<p style="font-size: 20px;">問{idx}) {question} </p>', unsafe_allow_html=True)
            with col2:
                p_answer = st.text_input(f'(回答{idx})', value=0)
            # answer_list.append(col2)
    

    スクリーンショット 2024-11-28 9.10.46.png
    スクリーンショット 2024-11-28 9.10.46

Your answer might help someone💌