Musical_Ant
Musical_Ant

Reputation: 67

If, else return else value even when the condition is true, inside a for loop

Here is the function i defined:

def count_longest(field, data):
    l = len(field)
    count = 0
    final  = 0
    n = len(data)
    for i in range(n):
        count = 0
        if data[i:i + l] is field:
            while data[i - l: i] == data[i:i + l]:
                count = count + 1
                i = i + 1
        else:
            print("OK")
        if final == 0 or count >= final:
            final = count
    return final

a = input("Enter the field - ")
b = input("Enter the data - ")
print(count_longest(a, b))

It works in some cases and gives incorrect output in most cases. I checked by printing the strings being compared, and even after matching the requirement, the loop results in "OK" which is to be printed when the condition is not true! I don't get it! Taking the simplest example, if i enter 'as', when prompted for field, and 'asdf', when prompted for data, i should get count = 1, as the longest iteration of the substring 'as' is once in the string 'asdf'. But i still get final as 0 at the end of the program. I added the else statement just to check the if the condition was being satisfied, but the program printed 'OK', therefore informing that the if condition has not been satisfied. While in the beginning itself, data[0 : 0 + 2] is equal to 'as', 2 being length of the "field".

Upvotes: 1

Views: 1689

Answers (1)

Tobias
Tobias

Reputation: 1371

There are a few things I notice when looking at your code.

First, use == rather than is to test for equality. The is operator checks if the left and right are referring to the very same object, whereas you want to properly compare them.

The following code shows that even numerical results that are equal might not be one and the same Python object:

print(2 ** 31 is 2 ** 30 + 2 ** 30)   # <- False
print(2 ** 31 == 2 ** 30 + 2 ** 30)   # <- True

(note: the first expression could either be False or True—depending on your Python interpreter).

Second, the while-loop looks rather suspicious. If you know you have found your sequence "as" at position i, you are repeating the while-loop as long as it is the same as in position i-1—which is probably something else, though. So, a better way to do the while-loop might be like so:

while data[i: i + l] == field:
    count = count + 1
    i = i + l         # <- increase by l (length of field) !

Finally, something that might be surprising: changing the variable i inside the while-loop has no effect on the for-loop. That is, in the following example, the output will still be 0, 1, 2, 3, ..., 9, although it looks like it should skip every other element.

for i in range(10):
    print(i)
    i += 1

It does not effect the outcome of the function, but when debugging you might observe that the function seems to go backward after having found a run and go through parts of it again, resulting in additional "OK"s printed out.

UPDATE: Here is the complete function according to my remarks above:

def count_longest(field, data):
    l = len(field)
    count = 0
    final = 0
    n = len(data)
    for i in range(n):
        count = 0
        while data[i: i + l] == field:
            count = count + 1
            i = i + l
        if count >= final:
            final = count
    return final

Note that I made two additional simplifications. With my changes, you end up with an if and while that share the same condition, i.e:

if data[i:i+1] == field:
    while data[i:i+1] == field:
        ...

In that case, the if is superfluous since it is already included in the condition of while.

Secondly, the condition if final == 0 or count >= final: can be simplified to just if count >= final:.

Upvotes: 3

Related Questions