def get_patterns(pattern_dict, random_seed, min_num_of_QAs):
    """sample the collection of patterns to update pattern_dict"""

    def _random_choose(candidates, weights=None):
        if weights is None:
            return random.Random(random_seed).choice(candidates)
        else:
            # choose based on probabilities
            return random.Random(random_seed).choices(candidates, weights=weights, k=1)[0]

    """Explaination for rc_mode
    Classic: the classic reading comprehension mode where the reading material is followed by a series of QA pairs, each is like `Question: xxx\nAnswer: xxx`
    Dialog: the reading material is followed by a two-person conversation like `Person1: xxx, Person2: xxx`
    Numbered_questions: in the followed comprehension test, we first present numerbed_questions, and ask the model to answer them all after all the questions
    Inline_FS: we first show a few examples as reference and then ask the model to answer a testing question
    Next_turn_dialog: first present one turn of dialog and then ask the model to generate more one turn"""

    rc_modes = ['Classic', 'Dialog']
    rc_weights = [95, 5] # set the probs of non_classic modes low
    if min_num_of_QAs >= 2: 
        rc_modes += ['Numbered_Questions', 'Inline_FS', 'Next_turn_dialog']
        rc_weights = [80, 5, 5, 5, 5]

    pattern_dict['rc_mode'] = _random_choose(rc_modes, weights = rc_weights)

    # rc_inversion = True means we first present context after the QAs
    pattern_dict['rc_inversion'] = _random_choose([True, False], weights = [5, 95]) # the reverse mode is very strange now, set as a very low ratio

    # rc_inversion
    pattern_dict['qa_start'] = _random_choose(QA_START_STRING_CANDIDATES)
    pattern_dict['qa_end'] = _random_choose(QA_END_STRING_CANDIDATES)
    pattern_dict['text_start'] = _random_choose(TEXT_START_STRING_CANDIDATES)

    if pattern_dict['rc_mode'] == 'Classic':
        pattern_dict['read_start'] = _random_choose(READ_START_STRING_CANDIDATES)
        pattern_dict['read_end'] = _random_choose(READ_END_STRING_CANDIDATES)
        pattern_dict['compre_start'] = _random_choose(COMPRE_START_STRING_CANDIDATES)
    elif pattern_dict['rc_mode'] in ['Dialog', 'Next_turn_dialog']:
        pattern_dict['dia_start'] = _random_choose(['\n\n', '\n', ' ', ' | ']) + _random_choose(DIALOG_START_STRING_CANDIDATES)

        # here we reverse the order of DIALOG_ITEM_NAME_CANDIDATES 
        # because we emperically found with the original order, we often sample the same dia_item_name with opt_itm_name
        dia_item_names = _random_choose(DIALOG_ITEM_NAME_CANDIDATES[::-1]) 
        
        dia_inputs_prefix = dia_item_names[0]
        dia_targets_prefix = dia_item_names[1]
        dia_end = _random_choose(DIALOG_ITEM_END_STR_CANDIDATES)[0]
        
        # the diag pattern already has some delimiter between each turn, here we add more
        dia_example_separator = _random_choose(['','\n'])
        
        # we just replace some args of fs_patterns to fit for the dialog pattern
        dia_fs_basic_pattern = copy.deepcopy(pattern_dict['fs_basic_pattern'])
        dia_fs_option_pattern = copy.deepcopy(pattern_dict['fs_option_pattern'])
        dia_fs_basic_cot_pattern = copy.deepcopy(pattern_dict['fs_basic_cot_pattern'])
        dia_fs_option_cot_pattern = copy.deepcopy(pattern_dict['fs_option_cot_pattern'])

        for pattern in [dia_fs_basic_pattern, dia_fs_option_pattern, dia_fs_basic_cot_pattern, dia_fs_option_cot_pattern]:
            pattern.inputs_prefix = dia_inputs_prefix
            pattern.targets_prefix = dia_targets_prefix
            pattern.x_y_delimiter = dia_end
            pattern.example_separator = dia_example_separator
        
        pattern_dict['fs_basic_pattern'] = dia_fs_basic_pattern
        pattern_dict['fs_option_pattern'] = dia_fs_option_pattern
        pattern_dict['fs_basic_cot_pattern'] = dia_fs_basic_cot_pattern
        pattern_dict['fs_option_cot_pattern'] = dia_fs_option_cot_pattern

        pattern_dict['next_turn_dialog'] = _random_choose(FEWSHOT_PATTERNS['next_turn_dialog'])

    elif pattern_dict['rc_mode'] == 'Numbered_Questions':
        # we re-use the OPT_ITEM_END_STR_CANDIDATES for sampling the qa_item_name
        # reverse the order to avoid sampling the same qa_item_name with the opt_item_name
        pattern_dict['qa_item_name'] = _random_choose(QUESTION_ITEM_NAME_CANDIDATES)
        pattern_dict['qa_item_end'] = _random_choose(OPT_ITEM_END_STR_CANDIDATES[::-1])
        pattern_dict['numbered_questions'] = _random_choose(FEWSHOT_PATTERNS['numbered_questions'])
    elif pattern_dict['rc_mode'] == 'Inline_FS':
        pattern_dict['inline_fs_pattern_yes_explain'] = _random_choose(INLINE_FEWSHOT_PATTERNS['explain_afterwards'])
        pattern_dict['inline_fs_pattern_no_explain'] = _random_choose(INLINE_FEWSHOT_PATTERNS['no_explicit_explain'])
    return pattern_dict
sample the collection of patterns to update pattern_dict
instruction_pretrain/utils/read_compre_pt.py