I wrote a function:
# given a n x m grid return how many different ways there are to move from top left to
# bottom right by only being able to move right or down
def grid(n, m, memo = {}):
if f'{n},{m}' in memo:
return memo[f'{n},{m}']
if n == 1 and m == 1:
return 1
if n == 0 or m == 0:
return 0
memo[f'{n},{m}'] = grid(n,m-1,) + grid(n-1,m)
return grid(n,m-1,) + grid(n-1,m)
Recently I read a bit about short-circuiting in Python and I am trying to understand it further.
As I understand it does not provide any boost in runtime, just sort of syntax sugar.
For example:
1 < 2 < 3 # is True
1 < 2 and 2 < 3 # is also True
# hence
(1 < 2 < 3) == 1 < 2 and 2 < 3 # is True
I was wondering can I write my function with this kind of short-circuiting in my if statements?
I came up with this:
def grid(n, m, memo = {}):
if f'{n},{m}' in memo:
return memo[f'{n},{m}']
if (n or m) == 1:
return 1
if (n and m) == 0:
return 0
memo[f'{n},{m}'] = grid(n,m-1,) + grid(n-1,m)
return grid(n,m-1,) + grid(n-1,m)
Is there any smarter way of using the short-circuit here?
(1 < 2 < 3) is not short-circuiting - I think you misunderstood the meaning of the term. You are correct that it is merely syntax sugar - although it can produce some very weird results in obscure cases. (1 < 2 < 3) expands to (1 < 2) and (2 < 3) - the middle operand is copied to both and and is used for the joining operator.
Short circuiting occurs when python already knows the answer to a boolean expression, even before calculating both the inputs. For example
def false():
print("false")
return False
def true():
print("true")
return True
print(false() and true())
The output would be
false
False
Because when python sees False and, it already knows that the result is False (because and requires both operands to be True), so it doesn't bother running the second half of the line.
This real short circuiting does result in a performance boost, but since you can't turn off short circuiting, it doesn't really matter ¯\_(ツ)_/¯
if (n or m) == 1 is definitely not the same thing as if n == 1 or m == 1. The first if statement is equivalent to:
value = n
if not value:
value = m
if value == 1:
# do something:
Or expressed more succinctly:
if (n if n else m) == 1:
# do something
In other words, n or m only evaluates m if n is False (or 0 if n is an integer), otherwise the result of the expression is n.
What you want to avoid redundancy is:
if 1 in (n, m): # equivalent to: if 1 is either n or m:
Update: Demo
n = 4
m = 1
if (n or m) == 1:
print('if branch taken')
else:
print('else branch taken')
Prints:
else branch taken
if (n or m) == 1
evaluates to
if (<bool>) == 1 # e.g. if {True,False} == 1
which is probably not what you want, since it is essentially evaluating the truthiness of n or m.
Your existing code already captures the nature of short-circuiting;
if n == 1 and m == 1
will only evaluate the second argument m == 1 iff n == 1, or will otherwise short-circuit.
To your comment
As I understand it does not provide any boost in runtime, just sort of syntax suggar.
Well, actually it does provide a runtime boost if Python is able to skip evaluating what would otherwise be "expensive" conditions to evaluate because it is able to short-circuit early.
I am pretty new to Python and just got started in Leet and I am doing the Happy Number question, only half of the test cases have been passed. I would appreciate any help. Thanks
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
My test cases were 19, 100 where it output True correctly but when I do 7, it is wrong
def isHappy(self, n: int) -> bool:
if (n == 1):
return True
sum = 0
flag = False
for j in range(1,100):
x = str(n)
a = list(x)
for i in range(0,len(a)):
sum += int(a[i])*int(a[i])
if sum == 1:
return True
break
else:
x = sum
return False
Here is an implementation using a set to keep track of numbers that we have already seen. (I've removed the self argument here for sake of something that can be run outside of your test class.)
def isHappy(n: int) -> bool:
seen = set()
while True:
if n == 1:
return True
if n in seen:
return False
seen.add(n)
n = sum(int(c) ** 2 for c in str(n))
Your code has various issues aside from the fact that the number 100 is arbitrary.
Mainly that you never update n in your loop. Also you do not wait for the completion of the for loop before testing sum (in fact your break is never reached), you initialise sum only once, and you return False prematurely. Here is a minimally corrected version of your code, although still subject to the fact that there is no rule about 100 maximum iterations.
def isHappy(n: int) -> bool:
if (n == 1):
return True
for j in range(1,100):
x = str(n)
a = list(x)
sum = 0
for i in range(0,len(a)):
sum += int(a[i])*int(a[i])
if sum == 1:
return True
else:
n = sum
return False
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'
def is_prime(x):
x = abs(x)
if x == 0 or x == 1:
return False
elif x == 2:
return True
for i in range(2, x):
if x%i == 0:
return False
return True
The tester says the above code shouldn't return true for x = -7.
Please help.
Thank you :)
**Edit: **
im so sorry, just read somewhere that any number less than 2 (i.e 0, 1 and all negative numbers are not prime
It does return True for me. Check the value of x after you call abs(x), it will maybe help.
It does return True for negative numbers for me.
Also you can run the loop from 2 to x/2 and reduce the complexity.
My Python is not good, but something like this should work better:
def is_prime(x):
# Handle 1, 0 and negatives.
if x < 2:
return False
# Handle even numbers.
elif x % 2 == 0:
return x == 2
# Test with odd divisors.
for i in range(3, sqrt(x), 2):
if x % i == 0:
return False
return True
The sqrt(x) limit is a big time saver, and dealing with even numbers separately can halve the time with well mixed inputs.
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