I did google it a lot, and I think I figured out what was causing it, but I don't understand why.
When I would try to run this code:
from random import randint
def getNums():
nums = set()
nums = randint(100, 999)
return str(nums)
def askUser():
try:
guess = int(input("Choose 3 digits to play the game: "))
except:
print("Please enter numbers only.")
return guess
def compare(num, guess):
try:
if guess == num:
print("Guessed!")
print(f"The number was {num}")
elif guess[0] in num or guess[1] in num or guess[2] in num:
print("Match")
elif num != guess:
print("Nope")
except IndexError:
pass
#GET RANDOM DIGITS
num = getNums()
#ASK THE USER TO ENTER THEIR GUESS
#GAME
while True:
guess = askUser()
guess = str(guess)
compare(num, guess)
if num == guess:
break
I would get
---> 23 elif guess[0] in num or guess[1] in num or guess[2] in num:
24 print("Match")
25 elif num != guess:
IndexError: string index out of range
When I would try with 0.
Removing the int(input) and casting the int variables to string seems like it fixed it, but I don't know why there was a problem to start with since they had the same length. Thank you
When you enter a number like '012', and you convert it to an int (12), then the resulting string will be '12'.
As you can see, you no longer have a string of length 3 in this example, but of length 2.
So you get an IndexError when accessing guess[2], since that index does not exist (at least you get the IndexError when you remove the try/except statement).
A simple way around this would be to store the user input in the variable without trying to parse as int, and then just use int() without changing guess.
Something like this:
def askUser():
try:
guess = input("Choose 3 digits to play the game: ")
int(guess)
except:
print("Please enter numbers only.")
return guess
There are other things that can be improved, like only returning guess when there's no error (otherwise you'll get an exception), only catching a ValueError instead of all exceptions, and actually testing if the user input is exactly three characters long.
If I am understanding your code and question, when you cast the int to a string, you are able to parse it as a string hence, why it works. If you pass it as an int, you cannot parse an int by positional reference such as guess[0].
To me, you corrected the issue by casting it to a string that allowed for your parsing.
Also, by using the Python "in" keyword, it will check to see if the value is in the string so, you do not need to parse through the string as "in" will return True or another output if you use an "if" statement.
Related
This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 4 months ago.
I am coding a guessing game where the user inputs an integer between 1 and 100 to try and guess the correct number (26). I have to count the number of guesses the user takes to get the correct number. I want to use try and except blocks to allow the user to keep trying until they guess it right.
Right now, my code only allows the user to input one ValueError. I don't want this, I want to keep inputting until I guess the number. Attached is my code. Any help is greatly appreciated!
ex:
I want to input errors ("a", 4.20, "hello") and still have them count as guesses until I guess the number
"a" > 4.20 > "hello" > 26 => Guessed it in 3 tries
def guess(n):
secret_number = 26
if n < secret_number:
return print("Too low!")
elif n > secret_number:
return print("Too high!")
def try_exp():
try:
n = int(input("What is your guess? "))
return n
except ValueError:
n = int(input("Bad input! Try again: "))
return n
def counter():
print("Guess the secret number! Hint: it's an integer between 1 and 100... ")
n = try_exp()
i = 0
while n != 26:
guess(n)
i += 1
n = try_exp()
print(f"You guessed it! It took you {i} guesses.")
counter()
Instead of making try_exp like that, you can use a while loop that will first ask for input, and if the input is valid, then it will break out of the while loop. This is one way to implement it:
def try_exp():
first_input = True
while True:
try:
if first_input:
n = int(input("What is your guess? "))
return n
else:
n = int(input("Bad input! Try again: "))
return n
except ValueError:
first_input = False
In this, we go through an infinite loop, and we have a flag that designates whether it is the first guess or if they have already guessed before. If it is the first guess, we ask them for input, and if it is the second guess, we tell them that they gave incorrect input and ask for more input. After receiving correct input, the function returns n. If the input is incorrect which is when it is not an integer, we set first_input as false. Then, the while loop loops again. It will keep on waiting for input until they submit an integer.
Newbie here. I'm using the variable number_guessed to store the guessed number and the correct number is 9. I want whoever's playing the game to only enter integers and I understand the variable stores string. Line 3 creates an error ValueError: invalid literal for int() with base 10: 'e'. I understand why this is and would appreciate some help with an interactive way to go about this problem. By the way, I'm using Python 3 and here's my code.
number_guessed = input('Guess a number between 0 and 10? ')
guess_count = 1
if type(int(number_guessed)) != int: # restricting input to integers: start
print('Whole numbers only!')
number_guessed = input('Guess a number between 0 and 10? ') # restricting input to integers: end
if int(number_guessed) == 9:
print("Correct. That's some good luck right there:)")
while int(number_guessed) != 9:
number_guessed = input('Try Again! Guess a number between 0 and 10? ')
if type(int(number_guessed)) != int: # restricting input to integers: start
print('Whole numbers only!')
number_guessed = input('Guess a number between 0 and 10? ') # restricting input to integers: end
guess_count += 1
if int(number_guessed) == 9:
print("Correct. That's some good luck right there:)")
exit()
if guess_count == 3:
msg = f"""
You're out of Luck!
It was 9 by the way
"""
print(msg)
Please save my soul. Would be very much appreciated.
Your problem is that int() will try to convert whatever is passed to it to an integer, which fails when it isn't a value that can be converted to an integer, resulting in the ValueError exception being thrown.
A solution is to 'catch' that exception like this:
number_guessed = input('Guess a number between 0 and 10? ')
try:
# try to convert it to an actual integer instead of a string
number_guessed = int(number_guessed)
except ValueError:
print('Whole numbers only!')
What doesn't work is to try and check the type of what was entered, that will always be a string, since you enter the number as text (that's the problem you're trying to solve), so some of the suggested solutions checking the type of the input won't work.
You cannot use int on a string. To fix this problem, you can do:
if type(number_guessed) is int:
print('Whole numbers only!')
Something like this might work. If a string is passed, it should use the strings length as a guess. In general, it’s more convenient to use the isinstance method, which is a built in function. Hope this is helpful :)
the_num = 9
guess = 0
guess_count = 0
while guess != the_num:
if guess_count >= 3:
print(“oh no!”)
break
guess = input(“guess a number in [0,10] “)
if isinstance(guess, int):
if guess == the_num:
print(“yay!”)
break
if guess != the_num:
guess_count += 1
elif isinstance(guess, str):
if len(guess) == the_num:
print(“yay”)
break
if len(guess) != the_num:
guess_count += 1
else:
guess_count += 1
My apology also for making edit, I’m not very efficient with the iOS app 🤷♂️
your logic is correct but you are casting your input to ing before the comparisson.
if type(int(number_guessed)) != int:
instead, you should try casting your raw input to int before comparing the number. You can do it by replacing the above line with
try:
number_guessed = int(number_guessed)
except:
pass
if type(number_guessed) != int:
...
this code will first try to convert your input to an int in the try block. If it is successful, your variable will be treated as an int later in the code thus redirecting the user to the if clause.
If the cast fails, then the code inside the except block will run. The pass keyword in the except clause tells your application to ignore what happened in the try clause thus your number_guessed will remain a string, redirecting the user to the else clause.
Another note - try to DRY your code up a bit. you are repeating
the same logic in two places - initial guess (lines 3-7) and
subsequent guesses (lines 10-14). try to restructure your code to
extract the key functionalities into separate functions.
Working code:
number_guessed = input('Guess a number between 0 and 10? ')
guess_count = 1
try:
number_guessed = int(number_guessed)
except:
pass
if type(number_guessed) != int: # restricting input to integers: start
print('Whole numbers only!')
number_guessed = input('Guess a number between 0 and 10? ') # restricting input to integers: end
if int(number_guessed) == 9:
print("Correct. That's some good luck right there:)")
while int(number_guessed) != 9:
number_guessed = input('Try Again! Guess a number between 0 and 10? ')
try:
number_guessed = int(number_guessed)
except:
pass
if type(number_guessed) != int: # restricting input to integers: start
print('Whole numbers only!')
number_guessed = input('Guess a number between 0 and 10? ') # restricting input to integers: end
guess_count += 1
if int(number_guessed) == 9:
print("Correct. That's some good luck right there:)")
exit()
if guess_count == 3:
msg = f"""
You're out of Luck!
It was 9 by the way
"""
print(msg)
import random
SecretNumber=(random.randint)
Guess=input("Please enter your guess: ")
NumberofGuesses=1
while Guess != SecretNumber:
NumberofGuesses=NumberofGuesses+1
if Guess>SecretNumber:
print("Please insert a smaller number")
else:
print("Please insert a bigger number")
print("Number of Guesses: {0}".format(NumberofGuesses))
from random import *
secretnumber = randint(0,10)
numberofGuesses += 1
guess = int(input())
just a few things to clean up the code, and fix the str problem
also, put the guessing part in the while loop
You never convert the user's guess into an integer. That takes care of the str part. Use Guess = int(input("Please enter your guess: ")).
You never actually call the random.randint function, with random.randint(). That means SecretNumber is a function, not an integer, which takes care of the method part. Use SecretNumber = random.randint(1, 10) (for a random number between 1 and 10, inclusive).
You never have another prompt for input. Either add another Guess =... at the end of the loop, or move the one you already have to the beginning of the loop and use a while True: with a break on a matching number (in an else branch for the if structure you already have - the current else should be an elif; see below).
If the guess is too big, you state as much. However, you say the guess is too small in every other case, even though the guess might actually match. Replace that else with elif Guess < SecretNumber.
I'm having a problem with some coding that I'm doing for a school assignment, the same thing happened and I managed to fix it but I did so without knowing how I did it.
def number():
num = input("please enter the number of people that would like play:")
try:
if int(num) >= 2:
if int(num) <=7:
return num
else:
print("number must be 7 or less")
number()
else:
print("number must be greater than 2")
number()
except:
print("that is not a valid number. number must be between 2 and 7")
number()
number = number()
print(number,"people are playing")
This is the code which is causing the problem. If I enter an invalid number it works fine, I can just re-enter a new number, but as you can see I have wanted to print out the "number of people playing" but it returns with "none people are playing" but this is only after I have entered an invalid number. What can I do?
In the ideal case, without any errors, number() returns the entered num and all is well. However, in all other cases, you end the function with a recursive call to number() without actually returning anything. So the function implicitly returns None (i.e. nothing).
Just change every recursive call to return number() and it should work.
Btw. you should avoid recursion for this; see this answer on how to best ask the user repeatedly for valid input.
You need to use a loop rather than calling your routine again which will not have the effect you are looking for (look into recursion). Something like the following approach would be better:
def number():
while True:
num = input("please enter the number of people that would like play: ")
try:
num = int(num)
if num > 7:
print("number must be 7 or less")
elif num <= 2:
print("number must be greater than 2")
else:
return num
except:
print("that is not a valid number. number must be between 2 and 7")
number = number()
print(number, "people are playing")
The reason you are seeing None is that it is possible to reach the bottom of your function without a return being used. In this case Python defaults the returned value to None.
I wrote this script but it always returns the same answer ("Your guess is too high"), no matter what the user inputs. Any insight would be helpful.
import random
number = random.randint(1, 10)
guess = input("Guess a number between 1 and 10: ")
if type(guess == int):
print(number) # this prints the randint to show the code isn't working
while(number != 0):
if(guess > number):
print("Your guess is too high!")
break
elif(guess < number):
print("That's too low.")
break
elif(guess == number):
print("Thats's right!")
break
else:
print("Please enter a number.")
Your while loop is useless, the problem of testing the input as an int is better handled with a try/except.
All together the correct answer is in Python3 :
import random
number = random.randint(1, 10)
found = False
while not found:
try:
guess = int(input("Guess a number between 1 and 10: "))
if guess > number:
print("Your guess is too high!")
elif guess < number:
print("That's too low.")
elif guess == number:
print("Thats's right!")
found = True
except ValueError:
print("Please enter a number.")
if type(guess == int):
This isn't doing what you expect. It always returns True because it's the equivalent to bool(type(False)). First make sure to convert your input to an int
guess = int(input("Guess a number between 1 and 10: "))
and then remove this if statement:
if type(guess == int):
Your problem is that this code:
if(guess > number)
is always comparing a string to an int, so once you correct that your code will be fixed.
I have just copied and pasted your code and it seems to function mostly correctly. There are some issues with it though. First, it appears that this is written for python 2 based on the way you are using the input function. However this is bad practice as the input() function in python 2 includes an implicit call to the eval() function which could allow for arbitrary code to be run.
In python 2 the better practice would be to use guess = int(raw_input("Guess a number between 1 and 10: ")).
In python 3, raw_input() has been removed and input() replaces it. So in python 3 you would use guess = int(input("Guess a number between 1 and 10: ")).
Your final else block is also indented where it should not be, although if you revise your code to make use of the advice given above, your if...else block is no longer necessary.
That's because input returns a string in Python 3. You need to call int() to make it an integer type:
guess = int(input("Guess a number between 1 and 10: "))
You're also using the type() function incorrectly. You probably want the function isinstance(): if isinstance(guess, int):
Also, in Python, we don't need parentheses like you've used. You can simply do if guess > number: