Python: random number game with input validation - python

I'm writing a program that is a guessing game where the user has one chance to guess a number between 1 and 20.
There are two problems with the code:
Number one is still the input validation. The firstGuess variable is actually in main().
firstGuess = userguess()
def userGuess():
while True:
try:
guess = int(input('Enter a number between 1 and 20: '))
if 1 <= guess >= 20:
return guess
except ValueError:
print (guess, 'is not a valid guess!')
break
What I'm trying to do is put the input validation in a loop (while True:) until the user gives good input (in this case a positive number between 1 and 20). If the user were to enter 'd', or '-5', the program should continue looping until good input is given. However, this is not the case. By adjusting the code, I have been able to ask for the input again once bad input is entered, but if bad input is given a third time I get "another exception occured while handling this exception."
*Removed other problem, #Henry Woody was correct in that I wasn't using the conditionals correctly.

The issues are with the conditionals.
The first is the line:
if 1 <= guess >= 20:
in userGuess, which is checking for a number greater than or equal to 20, which is not what you want. You can fix this issue by changing the condition to:
if 1 <= guess <= 20:
Next, the conditional:
if guess1 == randomOne or randomTwo or randomThree:
checks whether guess1 == randomOne or if randomTwo is truthy or if randomThree is truthy. It does not check if guess1 == randomOne or guess1 == randomTwo or guess1 == randomThree as intended. You can fix this by changing the condition to:
if guess1 in [randomOne, randomTwo, randomThree]:
to check if guess1 is equal to either of the three random variables.
Edit:
There is also an issue in the try/except block. If the user enters a non-digit character in the input, a ValueError will be raised before guess is defined. But then guess is referenced in the except block, but guess isn't defined at that point.
You can fix this by getting the user input and then, separately, trying to convert the input to an int.
Here's an example:
while True:
guess = input('Enter a number between 1 and 20: ')
try:
guess = int(guess)
if 1 <= guess <= 20:
return guess
except ValueError:
print (guess, 'is not a valid guess!')
break

Related

Why am I get a syntax error here when I am equating a variable containing an integer and a variable containing a numerical input from the user?

I am just learning the basics of Python and created a number guessing game. I want the user to be able to guess the number as many times as possible until they guess correctly. I did this through a while loop but the code, "else guess == a:" near the end is giving me a syntax error. I am confused because the while loop ensures that the input guess is an integer by the if statement,
if guess.isdigit():
guess = int(guess)
Please help
import random
a = random.randint(1,10)
print("this is a number guessing game")
question_one = input("Would you like to play? Yes or No?:")
if question_one == "Yes":
print("Let's go!")
else:
print("That sucks!")
exit()
guess = None
while guess != a:
guess = (input("Alright, guess a number from 1-10"))
if guess.isdigit():
guess = int(guess)
if guess > a:
guess = int(input("Guess lower!"))
elif guess < a:
guess = int(input("Guess higher!"))
else guess == a:
print("you got it!")
else doesn't let you define a condition. else will execute if all other conditionals return false. You should change that last else to elif. Or you can simply leave out the conditional guess == a all together. If it is not greater than or less than, the only other thing it can be is equal to.
If you have the last else, the code inside the else will be executed if any other condition goes false. So I think if you change the last else with an elif we work properly.
An else statement contains the block of code that executes if the conditional expression in all your if or elif statements is false. Hence in your case you're supposed to use the elif statement instead of else. See the following:
elif guess == a:
print("you got it!")

Why do I get "ValueError: invalid literal for int() with base 10". in this Python code?

I'm a beginner trying to improve my Python skills. I've found a very similar question to mine but since the source code was different, it did no benefit. Here is the link for the question: ValueError: invalid literal for int() with base 10: ''
Anyways, here is my code:
correct_answer= 41
guess = int(input("Guess the number"))
if int(input()) == correct_answer:
print ("You found my number!")
if int (input()) >= correct_answer:
print ("My number is lower.")
if int (input()) <= correct_answer:
print ("My number is higher.")
else:
print ("You didn't write any numbers!")
Here, I wanted to write a simple guessing game. The number computer has in mind is 41, and the user has to guess the number after "Guess the number". If the input of a user is greater than 41, the program says "My number is lower" and if the input is smaller than 41, the program says "My number is greater."
When I run this code, I get the "ValueError: invalid literal for int() with base 10: ''
Thank you in advance for helping me solve this problem :)
The problem is that you are calling input() again and again. Everytime you do this, the program expects input and the user has to retype their guess in order for the program to work as intended. Replace all instances of int(input()) (with an empty prompt) with guess, and you'll see more reasonable behavior. E.g.
if guess == correct_answer:
print ("You found my number!")
Try this -
correct_answer= 41
guess = raw_input("Guess the number")
try:
guess = int(guess)
except ValueError:
print "Wrong value entered"
if guess == correct_answer:
print ("You found my number!")
elif....
Let me know if that helps
When you take the input and someone enters an alphabet or something which is not an integer, and you try to typecast it, python will throw a ValueError.
To catch such cases, we use try except block will catch it. More about python try except in python
Couple of pointers about your code -
if int(input()) == correct_answer:
here, you are just calling input() function and your program will not work, use variable guess, this is the variable you have put your input into.
and
if int(input()) == correct_answer:
print ("You found my number!")
if int (input()) >= correct_answer:
print ("My number is lower.")
if int (input()) <= correct_answer:
print ("My number is higher.")
Use python's if elif elif else instead.
Also, since you have typecasted to integer already, you don't need to do that with every if condition, this would suffice -
if input > correct_answer and you don't need >= or <=.
>= means greater or equal, but you have handled the equal case in first condition, if it's equal, it'll be caught there, similar with less than or equal

Python: Why checking of types is a big no

I am learning python and was writing this game, where the program picks a random number and asks the user to guess the number. In this case, a user can enter an empty string or an alphabet by mistake. So, i felt the need to check the type of the user input before doing the comparison as shown below. Also, this lead me to the following stackoverflow entry
Checking whether a variable is an integer or not
My question is why checking of types is considered a bad practice and how can i accomplish my task by not checking the type?
import random
num = random.randint(1,10)
while True:
guess = input('Guess a number between 1 and 10: ')
if(bool(guess)):
try:
guess = int(guess)
except:
print("Please enter a numeric value")
continue
else:
print("you have to enter some number")
continue
if guess == num:
print("you guessed it right")
break
elif guess < num:
print("Try higher")
elif guess > num:
print("Try lower")
As the comments have stated, at no point do you check the type. What you do is validate and convert the input, which is appropriate for this program (and indeed, should be used in any program that accepts user input).
Try this instead:
import random
num = random.randint(1, 10)
while True:
try:
guess = int(input('Guess a number between 1 and 10: '))
if guess == num:
print('You have guessed the correct number')
break
if guess < num:
print('Try higher.')
else:
print('Try lower.')
except ValueError:
print('Please enter a number.')
The idea is that simply converting the input and handling the error leads to much cleaner code. In Python circles, checking the type via isinstance is known as Look Before You Leap which is discouraged. Just attempt the operation in question and handle the failure case (usually by exception handling). This is termed Easier to Ask Forgiveness than Permission.

How can I make this code less verbose?

I am making a simple 'guess a number between one and ten' game. I have used some basic error handling and am printing the number generated by the random module for testing purposes.
However I would like to know if there is a less verbose way to write this.
This is the code:
import random
while True:
"""Variable declaration"""
number_of_attempts = 1
number = random.randrange (1,11)
print (number)
print("Time to play a guessing game! Muhahaha...")
"""Error handling and main game code/while loop"""
while True:
try:
guess = int(input("Guess a number between one and ten."))
except ValueError:
print("Input a whole number between one and ten silly!")
continue
if guess >= 1 and guess <= 10:
pass
else:
print("Input a number between one and ten silly!")
continue
if guess == number:
print("You were successful and it took you", number_of_attempts, "attempts!!!")
break
else:
print("Try again!")
number_of_attempts = number_of_attempts +1
"""Game Exit/Restart"""
play_again = input("Would you like to play again, y/n?")
if "y" in play_again or "yes" in play_again:
continue
else:
break
Thanks,
Ben
if guess >= 1 and guess <= 10:
Can be written as:
if 1 <= guess <= 10:
Also, your first conditional can simply be written as:
if not 1 <= guess <= 10:
print("Input a number between one and ten silly!")
continue
But this can also be put inside the try bit, saving you from writing continue twice:
try:
guess = int(input("Guess a number between one and ten."))
if not 1 <= guess <= 10:
print("Input a number between one and ten silly!")
continue
except ValueError:
print("Input a whole number between one and ten silly!")
continue
Finally your last conditional can simply be:
if play_again not in ('y', 'yes'):
break
The continue isn't needed.
You may also want to wrap this all up into a function as well, to get rid of those infinite while loops and to prevent you from using continue and break so much.
Why not put the actual conditions on the while loops so you don't have to hunt for breaks to understand the loops? It would make your code clearer and smaller.
if guess == number:
print("You were successful and it took you", number_of_attempts, "attempts!!!")
break
For instance if you put guess == number as the while loop conditional then the print would be the first thing after the loop. Initialize guess to -1 so it always works the first time. The play again if statement could also disappear into the loop conditional as well.

Getting an Integer Input in a Range

I'm trying to take a raw input and detect whether it is in a range.
Here's my code.
def gold_room():
print "This room is full of gold. How much do you take?"
next = raw_input("> ")
if next == int in range(50):
how_much = int(next)
else:
dead("Man, learn how to type a number.")
if how_much < 50:
print "Nice, you're not greedy, you win!"
exit(0)
else:
dead("You greedy bastard!")
When I enter a number it gives me the else: "Man, learn how to type a number."
I guess the line that isn't working is "if next == int in range(50):
Could anyone help me out?
Thanks in advance!
Edit:
I'm a noob so that line was just me ballparking.
I thought it would check next to see if it was an integer in the range of numbers 0-50.
If you want to "get an integer input in a range", you'll need two things:
Check if the input is an int
Check if it's in your range
Check if the input is an int
try/except will be perfect here:
n = raw_input('> ')
try:
n = int(n)
except ValueError:
dead() # or what you want
Why this is good?
Because if n is an int you'll have it convert it to an integer and if it's not an exception get raised and you can call your dead() funcion.
Check if it's in your range
If you get to this point it means that the exception before it was not raised and n was converted to an integer.
So you just need to do:
if 0 <= n <= 50:
print 'You win'
else:
print 'You lose'
Don't do:
if n in range(50):
# ...
Beacuse it will build a list of 50 numbers for nothing.
Note: don't use next as a variable, beacuse it'll shadow the built-in next()
Since raw_input returns a string, you need to convert to an int first. Try replacing the line with this:
if int(next) in range(50):
The result of raw_input() will be a string, so first you need to check to see if next is all digits. There are a few ways to do this, the easiest is to use the str.isdigit() function:
next = raw_input("> ")
if next.isdigit():
how_much = int(next)
else:
dead("Man, learn how to type a number.")
Note that you do not need to check to see if the value for next is in the range from 0 to 50, since your next if statement already checks to see if the value is less than 50 and negative numbers will be excluded by next.isdigit().
The test "next == int in range(50)" evaluates to "(next == int) and (int in range(50))" which is fairly meaningless and always equates to false.
Instead you could try
try:
how_much = int(next)
if not (0<=how_much<50):
print 'Too greedy'
except ValueError:
dead("Man, learn how to type a number.")
Using try .. except will allow you to make sure entered value is an int. # raise is a place holder for your handling a non-int contition:
try:
next = int(raw_input("> "))
except ValueError:
# raise
if not 0 <= next <= 50:
print 'Too greedy'

Categories