0

Hi all I'm having trouble for PSET6 DNA. My code works fine for everything up until and including 4.txt but whenever I go to check the large.csv file and thus 5.txt, 6.txt, 7.txt and so on I seem to be hitting an infinite loop. You can see my check50 summary to clarify - https://submit.cs50.io/check50/ffc1a81b879dd928a7719cffc25bacbd164719a2 having now a bit of trouble testing with the large.csv file or I should rather say any txt file after 4.txt. You can see what I implemented below and for all of small.csv outcomes my program works, here is my output for that:

{'AGATC': 4, 'AATG': 1, 'TATC': 5} # this is my dict of consecutive STR values in the 
                                   # txt file

# this is my list of dicts of each person in the csv file with their respective STRs
[{'name': 'Alice', 'AGATC': 2, 'AATG': '8', 'TATC': '3'}, 
 {'name': 'Bob', 'AGATC': '4', 'AATG': 1, 'TATC': '5'}, 
 {'name': 'Charlie', 'AGATC': '3', 'AATG': '2', 'TATC': 5}]

Bob # this is my check functions output for printing out the dna match which seems to 
    # correct when passing in 1.txt and small.csv

When I tried running with the large.csv file I got an index error with my read_dna function, this was what the terminal used to print to me when I tried running with large.csv -

Traceback (most recent call last):

File "/home/ubuntu/pset6/dna/dna.py", line 219, in <module>

main()

File "/home/ubuntu/pset6/dna/dna.py", line 19, in main

people = read_people_dna(sys.argv[1], people, str_csv)

File "/home/ubuntu/pset6/dna/dna.py", line 77, in read_people_dna

dna[str_csv[j]] = int(dna[str_csv[j]])

IndexError: list index out of range

Then though I tried changing my read_dna function, this eliminated the index error but now it seems I might have a infinite loop as when I run with a text file after 4.txt i.e . even when I still use small.csv I also run into this problem where I think I'm getting an infinite loop since my program doesn't do anything with large or small.csv when using any txt file after 4.txt. I'd really appreciate an extra pair of eyes to look through my updated code to see where this problem might potentially be, please see it below -

import csv
import sys

def main():

    if len(sys.argv) != 3:
        sys.exit("Usage: python tournament.py CSV_STR_COUNTS DNA_FILE")

    people = []

    str_counts = {}

    str_csv = get_list_of_STRs(sys.argv[1])

    people = read_people_dna(sys.argv[1], people, str_csv)

    str_counts = repeatss(sys.argv[2], str_csv, str_counts)

    #print(str_counts)
    #print(people)
    
    check_match(str_csv, str_counts, people)

def get_list_of_STRs(dna):
    str_csv = []
    trans_str = ""
    with open(dna) as file_2:
        first_line = file_2.readline()
        for i in range(len(first_line)):
            if first_line[i] == ",":
                str_csv.append(trans_str)
                trans_str = ""
            trans_str += first_line[i]
        str_csv.append(trans_str)
        str_csv = ([s.replace(',', '') for s in str_csv])
        str_csv = ([s.replace('\n', '') for s in str_csv])
        str_csv.pop(0)
        return str_csv

def repeatss(dna, str_csv, str_counts):
    with open(dna) as file_2:
        dna_str = file_2.read()
        j = 0
        consec_str = 0
        curr_str = 0
        for i in range(len(str_csv)):
            j = 0
            len_str = len(str_csv[i])
            str_name = str_csv[i]
            while j < len(dna_str):
                if dna_str[j : j + len_str] in str_csv[i]:
                 while dna_str[j : j + len_str] in str_csv[i]:
                    curr_str += 1
                    j += len_str
                j += 1
                if j % len_str != 0 and curr_str > 0:
                    consec_str = curr_str
                    curr_str = 0
                str_counts[str_csv[i]] = consec_str
            i += 1
    return str_counts

# dna_csv is small.csv or large.csv, people is originally an empty list,
# str_csv is list of STRs needed to check through
def read_people_dna(dna_csv, people, str_csv):
    with open(dna_csv) as file:
        dna_dict = csv.DictReader(file)
        #for i in range(len(str_csv)):
        for dna in dna_dict:
            j = 0
            while j < len(str_csv):
                dna[str_csv[j]] = int(dna[str_csv[j]])
                j += 1
            people.append(dna)
    return people

def check_match(str_csv, str_counts, people):
    for person in people:
        k = 0
        for i in range(len(str_csv)):
            if int(person[str_csv[i]]) == str_counts[str_csv[i]]:
                k += 1
        if k == len(str_csv):
            print(person['name'])
            return True
    if i == (len(str_csv) - 1):
        print("No match")
        return False
            

main()

1 Answer 1

1

The proximate cause of the infinite loop is this while in the repeatss function:

while dna_str[j : j + len_str] in str_csv[i]:
                    curr_str += 1
                    j += len_str

In python, if i is greater than len(s) in slice notation (s[i : j]), it returns the empty string (even though s[i] would return index out of range error).

From Expressions doc:

For the string and bytes types, x in y is True if and only if x is a substring of y. An equivalent test is y.find(x) != -1. Empty strings are always considered to be a substring of any other string, so "" in "abc" will return True.

I have not reasoned out why it works with the "small" sequences files.

Don't forget, debug50 works with python programs.

You must log in to answer this question.

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