Python Recursion Exercise - python

I am doing exercise on Singpath and I am stuck at this question. This question is under recursion exercises but I have no idea what the question means.
A number, a, is a power of b if it is
divisible by b and a/b is a power of
b.
Write a function called is_power
that takes parameters a and b and
returns True if a is a power of b.
Update:
Just thought of the answer and I've posted it below.

It's a recursive definition of power. You are supposed to write the function
def is_power(a, b):
...
The definition give a general property. hint for the terminal case. if a and b are equals the function should answer true.

Think about what it will do, at present, if you give it, say a=32 and b=2. b*b will give you 4, 16, 256...
So, you have to keep track of the original b as you're calling your function recursively. You could have a third variable with a default value (original_b), but there's a way to do it without replacing b at all.

Look more closely at the information you are given:
A number, a, is a power of b if it is divisible by b and a/b is a power of b.
It says "... and a/b is a power of b". It does not say "... and a is a power of b*b". There is a reason for that: you don't get the same results with the two different definitions.
Now look at your code for the recursive call:
return is_power(a,b*b)
We don't care if a is a power of b*b; we care if a/b is a power of b. So why are we calling is_power(a, b*b) # is a a power of b*b? ? Instead, we should call... well, I think you can figure it out :)
Why it's different: let's say the recursion happens twice. When we start out calling the function, let's say b = 2. On the first recursion, we pass 2 * 2 = 4. On the next recursion, the input was 4, so we pass 4 * 4 = 16. But we skipped the check for 2 * 2 * 2 = 8. 8 is a power of 2, but if we call is_power(8, 2), then is_power(8,8) never happens, and then is_power(8, 16) returns False.

def isp(a,b):
if a%b==0 and isp(a/b,b):
return True
elif a/b==b:
return True
else:
return False

You should start with the trivial cases, there are two in fact: is_power(x,x) and is_power(1,x).
Once you have the edge case you just need to write down the definition correctly. It mentions a/b and b, but you wrote return is_power(a,b*b). Maybe you think that is the same, just scaled both arguments with b, but it is not. Think about the values of b in is_power(27,3).

Here is my answer...
def is_power(a,b):
if(a%b != 0):
return False
elif(a/b == 1):
return True
else:
return is_power(a/b,b)

def power(a,b):
if a<=b:
if a==b: return True
else:return False
elif a%b==0: return power(a/b,b)
else: return

You need to consider the edge case where a = 0 (which some of the answers above do). I just wanted to point in out in particular, because it's easy to see why a = 1 is an important edge case, but a = 0 is also important because if you don't acknowledge it in some way you may end up with infinite recursion.
If it helps, this is how I approached it:
def is_power(a, b):
if a == b or a == 1:
# a == b is the 'success' base case (a is a power of b)
# a == 1 is the success edge case where a is 1 (b ^ 0)
return True
elif a % b != 0 or a == 0:
# a % b != 0 is the 'failure' base case (a is not a power of b)
# a == 0 is the failure edge case where a is 0. If
# you don't acknowledge this case in some way, the function
# will recurse forever
return False
else:
# else, keep recursing
return is_power(a / b, b)
print is_power(8, 2) # True
print is_power(6, 2) # False
print is_power(0, 2) # False
print is_power(1, 2) # True

def is_power(a, b):
if a%b == 0 and a/b**b:
return True
else:
return False
is_power(10, 12)

Related

boolean recursion in python

I'm trying to see if a is a power of b. For this to be true a needs to be divisible by b and a/b needs to be a power of b as well. I'm struggling with the recursion here as it seems like it'll go on forever. Can anyone help?
def is_power(a,b):
if(a % b == 0):
a = a/b
if(is_power(a,b)):
return True
return False
An alternative approach is to take the logarithm of a with respect to the base b. If the result is a whole number, than b**x = a for some x
from math import log
def is_power(a, b):
return log(a, b).is_integer()
What you're missing is a base case that can return True. Your function only returns True if a recursive call to the same function returns True. Which can only happen if another recursive call to the same function returns True. Which can… and so on. So, the only things that can possibly happen are returning False, or recursing forever (or, rather, recursing 1000 times until you get an exception).
More generally, any recursive solution needs two parts: a base case that you can solve immediately, and a recursive case that reduces the problem down toward the base case. You've written the second part—the hard part—but missed the first part.
One obvious base case is either a == b, or a == 1. If either of those is true, then you know that a is a power of b (the first or zeroth power, respectively), so you can immediately return True. So, let's try one of those:
def is_power(a,b):
if a == b:
return True
if(a % b == 0):
a = a/b
if(is_power(a,b)):
return True
return False
Now it works for many values—is_power(16, 2), is_power(6561, 3), etc.
But, unless this is Python 2, there's another problem: a/b returns a float, not an int, which means that your next recursive step could, because of float rounding issues, calculate a % b and get something like 1e-302 instead of 0, so a % b == 0 will be False, and you'll go too far and keep on dividing. This would eventually reach 0 and finally return True (the right answer for the wrong reason), but if it takes more than 1000 steps to get there, you'll hit the recursion limit first and raise an exception.
To fix that, just use // instead of /.
You need a exit condition:
def is_power(a,b):
if a == b:
return True
elif a % b == 0:
a = a/b
return is_power(a,b)
return False
If mod is 0, you have to continue with the recursion until a/b is equal to 1 (meaning equals):
def is_power(a,b):
if(a % b == 0):
a = a/b
if(a == 1):
return True
else:
return is_power(a,b)
else:
return False
print(is_power(16,2))
True
def is_power(a,b):
if(a % b == 0):
a = a/b
return a == 1 or is_power(a,b)
return False

Function would not return value, instead it returns "None"

Please help me look at this piece of code which was supposed to calculate the greatest common division between two numbers (a, b). The problem I'm having is that the program would not return c as expected, instead it return None. But when I use a print statement, it prints out the value of c.
This is my code:
def gcd(a, b):
if a == 0:
return b
elif b == 0:
return a
elif a > b:
big, small = a, b
else:
big, small = b, a
c = big % small
if c == 0:
print(small)
return small
gcd(small, c)
print(gcd(1071, 462))
Thanks guys.
Python implicitly returns None when no explicit return is encountered and the function body ends.
In your case if it passes through all other cases it just hits:
gcd(small, c)
return None # you haven't put that in explicitly but that's how Python processes it
So you probably just need to change the last line to:
return gcd(small, c)

Any way to extract the sign of a number in Python?

I have am coding the algorithm of Bolzano in Python. This is my code for now:
def Bolzano(fonction, a, b, tol=0.000001):
while abs(b-a)>tol:
m=(a+b)/2
if cmp(fonction(m))==cmp(fonction(a)):
a=m
else:
b=m
return a, b
It works until it encounters cmp, which it doesn't recognise. However I don't see another way to do it, since Python doesn't have a sign function. Is there any other way to extract the sign of a number?
Is there any other way to extract the sign of a number?
How about writing your own?
Implementation
def sign(num):
return -1 if num < 0 else 1
Example
>>> sign(10)
1
>>> sign(-10)
-1
Ohh and cmp is a built-in that requires two parameters (numbers) and simply compares them and checks which of them is larger. You should have used it as follows
def Bolzano(fonction, a, b, tol=0.000001):
while abs(b-a)>tol:
m=(a+b)/2
if cmp(fonction(m), fonction(a)) == 0:
a=m
else:
b=m
return a, b
Maybe use:
if cmp(fonction(m),fonction(a)) == 0:
def same_sign(a, b):
return (a * b) >= 0
Examples:
>>> same_sign(3, 4)
True
>>> same_sign(-3, 4)
False
>>> same_sign(3, -4)
False
>>> same_sign(-3, -4)
True
>>> same_sign(-3, 0)
True

How this greatest common divisor (gcd) works in python

I have taken a piece of code from http://www.s-anand.net/euler.html, problem 5:
def gcd(a,b):
print a,b
return b and gcd(b, a % b) or a
print gcd(10,20)
Giving output:
10 20
20 10
10 0
10
Why the last line prints only "a" not b.
Can you please explain how the return statement in above code works.
I am little bit confused with "and" and "or" operators.
b and gcd(b, a % b) or a
was the old way of writing:
gcd(b, a % b) if b else a
Python's and and or operators use a type of short-circut evaluation that is a little confusing at first.
If they were written as function, they would work sort-of like this, except that they don't even evaluate the right value unless they need to.
def and(left, right):
if left:
return right
else:
return left
def or(left, right):
if left:
return left
else:
return right
So the line return b and gcd(b, a % b) or a could be written more verbosely as:
if b:
temp_1 = gcd(b, a % b)
else:
temp_1 = False
if temp_1:
return temp_1
else:
return a
If you work out the logic, this is equivalent to the common method for finding a GCD. However, unless you're already familiar with Python this code will be hard to read, so you might want to avoid this style.
Because 10 is the greatest common divisor in your case, e.g. result of gcd(10,20)
Your code(return b and gcd(...) or a) is the same as:
def gcd(a,b):
print a,b
if b:
return b
else:
res = gcd(b, a % b)
return res if res else a
Also note that there gcd method in fractions module:
from fractions import gcd
print gcd(10,20)

Finding out whether a is a power of b

I'm currently using singpath.com to practice on my python, but I face an issue with a problem:
A number, a, is a power of b if it is divisible by b and a/b is a power of b.
Write a function called is_power that takes parameters a and b and returns True if a is a power of b.
def is_power(a,b):
c = a/b
if (((a%b) == 0) and ((c%b) == 0)):
return True
else:
return False
Above is my solution but the system prompt me to generalize my solution.
Can anyone tell me whats wrong with my solution?
The reason why your original code does not work is the following: You just check (c%b) == 0) aka (a/b) is divisible by b, which is much weaker than the a/b is a power of b part of the definition.
When you want to solve a problem such as this you should always start with the trivial cases. In this case there are two such cases: is_power(x,x) and is_power(1,x) - in both the answer is True, because x**1==x and x**0==1.
Once you have these cases covered you just need to write down the rest of the definition. Write code for (a is divisible by b) and (a/b is a power of b) and put it all together.
The final function will look like this:
def is_power(a,b):
if <trivial case 1> or <trivial case 2>:
return True
# its a recursive definition so you have to use `is_power` here
return <a is divisible by b> and <a/b is a power of b>
The only question left is how to answer <a/b is a power of b>. The easiest way to do this is using the function is_power itself - this is called recursion.
def is_power(a,b):
'''this program checks if number1 is a power of number2'''
if (a<b): # lesser number isn't a power of a greater number
return False
elif (b==0) or (b==1) : # Exception cases
return False
elif a%b == 0 and is_power(a/b, b) == True: # Condition check for is_power (Recursion!)
return True
else:
return False
You are only checking the first two powers: a divides b and a/b divides b. It could be that a = b ** 3 or b ** 4 (or b ** n in general), so the actual solution will have to involve recursion or a loop.
Here is my solution.
def is_power(a,b):
if a == 1: # base case for recursion
return True
elif b == 0 or a%b !=0 or a<b: # exception cases.
return False
return is_power(a//b,b) # recursion
I tested with several cases (16,2),(6,2),(1,2),(0,0),(0,1) and it works well.
A much simpler solution is:
def is_power(a, b):
while a % b == 0:
a //= b
return a == 1
Recursion is really not needed for this problem. Moreover recusion may cause a recursion limit error if a = b ** 1001.
def is_power(a,b):
if a == b:
return True
if a % b == 0 and is_power(a/b,b):
return True
return False
The end condition which is a == b is crucial here which stops when both numbers are equal. If this is not included the function could show False for even legitimate numbers by dividing a/b in the next iteration which gives 1 where 1 % b = 1 which in turn returns False instead of True.
I wouldn't say to generalize it. I would say to correct it as it's incorrect. Using your solution is_power(12,2) returns True as does is_power(18,3).
I think that the reason that the system says to generalize it is that it's probably working correctly for some of their test cases, but not others. It's likely that the test cases for which it is working are coincidentally those for which it would work if it were hard-coded in a certain way (only checking powers of 2, for example).
You're checking whether a/b is divisible by b (in the expression (c%b) == 0), rather than whether a/b is a power of b. Hint: What function would you call to see whether something is a power of b?
To understand recursion, you need first to understand recursion.
def is_power(a, b):
if a < b: # 3 is never a power of 10, right?
return False # prevent recursion
if a == b: # a is always a**1, right?
return True # prevent recursion
else:
return is_power(a / b, b) # recursion!
Note that for integers a / b will give you rounding errors. Make sure you pass floats.
I don't think you have the right implementation. Based on the problem, the is_power function should look something like this:
def is_power(a,b):
if a%b == 0 and is_power(float(a)/float(b), b):
return True
else:
return False
You are answering to the first constraint but not to the second,
You check to see that (a/b)%b == 0 which is a special case of "(a/b) is a power of b".
Therefor the generalization error (try to think of generalizing that specific case.
What you wrote is not a solution to is power of for example you will indicate 12 as a power of 2 since:
12%2 = 0,
(12/2)%2 = 0
But that is clearly wrong.
As others said, think of recursion (or the less preferable looping solution).
I was just working on this question myself, and this is what I came up with.
To write this as a recursive function, you need the recursive part and the trivial part. For the recursive part, a number is the power of another number if:
((a%b)==0) and (is_power(a/b, b) # a is evenly divisible by b and a/b is also a power of b.
For the trivial case, b is a power of a if a=b.
However, we're not done. Because we are dividing by b, we have to make an exception for when b is zero.
And the other exception is when b = 1. Since when b=1, a/b is a, we will end up with infinite recursion.
So, putting it all together:
def is_power(a,b):
# trivial case
if (a==b): return True
# Exception Handling
if (b==0) or (b==1): return False # unless a==b==0 or a==b==1, which are handled by the trivial case above
# recursive case
return ((a%b)==0) and (is_power(a/b,b))
This example should fix your problem :
def is_power(a,b):
if a == 1:
return True
elif a%b == 0 and is_power(a/b, b) == True:
return True
else:
return False
You can use log.
import math
def is_power(a, b):
return math.log(a, b) % 1 == 0
I hope that this works, this one worked fine for me.
import math # I will use the math module for the next function
def is_power (a, b):
if b == 1 and a!= 1:
return False
if b == 1 and a == 1:
return True
if b == 0 and a!= 1:
return False
power = int (math.log(a, b) + 0.5)
return b ** power == a
Your solution is correct however you just need to remove ALL of the parenthesis in your if statement.
def ab(a, b):
c = b/a
if a%b == 0 and c%b == 0:
return True
else:
return False
print (ab(32, 2))

Categories