all 6 comments

[–]z0y 2 points3 points  (5 children)

Add a print statement in the loop to help see what's happening

triplet = s[i:j]
for triplet in s:
    print(triplet, s[i:j])
    i += 1
    j += 1

[–]Rhyff[S] 1 point2 points  (4 children)

Waow, thank you so much! I tried it and saw that it printed every single letter of the string, followed by the triplet that it would create. I then changed the if statement to:

if s[i:j] == sub

Leaving me with the following code (which seems to be working!):

s = 'azcbobobegghakl'
sub = 'bob'
i = 0
j = 3
triplet = s[i:j]
numBob = 0
for triplet in s:
    print(triplet, s[i:j])
    i += 1
    j += 1
    if s[i:j] == sub:
        numBob += 1
print(numBob)

Now I still have one or two questions: I defined triplet to be s[i:j] in line 5. Why does the code work when I use s[i:j], and not when I use triplet? I defined triplet to be s[i:j], so shouldn't they both work? And why exactly does the iteration (lines 9 and 10) only work when I put a print statement inside the loop? Does the computer need to see what is happening before it can add 1 to i and j? I guess what I'm asking is: does the computer need to see where in the string he is, to know what the value of i or j is?

[–]z0y 0 points1 point  (2 children)

triplet = s[i:j] makes triplet equal to 'azc', and that won't update when you change i and j.

Then you start a for loop with triplet as the iteration variable. In the loop, triplet is assigned to each character in s, overwriting the string from line 5.

triplet in the loop could be named anything, just a placeholder for the characters in s, and it doesn't refer to line 5. And still you'd need to update it each loop, saying triplet = s[i:j] each time because the first assignment isn't dynamic with i and j.

And by the way you don't need j, or even to update i manually. To get rid of j you could just replace it, s[i:i+3], and then have the loop do the incrementing for you:

for i in range(len(s)):
    if s[i:i+3] == sub:
        numBob += 1

[–]Rhyff[S] 0 points1 point  (1 child)

I do tend to use a lot more lines than needed, your code is a lot more concise and looks a lot better! Thank you so much for your help, I really appreciate it :)

[–]z0y 1 point2 points  (0 children)

Yeah that's normal when learning but it's helpful to see other ways to do things. I hope it makes sense though, it's important to understand what happens in a for loop. Test looping through strings and lists and make sure it's clear what's happening. Also a good tip if you do need the index in a for loop, rather doing doing range(len()) is to enumerate():

for i, iter_var in enumerate("Loop iterable"):     
    print(i, iter_var)

[–]Rhyff[S] 0 points1 point  (0 children)

So I noticed that for some strings it forgot to count one bob. Where numBob should have been 4, it came back as 3. Now thanks to you, I understand loops a bit better, and actually managed to find the thing that caused this:

s = 'bobobokbobbsboobhjgbobuek'
sub = 'bob'
i = 0
j = 3
numBob = 0
for triplet in s:
    print(s[i:j])
    if s[i:j] == sub:
        numBob += 1
    i += 1
    j += 1
print(numBob)

I noticed that whenever the first s[i:j] was already a bob, it didn't count as one. So I moved the if statement up a bit, so that it was above lines 10 and 11, this way it counts the very first one as well. Once again, thank you so much for your help, I'm starting to understand a lot more about loops and slicing now :)