<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def deleterious_permutation(obs_del, context_counts, context_to_mut, seq_context, gene_seq, num_permutations=10000, stop_criteria=100, pseudo_count=0, max_batch=25000):
 """Performs null-permutations for deleterious mutation statistics in a single gene. Parameters context_counts : pd.Series number of mutations for each context context_to_mut : dict dictionary mapping nucleotide context to a list of observed somatic base changes. seq_context : SequenceContext Sequence context for the entire gene sequence (regardless of where mutations occur). The nucleotide contexts are identified at positions along the gene. gene_seq : GeneSequence Sequence of gene of interest num_permutations : int, default: 10000 number of permutations to create for null pseudo_count : int, default: 0 Pseudo-count for number of deleterious mutations for each permutation of the null distribution. Increasing pseudo_count makes the statistical test more stringent. Returns ------- del_count_list : list list of deleterious mutation counts under the null """

    mycontexts = context_counts.index.tolist()
    somatic_base = [base
                    for one_context in mycontexts
                    for base in context_to_mut[one_context]]

    # calculate the # of batches for simulations
    max_batch = min(num_permutations, max_batch)
    num_batches = num_permutations // max_batch
    remainder = num_permutations % max_batch
    batch_sizes = [max_batch] * num_batches
    if remainder:
        batch_sizes += [remainder]

    num_sim = 0
    null_del_ct = 0
    for j, batch_size in enumerate(batch_sizes):
        # stop iterations if reached sufficient precision
        if null_del_ct >= stop_criteria:
            #j = j - 1
            break

        # get random positions determined by sequence context
        tmp_contxt_pos = seq_context.random_pos(context_counts.iteritems(),
                                                batch_size)
        tmp_mut_pos = np.hstack(pos_array for base, pos_array in tmp_contxt_pos)

        # determine result of random positions
        for i, row in enumerate(tmp_mut_pos):
            # get info about mutations
            tmp_mut_info = mc.get_aa_mut_info(row,
                                              somatic_base,
                                              gene_seq)

            # calc deleterious mutation info
            tmp_del_count = cutils.calc_deleterious_info(tmp_mut_info['Reference AA'],
                                                         tmp_mut_info['Somatic AA'],
                                                         tmp_mut_info['Codon Pos'])

            # update empricial null distribution
            if tmp_del_count >= obs_del: null_del_ct += 1

            # stop if reach sufficient precision on p-value
            if null_del_ct >= stop_criteria:
                break
        # update number of simulations
        num_sim += i + 1

    #num_sim = j*max_batch + i+1
    del_pval = float(null_del_ct) / (num_sim)

    return del_pval