You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Streamlit输入测试题答案时页面重置循环问题求助

Streamlit测试页面重置问题解决方案

问题根源

Streamlit的运行机制是每次用户交互都会重新执行整个脚本,你的代码没有通过st.session_state跟踪当前应用所处的阶段(候选人信息填写/测试答题)。所以当你在测试题输入框中输入内容时,页面重绘后脚本会重新执行main()函数,回到初始的信息填写界面。

解决方案

通过st.session_state管理应用状态,标记当前所处阶段,同时保存候选人信息、答题内容等关键数据,避免重绘时丢失状态。

修改后的完整代码

import streamlit as st
import pandas as pd

def main():
    st.title('Employer Test')
    
    # 初始化会话状态变量
    if 'stage' not in st.session_state:
        st.session_state['stage'] = 'info'  # info: 信息填写阶段, test: 测试阶段, completed: 测试完成
    if 'full_name' not in st.session_state:
        st.session_state['full_name'] = ""
    if 'answers' not in st.session_state:
        st.session_state['answers'] = [""] * 3

    # 信息填写阶段
    if st.session_state['stage'] == 'info':
        st.markdown('## Candidate Information')
        
        # 绑定输入到session_state,避免重绘丢失
        st.session_state['full_name'] = st.text_input('Full Name', value=st.session_state['full_name'])
        experience = st.selectbox("Experience", ["Fresher"], index=0)
        language = st.selectbox("Language", ["Python"], index=0)

        if st.button('Submit'):
            if st.session_state['full_name']:
                st.session_state['stage'] = 'test'  # 切换到测试阶段
                st.rerun()  # 立即重绘页面,显示测试内容

    # 测试答题阶段
    elif st.session_state['stage'] == 'test':
        run_python_test()

    # 测试完成阶段
    elif st.session_state['stage'] == 'completed':
        st.success("测试已完成,结果已保存!")

def run_python_test():
    st.title('Python Test')

    questions = [
        {
            'question': 'What is the output of the following code?\n\n```python\nx = 5\nprint(x)\n```',
            'options': ['5', '10', '0', 'Error'],
            'correct_answer': '5'
        },
        {
            'question': 'Which of the following is a Python data type?',
            'options': ['List', 'Streamlit', 'GitHub', 'HTML'],
            'correct_answer': 'List'
        },
        {
            'question': 'What is the result of the expression 3 + 7 * 2?',
            'options': ['13', '20', '17', 'Error'],
            'correct_answer': '17'
        }
    ]

    total_questions = len(questions)
    score = 0

    # 显示题目并绑定输入到session_state
    for i, question_data in enumerate(questions):
        st.write(f'Question {i+1}: {question_data["question"]}')
        st.session_state['answers'][i] = st.text_area(
            f"Enter answer for Question {i+1}", 
            value=st.session_state['answers'][i],
            key=f"answer_{i}"
        )

    if st.button("Submit Test", key="submit_test"):
        # 计算分数
        for i, ans in enumerate(st.session_state['answers']):
            if ans.strip() == questions[i]['correct_answer']:
                score += 1
            st.write(f"Question {i+1} Answer: {ans}")
        
        percentage_score = (score / total_questions) * 100
        st.write(f"Your score: {percentage_score}%")

        if percentage_score >= 60:
            save_result(st.session_state['full_name'], percentage_score)
            st.session_state['stage'] = 'completed'
            st.rerun()

def save_result(full_name, score):
    data = {'Full Name': [full_name], 'Score': [score]}
    df = pd.DataFrame(data)
    # 追加写入而不是覆盖,避免之前的结果丢失
    df.to_csv('test_results.csv', mode='a', header=not pd.io.common.file_exists('test_results.csv'), index=False)
    st.write('Result saved successfully!')

if __name__ == '__main__':
    main()

关键改动说明

  1. 状态管理:用st.session_state['stage']标记当前所处阶段,确保页面重绘后能保持在正确的界面。
  2. 数据持久化:将候选人姓名、答题内容绑定到st.session_state,避免交互时丢失输入内容。
  3. 页面切换:使用st.rerun()在状态切换后立即重绘页面,确保用户能看到对应阶段的内容。
  4. 结果保存优化:修改CSV写入逻辑为追加模式,避免覆盖之前的测试结果。

内容的提问来源于stack exchange,提问作者Dharniesh P R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:25:36