I was trying to create a simple random number guessing game. The problem is even if I type the correct number it replies with a 'The number is less than'. Can somebody provide me a solution for this one ?
Thanks in advance
import random
import sys
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
user = raw_input('Guess The Number\n Pick between 1 - 10\n >>> ')
try:
int(user)
except:
print "Numbers Only !"
sys.exit(0)
number = random.choice(numbers)
int(number)
for i in range(0, 4):
if number == user:
print 'You Won!'
if user > number:
print 'The number is less than', user
user = raw_input('>>> ')
try:
int(user)
except:
print "Numbers Only !"
if user < number:
print 'The number is bigger than', user
user = raw_input('>>> ')
int(user)
print "The Number was", number
The biggest problem is that you're not saving the conversion to int so you're using the guess as the string the user entered. You need to save it by doing user = int(raw_input('>>>'))
There are other ways you can improve this code, however. You repeat yourself a bit, and you don't need random.choice, you can use random.randrange(1, 10)
You shouldn't just say except:. You wanna only catch the exceptions you are looking for. The particular exception you are looking for is a ValueError
Additionally, I suggest you let the user try again when they enter something that's not a number. You can wrap up the whole thing in it's own function.
import random
def get_user_num(msg='>>> '):
"""Print the msg parameter as a prompt for the user to enter a number. If
they enter an invalid string, reprompt them until they enter a number.
"""
while True:
try:
return int(raw_input(msg)) # save the conversion to int
except ValueError: # only except the error you're actually looking for
print 'Numbers Only!'
# 'from 1-9' is probably better than 'between 1-10'
user = get_user_num('Guess The Number\n Pick from 1-9\n>>> ')
number = random.randrange(1, 10) # <- numbers list is unnecessary
#int(number) # this conversion was never needed, it was already a number
for _ in range(4): # you don't need (0, 4), 0 is assumed
if number == user:
print 'You Won!' # the correct number has been guessed
break # exit the loop once the number has been correctly guessed
elif user > number:
print 'The number is less than', user
elif user < number:
print 'The number is bigger than', user
# Don't repeat yourself, put this outside the `if`s
user = get_user_num()
else:
#only print the answer when it wasn't guessed correctly
print "The Number was", number
When you convert to int(user), you aren't saving a new int to user. So user still remains a string.
What you need to do is
user = int(user)
By the way, this is for all of the places where you use int(user)
This could be done with a much simpler implementation:
import random
number = random.randrange(10)
for i in xrange(4):
try:
user = int(raw_input('guess: '))
except ValueError:
print 'must be int'
continue
if user == number:
print 'bravo'
break
elif user < number:
print 'greater'
else:
print 'lesser'
print 'it was: %d' % number
Related
beginner here!
My question is, why doesn't the terminal say the prints?
import random
print(" Guess number between 1-5")
def Guessinggame(Number = int(random.randint(1, 5))):
if input == Number:
return "YOU'RE AWESOME!"
else:
return "Not correct"
while():
Guessinggame()
It's a guessing game where you have to guess between the number 1 and 5.
You can try this:
import random
def Guessinggame(inp):
Number = random.randint(1, 5)
print(inp,Number)
if inp == Number:
return "YOU'RE AWESOME!"
else:
return "Not correct"
while True:
inp=int(input("Guess number between 1-5"))
print(Guessinggame(inp))
Here what we are doing is, program starts from while loop. The correct way to use while loop is while <condition>, if you are doing while() then it is calling while function. After infinitely while loop start, we are asking user to input number and we are saving that number in inp variable. Now we are sending inp variable into Guessinggame function. Inside this we are creating new variable number which is random number. And now we are checking if user input number same to random number or not. And return YOU'RE AWESOME is true and return Not correct if false. And that return will be printed because we are calling function inside print.
return will only return the value, not print it. You need to call the print function to print the value.
print(Guessinggame())
Also, your program has some logical error it should be
import random
print(" Guess number between 1-5")
def Guessinggame(guess,Number):
if guess== Number:
return "YOU'RE AWESOME!"
else:
return "Not correct"
while True:
y=int(input("enter a number: "))
x= int(random.randint(1, 5))
print(Guessinggame(y,x))
Your guessing game function is returning either "YOU'RE AWESOME" or "Not correct", but there is no print statement included. To demonstrate what's going on, we could include an extra variable in your code:
import random
def Guessinggame():
# I've added in an input function to get the user input
user_input = input(" Guess number between 1-5")
Number = int(random.randint(1, 5)) # more readable here
if user_input == Number:
return "YOU'RE AWESOME!"
else:
return "Not correct"
while True:
outcome = Guessinggame()
print(outcome)
Now "YOU'RE AWESOME!" or "Not correct" gets stored inside of the outcome variable. Printing outcome will show the result. Note that you can cut out the outcome variable completely by printing Guessinggame(), I just wanted to show you what's happening.
Note that you'll also need to convert Number from an integer to string-type to compare it with the user input (user input is stored as string):
import random
def Guessinggame():
# I've added in an input function to get the user input
user_input = input(" Guess number between 1-5")
Number = str(random.randint(1, 5)) # convert to string-type
if user_input == Number:
return "YOU'RE AWESOME!"
else:
return "Not correct"
while True:
outcome = Guessinggame()
print(outcome)
For more on type conversion, you check out this article I posted on LearnDataSci:
https://www.learndatasci.com/solutions/python-typeerror-list-indices-must-be-integers-or-slices-not-str/
This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 5 years ago.
I would like to add an "if" statement to my code. If "guess" is not an integer, print ("You did not enter a number, please re-enter") and then repeat the code from the input area instead of the starting point. The following is my attempt, however when I enter a non-int at guess input, ValueError appears. Thanks in advance!
#This is a guess the number game.
import random
print ("Hello, what is your name?")
name = input()
print ("Well, " + name + " I am thinking of a number between 1 and 20, please take a guess.")
secretNumber = random.randint(1,20)
#Establish that they get 6 tries without specifically telling them
for guessesTaken in range(1, 7):
guess = int(input())
if type(guess) != int:
print ("You did not enter a number, please re-enter")
continue
if guess < secretNumber:
print ("The number you guessed was too low")
elif guess > secretNumber:
print ("The number you guessed was too high")
else:
break
if guess == secretNumber:
print ("Oh yeah, you got it")
else:
print ("Bad luck, try again next time, the number I am thinking is " + str(secretNumber))
print ("You took " + str(guessesTaken) + " guesses.")
Use a try and except:
for guessesTaken in range(1, 7):
try:
guess = int(input())
except ValueError:
print ("You did not enter a number, please re-enter")
continue
So you try to convert the input into an integer. If this does not work, Python will throw an ValueError. You catch this error and ask the user try again.
You can try a simple while loop that waits until the user has entered a digit. For example,
guess = input("Enter a number: ") # type(guess) gives "str"
while(not guess.isdigit()): # Checks if the string is not a numeric digit
guess = input("You did not enter a number. Please re-enter: ")
That way, if the string they entered is not a digit, they will receive a prompt as many times as necessary until they enter an integer (as a string, of course).
You can then convert the digit to an integer as before:
guess = int(guess)
For example, consider the following cases:
"a string".isdigit() # returns False
"3.14159".isdigit() # returns False
"3".isdigit() # returns True, can use int("3") to get 3 as an integer
Below is my code for guessing a random number. I had to check the input to make sure it was an integer and within the 1-20 range. Everything is working. It outputs the right response if it is not an integer or is out of range but then it continues through the while loop. I thought the try except would send it back before it continued. What have I done incorrectly here? I cannot figure out the problem. Thank you for any help!
import random
tries = 0
name=(raw_input('Hello! What is your name? '))
number = random.randint(1, 20)
print('Hello, ' + name + ', I am thinking of a number between 1 and 20.')
while tries < 6:
guess = (raw_input('Take a guess.' ))
try:
guess = int(guess)
except ValueError:
print 'You did not enter a valid number, try again.'
tries = tries + 1
if guess<1 or guess>20:
print 'Your guess is not between 1 and 20'
if guess < number:
print 'Your guess is too low.'
if guess > number:
print 'Your guess is too high.'
if guess == number:
break
if guess == number:
print 'Good job, ',name,'! You guessed my number in ',tries,' guesses!'
if guess != number:
print 'Sorry, The number I was thinking of was ',number
All you do is when a ValueError is raised is to have an extra line printed. If you want your loop to start from the beginning, add continue in the except block. If you want to count invalid inputs as tries, move the line where you increment tries to the beginning of your loop.
tries += 1 # increment tries here if invalid inputs should count as a try, too
# increment tries after the except block if only valid inputs should count as a try
# get input here
try:
guess = int(guess)
except ValueError:
# inform user that the input was invalid here
continue # don't execute the rest of the loop, start with the next loop
You can either put another continue where you check whether the number is too high or too low:
if guess<1 or guess>20:
print 'Your guess is not between 1 and 20'
continue
or use an if/elif construct:
if guess<1 or guess>20:
print 'Your guess is not between 1 and 20'
elif guess < number:
print 'Your guess is too low.'
elif guess > number:
print 'Your guess is too high.'
else: # guess == number
break
I recommend the if/elif. Having multiple continues in a loop can make it hard to follow.
You told it to print something, but Python doesn't know that you don't want it to do other things during that iteration. Sometimes you might want it to go on only if there was an error. To say "skip this loop", use continue:
try:
guess = int(guess)
except ValueError:
print 'You did not enter a valid number, try again.'
continue
You need to continue after both tests and only increment the tries once you have successfully passed the tests.
import random
tries = 0
name=(raw_input('Hello! What is your name? '))
number = random.randint(1, 20)
print('Hello, ' + name + ', I am thinking of a number between 1 and 20.')
while tries < 6:
guess = (raw_input('Take a guess.' ))
try:
guess = int(guess)
except ValueError:
print 'You did not enter a valid number, try again.'
continue
if guess<1 or guess>20:
print 'Your guess is not between 1 and 20'
continue
tries = tries + 1
if guess < number:
print 'Your guess is too low.'
if guess > number:
print 'Your guess is too high.'
if guess == number:
break
if guess == number:
print 'Good job, ',name,'! You guessed my number in ',tries,' guesses!'
if guess != number:
print 'Sorry, The number I was thinking of was ',number
This question already has answers here:
Accepting only numbers as input in Python
(2 answers)
Closed 7 years ago.
Hi i am trying to make the program only accept the numbers 0, 4, 6, and 12, and not allow anything else to be inputted. So far i have been successful in only allowing certain integers to be entered, however i am having trouble with not allowing any letters to be entered. When a letter is entered, the entire program crashes. Please could you help me only allow integers to be entered? Thank you.
My code is below:
from random import randint
def simul():
dice = int(input("What sided dice would you like to roll? 4, 6 or 12? 0 to not roll:"))
if dice != 4 and dice!=6 and dice!=12 and dice!=0:
print('You must either enter 4, 6, or 12')
simul()
elif dice==0:
exit()
else:
while dice !=0 and dice==4 or dice==6 or dice ==12 :
print (randint(1,dice))
dice = int(input("What sided dice would you like to roll? 4, 6 or 12? press 0 to stop."))
simul()
A couple of things you could look for in your code:
using try/catch is the recommended way to test input for many reasons including knowing the exact cause of the error
you can reduce some of your ifs and elses by thinking a little more about how they are nested
having the function call itself and using a while loop isn't the best way, use one or the other
in your case, you don't really need to allow only integer input, what you're looking for is to only allow a 0, 4, 6, or 12, which you do with the if statement
from random import randint
def simul():
while True:
try:
dice = int(input("What sided dice would you like to" \
" roll? 4, 6 or 12? 0 to not roll: "))
if dice not in (4, 6, 12, 0):
raise ValueError()
break # valid value, exit the fail loop
except ValueError:
print("You must enter either 4, 6, 12, or 0")
if dice == 0:
return 0
print(randint(1, dice))
return dice
if __name__ == '__main__':
while simul() != 0:
pass
I would encapsulate the "constrained input" functionality into a separate, reusable function:
def constrained_int_input(prompt, accepted, toexit=0):
msg = '%s? Choose %s (or %s to exit)' % (
prompt, ', '.join(str(x) for x in sorted(accepted)), toexit)
while True:
raw = raw_input(msg)
try:
entered = int(raw)
except ValueError:
print('Enter a number, not %r' % raw)
continued
if entered == toexit or entered in accepted:
return entered
print('Invalid number: %r -- please enter a valid one' % entered)
Now you can call e.g
dice = constrained_int_input('What sided dice would you like to roll', (4,6,12))
whenever required and be sure that dice will end up with one of the accepted integers, including possibly the to-exit value of 0.
put it in a try catch block like so:
try:
choice = int(raw_input("Enter choice 1, 2 or 3:"))
if not (1 <= choice <= 3):
raise ValueError()
except ValueError:
print "Invalid Option, you needed to type a 1, 2 or 3...."
else:
print "Your choice is", choice
copied from: limit input to integer only (text crashes PYTHON program)
while True:
x=input("4,6 or 12? 0 to not roll: ")
if x.isalpha():
print ("only numbers.")
continue
elif int(x)==0:
print ("quiting..")
break
elif int(x)!=4 and int(x)!=6 and int(x)!=12:
print ("Not allowed.")
else:
print (random.randint(1,int(x)))
Here is another method, use isalpha().
I am working on small python payroll project where you enter employee name, wage, and hours worked. When I enter decimals for the wage input, I am getting "invalid entry" because of my exception handling. Why are decimals being returned as invalid? Also, how can I loop this program so that it keeps the same 3 questions until the user types "Done"?
Any help will be greatly appreciated!
Thanks!
import cPickle
def getName():
strName="dummy"
lstNames=[]
strName=raw_input("Enter employee's Name: ")
lstNames.append(strName.title() + " \n")
def getWage():
lstWage=[]
strNum="0"
blnDone=False
while blnDone==False: #loop to stay in program until valid data is entered
try:
intWage=int(raw_input("Enter employee's wage: "))
if intWage >= 6.0 and intWage <=20.0:
lstWage.append(float(strNum)) #convert to float
blnDone=True
else:
print "Wage must be between $6.00 and $20.00"
except(ValueError): #if you have Value Error exception. Explicit on error type
print "Invalid entry"
def getHours():
lstHours=[]
blnDone=False
while blnDone==False: #loop to stay in program until valid data is entered
try:
intHrs=int(raw_input("Enter number of hours worked: "))
if intHrs >= 1.0 and intHrs <=60.0:
blnDone=True
else:
print "Hours worked must be 1 through 60."
except(ValueError): #if you have Value Error exception. Explicit on error type
print "Invalid entry"
def getDone():
strDone=""
blnDone=False
while blnDone==False:
try:
srtDone=raw_input("Type \"DONE\" if you are finished entering names, otherwise press enter: ")
if strDone.lower()=="done":
blnDone=True
else:
print "Type another empolyee name"
except(ValueError): #if you have Value Error exception. Explicit on error type
print "Invalid entry"
##### Mainline ########
strUserName=getName()
strWage=getWage()
strHours=getHours()
srtDone1=getDone()
Here's the core of it:
>>> int("4.3")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '4.3'
You can't convert a string to an integer if it's not an integer. So when you do intWage=int(raw_input("Enter employee's wage: ")) it throws the ValueError. Perhaps you should convert it directly to float.
Because you're converting the input to int:
intWage=int(raw_input("Enter employee's wage: "))
You are assuming that the wage is an integer, which by definition does not have a decimal place. Try this:
intWage=float(raw_input("Enter employee's wage: "))
Try using
intWage=int(float(raw_input("Enter employee's wage: ")))
This will accept a decimal number as input.
Error w/ Floats
As others said before, you are assuming the input will be a float. Either use float() or eval()instead of int():
intWage = float(raw_input("Enter employee's wage: "))
Or use input() instead of int(raw_input()):
intWage = input("Enter employee's wage:")
Both will accomplish the same thing. Oh, and change intWage to floatWage atleast, or even better, don't use Hungarian Notation.
The Code
As for your code, I did a couple of things:
Used break and/or return to terminate loops instead of keeping track of booleans (that's the whole purpose of the break and continue statements)
Changed intWage to floatWage
Rewrote number comparisons in a more concise way (x <= y and x >= z can be written as z >= x >= y)
Added return statements. I don't get why you didn't put them yourself, unless you wanted to assign None to strUserName, strWage and strHours)
Added a loop as you requested when asking for an employee's details.
Modified getDone() to work w/ the loop.
import cPickle
def getName():
strName = "dummy"
lstNames = []
strName = raw_input("Enter employee's Name: ")
lstNames.append(strName.title() + " \n")
return strName
def getWage():
lstWage = []
strNum = "0"
while True: #Loop to stay in program until valid data is entered
try:
floatWage = float(raw_input("Enter employee's wage: "))
if 6.0 <= floatWage <= 20.0:
lstWage.append(floatWage)
return floatWage
else:
print "Wage must be between $6.00 and $20.00"
except ValueError: #Catches ValueErrors from conversion to float
print "Invalid entry"
def getHours():
lstHours = []
while True: #loop to stay in program until valid data is entered
try:
intHrs=int(raw_input("Enter number of hours worked: "))
if 1.0 <= intHrs <= 60.0:
return intHrs
else:
print "Hours worked must be 1 through 60."
except ValueError: #Catches ValueErrors from conversion to int
print "Invalid entry"
def getDone():
strDone = ""
while True:
srtDone = raw_input('Type "DONE" if you are finished entering names, otherwise press enter: ')
if strDone.strip().lower() == "done":
return True
else:
print "Type another empolyee name"
while not getDone():
strUserName = getName()
strWage = getWage()
strHours = getHours()
An Example of break and continue
The break statements inside a loop (for and while) terminate the loop and skip all 'else' clauses (if there are any).
Thecontinue statements skips the rest of the code in the loop and the continues the loop as if nothing happened.
The else clause in a for...else construct, executes its code block when the loop exhausted all the items and exited normally, i.e., when it's not terminated by break or something.
for no in range(2, 10):
for factor in range(2, no):
if no % factor == 0:
if factor == 2:
print "%d is even" % no
continue
# we want to skip the rest of the code in this for loop for now
# as we've already done the printing
print "%d = %d * %d" % (no, factor, n/x)
break
# We've asserted that the no. isn't prime,
# we don't need to test the other factors
else:
# if 'break' wasn't called
# i.e., if the loop fell through w/o finding any factor
print no, 'is a prime number'