def parse_QA_list(QA_list, opt_start, opt_item_name, opt_item_end, opt_delimiter, unanswerable_option, random_seed):
    """Parse each QA pair in the QA_list to qa / qa_w_option / qa_w_cot / qa_w_cot_w_option"""
    new_QA_list = []
    for idx, qa_entry in enumerate(QA_list):
        try:
            # step 1. extract cot if exists
            if "\nLet's think step by step." in qa_entry['Q'] or "\nTherefore, the answer is " in qa_entry['A']:
                try:
                    assert qa_entry['Q'].endswith("\nLet's think step by step."), f"qa_entry['Q']: {qa_entry['Q']} does NOT ends with `\nLet's think step by step.`"
                    question_wo_cot = qa_entry['Q'][:-len("\nLet's think step by step.")].strip()
                    assert len(question_wo_cot) > 0, f'question_wo_cot: `{question_wo_cot}` is empty'

                    if len(qa_entry['A'].split("\nTherefore, the answer is ")) == 2:
                        cot, final_answer =  qa_entry['A'].split("\nTherefore, the answer is ")
                        cot, final_answer = cot.strip(), final_answer.strip()
                        if cot.endswith('.'): cot = cot[:-1] # remove the . at the end, we would add them in the fs template
                        assert len(cot) > 0 and len(final_answer) > 0, f'invalid cot: {cot} or invalid final_answer: {final_answer}'
                    else:
                        raise Exception(f"fail to extract cot and final answer from qa_entry['A']: {qa_entry['A']}")

                    has_cot = True

                except Exception as e:
                    continue
            else:
                question_wo_cot = qa_entry['Q']
                final_answer = qa_entry['A']
                has_cot = False

            # step 2. extract option if exists
            if '\nOptions:\n- ' in question_wo_cot:
                # parse question_str to raw question and the option_list
                assert len(question_wo_cot.split('\nOptions:\n- ')) == 2, f"invalid option question: {question_wo_cot}"
                question_wo_opt_wo_cot, option_str = question_wo_cot.split('\nOptions:\n- ')
                assert len(question_wo_opt_wo_cot) > 0, f'invalid question_wo_opt_wo_cot: {question_wo_opt_wo_cot}'
                option_list = option_str.split('\n- ')
                assert len(option_list) > 0, f'Failed to parse option list from: {option_str}'
                # format option_str and answer
                kw_dic = {'question': question_wo_opt_wo_cot, 'options': option_list, 'answer': final_answer}
                kw_dic = format_options(example=kw_dic, start_str=opt_start, item_names=opt_item_name, opt_end_str=opt_item_end, opt_delimiter=opt_delimiter, unanswerable_option=unanswerable_option, random_seed = random_seed*idx)
                                                                                                                                # random seed is used to shuffle the options
                                                                                                            # we hope each time we can use a different random seed for diversity
                if has_cot:
                    kw_dic['qa_mode'] = 'fs_option_cot_pattern'
                    kw_dic['cot'] = cot
                else:
                    kw_dic['qa_mode'] = 'fs_option_pattern'
            else:
                kw_dic = {'question': question_wo_cot, 'answer': final_answer}
                if has_cot:
                    kw_dic['qa_mode'] = 'fs_basic_cot_pattern'
                    kw_dic['cot'] = cot
                else:
                    kw_dic['qa_mode'] = 'fs_basic_pattern'
        except Exception as e:
            continue
        new_QA_list.append(kw_dic)
    return new_QA_list
Parse each QA pair in the QA_list to qa / qa_w_option / qa_w_cot / qa_w_cot_w_option
instruction_pretrain/utils/read_compre_pt.py