I'm doing an exercise where my code has to take a number and assign a category to it. Category is based on the numbers aliquot sum. Categories are perfect, abundant and deficient.
This is the code I've created:
def classify(number):
""" A perfect number equals the sum of its positive divisors.
:param number: int a positive integer
:return: str the classification of the input integer
"""
try:
sum = sum_of_dividers(number)
print(sum)
if sum == number:
return 'perfect'
elif sum > number:
return 'abundant'
elif sum < number:
return 'deficient'
elif sum == 0 or sum < 0:
raise ValueError
except ValueError:
print('Invalid input.')
def sum_of_dividers(number):
sum = 0
for i in range(1,number):
if number % i == 0:
sum +=i
return sum
My problem is that it's an excercise and my code is checked by chunk of code I've added below and throwing an error. Could you point me into where to look? I've checked Python docs about Errors and Exceptions but it seems that I'm raising the ValueError right.
Two tests are not passed:
InvalidInputs > zero is rejected as it is not a positive integer
InvalidInputs > negative integer is rejected as it is not a positive integer
CODE RUN
with self.assertRaises(ValueError) as err:
classify(0)
self.assertEqual(type(err.exception), ValueError)
self.assertEqual(
err.exception.args[0],
TEST FAILURE
AssertionError: ValueError not raised
Related
I just started learning python 3 and have been having some issues when trying to understand exception handling. I am going through a tutorial book that has given me a small project called the 'The Collatz Sequence'
its essentially a program that evaluates any integer down to '1' by using a some simple math.
I have been able to successfully get the program to work UNTIL the user inputs anything but an integer. At first I was getting ValueError, which was corrected by using the except ValueError:.
Now I seem to be getting NameError: name 'number' is not defined
Any help is appreciated. Just trying to get an understanding of exception handling.
def collatz(number):
if number % 2 == 0:
even_number = number//2
print(even_number)
return even_number
elif number % 2 == 1:
odd_number = (number * 3 + 1)
print(odd_number)
return odd_number
try:
number = int(input('Enter Number: '))
except ValueError:
print('Please enter an integer')
while int(number) != 1:
number = collatz(number)
A possibility would be to keep track of whether an integer was given as input using a boolean value. Consider the (adapted) code below:
def collatz(number):
if number % 2 == 0:
even_number = number//2
print(even_number)
return even_number
elif number % 2 == 1:
odd_number = (number * 3 + 1)
print(odd_number)
return odd_number
# Keep asking for input until the user inputs an integer
got_integer = False
while not got_integer:
try:
number = int(input('Enter Number: '))
got_integer = True
except ValueError:
print('Please enter an integer')
while int(number) != 1:
number = collatz(number)
As you can see, I define a boolean variable got_integer. Initially, I set its value to False. After this variable definition is a while loop, which keeps executing the loop body until the value of got_integer is True. Now you simply set the value of got_integer to True upon a succesfull input (i.e. if the execution of the line number = int(input('Enter Number: ')) succeeds).
You have to have the logic inside try block if you are getting exceptions.
Then you can handle it when you face with an exception. In your case you can have the while block inside the try like below. According to the exceptions you can handle them below as you have done already.
def collatz(number):
if number % 2 == 0:
even_number = number//2
print(even_number)
return even_number
elif number % 2 == 1:
odd_number = (number * 3 + 1)
print(odd_number)
return odd_number
try:
number = int(input('Enter Number: '))
if number != 1:
number = collatz(number)
except ValueError:
print('Please enter an integer')
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
I'm very new to python, in fact, to programming in general. I'm trying to do a program that compares three numbers and determines which one is smaller. I got the code done, but now i need to make it only accept numbers, and still running when it finds a literal value. For example, code will be ok if you put any number, but when you type a string value it crashes. here is the code
num1=0;
num2=0;
num3=0;
num1=int((raw_input("Type below the first number \n")));
num2=int((raw_input("Type below the second number\n")));
num3=int((raw_input("Type below the third number \n")));
if (num1<num2) and (num1<num3):
print "%i is the smallest number of all three"% num1;
elif (num2<num1) and (num2<num3):
print "%i is the smallest number of all three"% num2;
elif (num3<num2) and (num3<num1):
print "%i is the smallest number of all three"% num3;
elif (num1==num2) or (num1==num3) or (num2==num3):
print "Two equal numbers have been written.";
A simple while loop. You may put this in a function.
while True:
try:
num1=int((raw_input("Type below the first number \n")))
break
except ValueError: # catch the *specific* exception
print("Enter numbers only")
Read more on exceptions:
Handling Exceptions in Python
The most important point is probably to separate concerns, ie. keeping user input separate from validation. You've gotten a couple of good solutions using exceptions. Here is a solution that manually validates the input:
def is_int(strval):
"""A string represents an int if all characters are digits.
Returns True if strval represents a valid int, otherwise False.
"""
for ch in strval:
if not ch.isdigit(): # if '0' <= ch <= '9':
return False
return True
def read_int(prompt='Type number: '):
"""Read one integer from user.
"""
while True:
val = raw_input(prompt)
if is_int(val):
return int(val, 10) # the 10 is the radix (base)
else:
print 'That is not a number.., try again'
numbers = []
for pos in 'first', 'second', 'third':
numbers.append(read_int('Type %s number: ' % pos))
to use the exception handling code, all you have to do is change is_int:
def is_int(strval):
try:
int(strval, 10)
except ValueError:
# int() raised an exception, so strval is not an int
return False
else:
# int() didn't raise an exception, so it is an int
return True
it is also possible to be a bit more concise when finding the smallest:
def smallest(a, b, c):
if b > a < c: # if a is less than both b and c..
return a
if a > b < c:
return b
if a > c < b:
return c
return "Error: two of the numbers must be equal!"
you can call it like so:
smallest(numbers[0], numbers[1], numbers[2])
but Python has a shorthand that does exactly that which looks like:
smallest(*numbers)
def getNumber(i):
try:
num = int(raw_input("type in number %s : " %i))
return num
except Exception as e:
print('This is not a valid number')
return getNumber(i)
numbers = []
for i in range(1,4):
numbers.append(getNumber(i))
print(numbers)
You can simply add the input getting code in try except block and handle the ValueError exception with some meaningful code.
try:
num1=int((raw_input("Type below the first number \n")));
num2=int((raw_input("Type below the second number\n")));
num3=int((raw_input("Type below the third number \n")));
except ValueError:
print "Please enter integer only."
exit(-1)
I want to check if the input is a number(float with 0,one or two decimals) and greater than 0
def getnumber():
print ( "write a number: \n")
isValid = False
while not isValid:
try:
number = float(raw_input().replace(",","."))
if number >= 0:
isValid=True
else:
print ("Number not valid")
isValid = False
getnumber()
except:
print ("Number not valid")
return number
I have the following problems:
1- I don't know how to check if there are only two decimals
2- The code doesn't return the number if first I introduce a negative number
Does anyone know how to fix it?
Thanks a lot
The reason why your code isn't working with negative numbers is because the function calls itself recursively when the number is negative, but the value of isValid is always false after that call, so the loop repeats.
There isn't really any need for the Boolean variable.
That leaves you with the issue of detecting two decimal places. In order to be able to do that at string level you would have to retain the string that you converted to a floating-point number. Supposing you store it as s you could use some test like len(s) > 3 and s[-3] == '.'` to verify it.
This would give you a solution like:
def getnumber():
while True:
try:
s = raw_input("Write a number:").replace(",",".")
number = float(s)
if number >= 0 and len(s) > 3 and s[-3] ==".":
return number
else:
print("Negative or not two decimal places")
except Exception:
print("Invalid number")
print(getnumber())
I'm new to programming and currently learning Python. I would like to write a program that :
request user to input a non-negative even integer.
request the user to input again if not fulfil non-negative even integer.
N = input("Please enter an non-negative even integer: ") #request user to input
And the criteria checking code is:
N == int(N) #it is integer
N % 2 == 0 #it is even number
N >=0 # it is non-negative number
But how should I combine them?
since the question is tagged python-2.7, use raw_input instead of input (which is used in python-3.x).
Use str.isdigit to check if a string is an positive integer, int(N) would raise ValueError if the input couldn't be converted into integer.
Use a while loop to request user input if condition not fulfilled, break when you get a valid input.
e.g.,
while True:
N = raw_input("Please enter an non-negative even integer: ") #request user to input
if N.isdigit(): # accepts a string of positive integer, filter out floats, negative ints
N = int(N)
if N % 2 == 0: #no need to test N>=0 here
break
print 'Your input is: ', N
You can use the and operator:
while True:
s = input("Please enter an non-negative even integer: ")
# Use raw_input instead of input in Python 2
try:
N = int(s)
except ValueError:
continue # Not an integer, try again
if N % 2 == 0 and N >= 0:
break # Abort the infinite loop
Compared to other versions presented here, I prefer to loop without using the break keyboard. You can loop until the number entered is positive AND even, with an initial value set to -1:
n = -1
while n < 0 or n % 2 != 0:
try:
n = int(input("Please enter an non-negative even integer: "))
except ValueError:
print("Please enter a integer value")
print("Ok, %s is even" % n)
Just another solution:
>>> def non_neg(n):
... try:
... if n & 1 == 0 and n > 0:
... return 'Even Positive Number'
... except:
... pass
... return 'Wrong Number'
...
>>> for i in [-1,-2,2,3,4,0.5,'a']:
... print i, non_neg(i)
...
-1 Wrong Number
-2 Wrong Number
2 Even Positive Number
3 Wrong Number
4 Even Positive Number
0.5 Wrong Number
a Wrong Number
>>>
code for fun:
result=[ x for x in [input("Please enter a number:")] if isinstance(x,int) and x>0 and x%2 ==0]
Excuting this list comprehension ,will get you an empty list if occurs any illegal key-in like 0.1, 'abc',999.
code for best practice:
There is quite popular to take all validation expression into lambda for python, for example, like django so :
isPositiveEvenNum=lambda x: x if isinstance(x,int) and x>0 and x%2 ==0 else None
while not isPositiveEvenNum(input("please enter a number:")):
print "None Positive Even Number!"
this can also be writen as
isPositiveEvenNum=lambda x: (isinstance(x,int) and x>0 and x%2 ==0) or False
while not isPositiveEvenNum(input("please enter a number:")):
print "None Positive Even Number!"
to solve the input and raw_input difference between 2.x and 3.x:
import sys
eval_input =lambda str: input(str) if sys.version_info<(3,0,0) else eval(input(str))
then just call eval_input