Get function arguments value by pointer to this function? - python

I'd like to get value of function arguments by pointer to that function.
def cons(a, b):
def pair(f):
return f(a, b)
return pair
def car(cons):
# local_a = cons.a
# return local_a
pass
if __name__ == '__main__':
assert car(cons(3, 4)) == 3

You're on the wrong track. Looking at the code in the new version of your question, you're trying to extract the first element of a Church pair.
cons(3, 4) evaluates to a function that, when passed another function f, returns f(3, 4). To extract the 3, you should pass it a function that takes two arguments and returns its first argument:
def car(pair):
def firstarg(x, y):
return x
return pair(firstarg)
Then car(cons(3, 4)) calls cons(3, 4)(firstarg), which calls firstarg(3, 4), which returns 3.

Creating a Signature for the function is easy via the signature function:
from inspect import signature
def someMethod(self, arg1, kwarg1=None):
pass
sig = signature(someMethod)
Now, you can either view its parameters quickly by string it:
str(sig) # returns: '(self, arg1, kwarg1=None)'
or you can also get a mapping of attribute names to parameter objects via sig.parameters.
params = sig.parameters
print(params['kwarg1']) # prints: kwarg1=20
Additionally, you can call len on sig.parameters to also see the number of arguments this function requires:
print(len(params)) # 3
Each entry in the params mapping is actually a Parameter object that has further attributes making your life easier. For example, grabbing a parameter and viewing its default value is now easily performed with:
kwarg1 = params['kwarg1']
kwarg1.default # returns: None
similarly for the rest of the objects contained in parameters.

Related

Higher order function fixes parameters. Make it fix two parameters as equal

Mock version of the problem
For a function
def f(a,b,c):
return a+b+c
The function
def fix(func, **kwargs):
fa = kwargs.get('a')
fb = kwargs.get('b')
if fa is not None and fb is not None:
def f(*args):
return func(a=fa, b=fb, c=args[0])
elif fa is not None:
def f(*args):
return func(a=fa, b=args[0], c=args[1])
elif fb is not None:
def f(*args):
return func(a=args[0],b=fb, c=args[1])
else:
def f(*args):
return func(args)
return f
allows to obtain a new function by fixing some of the parameters of func.
For example: fix(g, b=3) would give us a function like
def fixed_b_in_g(a,c):
return g(a,3,c)
Question: I would like to see if there is some trick to use fix in such a way that produces a function like
def fix_a_equal_b_in_g(a,c):
return g(a,a,c)
Concrete problem
The function scipy.stats.rv_continuous.fit allows to fit parameters of a distribution to an input sample. It allows to input some keyword arguments (like fix above does) to tell it to keep some of the parameters fixed to values that the user inputs. Internally scipy.stats.rv_continuous.fit has a function, scipy.stats.rv_continuous._reduce_func, that does more or less what dix does (better implemented than my fix for example).
In my case, rather than fixing some parameters to values, I would like to fit to keep two parameters (say a and b) equal to each other, but still free during the fitting.
We can use this function to copy a keyword argument whose name is base_kwarg_name to added_kwarg_name:
def with_copied_kwargs(func, added_kwarg_names_by_base):
def fixed_func(*args, **base_kwargs):
added_kwargs = {
added_kwarg_name: base_kwargs[base_kwarg_name]
for base_kwarg_name, added_kwarg_name in added_kwarg_names_by_base.items()
}
return func(*args, **base_kwargs, **added_kwargs)
return fixed_func
Given:
def add(*, a, b, c):
return a + b + c
then modified_add = with_copied_kwargs(add, {"b": "c"}) is equivalent to:
def modified_add(*, a, b):
return add(a=a, b=b, c=b)
with_copied_kwargs can then be used along with functools.partial to both both copy keyword arguments and provide values incrementally. modified_add = functools.partial(with_copied_kwargs(add, {"b": "c"}), a=1) is equivalent to:
def modified_add(*, b):
return add(a=1, b=b, c=b)
Note that I add * (see PEP 3102) before all parameters in functions I then apply with_copied_kwargs to because the minute people start using positional arguments, things would get messy. So better to restrict it to keyword-only arguments.

Don't understand the inner function in python

I have this problem:
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 get the function.
It has an inner function and calls an other function in the return. As far as I understood the inner functions is that these functions should depend on the functions above them. In this case on cons(..).
But the function is not using a or b. And why is the function f there? The task is to implement car and cdr, and function f should be given.
So could someone explain me this function? And how could I start with the task?
First of all: Python function objects are first class objects. A def statement results in a new function object, and you can retrieve that object by using the function name:
>>> def foo():
... return 'foo was called'
...
>>> foo
<function foo at 0x11b3d8ae8>
What this means is that you can assign that object to other names too, and you can pass them as parameters to function calls. You can then later on call the function object by adding (...) to the reference:
>>> bar = foo
>>> bar()
'foo was called'
The function name is assigned to in the current namespace. In a module, that's the globals, but in a function such as cons, the name is added as a local. return pair in the cons function then returns the function object pair to the caller.
And function parameters such as f and a and b are also variables; if you pass in a function object as a parameter, then parameter_name(...) will call paramater_name and pass in any arguments in the ... part. f(a, b) calls f and passes in a and b.
The next item to understand are closures; closures are an extra namespace attached to function objects, for variables from a surrounding scope.
In the following example, spam is a name in the closure of the bar function:
>>> def foo():
... spam = 'Vikings'
... def bar():
... return spam
... return bar
...
>>> foo()
<function foo.<locals>.bar at 0x11b44bf28>
>>> foo()()
'Vikings'
Calling foo() returns a new function object; the bar() function inside of foo(). Calling that returned function object produces 'Vikings', the value of the spam variable in the foo function. How did bar() get access to that? Via the closure:
>>> foo().__closure__
(<cell at 0x11b3c05b8: str object at 0x11b469180>,)
>>> foo().__closure__[0].cell_contents
'Vikings'
So nested functions can have access to names from the surrounding scope via closures. (Side note: it's not the value that's stored in a closure, it's the variable. The variable can change over time, and just like other variables accessing the name later will reflect the new value; if spam was changed later on, calling bar() again would return the new value).
Now to your function: cons() creates an inner function pair(), and pair() has access to the parameters a and b via its closure:
>>> def cons(a, b):
... def pair(f):
... return f(a, b)
... return pair
...
>>> cons(42, 81)
<function cons.<locals>.pair at 0x11b46f048>
>>> pair_42_81 = cons(42, 81)
>>> pair_42_81.__closure__
(<cell at 0x11b3c02b8: int object at 0x10f59a750>, <cell at 0x11b3c05b8: int object at 0x10f59ac30>)
>>> pair_42_81.__closure__[0].cell_contents
42
>>> pair_42_81.__closure__[1].cell_contents
81
The pair() function takes a parameter f, and calls that parameter, passing in a and b. Lets see what happens when we pass in print.
print is a function too, it is an object that you can call, and it writes the arguments to the console with spaces in between:
>>> print
<built-in function print>
>>> print('arg1', 'arg2')
arg1 arg2
If you passed that to the pair() function that cons() returns, you can see what f(a, b) does:
>>> pair_42_81(print)
42 81
print, passed to pair(), is assigned to f, and f(a, b) is exactly the same thing as print(a, b).
We can see that print() was called because the values are written out to the console. But you could also create a function that returns a new value. Say you have a function that adds up two numbers, and returns that value:
>>> def add(first, second):
... return first + second
...
>>> add(42, 81)
123
>>> pair_42_81(add)
123
We can call the function directly, and 123 is returned, or we can have pair_42_81() do it for us, and the same result is returned to us. Simple!
All this works because functions are objects and can be passed around like other variables, and because pair_42_81 has a = 42 and c = 81 stored in a closure, and will use those to call a given object f with those two arguments.
Next up are cdr() and car(), which will return either the first or last element of a pair. If cons(a, b) produces pair(f) returning f(a, b), then cdr() and car() must each create a function to pass to pair() that'll extract either a or b.
So create a nested function in each, and have cdr() and car() call pair() with that function. The nested function does the work of picking either a or b, and returns that value. Then return the result of the call to the outside world:
def car(pair):
def return_first(a, b):
return a
return pair(return_first)
def cdr(pair):
def return_last(a, b):
return b
return pair(return_last)
pair(return_first) calls return_first(a, b), a is returned, and car() can return that to the caller:
>>> car(cons(42, 81))
42
and the same applies to pair(return_last), only now b is returned:
>>> cdr(cons(42, 81))
81
You may be interested in the background of these operations; car, cdr and cons come from LISP, where cons a b Constructs a cell with two pointers (explaining the name), and car (meaning Contents of the Address part of the Register number in the IBM 704 instruction set LISP was created on) and cdr (meaning Contents of the Decrement part of the Register number in 704 language) take the first and remainder parts of such a cell. See this Wikipedia article on the names.
This is called a closure. Two basic elements
the pair function knows the values of a and b. They are just like local variables in that respect
the cons function returns a function, not a value. You have to call the result again
So, when you call cons(a, b) you get a function that does something to a and b, only it doesn't know what yet. You have to pass another function for that. Eg
my_f = cons(1, 2)
result = my_f(lambda x, y: x + y)
print(result) # 3
How this is related to your assignment is not very clear. I would only assume that for car, you only want the element a (the head), and for cdr you want the element b (the rest of the list). So, the functions would just return the one argument and ignore the other. Eg
car_f = lambda x, y: x
cdr_f = lambda x, y: y
cons is a function which takes two arguments, a and b and returns a function pair.
The function pair takes a function f as an argument which consumes two arguments.
def cons(a, b):
def pair(f):
return f(a, b)
return pair
f = lambda n, m: n**2 + m**3
car = lambda n, m: n
cdr = lambda n, m: m
print(cons(2, 3)(f))
print(cons(2, 3)(car))
print(cons(2, 3)(cdr))
f returns 31 = 2**2 + 3**3
Note how cons has two times the parenthesis (...) - once, for its own call and another time for the returned functions call.
Please note this answer to be able to call car(cons(2, 3)). You might also be interested in Why would a program use a closure?
I manually converted cons function the Javascript version and then implemented the quiz:
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.
Here is the solution
function cons(a, b) {
function pair(f) {
return f(a, b);
}
return pair;
}
function car(pair) {
return pair((a, b) => a);
};
function cdr(pair) {
return pair((a, b) => b);
};
console.log(car(cons(3,4)));
console.log(cdr(cons(3,4)));
Use lambda expressions
def cons(a, b):
def pair(f):
return f(a, b)
return pair
def car(pair):
return pair(lambda a, b: a)
def cdr(pair):
return pair(lambda a, b: b)

How to call multiple functions as arguments inside another function? [duplicate]

This question already has answers here:
passing functions and its arguments to another function
(3 answers)
Closed 5 years ago.
I am struggling with the below exercise:
Arguments to particular functions should be passed to function_results_sum as keywords argumentsand it should look like FUNCTION_NAME=ARGUMENTS
The function_results_sum should return sum of all the results received after running each passing function with arguments
If the function has no arguments, the arguments shouldn't be passed to function_results_sum
If the function takes 1 argument, as keyword argument int will be passed to function_results_sum (for example one_arg_function_name=2)
If function takes more than 1 argument - tuple is expected to be passed (for example two_args_function_name=(1, 2) )
How it should work like:
1st example
functions signatures:
def no_arg()
def one_arg(a)
def multiple_args(a, b, c, e, f)
calling function_results_sum:
function_results_sum(
no_arg, one_arg, multiple_args,
one_arg=23,
multiple_args=(1, 2, 3, 4, 5)
)
2nd example of how to call function_results_sum:
function_results_sum(
no_arg, one_arg, multiple_args,
one_arg=-1245,
multiple_args=(45, 65, 76, 123456, 111.222)
)
! Use name attribute on the function object !
This is what I came up with, however I do not know why I get the result as the addresses of the cells where the outputs are stored:
Console output:
<function ident at 0x00000288C0A72048> <function no_arg at
0x00000288C0A6BF28>
<function mult at 0x00000288C0A720D0>
My implementation:
def function_results_sum(*args, **kwargs):
return [*args]
def no_arg():
return 5
def ident(x):
return x
def mult(x, y):
return x * y
a = function_results_sum(ident, no_arg, mult, ident = 2, mult = (2, 3))
print(a)
Here's a hint that calls the one-argument function:
def function_results_sum(*args, **kwargs):
func = args[0]
function_name = func.__name__
parameter = kwargs[function_name]
return func(parameter)
def ident(x):
return x
a = function_results_sum(ident,ident=2)
print(a)
args will contain a list of the functions to be called, and kwargs contains the list of parameters using the function names as keys. See if you can figure out how to call the three types of functions.

How to define a function that output another function?

I want to define a function that takes some arguments as input, and uses them to make another function, then outputs the new function.
For example:
makeIncrease(n) --> return a function that takes an argument, and return (argument + n)
applyIncrease(increaseFn, m) --> will apply increaseFn to argument m
So if I do this: applyIncrease(makeIncrease(n), m) --> will return m+n
How can I do it in python?
You can read about decorators in Python for more on this. For your specific question:
def applyIncrease(increaseFn, m):
return increaseFn(m)
def makeIncrease(n):
def _innerFn(arg):
return arg + n
return _innerFn
applyIncrease accepts a function and argument, and applies the function to the argument.
makeIncrease accepts an argument n.
Let's say n=2 for the sake of an example. makeIncrease(2) returns a function that takes an argument and adds 2 to it.
Although I began _innerFn with an underscore, this is only a convention - the underscore is not required for the decorator to work.
Note also that functions are first class objects in Python, and that makeIncrease returns _innerFn and not _innerFn(). Return functions exactly as you would variables or object references - no parentheses.
Here are your functions in the interpreter. Note that the object reference wrapped_function refers to _innerFn, i.e. the return value of makeIncrease(2)
>>> wrapped_function = makeIncrease(2)
>>> wrapped_function
<function _innerFn at 0x100496758>
>>> total = applyIncrease(wrapped_function, 3)
>>> total
5
class Example:
def result():
def nestedResult(a,b):
multiply = a*b
return multiply
return nestedResult
if __name__ == "__main__":
x = result()
print "multiplication_result:", x(1,10)

How to unpack a tuple while calling an external method in Python?

I call a method of an external library multiple times in my class like this:
class MyClass:
const_a = "a"
const_b = True
const_c = 1
def push(self, pushee):
with ExternalLibrary.open(self.const_a, self.const_b, self.const_c) as el:
el.push(pushee)
def pop(self):
with ExternalLibrary.open(self.const_a, self.const_b, self.const_c) as el:
return el.pop()
The lines containing the with statement are bugging me, because they require passing the the constants as arguments every time. I would like to store the arguments in a predefined data structure like a tuple and pass that to the external library.
You can do this:
args = (const_a, const_b, const_c)
ExternalLibrary.open(*args)
The * syntax unpacks an iterable (tuple, list, etc.) into individual arguments in a function call. There is also a ** syntax for unpacking a dictionary into keyword arguments:
kwargs = {'foo': 1, 'bar': 2}
func(**kwargs) # same as func(foo=1, bar=2)
You can also use both in the same call, like func(*args, **kwargs).

Categories

Resources