How can I debug a conditional based on isinstance? - python

I have written the function below. It will work if I pass it an integer or string: If I pass an integer, the program will calculate the factorial, and if I pass a string, it will check the type with isinstance and will print the error message.
But, if I pass a float number or a negative number, the program will print an error... in my second condition. I have said that if n is less than 0, then print that error message, but apparently it won't work, and I don't know why.
def factorial(n):
if not isinstance(n,int):
print('Factorial is only defined for integers.')
return(None)
elif n<0:
print('Factorial is not defined for negative integers.')
return(None)
elif n==0:
return(1)
else:
return(n*factorial(n-1))
How can I change the program so that my conditionals work for float and negative numbers? I don't want to use try and except.

Related

Validating given input and printing every prime number =< given input. (Python)

So I have read tons of solutions to this type of questions, but they all seem to be way too complicated, or I can't find any useful solutions in them.
I have written the first part where I have to ask for an input and validate it to be an integer, but I can't figure out how to write the code for the second part. Efficiency isn't a necessity here, but I think it's better if I learn the most efficient way from the get go. From what I read, using the radicle of the input and checking the divisors is the way to go here, but as I said, I can't figure out how to actually write the code and integrate it into what I already have.
while True:
x = str(input("Please enter an integer: "))
try:
x = int(x)
except ValueError:
print("Please enter a valid integer: ")
continue
break
Any help is greatly appreciated!
It is better to edit multi-line code into your question, rather than post a comment, because then you are not limited to a single line.
Your code appears to be:
def is_prime2(n):
if n == 2 or n == 3:
return True
#endif
if n % 2 == 0 or n < 2:
return False
#endif
for i in range(3, int(n**0.5)+1, 2):
if n % i == 0:
return False
#endif
#endfor
return True
#enddef
print(n)
I have added comments to indicate where I think that various statements end. I may have mistaken the indentation converting from a single line.
Apart from that print(n), which is either not part of the function definition or comes after a return, this appears to work correctly. It will be too slow for very large values of n though it will be fine for smaller values and for testing. For very large values have a look at the Sieve of Eratosthenes.
Write an isPrime(n) function that returns true if n is prime, false otherwise. Then test all the numbers from 2 up to the entered integer to see if they are prime.
We will help you to improve your code, but you have to write it first.

how to remove the runtime (NZEC) error in my python code?

I am trying to solve the prime generator problem PRIME1 in spoj.com but getting runtime error(NZEC). The problem needs to take a number of test cases and for each test case, it needs to input two numbers in a line for each different test case and then finally print the output as the prime numbers in the range of each number
The error is Runtime error time: 0.01 memory: 7736 signal:-1
# your code goes here
def is_prime(x):
if x<2:
return False
if x==2:
return True
for y in range(2,x):
if x%y==0:
return False
return True
t=int(raw_input())
mylist=[]
for i in range(0,t):
a=raw_input()
a=a.split(' ')
mylist.append(int(a[0]))
mylist.append(int(a[1]))
k=0
while k<len(mylist):
c=mylist[k]
k+=1
d=mylist[k]
k+=1
for z in range(c,d+1):
if is_prime(z):
print z
print
On running this on python 2.7.9, I found that there is only one error that you are using t in range(0, t) but t is string here, because our raw_input() method reads input and returns string. That raises in Python parlance. To remove this we should have to type cast the input we got. Like, t = int(raw_input()).
And this will result in t as an integer.
For info about raw_input() follow: https://docs.python.org/2/library/functions.html#raw_input
For reading integer in python you can follow this post on stackoverflow.
Your issue is raw_input() returns string , not integer. But you are trying to use it directly in your range() function - for i in range(0,t) . range() function only accepts integers as arguments, so you need to convert your input into int before using in range.
t=int(raw_input())

Running exceptions within a function - Python

I've been learning Python for about 3 weeks now, so what I'm working on is obviously going to be very simple. I've already written a couple programs that return values for certain calculations, and I have successfully used exceptions within functions in those programs. The program that I'm currently working on is only for the purpose of me getting some more practice writing functions, while loops, and exceptions. Here's what I've got so far:
def factorial(n):
while n > 0:
return n * factorial(n-1)
return 1
print factorial(n)
def user():
n = int(raw_input("What number would you like to use?"))
try:
factorial(int(n))
except ValueError:
print "You must choose a number. Please try again."
return user()
if __name__ == '__main__':
user()
I can't figure out why my exception within the user() function doesn't seem to be running. All I get when I run this code is the raw_input "What number would you like to use?". The factorial() function doesn't run, nor do the print or return statements that I've set if there is a ValueError. Can anyone help me figure out why this is (or rather isn't) happening?
Funny enough, all of the code is running! It just isn't showing anything, because the print statement isn't being called! Lets decompose the user function and see what it does.
What the code is doing
n = int(raw_input("What number would you like to use?"))
Convert the string the user types into an integer and store it into the variable (or, if you want to be pythonic-ly correct, the name) n.
try:
factorial(int(n))
Try to convert n into an integer (again) and send said integer to the factorial function. Note that n here is already an integer! So this will always succeed. Just call the function, nothing more.
except ValueError:
print "You must choose a number. Please try again."
return user()
If ValueError is raised, print an error message, then return the value of user.
We don't print anything whether the conversion was successful or not. We just run a single function then exit. What function do we run?
def factorial(n):
while n > 0:
return n * factorial(n-1)
return 1
print factorial(n)
Note that in this function the code says to print a value after returning a value. Once a function returns, nothing after the return statement is run. The print statement will not be executed! So this function correctly computes the factorial (recursively), and returns it. Nothing else!
This is why your program will seem to do nothing. This function is called, computes, and returns the answer. The returned answer is simply ignored!
What does this mean?
There are three key lines in your code that define why it's doing what it's doing.
You convert the input from the user into an integer and store it in n
This will raise ValueError if the user types anything that isn't an integer.
Note that this still happens! if you run the code, type b, then press enter, an exception (ValueError) will be raised.
You convert n into an integer and pass it to factorial.
Although this is in the try block (as it should be), n is already an integer. This is why your exception code will never run.
Your only print statement (after getting valid input from the user) is inside the factorial function, after the return statement. It will never be executed. This is why nothing is printed.
I don't recommend printing the result inside of a recursive function. It can be done, but it is generally better to return the result and print the returned value, outside of the recursive function. (perhaps in the user function, instead of calling factorial(n) printing what it returns would be better!)
I hope that this helped to clarify exactly what is going on with the code, and I hope I was able to answer your question! Happy coding! :D
Here are my comments expanded into an answer.
First, do not print inside the factorial function. Print the value returned from that function:
def factorial(n):
while n > 0:
return n * factorial(n-1)
return 1
>>> factorial(4)
24
Next, wrap the thing that you think will cause the exception in the try part of the block. In this case, the call to int with unknown user input might cause an exception; wrap that in the try -- no more. Finally, do not use recursion for user input. Use a while loop instead:
def user():
n=None
while not n:
user_int=raw_input("What number would you like to use? ")
try:
n=int(user_int)
except ValueError:
print "You must choose a number. Please try again."
print factorial(n)
if __name__ == '__main__':
user()
first of all you have to print the factorial(int(n)) to see the output,
And remove int conversion of your input,
here is my modified code:
def factorial(n):
2 while n > 0:
3 return n *factorial(n-1)
4 return 1
5 print factorial(n)
6
7
8
9
10 def user():
11 n = raw_input("What number would you like to use?")
12
13 try:
14
15 print factorial(int(n))
16 except ValueError:
17 print "You must choose a number. Please try again."
18 return user()
19
20 if __name__ == '__main__':
21 user()
hope this helps,

python IDLE fibonocci sequence my model doesn't work

need help with this, i tried something but it didn't work for some reason. I need some help to figure it out.
def F(n):
if n == 0: return 0
elif n == 1: return 1
else: return F(n-1)+F(n-2)
F('3')
and here is the original problem- Write a function called fib which takes as a parameter an integer, n, and returns the nth number in the Fibonocci sequence (see definition below). If n is zero or a negative number, your function should return an error message in the form of a string "Error: Invalid input.".
The Fibonocci sequence is 1, 1, 2, 3, 5, 8, 13, 21, ... where the first two numbers are 1, and each number beyond that is calculated as the sum of the previous two numbers (2 = 1+1, 3 = 2+1, 5 = 3+2, 8=5+3, etc).
i guess the problem is that you use string instead of integer.
try F(3) instead of F('3')
or give more information about the error you get
First, for the invalid numbers error you are supposed to print out, I would suggest adding another if statement in. Below shows an example of how you could set any negative number to return an error message.
if n < 0: return "Error: Invalid Input"
For the F function, it goes back to data types. When you put in quotes around something, that specifies an actual string. When you just have a number, it will be an integer data type. For this, we want an integer data type since we want to do math operations on our number. This is why you should remove the quotes.

Failing While loop in Python

I'm fairly new to python (coding in general really), but I mostly grasp what's put in front of me. I'm trying to create an input that will only accept integers, so I put together the following function:
def askFor(request):
"""Program asks for input, continues to ask until an integer is given"""
num = ' '
while (isinstance(num, int) == False):
num = input(request)
else:
return num
it works fine when i enter a number, but anything else breaks it instead of looping it back. Am I missing an element, or am I just best off to go with
str(input('wargharble: '))
You are on the safer side with raw_input in Python 2, because it will always return a string, whereas input will try to evaluate the given string, which is dangerous.
def askFor(prompt):
""" ask for input, continues to ask until an integer is given
"""
number = None
while True:
try:
number = int(raw_input(prompt))
break
except ValueError:
pass # or display some hint ...
print(number) # or return or what you need ...
The problem is that input() returns the raw user input evaluated as a python expression. So when you input something like "someinput" on the console here is what happens:
The raw input is captured from the console as a string
That string is then parsed as a python expression (so imagine you simply type this string into your program, in this case, it becomes a variable with the name "someinput"
When isinstance() is called on this python expression, the python interpreter can't find a variable named "someinput" which is defined - so it throws an exception.
What you really want to do is use raw_input(), this will return a string representing the user's input. Since you are receiving a string from the console now though, you need some way of checking if a string is an int (because isinstance will always return a string)
Now to determine if the string is a number, you could use something like isdigit() - but be careful - this function will validate any string that contains only digits (so 0393 would be valid).
Here are the corrections that need to be made:
def askFor(request):
"""Program asks for input, continues to ask until an integer is given"""
num = ' '
while (num.isdigit() == False):
num = raw_input(request)
else:
return num
This is because input() is failing on non-integer input (this has to do with the fact that input() is calling eval() on the string your inputting (see python builtins).
raw_input() does not. (in fact, input() calls raw_input())
Try this instead:
while True:
num = raw_input(request)
if num.isdigit():
break
The isdigit() function checks to see if each character in a string is a digit ('0' - '9')
input evaluates whatever's typed in as Python code, so if the user types something non-sensical in, it'll produce an error. Or worse, it can run arbitrary commands on your computer. Usually, you want to use raw_input and convert the string value it returns safely yourself. Here, you just need to call int on the string, which can still produce an error if the user enters a non-int, but we can handle that by looping.
And voila:
def read_int(request):
while True:
try:
return int(raw_input(request))
except ValueError:
pass
Note, there's no need for break or else; just return the value once you have parsed it successfully!
Well first off, your indentation if a bit off (the while loop's indentation level does not match the previous level).
def askFor(request):
"""Program asks for input, continues to ask until an integer is given"""
num, isNum = '', False # multiple assignment
while not isNum:
num = input(request)
if type(num) in (int, long): # if it is any of these
isNum = True
break
else: isNum = False
return num # at the end of the loop, it will return the number, no need for an else
Another way to do it:
def askFor(request):
"""Program asks for input, continues to ask until an integer is given"""
num, isNum = '', False
while not isNum:
num = raw_input(request)
try: # try to convert it to an integer, unless there is an error
num = int(num)
isNum = True
break
except ValueError:
isNum = False
return num

Categories

Resources