Then the call to the main function (or any code actually doing something (by opposition to just defining)) is usually behind an if name == "main": if name == "main": guard.
Then the call to the main function (or any code actually doing something (by opposition to just defining)) is usually behind an if name == "main": guard.
Then the call to the main function (or any code actually doing something (by opposition to just defining)) is usually behind an if name == "main": guard.
User input
At the moment, if the user inputs an invalid number, a non-handled exception is thrown and your program stops. It could be a good idea to try to handle this. Because this can make your code a bit more complicated, it is probably an even better idea to write a function to handle this job. Something like :
def get_int_from_user(prompt):
while True:
try:
return int(input(prompt))
except ValueError:
print("Invalid value")
Duplicated logic
In 2 different places (3 if you count the text in the prompt), you take into account the fact that replay == 1
means "play again". It might be just as easy to have this used in a single place.
For instance,
while True:
...
replay = get_int_from_user("\nWould you like to play again? Enter 1 for yes, any other character for no: ")
if (replay != 1):
print("Thank you for playing. See you next time")
break
Style
You don't need that many parenthesis in Python.
You have way too many comments explaining the obvious. If one reads youre code, he/she is expected to know what break
does.
Loops
You are using a while
loop to perform iterations but this can just as easily be done with for
and range
. Also, a quite unknown feature of Python is the fact that for
accept an else
block which is to be understood as a nobreak
.
for num_of_guesses in range(1, lives+1):
guess = get_int_from_user("Please enter your guess: ")
if guess == random:
print("Good guess, that is correct! You got the right answer on guess number", num_of_guesses, ", well done!\n")
break #if answer is correct this will exit the while loop
else:
print("Unlucky, that guess was incorrect. You have", (lives-num_of_guesses), "lives remaining.\n")
else: # nobreak
print("You have run out of guesses. The correct answer was:", random)
Organisation
It could be a good idea to split your program into small functions. Such a function could be used to handle a single game and be called again and again on demand from a function traditionnally named main
.
Then the call to the main function (or any code actually doing something (by opposition to just defining)) is usually behind an if name == "main": guard.
Final code
Here the final version of the code:
# In this program, the user must try to guess a random number generated by the computer
from random import randint
def get_int_from_user(prompt):
while True:
try:
return int(input(prompt))
except ValueError:
print("Invalid value")
def play_game():
lives = get_int_from_user("How many lives would you like? ")
max_value = get_int_from_user("Please choose the largest number that can be generated: ")
random = randint(0, max_value)
for num_of_guesses in range(1, lives+1):
guess = get_int_from_user("Please enter your guess: ")
if guess == random:
print("Good guess, that is correct! You got the right answer on guess number", num_of_guesses, ", well done!\n")
break
else:
print("Unlucky, that guess was incorrect. You have", (lives-num_of_guesses), "lives remaining.\n")
else: # nobreak
print("You have run out of guesses. The correct answer was:", random)
def main():
while True:
play_game()
replay = get_int_from_user("\nWould you like to play again? Enter 1 for yes, any other character for no: ")
if replay != 1:
print("Thank you for playing. See you next time")
break
if __name__ == "__main__":
main()
Further improvement
It could be a good idea to add proper documentation like docstrings to your module and functions.