A loop runs the same block many times. The for loop is ideal when you know the count up front — "do this N times" or "for each number from 1 to N".
def solve(n):
for i in range(1, n + 1): # i takes 1, 2, ..., n
print(i) # (illustration only; real solves return a value)
for (int i = 1; i <= n; i++) {
// body runs for i = 1..n
}
A while loop runs as long as a condition holds — use it when you do not know the count in
advance, such as "keep halving n until it reaches 0". Every loop has three moving parts: where
the counter starts, the condition that keeps it going, and how it changes each
time. Get those right and the loop does exactly N passes. Get the boundary wrong — < versus
<= — and you do one too few or one too many, a mistake called an off-by-one error. Check
your loop against a tiny case (n = 3) to be sure it runs the right number of times.