2
$\begingroup$

I have created a python code that prints out all lengths of ORFs in a DNA sequence (start codon - "ATG", stop codons - "TAG", "TAA" and "TGA". It seems to give correct answers, when compared with specialized ORF-finding programs. The thing is that besides correct answers it also gives an Index Error in the end:

Traceback (most recent call last):
  File "scripts.py", line 33, in <module>
    if list_start[i]>list_stop[n-1]:
IndexError: list index out of range

Now, I have created a dictionary from a FASTA file where key is a sequence name and value is the sequence itself and want to find ORFs for all sequences in that dictionary using a for loop and this code. However, the loop runs only once and I think that the Index Error to be the cause.

The code is the following:

#!/usr/bin/env python3
line="TCGGGCGAAGGCGGCAGCAAGTCGTCCACGCGCAGCGCGGCACCGCGGGCCTCTGCCGTGCGCTGCTTGGCCATGGCCTCCAGCGCACCGATCGGATCAAAGCCGCTGAAGCCTTCGCGCATCAGGCGGCCATAGTTGGCGCCAGTGACCGTACCAACCGCCTTGATGCGGCGCTCGGTCATCGCTGCATTGATCGAGTAGCCACCGCCGCCGCAAATGCCCAGCACGCCAATGCGTTCTTCATCCACATAGGGGAGCGTTACGAGGTAGTCGCAGACCACGCGGAAATCCTCGACGCGCAGTGTCGGGTCTTCGGTAAAACGTGGTTCGCCGCCGCTGGCACCCTGGAAGCTGGCGTCGAAGGCGATGACGACGAAACCTTCCTTGGCCAGCGCCTCGCCATACACGTTCCCCGATGTTTGCTCCTTGCAGCTGCCGATCGGATGCGCGCTGATGATGGCGGGATATTTCTTGCCTTCGTCGAAGTTCGGCGGGAAGTGGATGTCGGCTGCGATATCCCAATACACATTCTTGATCTTGACGCTTTTCATGACAGCTCCGTTCAGGGGGAGGGGGTAAGTTCGCCAGGCCGAATCGTTGGTAGCCAAGCGGCAACGACTCGAATATAGAGAGCCGATTGGAATTCCGTAAGATCGCAATCTGGACTACAGTGGTATCTTCAAATTGACAATGGCACCTACATGGATCCCTCACTGCTTCCGTCTCTCGCGTGGTTCGCCCACGTCGCACATCATCGTAGCTTCACGAAAGCGGCTGCGGAAATGGGCGTTTCTCGAGCAAACCTGTCGCAGAACGTGAAGGCGCTCGAACGCCGGTTGAACGTCAAGCTGCTGTATCGAACGACTCGCGACATGTCGCTGACCGAGGAGGGGCAGCGGCTCTACGAGGTGTGGTATCCCGCGCTGGTCGCGGTCGAGCGGACGGTCGACGCGCTGCACGAGGAGCGCGACGAGCCGTCGGGGTTGATTC"
r_frame=input('Enter a reading frame')
line=line[int(r_frame)-1:]
# making list of codons (3-nucleotide groups)
x=3
codon=[line[y-x:y] for y in range(x, len(line)+x,x)]
#defininig function  that will find all the indexes of codon in list of codons
def find_indices(list_to_check, item_to_find):
    indices = []
    for idx, value in enumerate(codon):
        if value == item_to_find:
            indices.append(idx)
    return indices
# makirng list with all the indexes of "ATG" (start codon)
list_start=find_indices(codon, "ATG")
#making list with all the indexes of "TGA", "TAA" or "TAG" (stop codons) and sorting it from smaller to bigger
list_stop=find_indices(codon, "TGA")+find_indices(codon, "TAA")+find_indices(codon, "TAG")
list_stop.sort()
i=0 # variable for indexes in list_start
n=0 #variable for indexes in list_stop
j=0 # variable that determines numer of times searching for ORF will be repeated
#first round without loop so that i and n will be >0 and we can make  if list_start[i]>list_stop[n-1] without errors
if list_start[i]<list_stop[n]:
    print(3*(list_stop[n]-list_start[i])+3)
    j=j+1
    n=n+1
    i=i+1
else:
    n=n+1
#loop that will search for suitable start codon-stop codon pairs and print the length of ORF
while j<codon.count('ATG'):
    if list_start[i]>list_stop[n-1]:
        if list_start[i]<list_stop[n]:
            print(3*(list_stop[n]-list_start[i])+3) 
#multiply by 3 'cause one item in list stands for 3 nucleotides and add 3 so the whole length of stop codon will be counted
            j=j+1
            n=n+1
            i=i+1
        else:
            n=n+1
    else: i=i+1

For sequence given in the code the ORFs lengths should be as following:

Reading frame 1:63; 36; 36; 213; 129

Reading frame 2: 39

Reading frame 3: 186

This code might seem weird as I'm new to python and bioinformatics. I will be very thankful if anyone gives me an advice how can I get rid of the Index Error here.

$\endgroup$
0

1 Answer 1

1
$\begingroup$

Firstly, there is a bug in the code,

Original,

def find_indices(list_to_check, item_to_find):
    indices = []
    for idx, value in enumerate(codon):
        if value == item_to_find:
            indices.append(idx)
    return indices

Corrected,

def find_indices(list_to_check, item_to_find):
    indices = []
    for idx, value in enumerate(list_to_check):
        if value == item_to_find:
            indices.append(idx)
    return indices

You renamed the variable codon for the function, but then retained its name as codon within the function. It should be list_to_check. Also it is convenient.

If you are certain your code is fine, the easiest way to silence the error is via a try and except statement. The critical variable is line and I'm not sure where that is being declared. Without that its difficult to unpick the underlying error, which is an out of range error.

def find_indices(list_to_check, item_to_find):
        indices = []
        for idx, value in enumerate(list_to_check):
            if value == item_to_find:
                indices.append(idx)
        return indices


if __name__ == '__main__':
    #line= sample DNA nucleotide sequence

    try:
        r_frame= input('Enter a reading frame')
        line = line[int(r_frame)-1:]
        line=line[int(r_frame)-1:]
        x=3
        codon=[line[y-x:y] for y in range(x, len(line)+x,x)]
        list_start=find_indices(codon, "ATG")
        list_stop=find_indices(codon, "TGA")+find_indices(codon, "TAA")+find_indices(codon, "TAG")
        list_stop.sort()
        i=0 # variable for indexes in list_start
        n=0 #variable for indexes in list_stop
        j=0 # variable that determines numer of times searching for ORF will be repeated
        if list_start[i]<list_stop[n]:
            print(3*(list_stop[n]-list_start[i])+3)
            j=j+1
            n=n+1
            i=i+1
        else:
            n=n+1
        while j<codon.count('ATG'):
            if list_start[i]>list_stop[n-1]:
                if list_start[i]<list_stop[n]:
                    print(3*(list_stop[n]-list_start[i])+3)
                    j=j+1
                    n=n+1
                    i=i+1
                else:
                    n=n+1
            else:
                i = i + 1
    except AssertionError as error:
        print (error)
    except:
        pass

If you want to see the error you simply deleted the late two lines of code.

However* to resolve the second bug is quite complicated, particularly without a line declaration. We would simply use is Biopython's .translate() method, we wouldn't do this from first principles. In a past question thats been done.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.