This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 1 year ago.
I've tried the following Python 3 code that transform from Roman to Integer.
The code is working fine. But there is a problem happened when I input an integer number or string (ex: 1, 2 or any integer number, string) it shows the message "Invalid input! Try again!" and the program ends. I want if the program input is valid it will end but if the input is invalid the input message should continue till its become a valid input.
Here is my code:
class Solution(object):
def roman_to_int(self, s):
"""
:type s: str
:rtype: int
"""
roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000,'IV':4,'IX':9,'XL':40,'XC':90,'CD':400,'CM':900}
i = 0
num = 0
while i < len(s):
if i+1<len(s) and s[i:i+2] in roman:
num+=roman[s[i:i+2]]
i+=2
else:
#print(i)
num+=roman[s[i]]
i+=1
return num
ob1 = Solution()
message = str(input("Please enter your roman number: "))
try:
n = ob1.roman_to_int(message)
if n > 3999: raise Exception()
print(n)
except Exception:
print("Invalid input! Try again!")
Try this:
while True:
message = input("Please enter your roman number: ")
try:
n = ob1.roman_to_int(message)
if n > 3999: raise Exception()
print(n)
break
except Exception:
print("Invalid input! Try again!")
Related
in the python code below, the desired output is to find the max and min from all of the key-in values (via input function) and when I key in "done", it stops (meaning that there will be no pop-up anymore), while other non-integer strings will print "Invalid output".
However, even if I key in "done", the pop-up still appears and it never ends, what is the problem of my code?
lar = None
smal = None
while True:
try:
num = int(input("Enter a number:"))
except:
if num == "done":
break
else:
print("Invalid input")
if lar is None:
lar = num
elif lar <= num:
lar = num
if smal is None:
smal = num
elif smal >= num:
smal = num
print("Maximum is", lar)
print("Minimum is", smal)
Its because of your try/except:
...
while True:
try:
num = int(input("Enter a number:")) # issue is here
except:
if num == "done":
break
else:
print("Invalid input")
...
When you cast int() on the result of input() when you've typed "done" in the terminal, this throws a ValueError (see example of the running below):
>>> Enter a number:h
Traceback (most recent call last):
File "main.py", line 5, in <module>
num = int(input("Enter a number:"))
ValueError: invalid literal for int() with base 10: 'h'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 7, in <module>
if num == "done":
NameError: name 'num' is not defined
In this example, the first value ever given to your while loop to try and assign to the variable num is "h", and this errors on int() since "h" is not a base 10 number (which is what int() tries to cast a string as). That ValueError is caught in the except portion of your block, but then the if num == "done" fails because num is never assigned to since the first try failed.
Lets look at another example:
>>> Enter a number:1
>>> Enter a number:h
Invalid input
>>> Enter a number:
Here we didn't receive the error traceback, but why?
Well the fact that we gave a valid base 10 integer as our first input, in this case "1", it was successfully assigned to the variable num and thus the if/else inside the except block executes correctly since num currently holds "1".
To resolve your issue, your loop needs to look like this:
lar = None
smal = None
while True:
# never give variables the same name as keywords
inpt = input('Enter a number (or done): ')
if inpt == 'done':
break
try:
num = int(inpt)
except ValueError as err:
# f-string to display error
print(f'Invalid input: {inpt}')
if not lar:
lar = num
elif lar <= num:
lar = num
if not smal:
smal = num
elif smal >= num:
smal = num
print("Maximum is", lar)
print("Minimum is", smal)
>>> Enter a number (or done): 1
>>> Enter a number (or done): 8
>>> Enter a number (or done): 3
>>> Enter a number (or done): 2
>>> Enter a number (or done): -1
>>> Enter a number (or done): 4
>>> Enter a number (or done): done
Maximum is 8
Minimum is -1
Personally I'd adjust even further using built-ins:
nums = []
while True:
# never give variables the same name as keywords
inpt = input('Enter a number (or done): ')
if inpt == 'done':
break
try:
num = int(inpt)
except ValueError as err:
# f-string to display error
print(f'Invalid input: {inpt}')
nums.append(num)
print("Maximum is", max(nums))
print("Minimum is", min(nums))
When a user inputs "done", it is then trying to be converted into an int. This throws an error and the value of num is not set, so when it is checked if it is equal to "done" it will never be. You should set check the user input before attempting to convert to an int.
lar = None
smal = None
while True:
try:
user_input =input("Enter a number:")
if user_input == "done":
break
num = int(user_input)
except:
print("Invalid input")
if lar is None:
lar = num
elif lar <= num:
lar = num
if smal is None:
smal = num
elif smal >= num:
smal = num
print("Maximum is", lar)
print("Minimum is", smal)
When the exception is raised, the new value that is inputted is never saved to the num variable.
You could add the if-statement before converting the input to an integer.
Here's a quick example:
num = input("Enter a number:")
if num == "done":
break
try:
num = int(num)
except ValueErorr:
print("Invalid input")
This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed last year.
Here is my code:
x = 1
while x == 1:
fav_number = int(input("Guess my favorite number: "))
print()
if fav_number == 8:
print("Gongrats, you guessed it!")
x = 2
else:
print("Nope, try again!")
print()
In this example, I want it to also say "Nope, try again!" when the user inputs in a float or a string without crashing the program.
while True:
try: #Use the try/except block to raise exception if value is not integer
fav_number = int(input("Guess my favorite number: "))
print()
except ValueError: # if value is anything but integer, exception is raised
print("Invalid entry. Try again.")
else:
if fav_number == 8:
print("Gongrats, you guessed it!")
break #code ends when number is guessed
else:
print("Nope, try again!")
To make it more interesting, you can add a predefined number of attempts. If attempts are exhausted, code stops:
attempts = 5
while attempts > 0:
attempts -= 1
try: #Use the try/except block to raise exception if value is not integer
fav_number = int(input("Guess my favorite number: "))
print()
except ValueError: # if value is anything but integer, exception is raised
print("Invalid entry. Try again.")
else:
if attempts > 0:
if fav_number == 8:
print("Gongrats, you guessed it!")
break #code ends when number is guessed
else:
print("Nope, try again!")
print(f"You have {attempts} left")
else:
print("You have exhausted your attempts.")
You can, use eval in python for the string would convert int to int and float to float without exception. Check the documentation here: https://docs.python.org/3/library/functions.html#eval
So basically you can change the int to eval:
x = 1
while x == 1:
fav_number = eval(input("Guess my favorite number: "))
print()
if fav_number == 8:
print("Gongrats, you guessed it!")
x = 2
else:
print("Nope, try again!")
print()
Question: how can my code could be written more succinctly?
Background:
Working on Automate the boring stuff challenges in Python. The program below is meant to:
get the user to enter an integer
check that what was entered was an integer (with try and except)
perform the collatz() function on that sequence
CODE:
def accept_int():
while True:
try:
i = int(input())
break
except ValueError:
print('Please enter an integer value: ')
continue
return i
def collatz(i):
while num > 1:
if i % 2 == 1:
return 3* i + 1
else:
return i // 2
print('Hello, please enter an integer: ')
num = accept_int()
while num > 1:
num = collatz(num)
print(num)
I am new to Python programming. Following is the code written and it works fine when I print any numeric digit and give me the desired result as expected but the problem comes when I enter string (anything other than integer/float) instead of giving me just the except statement, it also gives me an error which I don't want. So, what I want is when a user enter anything other than numeric digits, he should be prompted with a message i.e., "Invalid input. Enter a number please" instead of an error which I am getting after the except print statement in the end. Please help.
hours_string = input("Enter Hours: ")
rate_string = input("Enter Rate: ")
try:
hours_float = float(hours_string)
rate_float = float(rate_string)
except:
print("Invalid input. Enter a number please.")
result = hours_float * rate_float
print("Pay",result)
This is the error I am getting. If I enter string, I should simply get an except statement. That's it. Not any other error. How can I accomplish to get there?
Enter Hours: 9
Enter Rate: entered string by mistake
Invalid input. Enter a number please.
Traceback (most recent call last):
File "<string>", line 9, in <module>
NameError: name 'rate_float' is not defined
For a particular Error you can do a particular Exeption like in the Code below. Also note that each question is in a whileloop that you need to acomplish the task before you get to the next one.
while True:
try:
hours_string = input("Enter Hours: ")
hours_float = float(hours_string)
except ValueError:
print("Invalid input. Enter a number please.")
else:
break
while True:
try:
rate_string = input("Enter Rate: ")
rate_float = float(rate_string)
except ValueError:
print("Invalid input. Enter a number please.")
else:
break
result = hours_float * rate_float
print("Pay",result)
hours_float = None
rate_float = None
while hours_float is None:
hours_string = input("Enter Hours: ")
try:
hours_float = float(hours_string)
except ValueError:
print("Invalid input. Enter a number please.")
while rate_float is None:
rate_string = input("Enter Rate: ")
try:
rate_float = float(rate_string)
except ValueError:
print("Invalid input. Enter a number please.")
result = hours_float * rate_float
print("Pay", result)
In the while loop we repeatedly ask user for input, while they don't enter a valid number, separately for hours and rate.
Valid input changes the initially set None value to something else, which finishes the corresponding loop.
Since this is a expected situation and it can be treated as a test I would recommend instead of trying to execute the operation with wathever input the user provided you could ask the user for the input and while it is not an integer you ask for the input again.
def get_input(name, var_type):
userin = None
while userin is None:
userin = input(f'Input {name}: ')
try:
userin = var_type(userin)
except ValueError:
print(f'{name} must be {str(var_type)}, not {str(type(userin))}')
userin = None
return userin
hours = get_input('hours', int)
rate = get_input('rate', float)
result = hours * rate
print('Pay', result)
The function get_input tries to cast the input input value to the type you want and if it is not as desired it will keep asking until the type matches.
I'm trying to use 'while true' to ask the user to input 0 or a positive integer. I've tried a couple different ways and they all seem to have different issue. The function def positive_int rejects the letters and negative ints but will not allow the factorial function to work. The factorial function works on its own. I get an error code: TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' for this line for i in range(1,num + 1):. Thanks for the help.
def positive_int(prompt=''):
while True:
try:
num = int(input(prompt))
if num < 0:
raise ValueError
break
except ValueError:
print("Please enter a positive integer.")
print('\n')
print("The program will compute and output the factorial number.")
def factorial():
num = positive_int('Please enter the number to factorial: ')
factorial = 1
if num == 0:
print("\nThe factorial of 0 is 1")
else:
for i in range(1,num + 1):
factorial = factorial*i
print("\nThe factorial of", num,"is",factorial)
factorial()
The positive_int() function doesn't return anything, which means that num = positive_int() sets num to None. The code later fails when it tries to add this None value to an int.
You can fix this by either replacing the break statement with a return, or by returning num after breaking out of the loop:
def positive_int(prompt=''):
while True:
try:
num = int(input(prompt))
if num < 0:
raise ValueError
return num # Replacing break with return statement
except ValueError:
print("Please enter a positive integer.")
or
def positive_int(prompt=''):
while True:
try:
num = int(input(prompt))
if num < 0:
raise ValueError
break
except ValueError:
print("Please enter a positive integer.")
return num # Breaking out of the loop takes you here
You are using factorial both as a function name and as a variable name.
Problem is positive_int is not returning anything
Try:
def positive_int(prompt=''):
while True:
try:
num = int(input(prompt))
if num < 0:
raise ValueError
return num # change to return value rather than break
except ValueError:
print("Please enter a positive integer.")
print('\n')
print("The program will compute and output the factorial number.")
def factorial():
num = positive_int('Please enter the number to factorial: ')
factorial = 1
if num == 0:
print("\nThe factorial of 0 is 1")
else:
for i in range(1,num + 1):
factorial = factorial*i
print("\nThe factorial of", num,"is",factorial)
factorial()