I am writing a program that must find if a number is even or not. It needs to follow this template. I can get it to find if a number is even or not recursively
The key is that you need to return a boolean value:
def isEven(num):
if (num <= 0):
return (num == 0)
return isEven(num-2)
For larger numbers though this quickly exceeds the default maximum recursion depth for Python. That can be remedied by calling sys.setrecursionlimit(n) where n is the number of recursive calls you want to allow. n in turn is limited by the platform you are on.
Try this, it works for integer values with 0 <= n <= sys.getrecursionlimit()-2:
def even(n):
return True if n == 0 else odd(n - 1)
def odd(n):
return False if n == 0 else even(n - 1)
It's a nice example of a pair of mutually recursive functions. Not the most efficient way to find the answer, of course - but nevertheless interesting from an academic point of view.
This template will help. You need to fill in the commented lines. The one you have in the question won't work - you aren't passing anything into isEven. This will only work if n >= 0, otherwise it will crash your program. Easy enough to fix if you ever need to deal with negative numbers.
def isEven(n):
if n == 0:
# Number is even
elif n == 1:
# Number is odd
else:
# Call the function again, but with a different n
Taking up wim's challenge to find a "different" way to do this: The prototypical recursive pattern is foo(cdr(x)), with a base case for the empty list… so let's write it around that:
def isEven(num):
def isEvenLength(l):
if not l:
return True
return not isEvenLength(l[1:])
return isEvenLength(range(num))
A really dumb use case for recursion, but here is my version anyway
import random
def isEven(num):
if random.random() < 0.5:
# let's learn about recursion!
return isEven(num)
else:
# let's be sane!
return num % 2 == 0
disclaimer: if you submitted this you'd probably tick off the teacher and come across as a smartypants.
Related
Recently, I was trying to create an algorithm for finding a square root of a number. I am kind of new to python programming. This is my implementation:
def findSquareRt(num):
n = 8 #Initial Guess
while True:
if n**2 < num:
if not num/n == n:
temp = n
n = num/n
if (int((temp+n)/2))**2 == num:
return ((temp+n)/2)
else:
n = (temp+n)/2
But when i run the above code it just doesn't produce any output. Maybe it is the looping condition which is causing this, but i cant figure that out.
Your code has a lot of issues, one of them being that you will get an infinite loop if n**2 > num.
A simpler way of doing this would be something like this:
def findSquareRt(num):
return num**0.5
Thank you for responding to the question, From responses there were two problems:
first problem:
if n**2 < num:
this condition is always returning False on second or some other future iterations, and is redundant so this should be removed in order to get a solution.
second problem:
if (int((temp+n)/2))**2 == num:
The integer conversion of the expression ((temp+n)/2) is returning floor value of the float numbers, which effects the precision of the output hence the program stuck infinitely in the loop waiting for the condition to be True. Hence needed to be changed.
Final Solution:
def findSquareRt(num):
n = 8 #Initial Guess
while True:
if not num/n == n:
temp = n
n = num/n
if (((temp+n)/2))**2 == num:
return ((temp+n)/2)
else:
n = (temp+n)/2
else:
return n
I am studying Python by the book "a beginner guide to python 3" written by Mr.John Hunt. In chapter 8, which is about recursion, there is an exercise, that demands a code in which a prime number is found by recursion. I wrote first code below independently, but the answer key is written in different structure. Because I am very doubtful about recursion, What is your analysis about these two? Which is more recursive?
My code:
def is_prime(n, holder = 1):
if n == 2:
return True
else:
if (n-1 + holder)%(n-1) == 0:
return False
else:
return is_prime(n-1, holder+1)
print('is_prime(9):', is_prime(9))
print('is_prime(31):', is_prime(31))
Answer key:
def is_prime(n, i=2):
# Base cases
if n <= 2:
return True if (n == 2) else False
if n % i == 0:
return False
if i * i > n:
return True
# Check for next divisor
return is_prime(n, i + 1)
print('is_prime(9):', is_prime(9))
print('is_prime(31):', is_prime(31))
My suggestion in this case would be not to use recursion at all. Whilst I understand that you want to use this as a learning example of how to use recursion, it is also important to learn when to use recursion.
Recursion has a maximum allowed depth, because the deeper the recursion, the more items need to be put on the call stack. As such, this is not a good example to use recursion for, because it is easy to reach the maximum in this case. Even the "model" example code suffers from this. The exact maximum recursion depth may be implementation-dependent, but for example, if I try to use it to compute is_prime(1046527) then I get an error:
RecursionError: maximum recursion depth exceeded while calling a Python object
and inserting a print(i) statement shows that it is encountered when i=998.
A simple non-recursive equivalent of the "model" example will not have this problem. (There are more efficient solutions, but this one is trying to stay close to the model solution apart from not using recursion.)
def is_prime(n):
if n == 2:
return True
i = 2
while i * i <= n:
if n % i == 0:
return False
i += 1
return True
(In practice you would probably also want to handle n<2 cases.)
If you want a better example of a problem to practise recursive programming, check out the Tower of Hanoi problem. In this case, you will find that using recursion allows you to make a simpler and cleaner solution than is possible without it, while being unlikely to involve exceeding the maximum recursion depth (you are unlikely to need to consider a tower 1000 disks high, because the solution would require a vast number of moves, 2^1000-1 or about 10^301).
As another good example of where recursion can be usefully employed, try using turtle graphics to draw a Koch snowflake.
I'd say the Answer Key needs improvement. We can make it faster and handle the base cases more cleanly:
def is_prime(n, i=3):
# Base cases
if n < 2:
return False
if n % 2 == 0:
return n == 2
if i * i > n:
return True
if n % i == 0:
return False
# Check for next divisor
return is_prime(n, i + 2)
The original answer key starts at 2 and counts up by 1 -- here we start at 3 and count up by 2.
As far as your answer goes, there's a different flaw to consider. Python's default stack depth is 1,000 frames, and your function fails shortly above input of 1,000. The solution above uses recursion more sparingly and can handle input of up to nearly 4,000,000 before hitting up against Python's default stack limit.
Yes your example seems to work correctly. Note However, that by the nature of the implementation, the answer key is more efficient. To verify that a number n is a prime number, your algorithm uses a maximum of n-1 function calls, while the provided answer stops after reaching the iteration count of sqrt(n). Checking higher numbers makes generally no sense since if n is dividable without remainder by a value a > sqrt(n) it has to also be dividable by b = n % a.
Furthermore, your code raises an exception for evaluating at n = 1 since the modulo of 0 is not defined.
I am trying to use 'filter' the abstract function to solve is_prime problem.
I think this is logical works, But the result always be False. and when I add 'print (lon)', tring to find out the problem. It types something I don't understand.
I tried the recursive way, it works.
def is_prime(n):
if n == 2:
return True
lon = filter (lambda x: n % x == 0, list(range (2, n)))
if lon == []:
return True
else:
return False
the result always be False.
by adding
print(lon)
running
is_prime(7)
result is
<filter object at 0x039456D0>
False
To solve your immediate problem, you need to consider types. Because filter(…) returns a generator object of type filter, it can never be equal to [] – an object of type list. So you could just do if list(lon) == []: or, even better, if not any(lon): and call it a day, the function would work the way you wanted.
A few tips though:
comparing to [] is not very Pythonic, an empty list is considered False anyway
it'd be best to ditch if and else, and instead return not any(lon)
however, if you just want to check most efficiently if a given number is prime, you might want to reconsider your approach – checking n-2 numbers is not a good idea; consider for example that:
only one prime factor can be greater than sqrt(n) and non–primes by definition have more than that one factor, so you only need to check up to sqrt(n)
no even number is prime, so you only need to check every other number
and for anything more professional use a scientifically proven extremely optimized algorithm, such as the Miller–Rabin primality test (refer to section "Deterministic variants" for implementation guidance)
A filter object will never be == to a list so you will always get false.
Instead, check if the filter is empty.
def is_prime(n):
if n == 2:
return True
lon = filter (lambda x: n % x == 0, list(range (2, n)))
try:
min(lon)
except ValueError:
return True
return False
Edit: an even cleaner way
def is_prime(n):
if n == 2:
return True
lon = filter (lambda x: n % x == 0, list(range (2, n)))
if not any(lon):
return True
else:
return False
I would suggest that your current use of filter is the wrong approach generator-wise. By letting filter generate a complete result so you can measure it's length, you've lost any advantage of using a generator!
Instead consider a generator approach where if at any step in the generation we detect a remainderless division, the whole generation chain stops and we return False:
def is_prime(n):
if n <= 2 or n % 2 == 0:
return n == 2
return not any(filter(lambda x: n % x == 0, range(3, int(n ** 0.5) + 1, 2)))
Given that filter, any and range are all lazy, we only complete generation in the case of a prime. You don't care 15 has multiple prime divisors, but your original filter approach finds them both! The above approach should resolve the "is it a prime" question as soon as it finds its first divisor, and not look further.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I was curious if anyone could fix my code, this is for project Euler Question 3 (What is the largest prime factor of the number 600851475143 ?), as of now, I am sticking to a program that will find all the prime factors in 100, but am getting an error message for divide by 0, in my head the code seems to work, but it isn't. Unless absolutely necessary, I'd like to keep the while loops. Thanks.
def isPrime(A):
x = 2
while x < A:
if A % x == 0:
return False
x += 1
return A
def isInt(x):
if x == int(x):
return True
return False
A = int(input("Number? "))
counter = 2
while counter <= A:
if isInt(A/isPrime(counter)) == True:
print(counter)
counter += 1
print ("Done")
It seems the key issue is that isPrime() sometimes returns a boolean, and other times returns the input (an integer). You should avoid having functions that do too many things at once - a function called isPrime() should just indicate whether the input is prime or not (i.e. always return a boolean). Some other suggestions inline:
def isPrime(n): # n is a common variable name to use for "some number"
x = 2
while x < n:
if n % x == 0:
return False
x += 1 # this isn't an ideal way to detect primes, can you think of any improvements?
return True
def isInt(n): # use consistent variables - you used A above and x here, which is confusing
return n == int(n) # you can just return the boolean result directly
input = int(input("Number? ")) # use meaningful variable names when possible
counter = 2
while counter <= input:
# I *think* this is what you were trying to do:
# if counter is prime and input/counter is an integer.
# If not you may need to play with this conditional a bit
# also no need to say ' == True' here
if isPrime(counter) and isInt(input/counter):
print(counter)
counter += 1
print ("Done")
This should run (whether it works or not, I leave to you!), but it's still not as efficient as it could be. As you get into harder Project Euler problems you'll need to start paying careful attention to efficiency and optimizations. I'll let you dig into this further, but here's two hints to get you started:
Incrementing by one every time is wasteful - if you know something is not divisible by 2 you also know it's not divisible by 4, 8, 16, and so on, yet your code will do those checks.
In general finding primes is expensive, and it's a very repetitive operation - can you re-use any work done to find one prime when finding the next one?
I have a line code like this -
while someMethod(n) < length and List[someMethod(n)] == 0:
# do something
n += 1
where someMethod(arg) does some computation on the number n. The problem with this code is that I'm doing the same computation twice, which is something I need to avoid.
One option is to do this -
x = someMethod(n)
while x < length and List[x] == 0:
# do something
x = someMethod(n + 1)
I am storing the value of someMethod(n) in a variable x and then using it later. However, the problem with this approach is that the code is inside a recursive method which is called multiple times. As a result, a lot of excess instances of variables x are being created which slows the code down.
Here's the snipped of the code -
def recursion(x, n, i):
while someMethod(n) < length and List[someMethod(n)] == 0:
# do something
n += 1
# some condition
recursion(x - 1, n, someList(i + 1))
and this recursion method is called many times throughout the code and the recursion is quite deep.
Is there some alternative available to deal with a problem like this?
Please try to be language independent if possible.
You can use memoization with decorators technique:
def memoize(f):
memo = dict()
def wrapper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return wrapper
#memoize
def someMethod(x):
return <your computations with x>
As i understand your code correctly you are looking for some sort of memorization.
https://en.wikipedia.org/wiki/Memoization
it means that on every recursive call you have to save as mush as possible past calculations to use it in current calculation.