Python except ValueError: While True - python

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()

Related

How to stop Python while I key in a value that indicates "break"

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")

Trying to control the user's input to strictly a positive number only

I am trying to control the user's input using exception handling. I need them to only input a positive number, and then I have to return and print out that number.
I have to send a message if the user puts in non-number and I have to send a message if the user puts in a number less than 1. Here is what I have:
def input_validation(prompt):
boolChoice = True
while boolChoice == True:
try:
l = input(prompt)
x = int(l)
boolChoice = False
except ValueError:
print("Not a valid input")
if l.isalpha() == True:
print("Your input is not a number")
elif l.isalnum() == True:
print ("Your input is not completely a positive number")
elif l < 0:
print("Your number is not positive")
print("Try again")
return x
def main():
x = input_validation("Enter a positive number: ")
print (x)
main()
My program works fine until a negative integer gets inputted. It doesn't print the message and then goes through the loop again, it just returns and prints back the negative number, which I don't want. How can I fix this? Thank you.
You can use try...except to check if its an integer or letters
def input_validation(prompt):
while True:
try:
l = int(input(prompt))
if l<0: #=== If value of l is < 0 like -1,-2
print("Not a positive number.")
else:
break
except ValueError:
print("Your input is invalid.")
print("Try again")
return l
def main():
x = input_validation("Enter a positive number: ")
print (x)
main()
try
def input_validation(prompt):
boolChoice = True
while boolChoice == True:
try:
l = input(prompt)
x = int(l)
if x < 0:
print ("Your input is a negative number\n Please enter a postive number")
elif x == 0:
print("Your input is zero\n Please enter a postive number ")
else:
boolChoice = False
except Exception as e:
print("Not a valid input")
if l.isalpha() == True:
print("Your input is not a number")
elif l.isalnum() == True:
print ("Your input is not completely a positive number")
else:
print(f"Failed to accept input due to {e}")
print("Try again")
continue
return x
def main():
x = input_validation("Enter a positive number: ")
print (x)
main()

How can I break the while loop and go to the finally block if the user entered "done"

largest = None
smallest = None
l = []
while True:
try:
num = input("Enter a number: ")
except NameError as err:
if err == "done":
break
else:
print("Invalid input")
finally:
l.append(num)
l.sort()
largest = l[-1]
smallest = l[0]
print("Maximum", largest)
print("Minimim", smallest)
This code looks like it's for Python 2.x, where input() tried to evaluate the input, and signalled an error if you typed a string that's not a variable name. Python 3.x doesn't signal an error when you type done.
So just compare the input. You can later do error checking when you try to convert it to an int.
while True:
num = input("Enter a number")
if num == "done":
break
try:
num = int(num)
except ValueError:
print("Invalid input")
continue
l.append(num)
l.sort()
largest = l[-1]
smallest = l[0]
Refactored logic. NameError won't happen and finally not needed...just put it outside the while when "finally" done.
nums = []
while True:
num = input('Enter a number or "done": ') # num is a string at this point
if num == 'done':
break
try:
# try to convert num to integer...
num = int(num) # This can fail with ValueError, so is in try
nums.append(num) # This won't run if above raises exception
except ValueError:
print("Invalid input")
# No need to sort...
print("Maximum", max(nums))
print("Minimum", min(nums))

Collatz Sequence: Automate the Boring Stuff with Python Chapter 3 Practice Project

This is my working code:
number = int(input())
while number > 1:
if number % 2 == 0:
number = int(number) // 2
print (number)
elif number % 2 == 1:
number = 3 * int(number) + 1
print (number)
Now I'm trying to add the exception that if user input has non-integer value, it should print 'Enter a number'
while True:
try:
number = int(raw_input())
break
except ValueError:
print("Enter a number!")
while number > 1:
....
EDIT: As noted in a comment by Anton, use raw_input in Python 2, and input in Python 3.
I'm a complete beginner so I would appreciate all kinds of tips. Here is how I managed to solve the problem, and for now it seems to work fine:
def collatz(number):
if number%2 == 0:
return number // 2
else:
return 3*number+1
print ('Enter a number:')
try:
number = int(input())
while True:
if collatz(number) != 1:
number= collatz(number)
print(number)
else:
print('Success!')
break
except ValueError:
print('Type an integer, please.')
You could check for ValueError for the except. From docs:
exception ValueError
Raised when a built-in operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError.
try:
number = int(input())
while number > 1:
if number % 2 == 0:
number = int(number) // 2
print (number)
elif number % 2 == 1:
number = 3 * int(number) + 1
print (number)
except ValueError:
print('Enter a number')
You could do this-
while number != 1:
try:
if number % 2 == 0:
number = int(number) // 2
print (number)
elif number % 2 == 1:
number = 3 * int(number) + 1
print (number)
except ValueError:
print('Enter a number')
break
def collatz(number):
if number % 2 == 0:
return number // 2
else:
return 3 * number + 1
while True:
try:
value = int(input("Eneter a number: "))
break
except ValueError:
print("enter a valid integer!")
while value != 1:
print(collatz(value))
value = collatz(value)
def coll(number):
while number !=1:
if number%2==0:
number= number//2
print(number)
else:
number= 3*number+1
print(number)
while True:
try:
number = int(input("Enter the no:"))
break
except ValueError:
print("Enter a number")
print(coll(number))
I did it like this:
# My fuction (MINI-Program)
def collatz(number):
if number % 2 == 0:
return number // 2
else:
return 3 * number + 1
# try & except clause for errors for non integers from the users input
try:
userInput = int(input("Enter a number: "))
# Main loops till we get to the number 1
while True:
number = collatz(userInput)
if number !=1:
userInput = number
print(userInput)
else:
print(1)
break
except ValueError:
print("Numbers only! Restart program")

Python figuring out the maximum number?

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.
I have this so far but im confused on how to create a way to compare the maximum value? Im new to programming and im just asking for help. Also do I include the try and except block before the while with the try? and then error for the except?
largest = None
smallest = None
while True:
num = raw_input("Enter a number: ")
if num == "done" : break
print num
print "Maximum", largest
nums = []
while True:
n = raw_input("Enter a number: ")
if n == "done":
break
try:
nums.append(int(n))
except ValueError:
print "Invalid input"
print "Min: %d" % min(nums)
print "Max: %d" % max(nums)
largest = None
smallest = None
first_number = True
while True:
num = raw_input("Enter a number: ")
if num == "done" : break
try:
num = int(num)
if first_number:
largest = num
smallest = num
first_number = False
else:
largest = max(largest, num)
smallest = min(smallest, num)
except Exception, e:
print "Not Valid Input!!!"
continue
print "Maximum", largest
print "Minimum", smallest
numbers =[]
while True:
num = raw_input("Enter a number: ")
if num == "done" :
break
else:
numbers.append(num)
print max(numbers)
print min(numbers)
So, the logic is to add the numbers to a list and use functions max and min. You can write code to handle exceptions yourself.
largest = None
smallest = None
while True:
num = raw_input("Enter a number: ")
if num == "done": break
if len(num) < 1 : break
try:
num=int(num)
except:
print "Invalid input"
continue
if num is smallest:
smallest = num
if num > largest:
largest = num
print "Maximum is ", largest
print "Minimum is ", smallest
You can do this with a very small modification of your original program: just keep tabs of the smallest and largest numbers as you consider them.
largest = None
smallest = None
while True:
string = raw_input("Enter a number: ")
if string == "done":
break
try:
num = int(string)
except ValueError:
print "Not a number"
continue
if largest is None or num > largest:
largest = num
if smallest is None or num < smallest:
smallest = num
largest = None
smallest = None
while True:
num = raw_input('Enter a number: ')
if num == 'done':
print 'Maximum is %s' % largest
print 'Minimum is %s' % smallest
break
try:
num = int(num)
if smallest is None or num <= smallest:
smallest = num
if largest is None or num >= largest:
largest = num
except:
print 'Invalid input'
I am also a python beginning learner, this question I have noticed in 'Python for Everyone' by Charles Russell Severance. My answer is below.
prompt = 'Enter the number: '
initial_value = 0.0
while True:
thing = input(prompt)
if thing == 'done':
break
try:
num = float(thing)
except:
print('Invalid input')
continue
num = float(thing)
if num > initial_value:
max = num
min = initial_value
else:
min = num
print('Max', max)
print('Min', min)
By assigning num to a single value, you are overwriting it through every iteration of the loop. Use a list instead.
num = []
finish = "n"
while finish.lower() == "n"
try:
num.append(int(raw_input("Enter a number: ")))
except ValueError:
print "Not a number"
finish = raw_input("Would you like to add another number? (y/n): ")
print max(num)

Categories

Resources