I have 2 inputs to type and I want to loop through them if the user would enter incorrect input. What I did is I set while True and then try and except and then continue. However in case of second input if the input is wrong then whole loop is repeated from the start - that is from the first input. I would like it to be repeated from the second input. The only thing that I can think of is to put break in the code after first correct input and then set another while True for the second input. What are better ways to do this?
while True:
try:
a = int(input("Type positive integer: "))
except ValueError:
print(" Enter a positive NUMBER!")
continue
if a <= 0:
print("Input can't be 0 or negative!")
continue
else:
try:
b = int(input("Type second positive integer: "))
except ValueError:
print(" Enter a positive NUMBER!")
continue
if b <= 0:
print("Input can't be 0 or negative!")
continue
else:
break
Since your condition is the same for each loop, you could try storing the try-except part as a function which returns the value (or a bool indicating success or failure with a parameter for the value), running the lambda in a for loop for each input you require, storing the result in a list and then getting what you need out as a tuple.
E.g.
def try_get_number_input():
try:
value = int(input("Type positive integer: "))
except ValueError:
print(" Enter a positive NUMBER!")
return False, 0
if value <= 0:
print("Input can't be 0 or negative!")
return False, 0
return True, value
# We require 2 inputs from the user
required_inputs = 2
received_inputs = []
for num in range(0, required_inputs):
values = try_get_number_input()
while not values[0]:
values = try_get_number_input()
received_inputs.append(values[1])
This ensures that the code is DRY (doesn't repeat itself) and is easily changeable (if you require 3 inputs instead, you can easily change it rather than having to add another branch of your while loop)
def getNumber(second=False):
while True:
try:
if second:
number = int(input("Type second positive integer: "))
else:
number = int(input("Type positive integer: "))
except ValueError:
print(" Enter a positive NUMBER!")
continue
if number <= 0:
print("Input can't be 0 or negative!")
continue
return number
a, b = getNumber(second=False), getNumber(second=True)
print(a,b)
You asked what a for loop would look like, here's one example:
vals = []
for msg in ['', 'second ']:
while True:
try:
n = int(input(f"Type {msg}positive integer: ")) # PY3.6
# n = int(input("Type {}positive integer: ").format(msg))) # <=PY3.5
except ValueError:
print(" Enter a positive NUMBER!")
continue
if n <= 0:
print("Input can't be 0 or negative!")
continue
vals.append(n)
break
a, b = vals
you can use decorator for retry logic and single function to read int value
def retry(func):
def wrapper(msg):
while True:
try:
return func(msg)
except Exception as e:
print(e)
return wrapper
#retry
def read_int(msg):
try:
a = int(input(msg))
except:
raise ValueError('Invalid Number')
else:
if a < 0:
raise ValueError('Number should be positive')
return a
a = read_int('type valid positive number: ')
b = read_int('type other valid positive number: ')
print(a, b)
Related
I'm new to python and I'm looking to code a small calculator for divisions, that includes while loops and if conditionals
My code looks like this:
a = input('first number')
while type(a)!=int:
try:
a=int(a)
print('imput number is correct ',a)
except:
print('Imput data is not correct ')
a=input('first number')
b = input('second number')
while type(b)!=int and b!=0:
try:
b=int(b)
print('Imput data is correct',b)
except:
print(' imput data is not a number, please only imput numbers ')
b=input('second number')
while b==0:
try:
c=1/b
print('imput number is correct ',b)
except ZeroDivisionError:
print('Cant divide by 0')
b=input('second number again')
if type(a)==int and type(b)==int and b!=0:
c=a/b
print('the result is: ',c)
The program suddenly ends after you imput 0 a second time in the second number space, but the proccess should keep asking for a value that is a number and different from 0
After b=input('second number again') is executed, b is a string, so b == 0 is False(a string is never equal to an integer).
You'll find this easier if you write a common function to get the user input. Something like this:
def get_input(prompt, nonZero=False):
while True:
try:
if (n := int(input(prompt))) == 0 and nonZero:
raise ValueError('Value must be non-zero')
return n
except ValueError as e:
print(e)
a = get_input('Input first number: ')
b = get_input('Input second number: ', True)
print(a/b)
I'm processing integer inputs from a user and would like for the user to signal that they are done with inputs by typing in 'q' to show they are completed with their inputs.
Here's my code so far:
(Still very much a beginner so don't flame me too much)
def main():
print("Please enter some numbers. Type 'q' to quit.")
count = 0
total = 0
num=[]
num = int(input("Enter a number: "))
while num != "q":
num = int(input("Enter a number: "))
count += 1
total += num
del record[-1]
print (num)
print("The average of the numbers is", total / count)
main()
Any feedback is helpful!
You probably get a ValueError when you run that code. That's python's way of telling you that you've fed a value into a function that can't handle that type of value.
Check the Exceptions docs for more details.
In this case, you're trying to feed the letter "q" into a function that is expecting int() on line 6. Think of int() as a machine that only handles integers. You just tried to stick a letter into a machine that's not equipped to handle letters and instead of bursting into flames, it's rejecting your input and putting on the breaks.
You'll probably want to wrap your conversion from str to int in a try: statement to handle the exception.
def main():
num = None
while num != "q":
num = input("Enter number: ")
# try handles exceptions and does something with them
try:
num = int(num)
# if an exception of "ValueError" happens, print out a warning and keep going
except ValueError as e:
print(f'that was not a number: {e}')
pass
# if num looks like an integer
if isinstance (num, (int, float)):
print('got a number')
Test:
Enter number: 1
got a number
Enter number: 2
got a number
Enter number: alligator
that was not a number: invalid literal for int() with base 10: 'alligator'
Enter number: -10
got a number
Enter number: 45
got a number
Enter number: 6.0222
that was not a number: invalid literal for int() with base 10: '6.0222'
I'll leave it to you to figure out why 6.02222 "was not a number."
changing your code as little as possible, you should have...
def main():
print("Please enter some numbers. Type 'q' to quit.")
count = 0
total = 0
num=[]
num.append(input("Enter a number: "))
while num[-1] != "q":
num.append(input("Enter a number: "))
count += 1
try:
total += int(num[-1])
except ValueError as e:
print('input not an integer')
break
print (num)
print("The average of the numbers is", total / count)
main()
You may attempt it the way:
def main():
num_list = [] #list for holding in user inputs
while True:
my_num = input("Please enter some numbers. Type 'q' to quit.")
if my_num != 'q':
num_list.append(int(my_num)) #add user input as integer to holding list as long as it is not 'q'
else: #if user enters 'q'
print(f'The Average of {num_list} is {sum(num_list)/len(num_list)}') #calculate the average of entered numbers by divide the sum of all list elements by the length of list and display the result
break #terminate loop
main()
can you please tell me why do i get error for this?
Write a program that repeatedly prompts a user for integer numbers until the user enters 'done'. Once 'done' is entered, print out the largest and smallest of the numbers. If the user enters anything other than a valid number catch it with a try/except and put out an appropriate message and ignore the number. Enter 7, 2, bob, 10, and 4 and match the output below.
largest = None
smallest = None
while True:
try:
num=input("Enter a number: ")
if num == 'done':
break
num=int(num)
if largest == None or largest<num:
largest = num
elif smallest == None or smallest > num:
smallest = num
except ValueError:
print ("Invalid input")
break
print ("Maximum number is", int(largest))
print ("Minimum number is", int(smallest))
You may be using Python 2 instead of Python 3 - please check this. If you are using Python 2, you should be using raw_input() instead of input().
Change elif to if:
if largest == None or largest<num:
largest = num
if smallest == None or smallest > num:
smallest = num
That will guarantee both largest and smallest are both integers (unless the first input is done or another invalid value).
You need to check if largest or smallest is None.
Append the user input to a list inside the while loop, and then slice it in the final print statements:
largest = None
smallest = None
nums = []
while True:
try:
num = input("Enter a number: ")
if num == 'done':
break
num = int(num)
nums.append(num)
except ValueError:
print("Invalid input")
break
print("Maximum number is", max(nums))
print("Minimum number is", min(nums))
Example run:
Enter a number: 22
Enter a number: 2
Enter a number: done
Maximum number is 22
Minimum number is 2
Posting the output and/or the error would be very helpful to help you.
You have to change elif into if and remove the break clause inside the except in order to keep asking for numbers even after an invalid input.
largest = None
smallest = None
while True:
try:
num = input("Enter a number: ")
if num == 'done':
break
num=int(num)
if largest == None or largest < num:
largest = num
if smallest == None or smallest > num:
smallest = num
except ValueError:
print ("Invalid input")
print ("Maximum number is", int(largest))
print ("Minimum number is", int(smallest))
question:
Write a program that repeatedly prompts a user for integer numbers until the user enters 'done'. Once 'done' is entered, print out the largest and smallest of the numbers. If the user enters anything other than a valid number catch it with a try/except and put out an appropriate message and ignore it.
Input:
7 ,2 , bob, 10, 4, done.
Desired output:
Invalid input
Maximum is 10
Minimum is 2
Actual output:
Invalid input
Invalid input
Maximum is 10
Minimum is 2
Code:
largest=-1
smallest=None
while True:
num =input("Enter a number: ")
try:
if num == "done" :
break
elif smallest is None:
smallest=int(num)
elif int(num)<smallest:
smallest=int(num)
elif int(num)>largest:
largest=int(num)
else:
raise ValueError()
except ValueError:
print("Invalid input")
print("Maximum is",largest)
print("Minimum is",smallest)
I think there's a more Pythonic way of doing this. Try this:
inputList = []
while True:
num = input("Enter a number:")
try:
num = int(num)
inputList.append(num)
except:
if num == "done":
break
else:
print ("Invalid input. Ignoring...")
print ("Maximum is:",max(inputList))
print ("Minimum is:",min(inputList))
Edit: This code works with Python3. For Python2, you might want to use raw_input() instead of input()
You are already capturing the ValueError in Exception,
So inside, try, you are raising ValueError there you leave the scope for this error.
When you accept input, and it accepts 4 as input, which is neither larger than largest (i.e. 10) nor smaller than the smallest (i.e. 2). So it lands in else part and raises ValueError (as per your code). Hence prints Invalid input twice in your case. So this part is unnecessary as well as makes your solution bogus.
Again, from efficiency point of view -
1 - You are checking smallest == None for every input, which takes O(1) time and is unnecessary if you take it any integer
Here is the solution you are looking for :-
largest=None
smallest=None
while True:
try:
num = input("Enter a number: ")
num = int(num)
if smallest is None:
smallest = num
if largest is None:
largest = num
if num < smallest:
smallest = num
elif num > largest:
largest = num
except ValueError:
if num == 'done':
break
else:
print("Invalid input")
continue
print("Maximum is",largest)
print("Minimum is",smallest)
So the code before behaved properly before my "while type(number) is not int:" loop, but now when the user presses 0, instead of generating the sum of the list, it just keeps looping.
Would really appreciate some help with this! Thank you!
List = []
pro = 1
while(pro is not 0):
number = False
while type(number) is not int:
try:
number = int(input("Please enter a number: "))
List.append(number)
except ValueError:
print("Please only enter integer values.")
if(number == 0):
Sum = 0
for i in List:
Sum = i + Sum
ans = 0
print(Sum)
Actually, this should keep looping forever for all numbers the user may input, not just zero.
To fix this, you can just add this break condition after (or before, it doesnt really matter) appending:
number = int(input("Please enter a number: "))
List.append(number)
if number == 0:
break
So I got it to work, when written like this:
List = []
pro = 1
while(pro is not 0):
while True:
try:
number = int(input("Please enter a number: "))
List.append(number)
break
except ValueError:
print("Please only enter integer values.")
if(number == 0):
Sum = 0
for i in List:
Sum = i + Sum
pro = 0
print(Sum)
But I don't really understand how this is making it only take int values, any clarification would be really helpful, and otherwise thank you all for your help!
I'm guessing that you want to end while loop when user inputs 0.
List = []
pro = 1
while pro is not 0:
try:
number = int(input("Please enter a number: "))
List.append(number)
# This breaks while loop when number == 0
pro = number
except ValueError:
print("Please only enter integer values.")
Sum = 0
for i in List:
Sum += i
print(Sum)
EDIT: I have also cleaned the unnecessary code.
Put if number == 0: inside while type(number) is not int: loop like this:
List = []
while True:
try:
number = int(input("Please enter a number: "))
if number == 0:
Sum = 0
for i in List:
Sum = i + Sum
print(Sum)
break
List.append(number)
except ValueError:
print("Please only enter integer values.")