Loops That End Too Late, and Too Soon
A while loop re-checks its condition between passes, and that is the only moment it can stop. So there is exactly one question worth asking about any…
What actually ends a loop
A while loop re-checks its condition between passes, and that is the only moment it can stop. So there is exactly one question worth asking about any while loop: can the body ever make that condition false?When the answer is no, the loop ends too late, or never. When the condition turns false before the work is finished, it ends too soon. Both faults usually live in the same place: the value the condition is watching.
input() always hands back a string
Whatever the user types, input() returns it as text. The sentinel loop we wrote earlier compares that text with the empty string, so both sides are strings and the comparison works. Put a number on the other side and it stops working.Whole numbers land on zero. Floats drift past it.
Repeatedly cutting a number down until it reaches zero is the standard way to walk through its digits, and floor division is what makes it terminate.Floor division throws the fraction away, so a positive whole number is guaranteed to reach 0 and stop. Ordinary division keeps the fraction: it turns the value into a float on the very first pass, and from there the value is never a whole number again, so a test that looks for a particular last digit stops matching. A loop like that does still finish, because the value keeps shrinking until Python can no longer tell it from zero, but that takes hundreds of passes, and by then whatever it was counting has been wrong since the second pass.
Ending one pass too soon
The other half of the problem is a loop that stops before it has done everything. Three common causes, all of them about placement rather than about the condition itself: a boundary that is one short, something the loop needs that is never reset, and a variable set up in the wrong place.State that is not a counter
Almost every loop variable so far has climbed by a fixed step. It does not have to. A flag holds True or False and can end a loop the moment something is found. A step can change sign part way through, so the position it drives goes back down. And two variables can trade values in a single line, using a tuple that is packed on the right and unpacked on the left.The same off-by-one, away from loops
A boundary that lands one place from where you meant it does not only bite loop conditions. It decides how often a branch runs, too.