Home > Enterprise >  While loop doesn't work/loops forever | Beginner question
While loop doesn't work/loops forever | Beginner question

Time:12-07

Below is my attempted solution to this problem: The top prize in a lottery is won by matching three numbers between 1 and 30 to three random numbers drawn in the same order. When a ball is drawn it is put back into the machine before another ball is drawn. There are always 30 balls in the machine before a ball is drawn and a player may choose the same ball more than once. A draw takes place once a week. Write a function that takes three numbers as parameters, draws three random numbers between 1 and 30 and returns the number of weeks it took to win the jackpot. (E.g. Numbers chosen: 17, 12, 25 must match: ball one is 17, ball two is 12, ball three is 25.)

My attempt:

import random

chosen = []
for i in range(0, 3, 1):
  chosen.append(input("Please input your lucky number: "))

drawn_numbers = []
count = 0
week_count = 0

print("Your chosen numbers are: {}, {}, {}".format(chosen[0], chosen[1], chosen[2]))

while count != 3:
  for i in range(0, 3, 1):
    random_number = random.randint(1, 30)
    drawn_numbers.append(random_number)
  
  for i in range(0, 3, 1):
    if drawn_numbers[i] in chosen:
      count  = 1
    
  week_count  = 1
  drawn_numbers = []

print("It took you {} weeks to win.".format(week_count))

For some reason the while loop just ignores the count = 1 part and loops randomly generated drawn_numbers lists forever.

Obviously there is something wrong with my loop, but I can't see it D:

Some advice on how to make that loop work would be nice. Thanks.

CodePudding user response:

First of all - welcome to the world of Python!

You have several mistakes:

  • The input function returns a string and not an int. Meaning, the comparison you try to do implicitly in if drawn_numbers[i] in chosen would never be true, thus count is always 0 and you got yourself an infinite loop.

  • Assuming that you've fixed the mistake above, you still have a chance of count never hitting 3 at the evaluation of the loop. Consider the following scenario:

    1. A user enters the numbers [1, 2, 3]
    2. The drawn_numbers are [1, 2, 4]
    3. Thus, count will be now 2
    4. The while condition is count != 3 is True and thus the loop continues.
    5. The numbers are drawn again are [1, 2, 4]
    6. The count will be now 4
    7. From now on, count can only increase and will never be equal to 3!

    Do you see where this is going? Try to reset the count at the start of loop (inside)!

  • a lottery is won by matching three numbers ... in the same order

    But the comparison you've implemented only looks for existence in the list instead of comparing element by element.


So, a working (not written in the most Pythonic way) version will be:

import random

chosen = []
for i in range(0, 3, 1):
    chosen.append(int(input("Please input your lucky number: ")))  # notice the int cast

drawn_numbers = []
count = 0
week_count = 0

print("Your chosen numbers are: {}, {}, {}".format(chosen[0], chosen[1], chosen[2]))

while count != 3:
    count = 0  # notice that count is reset here 
    
    for i in range(0, 3, 1):
        random_number = random.randint(1, 30)
        drawn_numbers.append(random_number)
    
    for i in range(0, 3, 1):
        if drawn_numbers[i] == chosen[i]:  # notice that we compare the elements in the same location
            count  = 1

    week_count  = 1
    drawn_numbers = []

print("It took you {} weeks to win.".format(week_count))


If you're interested, here is a more Pythonic way:

import random

chosen = [int(input("Please input your lucky number: ")) for _ in range(3)]
print(f'Your chosen numbers are: {chosen}')

matched = False
week_count = 0

while not matched:
    drawn_numbers = [random.randint(1, 30) for _ in range(3)]    
    matched = drawn_numbers == chosen
    week_count  = 1

print(f"It took you {week_count} weeks to win.")

In which you might find several features that might be new to you but I strongly encourage you to master them:

  1. List comprehension
  2. range(3) is equivalent to range(0, 3, 1)
  3. Formatting string literals
  4. The == operator actually compares two lists element by element!

Funny side note: Running this code without the order restriction results in much less weeks to wait to win the lottery :)

CodePudding user response:

Have you checked your if-statement ever becomes true?

One thought is, that chosen might includes string-values as numbers. Try running:

print(type(chosen[0]))

This should be a int. Fix it by:

chosen.append(int(input("Please input your lucky number: ")))
  • Related