Using a while loop instead of a for loop

I was doing the over 9000 challenge over here.

I wrote:

def over_nine_thousand(lst):
  x = 0
  while x < 9000:
    for num in lst:
      x += num
  return x

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

When I run the code, it adds up everything ignoring my “while x < 9000” statement. I was wondering why.

The way the solution wrote it:

def over_nine_thousand(lst):
  sum = 0
  for number in lst:
    sum += number
    if (sum > 9000):
      break
  return sum

Thanks in advance.

2 Likes

Hi @asingher,

The condition specified in this header is checked only immediately before each potential iteration of the while loop:

  while x < 9000:

The work of adding up the numbers is performed by this for loop:

    for num in lst:
      x += num

That occurs entirely within the first iteration of the while loop. Therefore, the condition specified in the while loop header does not get checked during that process.

1 Like

Ah, I see. So it stays in the while loop and doesn’t recheck it until it goes through all the numbers in the list.

Got it, thanks, I am going to try to write it with defining the x in the while loop and see what happens.

Edit: I just tried doing that and got an error, which I understand. Since x is not defined prior to the while loop, the while loops doesn’t know where to find the x.

Is it possible to write this code with a while loop?

1 Like

Yes, you can do it with a while loop, however, it is more complicated than with a for loop. The for loop has the advantage that you do not need to manage an index to the list. With an index, you’ll need to increment it, as well as to make sure you don’t let it go past the position of the final element in the list.

Before considering an example of a working solution, try this with your original solution to demonstrate something else interesting about its behavior:

under_9000_list = [4000, 4000]
print(over_nine_thousand(under_9000_list))

Output:

16000

That time, the while condition was not ignored entirely, but the items in the list were added up twice.

The following is one way to do this with a while loop:

def over_nine_thousand(lst):
  # an index for lst
  i = 0
  # accumulate the total
  total = 0
  # the length of lst
  length = len(lst)
  # stop if we are over 9000 or if we exhausted lst
  while total <= 9000 and i < length:
    # add to total
    total += lst[i]
    # increment the index
    i += 1
  return total

You should test a variety of cases, for example:

empty_list = []
under_9000_list = [4000, 4000]
over_9000_list = [4000, 4000, 4000]
exactly_9000_list = [4500, 4500]
exactly_9000_plus_1000_list = [4500, 4500, 1000]
print(over_nine_thousand(empty_list))
print(over_nine_thousand(under_9000_list))
print(over_nine_thousand(over_9000_list))
print(over_nine_thousand(exactly_9000_list))
print(over_nine_thousand(exactly_9000_plus_1000_list))

Output:

0
8000
12000
9000
10000

As a challenge, you can also try it with a while True: header and a break.

2 Likes