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