Can anyone explain how this functional program work? - python

def apply_twice(func,arg):
return func(func(arg))
def add_five(x):
return x+5
print (apply_twice(add_five,10))
The output I get is 20.
This one is actually confusing me like how is it working.Can anybody explain me how this is working by breaking it down

The function apply_twice(func,arg) takes two arguments, a function object func and an argument to pass to the function func called arg.
In Python, functions can easily be passed around to other functions as arguments, they are not treated differently than any other argument type (i.e first class citizens).
Inside apply_twice, func is called twice in the line:
func(func(arg))
Which, alternatively, can be viewed in a more friendly way as:
res = func(arg)
func(res)
If you replace func with the name of the function passed in add_five you get the following:
res = add_five(arg) # equals: 15
add_five(res) # result: 20
which, of course, returns your expected result.
The key point to remember from this is that you shouldn't think of functions in Python as some special construct, functions are objects just like ints, listss and everything else is.

Expanding the code it executes as follows, starting with the print call:
apply_twice(add_five,10))
add_five(add_five(10)) # add_five(10) = 15
add_five(15) # add_five(15) = 20
Which gives you the result: 20.
When apply_twice is called, you are passing in a function object and a value. As you can see in the apply_twice definition, where you see func that is substituted with the function object passed to it (in this case, add_five). Then, starting with the inner func(arg) call, evaluate the result, which is then passed to add_five again, in the outer return func( ... ) call.

What you need to understand here is that
apply_twice(func,arg)
is a higher function which accepts two arguments (another function named func and an argument arg). The way it works is that it first evaluate the value of the other function, then use the value as an argument inside the higher function.
remember we have a function add_five(x) which add 5 to the argument supply in it...
then this function add_five(x) is then passed as an argument to another function called
apply_twice_(func,arg) which return func(func(arg)).
now splitting func(func(arg)) we have
func(arg) #lets called it a
then func(func(arg))==func(a) since a = func(agr)
and (a) is our add_five(x) function, after it add 5, then the value we got is re-used as another fresh argument to add another 5 to it, that is why we have 20 as our result.
Another example is:
def test(func, arg):
return func(func(arg))
def mult(x):
return x * x
print(test(mult, 2))
which give 16 as result.

Related

Passing return value to function

I'm having difficulty understanding how to use return values.
def grab_name(string):
return grab("users/self/profile", string)
def print_user_info(arg):
print(grab("users/self/profile", "janice"))
I need to consume the result of passing the first function in order to print the user info. But I'm not sure how to do that...the second function is not supposed to consume a string or call the function directly. I understand the return value doesn't exist outside the scope of the first function so I don't understand how to get the value into the second function without just calling it directly as I have above.
The first function is basically returning a dictionary and the second function needs to consume the result of calling the first function.
I think this small modification is what you are seeking.
def grab_name(string):
return grab("users/self/profile", string)
def print_user_info(arg):
print(grab_name("janice"))
def grab_name(string):
return grab("users/self/profile", string)
def print_user_info(arg):
return "janice"
print(print_user_info(grab_name))
result :
janice

Checking if an optional paramater is specified in a function inside another function

I have a function which has an optional parameter. Call this function func1 with optional argument a which is initially set to None
I want to use this function as an argument to another function call it func2.
Hence, I want a function like:
def func2(func1):
If a is not None:
.......
How would I achieve this?
If you are using func1's handler as an argument (which doesn't have arguments with parenthesis), you can't do this and need to define a as an argument for func2. Like this:
def func2(func1, a=None):
...
If you are using func1's return value, the argument's to func1 are lost when func2 is invoked and again the only solution I can think of is to define a as an argument for func2.
I'm not sure if this is the best way to do it, but to achieve what you desire, you can take advantage of the fact that functions (since they are objects) can be assigned with attributes.
def func(a=None):
func.a = a
print(a)
def func_2(f):
if f.a is not None:
print(f.a)
Note that in order for this to work as you want, you would need to make sure that func was called before func_2
>>> func(1)
1
>>> func_2(func)
1
You can't check what parameter is passed to func1 using this -
def func2(func1):
If a is not None:
.......
In this, You are just passing the func1 to func2 as parameter. Nowhere has it been explicitly specified what parameter func1 will be using. So, You will have to decide what you are going to pass to func1 inside your func2 code.
Maybe you are looking for something like this -
def func2(func1,a=None):
if a != None: # When a non - None parameter is passed
func1(a)
else :
# Something when a is none
Here, you can check what parameter is going to be passed to func1 since during the call to func2, you will have to specify either 1 or 2 arguments. a is set to None by default. If a 2nd parameter is not passed to func2, it means that no parameter for func1 has been given. This means func1 was meant to be called without a parameter ( or using the default set parameter value ).
Or maybe you are looking to do something like this -
def func1(a=None):
func1.a = a
print(a)
def func2(f):
f(2) # Called with a paramter, so f.a will not be None
print(f.a)
f() # Called without a param, so f.a will be None
print(f.a)
func2(func1)
Output :
2
2
None
None
Here, the function object will set the parameter passed to it as its object and then once it called, depending on what the value of func1.a is, you can get what was the value with which the function was called last time. You can modify the above snippet for what you asked in question as -
def func1(a=None):
func1.a = a
def func2(f):
if f.a is not None:
print("Last call with paramter - " + str(f.a))
else :
print("Last Function call was made without a paramter")
func1()
func2(func1)
func1(2)
func2(func1)
Output :
Last Function call was made without a paramter
Last call with paramter - 2
Hope this helps !

Getting inputs to a function from a python object

I have a class. This class has a list of functions that are to be evaluated by a different program.
class SomeClass(object):
def __init__(self, context):
self.functions_to_evaluate = []
There is a function that adds functions to an instance of SomeClass, via something like:
new_function = check_number(5)
SomeClassInstance.functions_to_evaluate.append(new_function)
Where check_number is a function that will check if number is greater than 10, let's say.
If I take SomeClassInstance.functions_to_evaluate and print it, I get a bunch of python objects, like so:
<some_library.check_number object at 0x07B35B90>
I am wondering if it is possible for me to extract the input given to check_number, so something like:
SomeClassInstance.functions_to_evaluate[0].python_feature() that will return "5" or whatever the input to check_number was to me.
You can use the standard library functools.partial, which creates a new partially applied function *.
>>> from functools import partial
>>> def check_number(input):
... return input > 10
>>> fn = partial(check_number, 5)
>>> fn.args # this attribute gives you back the bound arguments, as a tuple.
(5,)
>>> fn() # calls the function with the bound arguments.
False
*: actually the partial object is not a function instance, but it is a callable, and from a duck-type perspective it's a function.
If new_function = check_number(5) is a closure, then you can extract this value using __closure__[0].cell_contents:
Example:
def foo(x):
def inn(y):
return x
return inn
s = foo(5)
print(s.__closure__[0].cell_contents)
Output:
5
I understand your confusion, but:
new_function = check_number(5)
Is calling the function, and the new_function variable gets assigned the return value of the function.
If you have this check_number function:
def check_number(input):
return input > 10
Then it will return False, and new_function will be False. Never <some_library.check_number object at 0x07B35B90>.
If you're getting <some_library.check_number object at 0x07B35B90> then your check_number() function is returning something else.
There are probably several ways to skin this cat. But I'd observe first and foremost that you're not adding python function objects to the functions_to_evaluate list, you're adding the evaluations of functions.
You could simply add a tuple of function, args to the list:
SomeClassInstace.functions_to_evaluate.append((check_number, 5))
And then you can:
for f, args in SomeClassInstance.functions_to_evaluate:
print(args)

Python's lambda with underscore for an argument?

What does the following code do?
a = lambda _:True
From what I read and tested in the interactive prompt, it seems to be a function that returns always True.
Am I understanding this correctly? I hope to understand why an underscore (_) was used as well.
The _ is variable name. Try it.
(This variable name is usually a name for an ignored variable. A placeholder so to speak.)
Python:
>>> l = lambda _: True
>>> l()
<lambda>() missing 1 required positional argument: '_'
>>> l("foo")
True
So this lambda does require one argument. If you want a lambda with no argument that always returns True, do this:
>>> m = lambda: True
>>> m()
True
Underscore is a Python convention to name an unused variable (e.g. static analysis tools does not report it as unused variable). In your case lambda argument is unused, but created object is single-argument function which always returns True. So your lambda is somewhat analogous to Constant Function in math.
it seems to be a function that returns True regardless.
Yes, it is a function (or lambda) that returns True. The underscore, which is usually a placeholder for an ignored variable, is unnecessary in this case.
An example use case for such a function (that does almost nothing):
dd = collections.defaultdict(lambda: True)
When used as the argument to a defaultdict, you can have True as a general default value.
Below is the line of code in question:
a = lambda _:True
It creates a function having one input parameter: _. Underscore is a rather strange choice of variable name, but it is just a variable name. You can use _ anywhere, even when not using lambda functions. For example, instead of....
my_var = 5
print(my_var)
You could write:
_ = 5
print(_)
However, there was a reason that _ was used as the name of parameter name instead of something like x or input. We'll get to that in a moment.
First, we need to know that the lambda-keyword constructs a function, similar to def, but with different syntax. The definition of the lambda function, a = lambda _:True, is similar to writing:
def a(_):
return True
It creates a function named a with an input parameter _, and it returns True. One could have just as easily written a = lambda x:True, with an x instead of an underscore. However, the convention is to use _ as a variable name when we do not intend to use that variable. Consider the following:
for _ in range(1, 11):
print('pear')
Notice that the loop index is never used inside of the loop-body. We simply want the loop to execute a specified number of times. As winklerrr has written, "the variable name _ is [...] like a "throw-away-variable", just a placeholder which is of no use. "
Likewise, with ``a = lambda x:True the input parameter is not used inside the body of the function. It does not really matter what the input argument is, as long as there is one. The author of that lambda-function wrote _ instead of something like x, to indicate that the variable would not be used.
Note that the lambda does have an argument; So, writing
a(), will raise an error.
If you want a lambda with no argument write something like this:
bar = lambda: True
Now calling bar(), with no args, will work just fine.
A lambda which takes no arguments need not always return the same value:
import random
process_fruit = lambda : random.random()
The lambda function above is more complex that just a something which always returns the same constant.
One reason that programmers sometimes us the lambda keyword instead of def is for functions which are especially short and simple. Note that a lambda definition can usually fit all on one line, whereas, it is difficult to do the same with a def statement. Another reason to use lambda instead of def sf when the function will not be used again. If we don't want to call the function again later, then there is no need to give the function a name. For example consider the following code:
def apply_to_each(transform, in_container):
out_container = list()
for idx, item in enumerate(container, 0):
out_container[idx] = transform(item)
return out_container
Now we make the following call:
squares = apply_to_each(lambda x: x**2 range(0, 101))
Notice that lambda x: x**2 is not given a label. This is because we probably won't call it again later, it was just something short and simple we needed temporarily.
The fact that lambda functions need not be given a name is the source of another name to describe them: "anonymous functions."
Also note that lambda-statements are like a function-call in that they return a reference to the function they create. The following is illegal:
apply_to_each(def foo(x): x**2 , range(0, 101))
Whereas, apply_to_each(lambda x: x**2 range(0, 101)) is just fine.
So, we use lambda instead of def and _ instead of a long variable name when we want something short, sweet and probably won't want use again later.
Lambda means a function.
The above statement is same as writing
def f(_):
return True
For lambda a variable needs to be present. So you pass it a variable called _(Similarly you could pass x, y..)
Underscore _ is a valid identifier and is used here as a variable name. It will always return True for the argument passed to the function.
>>>a('123')
True

Python printing a procedure

I am trying to print a procedure in Python. How do I print it?
Here is my code
def proc(a,b):
if test(a):
return b
return a
print proc(a,b)
But I get this error:
NameError: name 'a' is not defined
Thanks in advance.
a is the name of the local variable used to hold the value of the first argument passed to the function when it is called. When actually calling it, you need an actual value, or a variable defined in the scope where the function is called. For example:
def proc(a,b):
if test(a):
return b
return a
x = 6
print proc(x, 7)
Now when proc is called, the value of the variable x and the value 7 are passed to proc. Inside proc, a will have the same value as x (at the time of the call) in the calling scope, and similarly b will have the value 7.
If you're trying to call proc and view the result, then there are two things you need to know:
You call a function by typing its name, followed by a pair of parentheses that contains the function's arguments: proc(23, 42)
You can print the result of an expression by typing print, followed by a pair of parentheses containing the expression: print(4 + 8 * sqrt(15) - 26).
Combine these two principles to view the result of a function call.
print(proc(23, 42))

Categories