Continuously re-running a while loop until a certain input [duplicate] - python

This question already has answers here:
If an exception is raised ask again for input
(5 answers)
Closed 9 years ago.
What I'm trying to do with this is ask the user for two inputs and then call a function on the inputs. If it doesn't raise an exception then do the while loop again. If it does raise an exception than print something and do the while loop again. The problem I have is that I can't find a way to do the while loop again if it doesn't raise an exception. It works if it does raise an exception. The only way I can think of it is where I put #Rerun loop paste the entire while True loop again but that would be really horrible in this case.
class Illegal(Exception):
pass
def add_input(first_input, second_input):
if first_input + second_input >= 10:
print('legal')
else:
raise Illegal
def play():
inp = input("Ready? <yes/no>: ")
if inp == 'yes':
while True:
first_input = input("First number: ")
second_input = input("Second number: ")
try:
if first_input or second_input == 'quit':
break
else:
add_input(int(first_input), int(second_input))
#Rerun loop
except Illegal:
print("Illegal")
else:
break
else:
return
>>> play()
Ready? <yes/no>: yes
First number: 1
Second number: 2
Illegal
First number: 9
Second number: 6
legal
First number: 1
Second number: 2
Illegal
First number: quit
What I thought of doing:
def play():
inp = input("Ready? <yes/no>: ")
if inp == 'yes':
while True:
first_input = input("First number: ")
second_input = input("Second number: ")
try:
if first_input or second_input == 'quit':
break
else:
add_input(int(first_input), int(second_input))
while True:
first_input = input("First number: ")
except Illegal:
print("Illegal move")
else:
break
except Illegal:
print("Illegal move")
else:
break
else:
return second_input = input("Second number: ")
try:
if first_input or second_input == 'quit':
break
else:
add_input(int(first_input), int(second_input))
#Rerun loop
But this is a horrible idea because then I'd have to paste the same thing continuously.

The break in your else: causes the loop to exit. You can remove this entirely:
else:
break

You want to run the loop while the user doesn't quit it via typing quit. So you just have to remove this else: break:
def play():
inp = input("Ready? <yes/no>: ")
if inp.lower() == 'yes':
while True:
first_input = input("First number: ")
second_input = input("Second number: ")
# quit if the user wants
if first_input or second_input == 'quit':
break
try:
add_input(int(first_input), int(second_input))
except Illegal:
print("Illegal")
Also, take the habit to put the minimum of code in your try/except blocks. It makes the debugging easier after. Your last else: return is also useless, you can remove it.

Related

If statement not executing. Python

I am still new to programming and I wanted to do a simple calculator in python. However, I could only reach this point of my code:
import operator as op
print("Greetings user, welcome to the calculator program.\nWe offer a list of functions:")
print("1. Add\n2. Subtract\n3. Multiply\n4. Divide\n5. Modulus\n6. Check greater number")
while True:
userInput = input("Please choose what function you would like to use based on their numbers:")
if userInput.isdigit():
if int(userInput) in range(1,7):
str(userInput)
break
else:
print("Number inputted is either below or above the given choices")
continue
else:
print("Incorrect input. Please try again.")
continue
def add(x,y):
return op.add(x,y)
def sub(x,y):
return op.sub(x,y)
def mul(x,y):
return op.mul(x,y)
def div(x,y):
return op.truediv(x,y)
def mod(x,y):
return op.mod(x,y)
def gt(x,y):
if x == y:
return "Equal"
else:
return op.gt(x,y)
variableA = 0
variableB = 0
while True:
variableA = input("Enter the first value: ")
if variableA.isdigit():
float(variableA)
break
else:
print("Incorrect input. Please try again.")
continue
while True:
variableB = input("Enter the second value: ")
if variableB.isdigit():
float(variableB)
break
else:
print("Incorrect input. Please try again.")
continue
if userInput == 1:
print("You chose to add the two numbers and the result is:")
print(add(variableA,variableB))
print("Thank you")
elif userInput == 2:
print("You chose to subtract with the two numbers and the result is:")
print(sub(variableA,variableB))
print("Thank you")
elif userInput == 3:
print("You chose to multiply the two numbers and the result is:")
print(mul(variableA,variableB))
print("Thank you")
elif userInput == 4:
print("You chose to divide with the two numbers and the result is:")
print(div(variableA,variableB))
print("Thank you")
elif userInput == 5:
print("You chose to find the modulo with the two numbers and the result is:")
print(mod(variableA,variableB))
print("Thank you")
elif userInput == 6:
print("Is the first input greater than the second?")
if sub(variableA,variableB) == True:
print(f"{sub(variableA,variableB)}. {variableA} is greater than {variableB}")
elif sub(variableA,variableB) == False:
print(f"{sub(variableA,variableB)}. {variableB} is greater than {variableA}")
else:
print(f"It is {sub(variableA,variableB)}")
print("Thank you")
Not sure why my if statement is not executing after all the correct inputs from the user. I mostly focused on the error handling part and after everything going well, the if statement is just not executing after that. There could probably be a simple mistake but even I can't understand what's going on here.
You have an issue with type casting. So when you are taking input from the user all the userInput is str not int, so you need to cast it like userInput = int(userInput) before doing further calculator operations.
Also, you need to assign the float casting to a variable like this variableA = float(variableA) and variableB = float(variableB) otherwise your add/sub/divide/multiply etc. will not do expected operations.
For example add will do concatenation i.e '2' + '4' = 24 not 2 + 4 = 6.0
import operator as op
print("Greetings user, welcome to the calculator program.\nWe offer a list of functions:")
print("1. Add\n2. Subtract\n3. Multiply\n4. Divide\n5. Modulus\n6. Check greater number")
while True:
userInput = input("Please choose what function you would like to use based on their numbers:")
if userInput.isdigit():
if int(userInput) in range(1,7):
str(userInput)
break
else:
print("Number inputted is either below or above the given choices")
continue
else:
print("Incorrect input. Please try again.")
continue
def add(x,y):
return op.add(x,y)
def sub(x,y):
return op.sub(x,y)
def mul(x,y):
return op.mul(x,y)
def div(x,y):
return op.truediv(x,y)
def mod(x,y):
return op.mod(x,y)
def gt(x,y):
if x == y:
return "Equal"
else:
return op.gt(x,y)
variableA = 0
variableB = 0
while True:
variableA = input("Enter the first value: ")
if variableA.isdigit():
variableA = float(variableA) # <-- fix this line
break
else:
print("Incorrect input. Please try again.")
continue
while True:
variableB = input("Enter the second value: ")
if variableB.isdigit():
variableB = float(variableB) # <-- fix this line
break
else:
print("Incorrect input. Please try again.")
continue
userInput = int(userInput) # <-- fix this line
if userInput == 1:
print("You chose to add the two numbers and the result is:")
print(add(variableA,variableB))
print("Thank you")
elif userInput == 2:
print("You chose to subtract with the two numbers and the result is:")
print(sub(variableA,variableB))
print("Thank you")
elif userInput == 3:
print("You chose to multiply the two numbers and the result is:")
print(mul(variableA,variableB))
print("Thank you")
elif userInput == 4:
print("You chose to divide with the two numbers and the result is:")
print(div(variableA,variableB))
print("Thank you")
elif userInput == 5:
print("You chose to find the modulo with the two numbers and the result is:")
print(mod(variableA,variableB))
print("Thank you")
elif userInput == 6:
print("Is the first input greater than the second?")
if sub(variableA,variableB) == True:
print(f"{sub(variableA,variableB)}. {variableA} is greater than {variableB}")
elif sub(variableA,variableB) == False:
print(f"{sub(variableA,variableB)}. {variableB} is greater than {variableA}")
else:
print(f"It is {sub(variableA,variableB)}")
print("Thank you")
If the user input is supposed to be an int, convert it early and fail fast.
while True:
userInput = input(...)
try:
userInput = int(userInput)
except ValueError:
print("Not an integer, try again")
continue
if userInput in range(1, 7):
break
print("Number out of range, try again")
and similarly for the operands
while True:
variableA = input("Enter the first value: ")
try:
variableA = float(variableA)
break
except ValueError:
print("not a float")
There's little reason to convert the menu choice to an integer, though. You could simply write
while True:
userInput = input(...)
if userInput in "123456": # ... in ["1", "2", "3", "4", "5", "6"]
break
print("Invalid choice, try again")

Asking user whether he/she wants to play again but typing yes just repeats this question again rather starting again

It is a number guessing game
Explanation
At first it asks the user to enter a number between 1 to 50
Then if the number is correct then you win else you have to try again (The winning number is random offcourse)You also have limited guesses
The problem is mentioned below the code
Here is my code:)
import random
winning_num = 23
guesses = 1
guesses_left = 9
game_over = False
end_game = False
number_enter = False
while not end_game:
while not number_enter:
try:
ask = int(input("ENTER A NUMBER BETWEEN 1 AND 50: "))
print(f"TOTAL GUESSES = {guesses_left}")
break
except ValueError:
print("INVALID INPUT!!")
continue
while not game_over:
if ask==winning_num:
print(f"YOU WON BY GUESSING THE NUMBER IN {guesses} TIME(S)!!")
print("DO YOU WANT TO PLAY AGAIN?")
while True:
ask1 = input("ENTER 'YES' OR 'NO' ONLY: ")
ask1 = ask1.lower()
if ask1=='yes':
print("YOU CHOSE TO PLAY AGAIN")
game_over = False
break
elif ask1=="no":
print("THANK YOU FOR PLAYING THIS GAME")
game_over = True
end_game = True
break
else:
print("PLEASE WRITE 'YES' OR 'NO' ONLY ")
continue
elif ask>winning_num:
print("TOO HIGH!!")
guesses+=1
guesses_left-=1
while True:
try:
ask = int(input("TRY AGAIN: "))
print(f"GUESSES LEFT = {guesses_left}")
break
except ValueError:
print("INVALID INPUT!!")
continue
if guesses_left==1:
print("ONLY ONE GUESS LEFT!!")
continue
elif guesses_left==0:
print("YOU LOSE!!")
break
elif ask<winning_num:
print("TOO LOW!!")
guesses+=1
guesses_left-=1
while True:
try:
ask = int(input("TRY AGAIN: "))
print(f"GUESSES LEFT = {guesses_left}")
break
except ValueError:
print("INVALID INPUT!!")
continue
if guesses_left==1:
print("ONLY ONE GUESS LEFT!!")
continue
elif guesses_left==0:
print("YOU LOSE!!")
break
The problem is when the game ends
It asks whether we want to play again
But if we type "Yes" it again asks the same "Do you want to play again"
However typing "No" works fine and the program ends
you have to set game_over = False in case ask1 = yes so that it can come out of the parent while loop and proceed. Also, you'll have to reset number of guesses etc so that it starts as a new game.
import random
winning_num = 23
guesses = 1
guesses_left = 9
game_over = False
end_game = False
number_enter = False
while not end_game:
while not number_enter:
try:
ask = int(input("ENTER A NUMBER BETWEEN 1 AND 50: "))
print(f"TOTAL GUESSES = {guesses_left}")
break
except ValueError:
print("INVALID INPUT!!")
continue
while not game_over:
if ask==winning_num:
print(f"YOU WON BY GUESSING THE NUMBER IN {guesses} TIME(S)!!")
print("DO YOU WANT TO PLAY AGAIN?")
while True:
ask1 = input("ENTER 'YES' OR 'NO' ONLY: ")
ask1 = ask1.lower()
if ask1=='yes':
print("YOU CHOSE TO PLAY AGAIN")
game_over = True
break
elif ask1=="no":
print("THANK YOU FOR PLAYING THIS GAME")
game_over = True
end_game = True
break
else:
print("PLEASE WRITE 'YES' OR 'NO' ONLY ")
continue
elif ask>winning_num:
print("TOO HIGH!!")
guesses+=1
guesses_left-=1
while True:
try:
ask = int(input("TRY AGAIN: "))
print(f"GUESSES LEFT = {guesses_left}")
break
except ValueError:
print("INVALID INPUT!!")
continue
if guesses_left==1:
print("ONLY ONE GUESS LEFT!!")
continue
elif guesses_left==0:
print("YOU LOSE!!")
break
elif ask<winning_num:
print("TOO LOW!!")
guesses+=1
guesses_left-=1
while True:
try:
ask = int(input("TRY AGAIN: "))
print(f"GUESSES LEFT = {guesses_left}")
break
except ValueError:
print("INVALID INPUT!!")
continue
if guesses_left==1:
print("ONLY ONE GUESS LEFT!!")
continue
elif guesses_left==0:
print("YOU LOSE!!")
break
You toggle game_over incorrectly, it should be set to True, not to False if the answer to replay is yes.
while not end_game: # End game must be false to replay
while not number_enter:
#... ask number
while not game_over: # But Game_over should be True to stop asking to replay
#... Check number good
#... Ask to replay
while True:
ask1 = input("ENTER 'YES' OR 'NO' ONLY: ")
ask1 = ask1.lower()
if ask1=='yes':
print("YOU CHOSE TO PLAY AGAIN")
game_over = True # <<<< Thats the problematic part, it must be True
# in your code it is False, So it result in
# an "infinite" loop, if yes.
break

Python catch int or str

I've written a program that generates a random number for the user to guess. I'm working on trying to catch all the possible errors. The only one I can't seem to figure out is this. At the beginning I ask the user to hit enter to continue to the game. The program catches if they type a string or even special characters and punctuation. The only thing I can't seem to prevent is if they they type a number, the program terminates. This is what I have. The issue is in the first while loop in the try block. Any suggestions or help would be appreciated.
Thanks in advance.
from random import randint #imports randint from random class
cont = input('Press enter to continue')
while True:
if cont != '':
try:
int(cont)
str(cont)
break
except ValueError:
print('Just hit enter')
cont = input()
continue
elif cont == '':
while True:
randNum = randint(1, 100)
print('Try guesssing a number between 1 and 100')
num = input()
while True:
try:
int(num)
break
except ValueError:
print('Please enter a number')
num = input()
int(num)
if num == randNum:
print('Good job, ' + str(num) + ' is correct.')
else:
print('Sorry, the number was ' + str(randNum) + '.')
print('Would you like to try again?')
answer = input().lower()
if answer == 'yes':
continue
elif answer == 'no':
print('Thanks for playing')
exit()
else:
while True:
print('Please type yes or no')
answer = input()
if answer == 'yes':
break
elif answer == 'no':
print('Thanks for playing.')
exit()
What happens when you enter a number is that the program tries to convert the number to an int (which works), and then to a str (which also works), after which it breaks. Instead, try the following:
from random import randint #imports randint from random class
cont = input('Press enter to continue')
while cont != '':
cont = input('Press enter to continue')
while True:
randNum = randint(1, 100)
print('Try guesssing a number between 1 and 100')
num = input()
while True:
try:
int(num)
break
except ValueError:
print('Please enter a number')
num = input()
num = int(num)
if num == randNum:
print('Good job, ' + str(num) + ' is correct.')
else:
print('Sorry, the number was ' + str(randNum) + '.')
print('Would you like to try again?')
answer = input().lower()
if answer == 'yes':
continue
elif answer == 'no':
print('Thanks for playing')
exit()
else:
while True:
print('Please type yes or no')
answer = input()
if answer == 'yes':
break
elif answer == 'no':
print('Thanks for playing.')
exit()
while True:
if cont != '':
try:
int(cont)
str(cont)
break
What it does here is try and convert cont to an int, if it succeeds it tries to convert it to a string (which is virtually always possible). If that succeeds it breaks the while loop and ends the program.
In any other scenario other than an int when it tries to parse it int(cont) it raises an error and you continue to your program.
Once he pressed enter cont starts. there is no reason for you to verify he didn't write something before entering the text.

Specific Try and Except

continue = True
while continue:
try:
userInput = int(input("Please enter an integer: "))
except ValueError:
print("Sorry, wrong value.")
else:
continue = False
For the code above, how would I be able to catch a specific ValueError? What I mean by that is if the user inputs a non-integer, I would print out "Sorry, that is not an integer.". But if the user input is an empty input, I would print out "Empty Input.".
Move the call to input outside of the try: block and place only the call to int inside it. This will ensure that userInput is defined, allowing you to then check its value with an if-statement:
keepgoing = True
while keepgoing:
userInput = input("Please enter an integer: ") # Get the input.
try:
userInput = int(userInput) # Try to convert it into an integer.
except ValueError:
if userInput: # See if input is non-empty.
print("Sorry, that is not an integer.")
else: # If we get here, there was no input.
print("Empty input")
else:
keepgoing = False
Perhaps something like this:
keepgoing = True
while keepgoing:
try:
userInput = input("Please enter an integer: ")
if userInput == "":
print("Empty value")
raise ValueError
else:
userInput = int(userInput)
except ValueError:
print("Sorry, wrong value.")
else:
keepgoing = False

try: statement fails

I have some python code that fails:
import sys
print ("MathCheats Times-Ed by jtl999")
numbermodechoice = raw_input ("Are you using a number with a decimal? yes/no ")
if numbermodechoice == "yes":
try:
numberx1 = float(raw_input('Enter first number: '))
except ValueError:
print ("Oops you typed it wrong")
try:
numberx1 = float(raw_input('Enter first number: '))
except ValueError:
print ("Oops you typed it wrong")
numberx2 = (float)(raw_input('Enter second number: '))
elif numbermodechoice == "no":
print ("Rember only numbers are allowed")
numberx1 = (int)(raw_input('Enter first number: '))
numberx2 = (int)(raw_input('Enter second number: '))
else:
print ("Oops you typed it wrong")
exit()
print ("The answer was")
print numberx1*numberx2
ostype = sys.platform
if ostype == 'win32':
raw_input ("Press enter to exit")
elif ostype == 'win64':
raw_input ("Press enter to exit")
(Full code here)
I want to wrap the float operations with try statements so if a ValueError happens, it gets caught. Here is the output:
File "./Timesed.py", line 23
try:
^
IndentationError: expected an indented block
What is wrong with it and how can I fix this?
Python is whitespace sensitive, with regards to the leading whitespace.
your code probably should be indented like
import sys
from sys import exit
print ("MathCheats Times-Ed by jtl999")
numbermodechoice = raw_input ("Are you using a number with a decimal? yes/no ")
if numbermodechoice == "yes":
try:
numberx1 = float(raw_input('Enter first number: '))
numberx2 = float(raw_input('Enter second number: '))
except ValueError:
print ("Oops you typed it wrong")
exit()
elif numbermodechoice == "no":
print ("Remember only numbers are allowed")
try:
numberx1 = (int)(raw_input('Enter first number: '))
numberx2 = (int)(raw_input('Enter second number: '))
except ValueError:
print ("Oops you typed it wrong")
exit()
else:
print ("Oops you typed it wrong")
exit()
print ("The answer was")
print numberx1*numberx2
ostype = sys.platform
if ostype == 'win32':
raw_input ("Press enter to exit")
elif ostype == 'win64':
raw_input ("Press enter to exit")
In python, the indentation of your code is very important. The error you've shown us points here:
if numbermodechoice == "yes":
try:
numberx1 = float(raw_input('Enter first number: '))
except ValueError:
print ("Oops you typed it wrong")
All code that is part of a block must be indented. By starting a try block, the following line is part of that block and must be indented. To fix it, indent it!
if numbermodechoice == "yes":
try:
numberx1 = float(raw_input('Enter first number: '))
except ValueError:
print ("Oops you typed it wrong")
You had a wrong syntax. It should be except ValueError: and not except: ValueError. Correct it for you in the question too.
You need to indent the second print statement.
Indentation is important in Python. It's how you delimit blocks in that language.
The conversion to float is using an incorrect syntax. That syntax is valid for C/C++/Java, but not in Python. It should be:
numberx1 = float(raw_input('Enter first number: '))
Which will be interpreted like float("2.3"), which is a constructor for the float type being called with a string parameter. And, yes, the syntax is exactly the same for the function call, so you might even think the constructor is a function that returns an object.
import sys
class YesOrNo(object):
NO_VALUES = set(['n', 'no', 'f', 'fa', 'fal', 'fals', 'false', '0'])
YES_VALUES = set(['y', 'ye', 'yes', 't', 'tr', 'tru', 'true', '1'])
def __init__(self, val):
super(YesOrNo,self).__init__()
self.val = str(val).strip().lower()
if self.val in self.__class__.YES_VALUES:
self.val = True
elif val in self.__class__.NO_VALUES:
self.val = False
else:
raise ValueError('unrecognized YesOrNo value "{0}"'.format(self.val))
def __int__(self):
return int(self.val)
def typeGetter(dataType):
try:
inp = raw_input
except NameError:
inp = input
def getType(msg):
while True:
try:
return dataType(inp(msg))
except ValueError:
pass
return getType
getStr = typeGetter(str)
getInt = typeGetter(int)
getFloat = typeGetter(float)
getYesOrNo = typeGetter(YesOrNo)
def main():
print("MathCheats Times-Ed by jtl999")
isFloat = getYesOrNo("Are you using a number with a decimal? (yes/no) ")
get = (getInt, getFloat)[int(isFloat)]
firstNum = get('Enter first number: ')
secondNum = get('Enter second number: ')
print("The answer is {0}".format(firstNum*secondNum))
if __name__=="__main__":
main()
if sys.platform in ('win32','win64'):
getStr('Press enter to exit')

Categories

Resources