Another dna.py failure

https://www.codecademy.com/courses/learn-python/projects/dna
Hello, I read through the others having this problem, and tried those solutions to no avail. So here is my code. It isn’t throwing any errors when it gets compiled, but it seems to not be getting ANY hits for matches, and all three suspect go free with no dna matches.:

sample = ['GTA','GGG','CAC']

def read_dna(dna_file):
  dna_data = ''
  with open(dna_file, 'r') as f:
    for line in f:
      dna_data += line
  return dna_data

def dna_codons(dna):
  codons = []
  for i in range(0, len(dna), 3):
    if (i+3) < len(dna):
      codons.append(dna[i:1+3])
  return codons

def match_dna(dna):
  matches = 0
  for codon in dna:
    if codon in sample:
      matches += 1
  return matches

def is_criminal(dna_sample):
  dna_data = read_dna(dna_sample)
  codons = dna_codons(dna_data)
  num_matches = match_dna(codons)
  if num_matches >= 3:
    print 'There are %s matches. The \
    investigation should continue' % \
    (num_matches)
  else:
    print 'There are %s matches. Set them free.'\
    % (num_matches)
    
is_criminal('suspect1.txt')
is_criminal('suspect2.txt')
is_criminal('suspect3.txt')

Wish the indenting was preserved when this posted. :frowning: Though it does appear to indent when you hit the “quote” button in this reply box…

Hello, @lotninja.

If you use the </> button, your code will retain it’s original formatting.

2 Likes

ooh, thanks! (the rest of this message is to pad out to 20 characters so that I may porperly show my appreciation for your kind teaching of this button to my newbish hands)

1 Like

Does that slice look correct?

Furthermore, is it necessary to have a conditional in the function?

A simple loop is all we should need. Consider the following comprehension…

def dna_codons(dna):
  return [dna[c:c+3] for c in range(0, len(dna), 3)]
1 Like

Ah, yes! eye-blind to 1 not being i there. should have been more descriptive with my variable.
Now for your second point, I have it currently that way as an if statement where the return statement exists so it iterates over the whole sample in batches of 3 for each letter as a starting point.

Is it a better practice to have that function just in the return statement instead of the way I have it now?

Since you are taking slices, then no conditional need apply. You have a stride value in your range. Trust it.

The range function calculates the stride into its next value. If it exceeds the given upper bound, it excludes that iteration and terminates.