Update: Once I don't know 3 %4 =0 ...
def gcd(a, b):
"""Calculate the Greatest Common Divisor of a and b.
Unless b==0, the result will have the same sign as b (so that when
b is divided by it, the result comes out positive).
"""
while b:
a, b = b, a%b
return a
I think it works like this:
gcd(3,4) => while 4: => 3,4 = 4, 3%4 =>
Let's walk through this step-by-step.
def gcd(a, b):
This defines a new function gcd which uses the variables a and b in its calculations. These values must be set before the function begins.
while b:
Unless a number is equivalent to 0, it is thought of as true. So, if b = 0, then this part of the code will not execute.
a, b = b, a%b
For clarity, I am going to expand this to two lines.
a = b
b = a%b
The first part is rather self explanatory - the second is decidedly not. a%b is a python expression for a (mod b) Modulo's are mathematical functions which, at their most basic state, return the remainder of two numbers. For instance, 12%5 = 2; the remainder of 12/5is 2.
When writing the actual code though, make sure to keep them on the same line. "In one line the assignments happen at the same time (courtesy of tuple packing and unpacking). In two lines the assignments happen one after the other, which gives an incorrect answer (b will always be 0)" - Tim
Those lines repeat indefinitely until the variable b is equivalent to 0. After that, the code executes this:
return a
That returns the value a to the rest of the program, so that it can be used later on. It also ends the function.
To read more about Euclid's Equation (And... since I love cryptography and math, the 'Extended' edition) go to this Wikipedia page.
I hope that this was helpful!
Here is a recursive version of the gcd function.
def gcd(a, b):
c = a%b
if c == 0:
return b
return gcd(b, c)
Related
I have the following code, which i know to be wrong and also know what exactly is wrong, lack of 'return' before both iterative calls:
alpha = 546
beta = 66
def Euclid(a, b):
while not (a == 0 or b == 0):
if a >= b:
Euclid(a % b, b)
else:
Euclid(a, b % a)
return max(a, b)
print(Euclid(alpha, beta))
My question is why does the code above not still work? I viewed it in code visualiser, and it shows that the last value it returns is indeed max(a,b), so GCD, but then after the function keeps executing the code forever, going from arguments of (6,12) to (6,0), and then starting all over again with (6,12), after returning (6,0). Would just like to know what exactly is happening, since i thought function always quits after the last return.
Let's take a look at your Euclid function and try to understand what happens line by line (and also pay close attention to the values of the variables):
def Euclid(a, b):
while not (a == 0 or b == 0):
if a >= b:
Euclid(a % b, b)
else:
Euclid(a, b % a)
return max(a, b)
You call it with a = 546 and b = 66. (a=546 and b=66)
You enter the while loop because a!=0 and b!=0 (a=546 and b=66)
Since a>=b you call the Euclid function with a%b and b (a=546 and b=66)
You ignore the return value (a=546 and b=66) (actually this call never returns either, but let's assume for now it does)
You go back to the start of your while loop and start again (a=546 and b=66)
The problem is that you never modify the values of a and b, so your while condition will always be true, and your first call of the function never reaches the return.
Ps.: B Remmelzwaal is right about how to fix your code, I only explained what is happening, which makes you get stuck in an infinite loop. Based on his answer the correct code would be:
def Euclid(a, b):
while not (a == 0 or b == 0):
if a >= b:
return Euclid(a % b, b)
else:
return Euclid(a, b % a)
return max(a, b)
Ps2.: To clarify some misunderstanding, the while loop is un necessary in the code, since you would enter only once and return from it. The commands inside the while are never repeated.
The code which reflects better what is happening would be:
def Euclid(a, b):
if a!=0 and b!=0:
if a >= b:
return Euclid(a % b, b)
else:
return Euclid(a, b % a)
return max(a, b)
So in this case when you call the function with a = 546 and b = 66, the following is going to happen:
Euclid(546,66)
Euclid(18,66)
Euclid(18,12)
Euclid(6,12)
Euclid(6,0) --> This is not calling any more Euclids and returns 6
return 6
return 6
return 6
return 6
return 6
So the Euclid(6,0) gives you 6, the Euclid(6,12) returns the return value of Euclid(6,0), which was 6. And so on while you reach back to the Euclid(546,66).
You can imagine it as a matryoshka doll, every outer doll tells you the number which the inner doll told it. In this analogy the smallest inner doll is the Euclid(6,0) and every other doll just repeats it as it proceeds through the layers.
Consider a function getf taking a numpy array a and integer b. I want to return a callable function f such that f has value 0 for a< b and a>b and value 1 for a=b.
Something like
getf(a,b):
if a< b & b>a:
return 0
else:
return 1
does not work.
How do I can ensure that my return value is a function?
Example
a = [1,2,3,4,5]
b=2
return function with result array [0,1,0,0,0]
I don't understand why you need this, but this code defines a function and returns it, which can be called with two keyword arguments.
def getf():
def f(a, b):
return [int(b==i) for i in a]
return f
print(getf()(a = [1,2,3,4,5], b=2))
You need to use vectorial code, not return a scalar. Also, use a numpy array for a.
Finally, your conditions were incorrect (you had twice the same condition). I imagine you want to check if a is greater of equal b and lower or equal b (which is a == b, but let's keep it like this for the sake of the example).
def getf(a,b):
return ((a >= b) & (b >= a)).astype(int)
a = np.array([1,2,3,4,5])
b = 2
getf(a, b)
# array([0, 1, 0, 0, 0])
Here is the code:
def smart_divide(func):
def inner(a,b):
print("I am going to divide",a,"and",b)
if b == 0:
print("Whoops! cannot divide")
else:
return func(a,b)
return inner
#smart_divide
def divide(c,d):
return c/d
divide(5,2)
This is a program to divide two numbers and give an error message if the denominator is 0.
We are passing 5 and 2 as an argument to the function divide. How does inner function know that the value of a and b is 5 and 2 respectively?
According to what I read on internet : #smart_divide means that divide = smart_divide(divide(c,d))
The function divide has parameters c,d while the function inner has parameters a,b. How does the interpreter know that a = c and b = d?
#smart_divide means that
result = smart_divide(divide)(c,d)
That means, divide no points to inner function, and inner function calls the original function divide via func.
divide = smart_divide(divide(c,d)) is not really a good description of what happens. Have a look at the logical expansion step by step, in some kind of pseudo-Python:
divide(x, y)
= smart_divide(lambda c, d: c / d)(x, y)
= inner[func ~> lambda c, d: c / d](x, y)
= (def inner(a,b):
print("I am going to divide",a,"and",b)
if b == 0:
print("Whoops! cannot divide")
else:
return (lambda c, d: c / d)(a, b))(x, y)
= print("I am going to divide",a,"and",b)
if y == 0:
print("Whoops! cannot divide")
else:
return (lambda c, d: c / d)(x, y))
= print("I am going to divide",a,"and",b)
if y == 0:
print("Whoops! cannot divide")
else:
return x / y
The important thing that happens is lexical scoping. If you substitute an expression in another expression (the ~> operation above), then you assume that the names don't get mangled. That is, (lambda a: lambda b: a)(b)) does not become lambda b: b, but (something equivalent to) lambda b_prime: b. Names don't matter: this is called alpha equivalence.
Your understanding of decorators is almost right, this should clarify things.
The code in your example:
#smart_divide
def divide(c,d):
return c/d
Is functionally identical to:
def simple_div(c,d):
return c/d
divide = smart_divide(simple_div)
divide is defined as the inner of the smart_divide decorator.
smart_divide is given simple_div as a parameter (func), which is what inner uses to call the originally decorated simple_div method.
Furthermore: smart_divide can be used to decorate multiple functions because a new inner function is created each time smart_divide is called, so the func reference is different each time.
I have a function, and when it is called, I'd like to know what the return value is going to be assigned to - specifically when it is unpacked as a tuple. So:
a = func() # n = 1
vs.
a, b, c = func() # n = 3
I want to use the value of n in func. There must be some magic with inspect or _getframe that lets me do this. Any ideas?
Disclaimer (because this seems to be neccessary nowadays): I know this is funky, and bad practice, and shouldn't be used in production code. It actually looks like something I'd expect in Perl. I'm not looking for a different way to solve my supposed "actual" problem, but I'm curious how to achive what I asked for above. One cool usage of this trick would be:
ONE, TWO, THREE = count()
ONE, TWO, THREE, FOUR = count()
with
def count():
n = get_return_count()
if not n:
return
return range(n)
Adapted from http://code.activestate.com/recipes/284742-finding-out-the-number-of-values-the-caller-is-exp/:
import inspect
import dis
def expecting(offset=0):
"""Return how many values the caller is expecting"""
f = inspect.currentframe().f_back.f_back
i = f.f_lasti + offset
bytecode = f.f_code.co_code
instruction = ord(bytecode[i])
if instruction == dis.opmap['UNPACK_SEQUENCE']:
return ord(bytecode[i + 1])
elif instruction == dis.opmap['POP_TOP']:
return 0
else:
return 1
def count():
# offset = 3 bytecodes from the call op to the unpack op
return range(expecting(offset=3))
Or as an object that can detect when it is unpacked:
class count(object):
def __iter__(self):
# offset = 0 because we are at the unpack op
return iter(range(expecting(offset=0)))
There is little magic about how Python does this.
Simply put, if you use more than one target name on the left-hand side, the right-hand expression must return a sequence of matching length.
Functions that return more than one value really just return one tuple. That is a standard Python structure, a sequence of a certain length. You can measure that length:
retval = func()
print len(retval)
Assignment unpacking is determined at compile time, you cannot dynamically add more arguments on the left-hand side to suit the function you are calling.
Python 3 lets you use a splat syntax, a wildcard, for capturing the remainder of a unpacked assignment:
a, b, *c = func()
c will now be a list with any remaining values beyond the first 2:
>>> def func(*a): return a
...
>>> a, b, *c = func(1, 2)
>>> a, b, c
(1, 2, [])
>>> a, b, *c = func(1, 2, 3)
>>> a, b, c
(1, 2, [3])
>>> a, b, *c = func(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: need more than 1 value to unpack
I just recently started programming in Python and I've been trying to create a simple function that takes two parameters, a and b, and returns the result of the sum of a and |b|. I want to return f(a, b) and not just f. I know that I'm assigning f to be an int in my current code and so it returns "int not callable error" when I run. So I have to assign f to be a function of some sort. I'm fairly certain I'm missing something fundamental here, I'm just not sure exactly what. Thanks for any help!
from operator import add, sub
def a_plus_abs_b(a, b):
"""Return a+abs(b), but without calling abs.
>>> a_plus_abs_b(2, 3)
5
>>> a_plus_abs_b(2, -3)
5
"""
if b < 0:
f = sub(a, b)
else:
f = add(a, b)
return f(a, b)
f = sub(a, b)
doesn't create a function it computes the result, so when you're calling f(a, b) you're calling an integer.
To fix it, assign the function in-line with a ternary to select which function to create depending on the sign of b
f = sub if b < 0 else add
Jean-Fançois's answer is great, but if you're not understanding the fundamentals behind this, you should look into another example that uses lambdas:
def returns_function_example():
return lambda arg1: arg1 + 2
function_returned = returns_function_example()
print(function_returned(1))
# Output = 3
Run this in your debugger to see that "function_returned" in indeed a function. You can connect the dots after the "print" function is called.
Functions are first-class citizens in Pythonland, so that you can manipulate them as any other object.
Suppose you create your function:
def add(a, b): return a + b
If you write add, that's a function. But if you write add(2,4), or add(a, b) assuming that a and b are defined, then you are calling the function, so you get a result. These are two completely different things: there is f, a callable, and f(a,b) which returns a value.
So if you write:
>>> f = add
>>> type(f)
<class 'function'>
That's what you want, you now have a function that does exactly what add does (and you could say it actually is add).
By contrast, if you write:
>>> f = add(a,b)
>>> type(f)
<class 'int'>
>>> f
11
That's a value.
So to make a long story short:
from operator import add, sub
def a_plus_abs_b(a, b):
"""
Return a+abs(b), but without calling abs.
>>> a_plus_abs_b(2, 3)
5
>>> a_plus_abs_b(2, -3)
5
"""
if b < 0:
f = sub
else:
f = add
return f(a, b)