0

I have a question about DNA, specifically this while statement:

while dna_string[char: char + length_str] == dna_string[char - length_str: char]:

I'm not getting dna_string[char - length_str: char] even after printing all of the values. If char is 0 then char - length_str: char should be negative. I can't visualize how this part of the code is working in detail!?

Complete loop

for str in str_dict:  # For each STR
    length_str = len(str)
    longest_sequence = 0

    # Check for each char if it is the start of a sequence
    for char in range(len(dna_string)):
        temp_current_str = 0

        if dna_string[char: char + length_str] == str:
            temp_current_str += 1  # If char is start of a sequence, add 1 to temp_current_str

            # While the next char is the same as the current char
            while dna_string[char: char + length_str] == dna_string[char - length_str: char]:

                temp_current_str += 1  # Increment counter for each str found
                char += length_str  # Move to the next char

            if temp_current_str > longest_sequence:
                longest_sequence = temp_current_str

    # For each STR, store the length of the longest sequence
    srt_count.update({str: longest_sequence})
7
  • It looks like your code formatting needs attention. I assume for char in.. should be inside this loop: for str in str_dict:. Correct? I will look at it once you get that cleaned-up.
    – kcw78
    Dec 30, 2021 at 21:06
  • Dumb question: why don't you use the longest_match() function that was provided to do this?
    – kcw78
    Dec 30, 2021 at 23:19
  • @kcw78 Didn't paste the code correctly here.. but now it displays correctly
    – Drallas
    Dec 31, 2021 at 22:28
  • I'm smart enough to use a longest_match() function but it isn't in the distribution code and can't find it on the page? cs50.harvard.edu/x/2021/psets/6/dna Btw my script is working and passed with 100%, only can't wrap my head around the [char: char + length_str] == dna_string[char - length_str: char] part
    – Drallas
    Dec 31, 2021 at 22:37
  • re: longest_match() -- I went thru the "Getting Started" steps, and it was included in the dna.py file provided as the starting template. No worries.
    – kcw78
    Jan 1, 2022 at 0:28

1 Answer 1

1

Your confusion is understandable and a good learning point.
You are correct, when char=0 then char-length_str will always be negative. This "works" because negative indices are not part of the string, so it returns a null (empty) string. That will not be equal to the string characters at [char: char+length_str], so your while loop is skipped.

To demonstrate this behavior, I added some print statements to your code (along with some dummy data). You can run standalone to see how the negative string indices return a null string. Also, I noticed a few things you should consider in the future:

  1. Don't use str as a name (for variables, functions or anything). Why? str() is a Python function that converts the input to a string. For example, str(8) returns '8'. At some point, using str will be a source of confusion and heartache.
  2. You modified the value of the loop counter (char) inside the loop. This doesn't work as you expect (or at least as I think you expect). You should use a different variable for this purpose. I will try to explain. The value of char comes from for char in range(), and range is an "iterable" ("lazy iterable" to be precise). The next value of char in the loop comes from the next range() value and is not affected by calculations in the loop. Your equation only temporarily changes the value.

Your code with my modifications below:

str_dict = {'ABCD': '1'}
dna_string = 'ABCDABCDEFGHWXYZWXYZABCD'
srt_count = {}

for str_key in str_dict:  # For each STR
    length_str = len(str_key)
    longest_sequence = 0

    # Check for each char if it is the start of a sequence
    for char in range(len(dna_string)):
        print(f'char = {char}')
        temp_current_str = 0

        if dna_string[char: char + length_str] == str_key:
            temp_current_str += 1  # If char is start of a sequence, add 1 to temp_current_str
            print(f'Found str_key at: {char}:{char + length_str}')
            # While the next char is the same as the current char
            print(f'Checking backwards finds: |{dna_string[char - length_str: char]}|')
            while dna_string[char: char + length_str] == dna_string[char - length_str: char]:
                print(f'Found duplicate at: {char}:{char+length_str} and {char-length_str}:{char}')

                temp_current_str += 1  # Increment counter for each str found
                char += length_str  # Move to the next char
                print(f'char increased to = {char}')

            if temp_current_str > longest_sequence:
                longest_sequence = temp_current_str

    # For each STR, store the length of the longest sequence
    srt_count.update({str_key: longest_sequence})
    print(srt_count)
4
  • Thank you very much for your detailed answer! I'm planning to refactor my solution this weekend (before i move on to the next week). Planning to study your Code with my modifications and integrate them in my refactored code! I'm in this to learn an improve my coding skills and i don't feel good submitting code if i don't understand it 100%.
    – Drallas
    Jan 1, 2022 at 12:11
  • "I don't feel good submitting code if I don't understand it 100%". Every coder should think like this!! Too many say: "I'm glad it works even if I'm not sure why. I'm just happy to be done" That's a recipe for a future disaster.
    – kcw78
    Jan 1, 2022 at 15:33
  • Found some time to study your modifications and also compare it against the distributed code by CS50 staff. I added some additional print statements to the mod file to make it totally visible what the code does. Tnx again I understand my code now! :)
    – Drallas
    Jan 2, 2022 at 13:09
  • Yeah. I looked at the staff code too. You procedure is similar. The biggest difference I saw -- they compare substrings after the current string and you compared before the current string.
    – kcw78
    Jan 2, 2022 at 15:26

You must log in to answer this question.

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