St.radio not capturing user selection

Dear Streamlit community,
Your help will be greatly appreciated.
In my script, I am attempting to create a synonym test of 20 questions.
No matter, what I click as a radio choice, the selected_choice is always None. So every time, I click a choice, selected_choice is None, the list of choices shuffles but the question doesnt change and therefore no score is done.
Attached is script of the app with session states.

import streamlit as st
import controller_vocab as controller
import model_vocab as model


def synonym_test():
    """Executes the synonym test"""

    st.title("Synonym Test")

    # Initialize the test if it hasn't been started yet
    if "question_index" not in st.session_state:
        st.session_state.test_number = controller.start_synonym_test()
        st.session_state.synonym_test_active = True
        st.session_state.question_index = 0
    

    test_number = st.session_state.test_number
    question_index = st.session_state.question_index #Load index number 
    total_questions = controller.get_the_number_words()

    if(question_index >= total_questions): #If the test is finished
        #Calculate and render results.
        total_score = controller.submit_synonym_test(test_number)
        st.write("All 20 words attempted")
        st.write("Total Score",total_score)
        st.session_state.question_index = 0 #set to 0 as default
        st.session_state.test_submitted = False #set to test to be false
        del st.session_state['test_number']
        del st.session_state['question_index']
        del st.session_state['synonym_test_active']
       

    #Present the Synonym Game, or show that it is completed
    
    current_word = controller.get_current_question(question_index,test_number) # load words for question
    print('Current word: ' + str(current_word))

    if (current_word != -1 and question_index < total_questions): #If the test is setup and is not end of test, present question.

        #Load the variables
        synonym_choices, correct_ans = controller.get_synonym_choices(current_word)
        st.subheader(f"What is a synonym for: **{current_word}**?")
        

        #Set defaults, so the memory is refreshed each load
        selected_choice = st.radio("Choose a synonym:", synonym_choices, index=None, 
                                   key=f"radio_q_{question_index}")
        st.write(selected_choice)
        st.write (st.session_state)
        print ('correct_ans ', correct_ans)
        print('selected_choice ', selected_choice )
      
        
        #After selection, we do the following (To force each choice on it.)
        if selected_choice:
            #controller.score_answer(selected_choice,question_index,test_number) #Moved to the click event
            
             if st.button("Next", key=f"button_next_{question_index}"):
                controller.score_answer(selected_choice, question_index, test_number)
                st.session_state.question_index += 1   #Added this because streamlite action, requires action
                st.rerun() #rerun and show next page
        else:
             st.write ("Make a selection for all words") #If is not what to do

    else:
        #Calculate and render results. This is the code after the last is selected.
        total_score = controller.submit_synonym_test(test_number)
        st.write("All 20 words attempted")
        st.write("Total Score",total_score) #If there more than 1
        st.session_state.question_index = 0 #set to 0 as default
        #if f"test" in st.session_state: del st.session_state['test']
        # st.info("Select synonym from sidebar to test you know all your stuff")
        #You have to wipe after all is said and done
        test_memory_dump =['test_number','question_index','synonym_test_active', 'radio_selection']
        for memory in test_memory_dump: #To have a clean code to read memory location for all items with del
             if memory in st.session_state: del st.session_state[memory]
        #Load default pages for action        
        test_action_dump =  []  #To have a clean code to read load key
        test_action = ['test_submitted' ]  #Test cases
        test_memory_action = {}

if __name__ ==  '__main__' : synonym_test()
`type or paste code here`

I dont understand why selected_choice is always None no matter what I select. Also somethings, I see the key of the radio selection having a value and sometimes it’s a null. The session state variables are defined in this script and few of them are in the controller script that this script imports.
I am using:
Python 3.10.7
Streamlit, version 1.45.0

Please advise, if possible.

Sincerely,
Martin

The index is always “None” each time the code rerun (each time you click a choice).
You should had a session state there :

#An example of session state i would used
        if radio_key not in st.session_state:
            st.session_state[radio_key] = None

        selected_choice = st.radio(
            "Choose a synonym:",
            synonym_choices,
            index=None,
            key=radio_key
        )

        # This gets the stored value, even across reruns
        selected_choice = st.session_state[radio_key]

And clear after Next question as you did :

if st.button("Next", key=f"button_next_{question_index}"):
    controller.score_answer(selected_choice, question_index, test_number)
    del st.session_state[radio_key]  # Clear selection for next question
    st.session_state.question_index += 1
    st.rerun()