rsokl / Learning_Python

Source material for Python Like You Mean it
https://www.pythonlikeyoumeanit.com/
Other
166 stars 54 forks source link

The solution seems not to work correctly #195

Closed hiro106 closed 1 year ago

hiro106 commented 2 years ago

Thank you so much for your making great learning materials. I am relearning Python with PLYMI now.

By the way, the solution of the exercise below seems not to work correctly for me.

https://github.com/rsokl/Learning_Python/blob/64653935e85643b10926edb0e7daa0019219b186/Python/Module2_EssentialsOfPython/ForLoops.md?plain=1#L257-L280

Using the original solution in the page above

The code below outputs 240. (It seems that too many iterations have occurred.)

x = list(range(1, 31))
num_loop = 0
total = 0

while total < 100:
    for item in x:
        if item % 2 == 1:
            num_loop += 1
            # Additional code for checking the process
            print (f"num_loop: {num_loop}, item: {item}, total: {total}")
            continue
        else:
            total += item
            num_loop += 1
            # Additional code for checking the process
            print (f"num_loop: {num_loop}, item: {item}, total: {total}")

    # break from while-loop if
    # more than 50 items tallied
    if 50 < num_loop:
        break
else:
    print(total)

Revising the code

The code below outputs 110. (It seems to have worked correctly.)

The while-for nest seemed not to work correctly (as intended) for me, so I removed the while-loop and added some conditional statements in the for-loop instead. (I don't think this is the best way..., so would like to know more elegant one. )

x = list(range(1, 31))
num_loop = 0
total = 0

for item in x:
    if (100 < total) or (50 < num_loop):
        # Additional code for checking the process
        print (f"num_loop: {num_loop}, item: {item}, total: {total}")
        break
    elif item % 2 == 1:
        num_loop += 1
        # Additional code for checking the process
        print (f"num_loop: {num_loop}, item: {item}, total: {total}")
        continue
    else:
        total += item
        num_loop += 1
        # Additional code for checking the process
        print (f"num_loop: {num_loop}, item: {item}, total: {total}")

print(total)

I'm sorry and please ignore this issue if I am just mistaken.

Thanks,

davidmascharka commented 2 years ago

Hi @hiro106, the issue you're seeing is that the for item in x loop will complete before we check total < 100 again. So it will iterate over every element in x before it checks the condition total < 100 again. Because the sum of the even elements in your x is 240, that's the return value that you get.

To avoid this, you can have the inner loop also check against total:

x = list(range(1, 31))
num_loop = 0
total = 0

while total < 100:
    for item in x:
        if total >= 100:  # added this condition
            break
        if item % 2 == 1:
            num_loop += 1
            continue
        else:
            total += item
            num_loop += 1

and we get what we expect:

>>> total
110

>>> num_loop
20