Selecting options for st.radio from dictionary going through session state

Summary

I have a yes/no game created that goes through questions.
I want a radio button instead of text_area field but I donโ€™t know how to satisfy the options variable. Using the text field I had my questions iterate though the value variable.

Steps to reproduce

Code snippet:

import streamlit as st
import pandas as pd
def run_python_test():
    
    st.title('Is the follow statement or question related to XYZ') 
    # Dummy test questions and answers 
    questions = [
        { 'question': 'Question 1',
          'options': ['Yes', 'No'], 
          'correct_answer': 'Yes' 
        },
        { 
          'question': 'Question 2', 
          'options': ['Yes', 'No'], 
          'correct_answer': 'No' 
        },
        { 
          'question': 'Question 3', 
          'options': ['Yes', 'No'], 
          'correct_answer': 'Yes' 
        } 
        # Add more questions here... 
    ]

    total_questions = len(questions) 
    if  'answer' not in st.session_state:
        st.session_state['answer'] = [''] * total_questions 
    for i, question_data in enumerate(questions):
        question = question_data['question']
        
        st.write(f'Question {i+1}: {question}') 
        
        # Display options for each question 
        st.session_state['answer'][i] = st.radio("Test Questin", options = st.session_state['answer'][i], index = 0, key=f"answer_{i}")
        #The following works now but I would like a radio instead. 
        #st.session_state['answer'][i] = st.text_area(f"Enter answer for Question {i+1}", value=st.session_state['answer'][i], key=f"answer_{i}") 

        
        # Add a submit button  
        if st.button("Submit Test", key=f"submit_answer_{i}"):
            score = 0 
            # Process the answers and calculate score  
            for i, ans in enumerate(st.session_state['answer']): 
                if ans == questions[i]['correct_answer']:
                    score += 1
                st.write(f"Question {i+1} Answer: {ans}")
        
            percentage_score = (score / total_questions) * 100 
        
            if percentage_score >= 60:
                save_result(st.session_state['full_name'], percentage_score)
                st.session_state['test_completed'] = True

If applicable, please provide the steps we should take to reproduce the error or specified behavior.

Expected behavior:

Options for each question the correspond to pop up.

Actual behavior:

No options come up for my radio button

Debug info

  • Streamlit version: Version 1.25.0
  • Python version: Python 3.8.3
  • Using PyEnv

Hi @Aragon, is this what you are looking for?

import streamlit as st

mystate = st.session_state
if "qlst" not in mystate:
    mystate.qlst =  [{'question': 'My Qstn #1', 'options': ('Yes', 'No'), 'correct_answer': 'Yes', "marks": 2, "user_response": ""},
                     {'question': 'My Qstn #2', 'options': ('Yes', 'No'), 'correct_answer': 'No',  "marks": 5, "user_response": ""},
                     {'question': 'My Qstn #3', 'options': ('Yes', 'No'), 'correct_answer': 'Yes', "marks": 7, "user_response": ""},]

def QCB(i):
    mystate.qlst[i]['user_response'] = mystate[f'Qkey{i}']

def run_python_test():
    st.subheader('Is the follow statement or question related to XYZ') 
    
    for i in range(len(mystate.qlst)):
        st.radio(mystate.qlst[i]['question'], options = mystate.qlst[i]['options'], 
                 on_change=QCB, args=(i,), horizontal=True, index = None, key=f"Qkey{i}")

    if st.button("Submit Test", key=f"Akey{i}"):
        myscore = sum([x['marks'] for x in mystate.qlst if x['user_response'] == x['correct_answer'] ])
        percentage_score = ((myscore / sum([x['marks'] for x in mystate.qlst])) * 100)
        st.write(f"Your score: {myscore} | % score: {percentage_score:0.2f}%")

run_python_test()

You can have different scores for different questions:

Cheers

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