0

I got to a point in this problem where my code was working alright for the small csv, but it was clumsy and repetitive, so I tried to make it more elegant by making more complicated nested loops to get my program working less lines of code.

While trying hard to get there, I got lost a couple of times, but finally I am at a point where my code should be working. However, it is only resolving correct matching results for the small sequences. Not for the large ones. And I can't get my head around that.

To solve issues that raised when trying to get there I decided to store my RTAs and names provided in the csv in separated lists, called rtas[] and people[] respectively. And work out the rest of the problem with a 2D list called list[] from which I remove the peoples's names and RTAs provided. So in the last lines of code is easier to make this list a list of strings and compare it with my results list to print out the correct name of the subject.

So, I get these results with the algorithm that compares each RTA provided with my DNA sequence and store these results in a list of ints called results[], that later I will convert to a list of strings called results_str[] in order to compare it and find the subject whose DNA has the same number of repetitions stored in my results[] list.

But results calculated in this list are not correct. Seemengly there's something wrong in my comparison algorithm that works for small.csv but not for large.csv.

In this algorithm basically what I am doing is compare the DNA sequence, which has been read into memory and stored in a string called in_mem_seq_file, with each of my RTAs stored in the list rtas[]:

for x in range(len(rtas)):
    for i in range(len(in_mem_seq_file) - len(rtas[x])):
        if in_mem_seq_file[i:len(rtas[x]) + i] == rtas[x]:
            results[x] += 1

After a lot of debugging with prints here and there I don't get what am I missing. Can someone please point me in the right direction? I have been walking in circles for long time and I can not see it. Many thanks, here is my code:

import sys
import csv

# Check for user arguments
if len(sys.argv) > 3:
    print("Error, too many arguments")

# Read in memory csv file
with open(sys.argv[1], 'r') as csv_file:
    in_mem_csv_file = csv_file.read()

spamreader = csv.reader(in_mem_csv_file.splitlines(), delimiter=',', quotechar='|')

# Populate a 2D list with data from csv file
list = []
for row in spamreader:
    list.append(row)

# Initialize list to save names
people = []
for i in range(1, len(list)):
  people.append(0)

for i in range(len(list) - 1):
  people[i] = list[i + 1][0]

# Initialize list to save RTA samples
rtas = []
for j in range(1, len(list[0])):
  rtas.append(0)

for j in range(len(list[0]) - 1):
  rtas[j] = list[0][j + 1]


# Remove from the 2D list 1st row and 1st column
list.pop(0)
for i in range(len(list)):
    list[i].pop(0)


# Read in memory DNA sequence
with open(sys.argv[2], 'r') as seq_file:
    in_mem_seq_file = seq_file.read()

# Check for number of coincidences of different RTAs in the DNA sequence
# Initialize a list to store results
results = []
for i in range(0, len(list[0])):
  results.append(0)

# For each STR add 1 to the STR counter when 1 coincidence is found
for x in range(len(rtas)):
    for i in range(len(in_mem_seq_file) - len(rtas[x])):
        if in_mem_seq_file[i:len(rtas[x]) + i] == rtas[x]:
            results[x] += 1
        # DEBUG: print(in_mem_seq_file[i:len(rtas[x]) + i] + ' Equal to ' + rtas[x])


# For each RTA counter, compare it with the database and print a name from it or invalid
# Define a as many row counters as rows are there in list - 1

# Convert list of ints to list of strings for final comparison
results_str = [ str(n) for n in results ]

for i in range(len(list)):
    if list[i] == results_str:
        print(people[i])
        break
    else:
        print("No match")
        break

1 Answer 1

0

I definitely got lost while trying to nest loops inside of loops to make my code more elegant, sooo lost. I was calculating wrong results, I should be computing how many consecutive repetitions there are and not only how many copies of a certain RTA were found.

Here is the part of the code that does that:

# For each STR
# Traverse DNA sequence
# In case of STR found, do this iteratively:
#    Look up next block of characters, if STR found add +1 to counter
#    Only update results list if counter is bigger than current value
#    So the value in results list will save the maximum consecutive repetitions only
for x in range(len(rtas)):
    counter = 0
    for y in range(len(in_mem_seq_file) - len(rtas[x])):
        counter = 0
        if in_mem_seq_file[y:y + len(rtas[x])] == rtas[x]:
            counter += 1
            while True:
                y = y + len(rtas[x])
                if in_mem_seq_file[y:y + len(rtas[x])] != rtas[x]:
                    break
                elif in_mem_seq_file[y:y + len(rtas[x])] == rtas[x]:
                    counter += 1
                    if counter > results[x]:
                        results[x] = counter

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .