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])
Related
So i'm working on the daily coding problems and the one i got today got me stumped.
cons(a, b) constructs a pair, and car(pair) and cdr(pair) returns the
first and last element of that pair. For example, car(cons(3, 4))
returns 3, and cdr(cons(3, 4)) returns 4.
Given this implementation of cons:
def cons(a, b):
def pair(f):
return f(a, b)
return pair
Implement car and cdr.
I don't understand what the "f" represents.
I tried printing the thing i get from that function:
x = cons(3, 4)
<function cons.<locals>.pair at 0x2adc0ec45ae8>
But i still don't understand what it is. Any ideas?
Let's examine cons:
def cons(a, b):
def pair(f):
return f(a, b)
return pair
So calling cons(3, 4) dynamically creates a function as if you statically define it like this :
def pair_3_4(f)
return f(3, 4)
Similarly :
pair1 = cons(2, 6)
pair2 = cons(5, 8)
pair3 = cons("a", "b")
is equivalent to :
def pair1(f)
return f(2, 6)
def pair2(f)
return f(5, 8)
def pair3(f)
return f("a", "b")
Now, let's examine pair:
def pair(f):
return f(a, b)
From this, you can guess that f must be a callable object, and that it takes two arguments. The most simple callable object is a function, so let's say that f is a function.
Also you can see that pair simply calls f with whatever a and b were bound to it by cons.
Here is an example where I use print as the f :
>>> pair_3_4 = cons(3, 4)
>>> pair_3_4(print)
3 4
>>> cons(3, 4)(print)
3 4
>>> print(3, 4)
3 4
I'd like some help clarifying the logic behind this.
from operator import add, sub
def a_plus_abs_b(a, b):
if b < 0:
f = sub # subtract a negative value
else:
f = add # add a positive one
return f(a, b)
I originally thought that I would have to think of some complex mathematical expression to allow this function to work, but someone showed me that just adding sub and add to f allows it to work properly. I'm having difficulty trying seeing how this works, so any clarifying remarks would be greatly appreciated.
Well, the logic itself works because a + abs(b) == a + b when b >= 0 and a + abs(b) == a - b when b < 0. I have commented out your code below.
from operator import add, sub
# two functions are imported:
# add(x,y) -> (x + y)
# sub(x,y) -> (x - y)
def a_plus_abs_b(a, b):
# when b < 0, (a + abs(b)) == (a - b)
if b < 0:
# f is a temporary variable holding the function sub
f = sub
# when b >= 0, (a + abs(b)) == (a + b)
else:
# f is a temporary variable holding the function add
f = add
# apply the arguments to the function determined above
return f(a, b)
However, this function could be written in a single line.
def a_plus_abs_b(a, b):
return a + abs(b)
The interesting thing about your function is that it highlights that functions are first-order objects in Python. This means that they can be passed around and assigned to variables and many other things.
sub is just the name of a reference to a function object that implements subtraction. Like any other reference, you can assign its value to another name, so f = sub simply makes f another name for reference stored in sub. As such, f(a, b) and sub(a, b) both call the same underlying function.
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
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)
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)