# Python number guessing game

I'm a PHP Developer. I'm trying to learn Python. So I tried to create a simple game, a Number Guesser.

I tried to comment out as much as possible without making super obvious comments.

I also made the attempts message color to be red.

Here's my code.

# 1. Print a message about the game
# 2. Tell the user that the random number is between some numbers
# 3. Run a while loop to continue the input, break the loop when the guess is right.
# 4. When the user guessed the number, tell them that they're right.

import random

# Simple message to the user.
print "Welcome to the Number Guesser game."
print "I have a number in my mind that's between 1-20."

number = random.randint(0, 20)

# Guess the number
# >
prompt = "> "

# Start out as 5 and then decrement it on wrong guesses.
attempts = 5

while attempts > 0:

# Simple validation
try:
guess = int(raw_input(prompt))
except ValueError:
print "Only numbers are allowed. \n"
break

if guess > number:
print "Go lower."
elif guess < number:
print "Go higher."
else:
print "Nice! You've guessed it right. The number was %d." % number
print "And you got it with %d attempts!" % attempts
# Exit.
break

# Decrement the attempts each time the guess isn't right.
attempts -= 1

if attempts == 0:
print "You didn't guessed it, the number was %d. You lose." % number
# Exit the script.
break
# Print with the color red.
print("\033[91m You have {} guesses left. \033[00m").format(attempts)


number = random.randint(0, 20)


You just told the user that the number is between one and twenty, but you use random.randint(0, 20). What if the result was 0? One disgruntled player. You should be using number = random.randint(1, 20).

prompt = "> "


You aren't hard-coding the value. That's very good. Since it is a constant, however, you should use ALLCAPS.

attempts = 5
while attempts > 0:


You are starting out at the high point and decrementing until you get to zero. That isn't really the number of attempts. That is how many attempts are left. I would define a constant for the number of attempts allowed, define attempts as 0, and have the while make sure that attempts is lower than that number. This becomes especially useful when printing how many attempts it took. As it is, your program displays the wrong number: the number of attempts that were left.

try:
guess = int(raw_input(prompt))
except ValueError:
print "Only numbers are allowed. \n"
break


It's good that you try to validate the input, but you should use continue instead of break. One invalid input shouldn't end the program.

print "Nice! You've guessed it right. The number was %d." % number


Using % for a format string isn't officialy deprecated, but it is recommended to use .format().

What if the user wants to play again? You make him re-run the script. I would use a while loop and a function:

import random

PROMPT = "> "
GUESSES = 5

def guess_number(start=1, end=20):
print "I have a number in my mind that's between {}-{}.".format(start, end)
number = random.randint(start, end)
attempts = 0
while attempts < GUESSES:

# Simple validation
try:
guess = int(raw_input(prompt))
except ValueError:
print "Only numbers are allowed. \n"
continue

if guess > number:
print "Go lower."
elif guess < number:
print "Go higher."
else:
print "Nice! You've guessed it right. The number was {:d}.".format(number)
print "And you got it with {:d} attempts!".format(attempts + 1)
break

# Increment the attempts each time the guess isn't right.
attempts += 1

if attempts == GUESSES:
print "You didn't guess it; the number was {:d}. You lose.".format(number)
break
# Print with the color red.
print("\033[91m You have {} guesses left. \033[00m").format(attempts)

if __name__ == "__main__":
print "Welcome to the Number Guesser game."

again = True
while again:
print "I have a number in my mind that's between 1-20."
guess_number()
play_again = raw_input("Would you like to play again? ")
while play_again.lower() not in "yn":
play_again = raw_input("Invalid input. [y/n] ")
again = (play_again.lower() == "y")


I would say to go with what zondo said, except that you should probably get rid of the extra check for attempts == GUESSES.

if attempts == GUESSES:
print "...the number was {:d}. Youlose.".format(number)
break


Your while loop is already checking that attempts is less than GUESSES. You can just put the ending print statement at the end of the guess_number function.

As it was mentioned, the function with this change will print "You lose" even if you've won. Instead of breaking out of the loop when the correct number is guessed, you can use return to make the function exit instead.

Also, zondo said you should use continue instead of break on invalid inputs for guesses. In case you didn't learn about the continue statement, what it will do is skip the remaining statements in the current iteration of a loop and move control back to the top of the loop.

• I didn't change the first because the while loop ends even if the player wins. If you put the Youlose just after the while loop, it might print it after saying that you won. – zondo Apr 2 '16 at 10:31
• return` can work there. Instead of breaking out of the loop when the correct number is guessed, it would make sense for the guess_number function to exit. – abrarisme Apr 2 '16 at 15:25
• Good suggestion, but it doesn't right now. Perhaps you should add that instruction to your answer? – zondo Apr 2 '16 at 15:27