使用 Streamlit 构建交互式测验应用程序 🚀

介绍

Streamlit 是一个出色的框架,可用于用 Python 创建交互式 Web 应用程序。在本教程中,我们将构建一个功能齐全的测验应用程序,该应用程序具有实时反馈、评分和重新启动测验的选项。该项目演示了如何使用片段构建 Streamlit 应用程序以实现模块化和可维护性。

读完本文后,您将获得一个具有以下功能的测验应用程序:

  • 显示多项选择题。
  • 对用户响应提供即时反馈。
  • 跟踪并显示用户的分数。
  • 允许重新开始测验。
  • 为什么要使用Streamlit Fragments?

    Streamlit 中的 `@st.fragment` 装饰器允许开发人员通过将相关组件封装到可重复使用且独立的块中来模块化他们的应用程序。这种方法简化了开发过程,提高了可维护性,并通过避免不必要地重新运行应用程序的不相关部分来提高性能。

    在这个测验应用中,我们利用片段来管理不同的功能,例如显示问题、提供反馈、显示分数和重新开始测验。

    代码

    以下是 Streamlit 测验应用程序的完整代码:

    import streamlit as st
    
    # Initialize session state variables
    if "questions" not in st.session_state:
        st.session_state.questions = [
            {"question": "What is the capital of France?", "options": ["Paris", "London", "Berlin"],
             "answer": "Paris"},
            {"question": "What is the largest ocean in the world?", "options": ["Atlantic", "Pacific", "Indian"],
             "answer": "Pacific"},
            {"question": "What is the chemical symbol for water?", "options": ["H2O", "O2", "CO2"], "answer": "H2O"},
        ]
    
    if "current_question" not in st.session_state:
        st.session_state.current_question = 0
    
    if "score" not in st.session_state:
        st.session_state.score = 0
    
    if "feedback" not in st.session_state:
        st.session_state.feedback = None
    
    @st.fragment
    def question_fragment():
        """
            Fragment to display a question and capture the user's response.
        """
        question_data = st.session_state.questions[st.session_state.current_question]
        st.subheader(f"Question {st.session_state.current_question + 1}/{len(st.session_state.questions)}")
        st.write(question_data['question'])
    
        selected_option = st.radio('Choose an answer: ', question_data['options'])
        if st.button('Submit'):
            if selected_option == question_data['answer']:
                st.session_state.feedback = ('success', 'Correct! 🎉')
                st.session_state.score += 1
            else:
                st.session_state.feedback = ("error", f"Wrong! The correct answer was: {question_data['answer']}")
    
            if st.session_state.current_question + 1 < len(st.session_state.questions):
                st.session_state.current_question += 1
                st.rerun()
            else:
                st.session_state.current_question = None
                st.rerun()
    
    @st.fragment
    def feedback_fragment():
        """
        Fragment to display feedback messages.
        """
        if st.session_state.feedback:
            msg_type, msg_content = st.session_state.feedback
            if msg_type == "success":
                st.success(msg_content)
            elif msg_type == "error":
                st.error(msg_content)
            st.session_state.feedback = None
    
    @st.fragment
    def score_fragment():
        """
            Fragment to display the user’s current score.
        """
        st.metric('Current Score', st.session_state.score)
    
    @st.fragment
    def restart_quiz_fragment():
        """
            Fragment to restart the quiz.
        """
        if st.button('Restart Quiz'):
            st.session_state.current_question = 0
            st.session_state.score = 0
            st.session_state.feedback = None
            st.rerun()
    
    # Main application
    st.title('Interactive Quiz App')
    
    feedback_fragment()
    
    if st.session_state.current_question is not None:
        score_fragment()
        question_fragment()
    else:
        st.subheader('Quiz Finished! 🎉')
        st.write(f"Your final score is {st.session_state.score}/{len(st.session_state.questions)}.")
        restart_quiz_fragment()

    代码解析

    1. 会话状态初始化

    会话状态变量可确保测验数据(问题、当前问题索引、分数和反馈)在用户交互过程中持久保存。这些变量在应用的生命周期内仅初始化一次。

    2. 模块化设计的片段

    该应用程序使用 Streamlit 片段(`@st.fragment`)将功能封装到可重用的组件中:

  • question_fragment():显示当前问题和选项,验证用户的答案,并更新状态。
  • feedback_fragment():对用户的答案(正确或不正确)提供即时反馈。
  • score_fragment():动态显示用户的分数。
  • restart_quiz_fragment():重置所有会话状态变量,允许用户重新开始测验。
  • 3.实时反馈

    每次回答后,应用程序都会显示成功或错误消息,增强测验的互动性。

    4. 动态状态更新

    该应用程序更新问题索引(“current_question”),并在每个问题之后使用“st.rerun()”重新渲染界面。

    特征

  • 动态问题进展:应用程序验证后自动转到下一个问题。
  • 实时反馈:用户可以立即收到对其答案的反馈。
  • 分数追踪:测验期间实时显示分数。
  • 重新开始选项:用户可以随时重新开始测验。
  • 逐步执行

  • 显示问题:question_fragment 每次显示一个问题及其多项选择选项。选择答案并点击“提交”后,应用会验证答案并更新状态。
  • 提供反馈:feedback_fragment 显示答案是否正确。显示后会重置反馈以避免重复。
  • 更新分数:正确答案会增加分数,并使用 score_fragment 动态显示。
  • 测验结束:当所有问题都得到回答后,应用程序将显示最终得分并提供重新开始的选项。
  • 潜在的改进

  • 随机排列问题:添加功能,以随机化每个测验环节的问题顺序。
  • import random
       random.shuffle(st.session_state.questions)
  • 添加计时器:为每个问题引入倒计时器以增加难度。
  • 自定义问题:允许用户在开始测验之前输入自己的问题和答案。
  • 多种测验类别:提供从不同测验主题或类别中选择的选项。
  • 结论

    这款 Streamlit 测验应用展示了模块化设计和交互元素的强大功能。通过实时反馈和分数跟踪,它提供了引人入胜的用户体验。您可以通过添加问题打乱、计时器或多个测验主题等功能进一步增强它。