Shuffle the order of the options for each question in the question_data. Also updates the "answer" field so that it uses the new letter corresponding to the correct option. Parameters: question_data (dict): A dictionary where keys are question identifiers (e.g., "Questi
(question_data)
| 933 | return overall_accuracy, aspect_summary |
| 934 | |
| 935 | def shuffle_question_options(question_data): |
| 936 | """ |
| 937 | Shuffle the order of the options for each question in the question_data. |
| 938 | Also updates the "answer" field so that it uses the new letter corresponding |
| 939 | to the correct option. |
| 940 | |
| 941 | Parameters: |
| 942 | question_data (dict): A dictionary where keys are question identifiers (e.g., "Question 1") |
| 943 | and values are dictionaries containing at least the keys "options" (a list |
| 944 | of option strings) and "answer" (a string matching one of the options). |
| 945 | |
| 946 | Returns: |
| 947 | dict: A new dictionary with the same structure as question_data but with options shuffled |
| 948 | and answers updated. |
| 949 | """ |
| 950 | # Make a deep copy so we do not modify the original data |
| 951 | new_data = deepcopy(question_data) |
| 952 | |
| 953 | # Loop over each question |
| 954 | for q_key, q_content in new_data.items(): |
| 955 | original_options = q_content.get("options", []) |
| 956 | original_answer = q_content.get("answer", "") |
| 957 | |
| 958 | # Extract the text portion of the original answer. |
| 959 | # We assume that each option (and the answer) has the format "X. <option text>" |
| 960 | if ". " in original_answer: |
| 961 | orig_letter, orig_text = original_answer.split(". ", 1) |
| 962 | else: |
| 963 | # If format not as expected, use the whole answer string |
| 964 | orig_text = original_answer |
| 965 | |
| 966 | # Remove the letter prefixes from each option to obtain a list of option texts. |
| 967 | option_texts = [] |
| 968 | for opt in original_options: |
| 969 | if ". " in opt: |
| 970 | _, text = opt.split(". ", 1) |
| 971 | else: |
| 972 | text = opt |
| 973 | option_texts.append(text) |
| 974 | |
| 975 | # Shuffle the list of option texts |
| 976 | random.shuffle(option_texts) |
| 977 | |
| 978 | # Reassign new letter labels (A, B, C, etc.) to the shuffled options. |
| 979 | new_options = [] |
| 980 | correct_answer_new = None |
| 981 | letters = list(string.ascii_uppercase) |
| 982 | for idx, text in enumerate(option_texts): |
| 983 | new_opt = f"{letters[idx]}. {text}" |
| 984 | new_options.append(new_opt) |
| 985 | # When the option's text matches the original answer text, update the answer field. |
| 986 | if text == orig_text: |
| 987 | correct_answer_new = new_opt |
| 988 | |
| 989 | # Fallback in case no match is found (should not happen if data is consistent) |
| 990 | if correct_answer_new is None: |
| 991 | correct_answer_new = original_answer |
| 992 |