Think python exercise 6.4 - python

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. Note: you will have to think about the base case.
I found this peace of code as it's solution:
def is_power(a,b):
if (a % b == 0):
return True
if (a/b == 1):
return True
else:
(is_power (a/b, b) )
else:
return False
But I guess some lines are not necessary. Here is my own code:
def is_power(a,b):
if (a % b == 0):
return True
else:
return False
What is the reason of existence of extra lines?
Both codes don't work for float numbers such as is_power(2.25, 1.5). Both, return False.

To answer part-1 of your question I have to remind you that the question here doesn't ask you to check whether a is divisible by b, but rather it requires you to find out if 'a' can be expressed as (+ve) exponential of 'b' i.e. a = b^n
As for part-2 of your question consider the function below, as it works for both integral & floating point inputs.
def is_power(a,b):
if a==b:
return True
elif (abs(a)>1 and abs(b)>1) or (abs(a)<1 and abs(b)<1):
return is_power(a/b, b)
return False
The second conditional statement arises from the fact that +ve exponents of any number with an absolute value greater(or less) than 1 will always be greater(or less) than 1. If absolute values of 'a' & 'b' lie on either side of unity then you can never find a +ve exponent such that a = b^n
The above function also takes care of the situation when either 'a' or 'b' is 1. In neither of these situations will you be able to find a +ve exponent 'n' such that a = b^n.

your second code is not correct, take the example of 6 and two your function will return true, but 6 is not a power of two .
def is_power(a, b):
while a % b == 0:
if a == b: return True
a /= b
return False
print(is_power(6, 2))
print(is_power(8, 2))
for the second example, comparing if two doubles are equal is usually done to a given magnitude like given eps = 0.0000001
a == b => abs(a - b) < eps .

#mehdi maick thanks for your correct answer. Here's recursive version, by help of your answer, which I was looking for.
def is_power2(a, b):
if a % b == 0 :
if a == b:
return True
else:
return is_power(a/b, b)
return False

helper Function
def is_divisible(a, b):
if a % b == 0:
return True
else:
return False
main Function
def is_power(a, b):
if a == b:
return True
elif b == 1:
return False
else:
return is_divisible(a,b) and is_power(a/b, b)
TEST CASES
print("is_power({0},{1}) returns: {2} ".format(10,2,is_power(10,2)))
print("is_power({0},{1}) returns: {2} ".format(27,3,is_power(27,3)))
print("is_power({0},{1}) returns: {2} ".format(1,1,is_power(1,1)))
print("is_power({0},{1}) returns: {2} ".format(10,1,is_power(10,1)))
print("is_power({0},{1}) returns: {2} ".format(3,3,is_power(3,3)))
Outputs
is_power(10,2) returns: False
is_power(27,3) returns: True
is_power(1,1) returns: True
is_power(10,1) returns: False
is_power(3,3) returns: True

What is the reason of existence of extra lines?
The question asks you to think about "Edge Cases". This part of the code "if (a/b == 1)" is handling an edge case.
Also, the question says "True if a is a power of b". By removing the else part of the loop, you are avoiding this from happening.

We can concise this code even more by simple mentioning the conditions with return function.
As conditions themselves are boolean, we can get a simple True or False:
def is_divisible(a,b):
return a%b==0 and (a/b)%b==0
print(is_divisible(121,11))

def is_divisible(x, y):
return x % y == 0
def is_power(a, b):
if a == 1: #every positive integer that has an exponent of 0 is a power of "1".
return True
elif is_divisible(a, b): #a is divisible by b
if a == b: #see explanation below
return True
elif b == 1 and a != 1: #the only positive integer that is a power of "1" is "1" itself
return False
else:
return is_power(a/b, b) #a/b is a power of b
return False
# Conditional if a == b, is a safeguard to avoid a/b < b as a result of recursion.
# e.g. a=4, b=2.
# First iteration. 4 % 2 == 0 is True. Then is_power( 4/2, 2 )
# Second iteration 2 % 2 == 0 is True. Then is_power ( 2/2, 2 ).
# Third iteration 1 % 2 == 0 is False.
# 4 is a power of 2. Without this conditional it would mistakenly return false.
print("is_power(10, 2) returns: ", is_power(10, 2))
print("is_power(27, 3) returns: ", is_power(27, 3))
print("is_power(1, 1) returns: ", is_power(1, 1))
print("is_power(10, 1) returns: ", is_power(10, 1))
print("is_power(3, 3) returns: ", is_power(3, 3))

#with edge conditions and negative value of a and b.
def is_power (a,b):
if a==1 or a==b: #always true for power of 0, always true for power of 1
return True
elif (a==0 or b==0 or b==1) or (b>a and b>0):
return False
else:
if a%b == 0 and is_power (a/b,b):
return True
else:
return False
Test Cases:
is_power(0, 0) returns: True
is_power(1, 0) returns: True
is_power(0, 1) returns: False
is_power(1, 1) returns: True
is_power(1, 2) returns: True
is_power(2, 1) returns: False
is_power(2, 2) returns: True
is_power(3, 2) returns: False
is_power(4, 2) returns: True
is_power(5, 2) returns: False
is_power(6, 2) returns: False
is_power(7, 2) returns: False
is_power(8, 2) returns: True
is_power(9, 2) returns: False
is_power(10, 2) returns: False
is_power(-1, 0) returns: False
is_power(-1, -1) returns: True
is_power(1, -1) returns: True
is_power(0, -1) returns: False
is_power(-4, 2) returns: False
is_power(-8, 2) returns: False
is_power(4, -2) returns: True
is_power(8, -2) returns: False
is_power(-4, -2) returns: False
is_power(-8, -2) returns: True
is_power(-2, -2) returns: True
is_power(-2, -4) returns: False
is_power(-2, -8) returns: False

Try this code, but remember it will only work for integers not floating point numbers:
def is_power(a,b):
if a==b:
return True
if a%b != 0:
return False
return is_power(a/b,b)
Also, the code you are using will not just hold true for exponentials but every multiple of 'b'

Related

A problem in python odd or even function. Returning True is not working

def is_even(x) :
while x:
if x==0:
return True
elif x==1:
return False
x-=2
print(is_even(5))
print(is_even(6))
output
False
None
If the x==0 is replace with x==2 it works fine. Please explain why returning True is not working for x==0.
In the last iteration, x is reduced to 0 so the while loop is not entered, and the function is terminated. Since it doesn't explicitly return anything, it implicitly returns None, which is a false-y.
You could use a single if inside the while loop and use the while's condiiton itself to indicate an even number:
def is_even(x) :
while x:
if x==1:
return False
x-=2
return True
If x = 0, then you fail your whilecheck and break out of the loop before you can check if x==0: return True.
You should instead use the modulo function, which returns the remainder of division.
3 % 2 == 1 # Odds
5 % 2 == 1
7 % 2 == 1
2 % 2 == 0 # Evens
4 % 2 == 0
6 % 2 == 0
Because when x == 0 it fails your while x check (0 is not truthy), so it exits the loop before it checks your condition again.
BTW the normal way to check parity is with the modulus (%) operator.
x % 2 == 0 # is_even
x % 2 != 0 # is_odd
If you use x as a condition while x that condition will be False if x equals 0.
The correct way should be:
def is_even(x):
while True:
if x==0:
return True
elif x==1:
return False
x-=2
Obviously this is a very weird way to check if a number is even, you can do:
def is_even(x):
return not bool(x%2)
In Python, integers have True and False values. Any integer that is not 0, will always evaluate True, and 0 will evaluate False.
In your code you are using a while loop, which only runs if the subsequent statement evaluates True. When you check while x, if the value of x is 0 (due to the calculation inside the loop), your statement will be the same as while False, which will not run the code inside.
To avoid this issue you can use the modulo operation, which gives you the remainder of an operation. Hence, x % 2 will return 0, if x is even, and 1 if it is odd. You can make a check on that and return the correct value in fewer lines, using fewer operations.
return (x % 2 == 0)
The above statement will return True if there is no remainder, and False if there is.
This should work
def is_even(x):
while x>=0:
if x == 0:
return True
elif x == 1:
return False
x -= 2
print(is_even(5))
print(is_even(6))
in your code the loop terminates when x reaches 0, put a condition such that the loop runs even when x is 0
cheers

Prime number function returns true instead of false

I'm currently learning Python with Codecademy. I am on exercise 6 called "is_prime". I wrote the function step by step from the instructions, but it returns True instead of False. Why?
Instructions:
My code:
def is_prime(x): # step 1
for n in range(2,x-1): # step 2
if (x % n) == 0: # step 3
return False
else: # step 4
return True
Error: Your function fails on is_prime(0). It returns True when it should return False.
The for loop never runs, because range(2, 0-1) is empty. This means that the else block executes (think of for/else as for/nobreak) which returns True.
First of all: the else statement is completely useless, you can simply remove it.
Beside, what's contained in the for loop doesn't run when you pass 0, 1 or 2 as a parameter because the loop starts from 2 and ends at the parameter's value - 1.
To get your function working you can change it as follows:
def is_prime(x):
for n in range(2,x-1):
if (x%n) == 0:
return False
return (True if x>1 else False)
Dave
for 0 you should have extra if condition
def is_prime(x): # step 1
if(x==0 or x==1):
return False
for n in range(2,x-1): # step 2
if (x % n) == 0: # step 3
return False
else: # step 4
return True
The following code should do what you want...
0 and 1 are never prime, so should always return False.
The number 2 should return True, but won't fit conveniently in the range() function, as described by other commenters.
def is_prime(x): # step 1
if x == 0 or x == 1:
return False
elif x == 2:
return True
for n in range(2,x-1): # step 2
if x % n == 0: # step 3
return False
else: # step 4
return True

Write a function that tests if a number is divisible by n

def div(num1,num2):
n = 0
while n > 0:
if num1%n == 0 and num2%n==0:
print(True)
n+=1
else:
print(False)
This is probably wrong though.
EDIT:
def div(num1,num2):
if num1%num2==0:
return True
else:
return False
this question is good use for ternary return
def div(number, n):
# check if denominator is zero or modulo not 0
return False if ((n==0) or (number%n!=0)) else True
print div(10,0),div(0,10),div(2,10),div(10,2)
>>>False True False True
possible duplicate
How do you check whether a number is divisible by another number (Python)?

Checking Powers of Four - Edge Case

Disclosure: This question is from codewars.
Write a method that returns true if a given parameter is a power of 4, and false if it's not. If parameter is not an Integer (eg String, Array) method should return false as well.
I cannot for the life of me figure out what edge case I'm missing. Both code samples produce the same error that 'True should equal False' for some test. (I tried it two ways when the first didn't work, since I was positive the second would.)
def powerof4(n):
if n <= 0 or not isinstance(n, int): return False
else:
while (n != 1):
if (n%4 != 0): return False
else: n = n/4
return True
and
import math
def powerof4(n):
if ((not isinstance(n, int)) or n&(n-1) != 0 or n == 0):
return False
#Now, I cheat, since 4^n = (2^n)^2
reduce_to_2 = math.sqrt(n)
if math.floor(reduce_to_2) != reduce_to_2:
return False
else:
reduce_to_2 = int(reduce_to_2)
return reduce_to_2&(reduce_to_2 - 1) == 0
Your first problem is that you are checking if the type of the argument is int but starting with numbers larger than 2^32 thats not true for Python 2 which codewars is using.
The next error is if you print the value at codewars at which the test fails you see it's for the call powerof4(True). isinstance(True, (int,long)) is True because bool is a subclass of int.
In your first code change your typecheck to
if n <= 0 or type(n) not in (int,long): return False
To add another variation on the problem. When I solved this problem initially some time ago I did it with some bit fiddling :)
def powerof4(n):
if type(n) not in (int, long):
return False
bin_repr = bin(n)[2:]
return bin_repr[0]=="1" and bin_repr.count("0")%2==0 and bin_repr.count("1")==1
There's an easier way.
import math
def powerof4(n):
return math.log(n, 4) % 1 == 0
There is one less obvious gotcha. In Python 2 the number could be too big to fit in an int and it would be a long instead:
>>> isinstance(1000000000000000000000000000000, int)
False
whereas Python 3 would return
>>> isinstance(1000000000000000000000000000000, int)
True
The easiest algorithm on any CPython (*except for the isinstance check) could be
def powerof4(n):
if n <= 0 or not isinstance(n, (int, long)):
return False
return hex(n).rstrip('0') in ('0x1', '0x4')
This converts the number into hex, and removes trailing zeroes; a number is a power of 4 if and only if the hex representation is 1 or 4 followed by any number of zeroes. (hint: it would be a power of 16 if it were 1 followed by zeroes).
With bitwise logic:
test = 1
while n < test:
test <<= 2
return n == test
In Python 2.7 and 3.3+ this is even easier, no loop needed:
b = n.bit_length()
return bool(b & 1) and 1 << (b - 1) == n
Like this?
def isPowerOf4(n):
try:
while n:
if n==1:
return True
if ((n>>2)<<2) != n:
return False
n >>= 2
except:
return False
return False

Python function, odd, that takes in one number and returns True

Here is condition.
Write a Python function, odd, that takes in one number and returns True when the number is odd and False otherwise.
Condition is x: int or float.
and returns: True if x is odd, Falae otherwise
My code is
def odd(x):
while x % 2 != 0:
return (x % 2 == 1)
When if odd(62) above code is works, but odd(62) output is None. How can I correct False answer?
Please Help me.
Your function doesn't return anything if the number is not odd. You don't need a while loop at all:
>>> def odd(x):
... return x % 2 != 0
...
>>> odd(62)
False
>>> odd(63)
True
Also see other ways to check if the number is odd or not:
How to determine if an integer is even or odd
You don't want to use a while loop, a simple if will do it. The reason you get none is because the while loop doesn't run in the "even" condition so there is no return.
An even simpler way of writing it is to return the condition itself:
def odd(x):
return x % 2 == 1
The while loop is messing it up.
def odd(x):
return x % 2 == 1
return (x % 2 != 0)
This will return a boolean value; evaluates True if number is odd and False otherwise.
def odd(x):
'''
x: int
returns: True if x is odd, False otherwise
'''
while x%2 != 0:
return True
else:
return False

Categories

Resources