Loops Advanced: Over 9,000 (While loop not working)

Here’s a link to the Loops Advanced Exercise: https://www.codecademy.com/paths/computer-science/tracks/cspath-cs-101/modules/cspath-code-challenges/articles/advanced-python-code-challenges-loops

Using the code below, I expected to be able to use a While loop to terminate the ‘for every num in lst’ loop when the value exceeded 9000.
The unexpected result was the for-in loop continued to execute, adding every element in the list, even when the 9000 threshold was exceeded. Any insight would be appreciated!

My code:

def over_nine_thousand(lst): sum_elements = 0 while sum_elements <= 9000: for num in lst: sum_elements += num return sum_elements print(over_nine_thousand([8000, 900, 120, 5000]))

print(over_nine_thousand([8000, 900, 120, 5000]))

Output in terminal: 14020

The for loop is inside the while loop, so the while condition wont be checked until after it’s finished.

Summary

Do you need the while loop ? It’d be easier to check as you do the additions if the condition’s been met.

Thank you for your response! The suggested solution checks with each For Loop, as you mentioned, but when I originally wrote my own solution I used a While Loop. I guess I am not fully understanding the way to nest loops. Thanks again.

There is nothing wrong with using while for this problem as it has an indefinite termination. There are two errors in your code, though. Have you spotted them?

I don’t see the errors. The variable sum_elements is declared before the While loop.

On the first round of the while loop, sum_elements = 0
so we enter the for loop:

sum_elements = 0+ 8000, therefore, sum_elements = 8000
8000 is <= 9000 so the while condition is satisfied.

enter for loop again

sum_elements = 8000 + 900, therefore, sum_elements = 8900
8900 is <= 9000, so while condition still satisfied

enter for loop again

sum_elements = 8900 + 120, therefore, sum_elements now 9020
9020 <= 9000 is False.
return sum_elements should return 9020

Instead the output is the sum of all num in lst.
It’s like the While loop is totally ignored!

The code in your initial post has a return inside the while loop, and the print statement is inside the function. Not sure what you’re expecting from the for loop.

That loop is iterating over the entire list and arriving at a complete sum, unconditionally. The sum is then returned, making everything seem correct but the while loop is ignored, just as you have observed.

Your output is the total sum, not the sum as it crests 9000. The correct result should be 9020.

There are two approaches one could use, the while loop as elements are popped off the front of the list, or a for loop with a breaking condition. Pick one. Be sure the print statement is outside of the function.

Thank you. I will work through this tomorrow and see if it makes sense to me. Much appreciated.

1 Like

Thank you for your response. I moved the print statement outside of the function. That was not part of the original function, just sloppy transcription of my code on my part =) It is a function call.
As for the indentation of the ‘Return sum_elements’, even when I line it up with ‘while’, it continues to not break out of summing every number in the list, returning 14020. This is in clear violation of the while statement.

Huh? Please explain. Better still, post your latest code. Might have drawn a blank and need a kick start.

If I’m reading through your comments correctly, I believe you’re misunderstanding the way the loops are working.
The conditions of the while loop are only checked each time it cycles through - it wont automatically leave whenever the condition occurs.

So, with your code, it’ll check initially whether sum_elements is <= 9000, but it wont do it again until the block of code inside it is finished ( lines 4 - 6 in your code. )
That block of code contains the for loop. Which means the for loop will complete before the while loop condition will be checked again.
So, ultimately, you’ve got nothing in your code checking >IF< your total has exceeded 9000 each time it goes through the for loop.

Which basically supports what was already stated above. The member need only decide upon which approach to take: while or for.

Thank you and mtf for your comments. I thought about this some more and have come to terms with the fact that for loops are the best approach. The while loop is doable, but you need two variables:

  • one to track the sum

  • one to track the index

This is not as clean as a for loop.

#Write your function here def over_nine_thousand2(lst): sum_elements = 0 index = 0 while sum_elements <= 9000 and index < len(lst): sum_elements += lst[index] index = index + 1 return sum_elements # uncomment to test function #print(over_nine_thousand2([8000, 900, 120, 5000])) #print(over_nine_thousand2([1000, 900, 120, 5000, 2000]))

The two variables become one when we use list.pop() in the while loop.

while len(lst) and t <= 9000:
    t += lst.pop(0)

for with break is less conditional.

>>> def over9k(lst, t=0):
    for x in lst:
        t += x
        if t > 9000: break;
    else:
        t = 0
    return t

>>> over9k([8000, 900, 120, 5000])
9020
>>> over9k([8000, 900, 20, 50])
0
>>> 

That’s a nice approach! I like the use of the .pop method.

1 Like