Python Traceback error in while loop after error handling - python

I have created a program in Python 3.4.1 that;
asks for a whole number,
verifies that it is a whole number,
throws an error message and asks for the number to be re-input if not a whole number,
once the number is verified adds it to a list,
ends if -1 is input.
mylist = []
def checkint(number):
try:
number = int(number)
except:
print ("Input not accepted, please only enter whole numbers.")
number = input("Enter a whole number. Input -1 to end: ")
checkint(number)
number = input("Enter a whole number. Input -1 to end: ")
checkint(number)
while int(number) != -1:
mylist.append(number)
number = input("Enter a whole number. Input -1 to end: ")
checkint(number)
This all works fine, except in one scenario. If a non-whole number is input e.g. p (which gives an error message) followed by -1 to end the program, I get this message:
Traceback (most recent call last):
File "C:/Users/************/Documents/python/ws3q4.py", line 15, in <module>
while int(number) != -1:
ValueError: invalid literal for int() with base 10: 'p'
I don't understand why this is happening, as the input of p should never get as far as
while int(number) != -1:

Here is a minimal example to illustrate the issue:
>>> def change(x):
x = 2
print x
>>> x = 1
>>> change(x)
2 # x inside change
>>> x
1 # is not the same as x outside
You need to fix the function to return something, and assign that to number in the outer scope:
def checkint(number):
try:
return int(number) # return in base case
except:
print ("Input not accepted, please only enter whole numbers.")
number = input("Enter a whole number. Input -1 to end: ")
return checkint(number) # and recursive case
number = input("Enter a whole number. Input -1 to end: ")
number = checkint(number) # assign result back to number
Also, it is better to do this iteratively rather than recursively - see e.g. Asking the user for input until they give a valid response.

Related

How to exit loop when input is nothing

I'm trying to work out the average of numbers that the user will input. If the user inputs nothing (as in, no value at all) I want to then calculate the average of all numbers that have been input by the user upto that point. Summing those inputs and finding the average is working well, but I'm getting value errors when trying to break the loop when the user inputs nothing. For the if statement I've tried
if number == ''
First attempt that didn't work, also tried if number == int("")
if len(number) == 0
This only works for strings
if Value Error throws up same error
Full code below
sum = 0
while True :
number = int(input('Please enter the number: '))
sum += number
if number == '' :
break
print(sum//number)
Error I'm getting is
number = int(input('Please enter the number: '))
ValueError: invalid literal for int() with base 10:>
Any help much appreciated!
EDIT: Now getting closer thanks to the suggestions in that I can get past the problems of no value input but my calculation of average isn't working out.
Trying this code calculates fine but I'm adding the first input twice before I move to the next input
total = 0
amount = 0
while True :
user_input = input('Please enter the number: ')
try:
number = int(user_input)
total = number + number
amount += 1
except:
break
total += number
print(total/amount)
Now I just want to figure out how I can start the addition from the second input instead of the first.
sum = 0
while True :
number = input('Please enter the number: '))
if number == '' :
break
sum += int(number)
print(sum//number)
try like this
the issue is using int() python try to convert input value to int. So, when its not integer value, python cant convert it. so it raise error. Also you can use Try catch with error and do the break.
You will always get input as a string, and if the input is not a int then you cant convert it to an int. Try:
sum = 0
while True :
number = input('Please enter the number: ')
if number == '' :
break
sum += int(number)
print(sum//number)
All of the answers dont work since the print statement referse to a string.
sum = 0
while True :
user_input = input('Please enter the number: ')
try:
number = int(user_input)
except:
break
sum += number
print(sum//number)
including a user_input will use the last int as devisor.
My answer also makes sure the script does not crash when a string is entered.
The user has to always input something (enter is a character too) for it to end or you will have to give him a time limit.
You can convert character into int after you see it isn't a character or
use try & except.
sum = 0
i = 0
while True :
try:
number = int(input('Please enter the number: '))
except ValueError:
break
i += 1
sum += number
try:
print(sum/number)
except NameError:
print("User didn't input any number")
If you try to convert a character into int it will show ValueError.
So if this Error occurs you can break from the loop.
Also, you are trying to get the average value.
So if a user inputs nothing you get NameError so you can print an Error message.

How to exclude specific type of an input variable in Python?

I created a row of Fibonacci numbers. At the beginning is desired input the number to specify the size of Fibonacci series, in fact the size of the row. The number is required to be an integer number >=2.
The outcome is printing out all Fibonacci number until the last number of the row, with their respective indices within the row! After that it's required to take out a slice of the row, and the outcome is to print out all numbers within the slice with their respective indices.
I successfully mastered to exclude all values that do not fall within range specified, but however I had not succeed to exclude numbers and other inputs of undesired types, example would like to exclude float type of an input variable, and string type of an input variable.
I specified that undesirable types of an input variable are float and string! However it reports me an error! How to overcome that, or by another words how to specify the requirement to exclude a floating variable as well as string variable to not report me an error?
The code:
while True:
n = int(input('Please enter the size of Fibonacci row - positive integer number(N>=2)!'))
if n < 2:
print('This is not valid number! Please enter valid number as specified above!')
continue
elif type(n)==float: # this line is not working!
print('The number has to be an integer type, not float!')
continue
elif type(n)==str: # this line is not working!
print( 'The number has to be an integer type, not string!')
continue
else:
break
def __init__(self, first, last):
self.first = first
self.last = last
def __iter__(self):
return self
def fibonacci_numbers(n):
fibonacci_series = [0,1]
for i in range(2,n):
next_element = fibonacci_series[i-1] + fibonacci_series[i-2]
fibonacci_series.append(next_element)
return fibonacci_series
while True:
S = int(input('Enter starting number of your slice within Fibonacci row (N>=2):'))
if S>n:
print(f'Starting number can not be greater than {n}!')
continue
elif S<2:
print('Starting number can not be less than 2!')
continue
elif type(S)==float: # this line is not working!
print('The number can not be float type! It has to be an integer!')
continue
elif type(S)==str: # this line is not working!
print('Starting number can not be string! It has to be positive integer number greater than or equal to 2!')
continue
else:
break
while True:
E = int(input(f'Enter ending number of your slice within Fibonacci row(E>=2) and (E>={S}):'))
if E<S:
print('Ending number can not be less than starting number!')
continue
elif E>n:
print(f'Ending number can not be greater than {n}')
continue
elif E<2:
print('Ending number can not be greater than 2!')
continue
elif type(E)==float: # this line is not working!
print('Ending number can not be float type! It has to be an integer type!')
continue
elif type(E) ==str: # this line is not working!
print(f'Ending number can not be string! It has to be positive integer number greater than or equal to {S}')
continue
else:
break
print('Fibonacci numbers by index are following:')
for i, item in enumerate(fibonacci_numbers(n),start = 0):
print(i, item)
fibonacci_numbers1 = list(fibonacci_numbers(n))
print('Fibonacci numbers that are within your slice with their respective indices are following:')
for i, item in enumerate(fibonacci_numbers1[S:E], start = S):
print(i, item)
Solved :-) simply add try except block in ur code like the following:
while True:
try:
num = int(input("Enter an integer number: "))
break
except ValueError:
print("Invalid input. Please input integer only")
continue
print("num:", num)
upvote & check :-)
at the first line
n = int(input('Please enter the size of Fibonacci row - positive integer number(N>=2)!'))
you're converting the input to int, so whatever the user provides it will be converted to an int.
if you want your code to be working, replace it with this
n = input('Please enter the size of Fibonacci row - positive integer number(N>=2)!')
Use an try/except/else to test the input. int() raises a ValueError if a string value isn't strictly an integer.
>>> while True:
... s = input('Enter an integer: ')
... try:
... n = int(s)
... except ValueError:
... print('invalid')
... else:
... break
...
Enter an integer: 12a
invalid
Enter an integer: 1.
invalid
Enter an integer: 1.5
invalid
Enter an integer: 1+2j
invalid
Enter an integer: 5
>>>
If you need to check type, isinstance is usually better, e. g.:
if isinstance(var, int) or isinstance(var, str):
pass # do something here

Validating int numbers in a certain range. Python-3.x [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 2 years ago.
I am making this game where the user has to choose from 5 options. So, he must type any number from 1 to 5 to choose an option. Now here is the problem I am facing, I just can't figure out a way in which the user cannot type in any other character except the int numbers from 1 to 5, and if he does type in a wrong character, how should I show his error and make him type in the input again? Here is what I've tried:
def validateOpt(v):
try:
x = int(v)
if int(v)<=0:
x=validateOpt(input("Please enter a valid number: "))
elif int(v)>5:
x=validateOpt(input("Please enter a valid number: "))
return x
except:
x=validateOpt(input("Please enter a valid number: "))
return x
Here validateOpt is to validate the number for the option, i.e., 1,2,3,4,5. It works fine, but whenever I type 33,22, 55, or any other int number from 1 to 5 twice (not thrice or even four times, but only twice), it doesn't show any error and moves on, and that, I suppose, is wrong. I am just a beginner.
You can do this with a while loop, something like this should be a good start:
def getValidInt(prompt, mini, maxi):
# Go forever if necessary, return will stop
while True:
# Output the prompt without newline.
print(prompt, end="")
# Get line input, try convert to int, make None if invalid.
try:
intVal = int(input())
except ValueError:
intVal = None
# If valid and within range, return it.
if intVal is not None and intVal >= mini and intVal <= maxi:
return intVal
Then call it with something like:
numOneToFive = getValidInt("Enter a number, 1 to 5 inclusive: ", 1, 5)
use a while loop instead of recursion, you can check the user data and return if its valid, although you might want to consider a break out clause should the user want to exit or quit without a valid input.
def get_input(minimum, maximum):
while True:
try:
x = int(input(f"please enter a valid number from {minimum} to {maximum}: "))
if minimum <= x <= maximum:
return x
except ValueError as ve:
print("Thats not a valid input")
value = get_input(1, 5)
Use for loop in the range between 1 and 5
Try this code, it will keep prompting user till he enters 5, note that this may cause stackoverflow if recursion is too deep:
def f():
x = input("Enter an integer between 1 and 5:")
try:
x = int(x)
if x<=0 or x>5:
f()
except:
f()
f()

Cannot figure out why I am getting UnboundLocalError

I am trying to get the code to "except" a string for an int. - "length". When I put except ValueError, I get back "Please enter a number", but more error is added. I also added to except UnboundLocalError, but that does not seem to work. Please let me know what I'm doing wrong! Here is my code:
import random
import string
def RPG():
try:
RPG = ""
count = 0
length = int(
input("How many characters would you like in your password? "))
except (ValueError, UnboundLocalError):
print("Please enter a number.")
while count != length:
upper = [random.choice(string.ascii_uppercase)]
lower = [random.choice(string.ascii_lowercase)]
num = [random.choice(string.digits)]
symbol = [random.choice(string.punctuation)]
everything = upper + lower + num + symbol
RPG += random.choice(everything)
count += 1
continue
if count == length:
print(RPG)
# could also use string.printable for digits, letters, punct., and whitespace.
RPG()
Here is what I got back from using this code and typing a string instead of an integer into length:
How many characters would you like in your password? j
Please enter a number.
Traceback (most recent call last):
File "c:\Users\jkelly\Desktop\python\code.py", line 28, in <module>
pwd()
File "c:\Users\jkelly\Desktop\python\code.py", line 14, in pwd
while count != length:
UnboundLocalError: local variable 'length' referenced before assignment
I only expect the "Please enter a number", not the rest of the error, any help would be greatly appreciated. Thank you for your time!
The problem with the original code is that while count != length always gets executed, no matter the try-except part. This can be avoided by only proceeding to the while loop if an ValueError or UnboundLocalError was not raised. By initializing c=1 before the try-except and changing it to 0 only in the try part, the program only proceeds to the while loop if exception didn't happen.
import random
import string
def RPG():
c=0
try:
RPG = ""
count = 0
length = int(
input("How many characters would you like in your password? "))
except (ValueError, UnboundLocalError):
print("Please enter a number.")
c=1
if c==0:
while count != length:
upper = [random.choice(string.ascii_uppercase)]
lower = [random.choice(string.ascii_lowercase)]
num = [random.choice(string.digits)]
symbol = [random.choice(string.punctuation)]
everything = upper + lower + num + symbol
RPG += random.choice(everything)
count += 1
continue
if count == length:
print(RPG)
# could also use string.printable for digits, letters, punct., and whitespace.
RPG()
If you cause an error, the rest of the program will still be executed. You need to repeat the input, until you get the correct input.
import random
import string
def RPG():
while True:
try:
RPG = ""
count = 0
length = int(
input("How many characters would you like in your password? "))
break
except (ValueError, UnboundLocalError):
print("Please enter a number.")
while count != length:
upper = [random.choice(string.ascii_uppercase)]
lower = [random.choice(string.ascii_lowercase)]
num = [random.choice(string.digits)]
symbol = [random.choice(string.punctuation)]
everything = upper + lower + num + symbol
RPG += random.choice(everything)
count += 1
continue
if count == length:
print(RPG)
# could also use string.printable for digits, letters, punct., and whitespace.
RPG()

Does While loop ends when the program return value?

I am a new learner for Python. I have a question about while loop.
I wrote a program below to look for square roots.
When I input anything but integers, the message "is not an integer" shows up and it repeats itself until I input correct data(integers).
My question is, why does it end loop when it return value on line 5, return(int(val))?
Thank you for your attention.
def readInt():
while True:
val = input('Enter an integer: ')
try:
return(int(val))
except ValueError:
print(val, "is not an integer")
g = readInt()
print("The square of the number you entered is", g**2)
To answer your original question, 'return' effectively exits the loop and provide the result that follows the 'return' statement, but you have to explicity print it like so:
def read_int(num1, num2):
while True:
return num1 + num2
print(read_int(12, 15))
If you simply put 'read_int(12, 14)' instead of 'print(read_int(12, 15))' in this scenario, you won't print anything but you will exit the loop.
If you allow me, here are some modifications to your original code:
def read_int(): # functions must be lowercase (Python convention)
while True:
val = input('Enter an integer: ')
try:
val = int(val) # converts the value entered to an integer
minimum_value = 0 # There is no need to evaluate a negative number as it will be positive anyway
maximum_value = 1000000 # Also, a number above 1 million would be pretty big
if minimum_value <= val <= maximum_value:
result = val ** 2
print(f'The square of the number you entered is {result}.')
# This print statement is equivalent to the following:
# print('The square of the number you entered is {}.'.format(result))
break # exits the loop: else you input an integer forever.
else:
print(f'Value must be between {minimum_value} and {maximum_value}.')
except ValueError: # If input is not an integer, print this message and go back to the beginning of the loop.
print(val, 'is not an integer.')
# There must be 2 blank lines before and after a function block
read_int()
With the final 'print' that you actually have at the end of your code, entering a string of text in the program generates an error. Now it doesn't ;). Hope this is useful in some way. Have a great day!

Categories

Resources