Can someone explain why this code of python outputs 30? It seems like add = func ? But how does python knows this without declaring. It's a question in the python course from sololearn.com, a lot of people don't seem to understand
def add(x, y):
return x + y
def do_twice(func, x, y):
return func(func(x, y), func(x, y))
a = 5
b = 10
print(do_twice(add, a, b))
def do_twice(func, x, y):
return func(func(x, y), func(x, y))
when called with add, 5 and 10 will return
add(add(5, 10), add(5, 10))
i.e.
add(15, 15)
which is indeed 30
add has been passed as the first parameter, so is called func inside do_twice. Likewise a is 5 and b is 10.
A is set to 5 and B to 10. This add function simply returns the sum of two inputs.
You call do_twice with the add function, 5, and, 10 as inputs.
First, do_twice evaluates the sum of 5 and 10 in both inner calls of func(x, y). This leaves us with "return func(15, 15)". This adds 15 and 15, yielding 30. Finally, you print out this value. This is why it is 30. Feel free to follow up for any clarifications!
Python don't care what you pass in for func for your function do-twice.
But in the body of your function do_twice you are invoking func passed in i.e You are using func as if it supposed to be a callable(something you can invoke. A function is one such thing.). You can verify it by passing a string to do_twice and you should see an error stating string is not callable or something.
Related
Premise:
Suppose I have a variable x and two function f(x) and g(x)
such that when f(x) has the ability to change the value of x (maybe it wants to keep track on how many times f(x) has been called) and g(x) doesn't want to change the value of x at any cost.
Now if i was choose x as an integer, I can accomplish g(x) and if x is a list, I can accomplish f(x).
Question:
But what if I want to accomplish both of them in the same program?
What should I do then?.
If its not possible, then doesn't this severely handicap python wrt other languages.
Note:
Basically my question is motivated by finding the drawbacks of not having pointers in python as in other language like C++, the above task can easily be implemented by choosing the *x instead of x.
If all you need to do is change the value of a variable that you pass to f, you can simply return the new value:
def f(x):
return x + 1
x = 30
x = f(x)
# x is now 31
If there is already another value you need to return from f, you can return a tuple and unpack the return value to multiple variables:
def f(x):
return 46, x + 1
x = 30
y, x = f(x)
# x is now 31
In C++, the use of pointers that you bring up compensates for the fact that it's relatively difficult to return multiple values from a function. In Python, while we're still technically returning one value, it's much easier to create tuples and unpack them.
You could make your own class:
`class some_class():
self._value = 0
self._access_counter = 0
def update_value(self):
<your code here>
def get_value_by_ref(self):
self._access_counter += 1
return self._value
`
I am new in stackflow. I will so thankful if someone can help me.
I have to resolve this:
Define a nested function called nested_sum, where in the first part of the function you accept an argument called x, and in the second part (the function inside) you take another argument called y. In the function inside you have to calculate the sum of x and y.
To test your function create a variable called res_1 where you pass the x argument to nested_sum, and then create a variable called res_2 where you pass the y argument of the res_1 variable to get the final solution.
Have x equal 2 for res_1 and y equal 10 for res_2.
After looking on the internet I found a similar code, but I don't really understand how it works!
def nested_sum(x):
def in_sum(y):
return x+y
return in_sum
res_1 = nested_sum(2)
res_2 = res_1(10)
Thank you
First of all you need to realise res_1 is simply the in_sum() function.
Therefore as per your code:
nested_sum(2) puts x = 2 and then returns the in_sum() function.
res_2 = res_1(10) = in_sum(10)
Therefore x = 2 and y = 10, so thus
x + y = 2 + 10 = 12
You can write the code (easier to understand) as follows:
def nested_sum(x):
def in_sum(y):
return x+y
return in_sum
res_1 = nested_sum(2) #nested_sum return in_sum(y) location with x=2 so --> res_1= in_sum (2+y)
res_2 = res_1(10) #Cause res_1 points in_sum(2+y) res2=in_sum(2+10)=12
First of all, function in Python is an object. Think of it as a piece of paper where it is written what arguments it needs an what to do with them.
nested_sum(2) creates a new piece of paper where it is writen: «take the 𝑦 argument, add 2 to and return it.»
nested_sum(𝑥) creates a new piece of paper where it is writen: «take the 𝑦 argument, add 𝑥 and return it.»
Let me rename variables in your code:
def increaser_function_maker(x):
def the_new_function(y):
return x + y
return the_new_function
function_that_takes_number_and_adds_two_to_it = increaser_function_maker(2)
result = function_that_takes_number_and_adds_two_to_it(10)
There is another way to make this function. Maybe it will be easier to understand:
def increaser_function_maker(value_to_add):
return lambda i: i + value_to_add
Say I have these two functions:
def s(x,y,z):
if x <= 0:
return y
return z
def f(a,b):
return s(b, a+1, f(a,b-1)+1)
If I were to try and find f(5,2) in my head, it would go like this:
f(5,2) = s(2,6,f(5,1)+1)
f(5,1) = s(1,6,f(5,0)+1)
f(5,0) = s(0,6,f(5,-1)+1) = 6
f(5,1) = 7
f(5,2) = 8
I never evaluate f(5,-1) because it is not needed. The s function is going to return 6, since argument x is zero, thus evaluation of argument z is unnecessary.
If I were however to try and run this in python, it would keep recursing forever or or until I get a maximum recursion depth error, presumably because python wants to evaluate all the arguments before executing the s function.
My question is, how would I go about implementing these functions, or any similar scenario, in such a way that the recursion stops when it is no longer needed? Would it be possible to delay the evaluation of each argument until it is used in the function?
Your mind is working with 'insider knowledge' of how s() works. Python can't, so it can only follow the strict rules that all argument expressions to a call will have to be evaluated before the call can be made.
Python is a highly dynamic language, and at every step of execution, both s and f can be rebound to point to a different object. This means Python can't optimise recursion or inline function logic. It can't hoist the if x <= 0 test out of s() to avoid evaluating the value for z first.
If you as a programmer know the third expression needs to be avoided in certain circumstances, you need to make this optimisation yourself. Either merge the logic in s into f manually:
def f(a, b):
if b <= 0:
return a + 1
return f(a, b - 1) + 1
or postpone evaluating of the third expression until s() has determined if it needs to be calculated at all, by passing in a callable and make s responsible for evaluating it:
def s(x, y, z):
if x <= 0:
return y
return z() # evaluate the value for z late
def f(a, b):
# make the third argument a function so it is not evaluated until called
return s(b, a+1, lambda: f(a, b - 1) + 1)
When a function is called, all arguments are fully evaluated before they're passed to the function. In other words, f(5,-1) is being executed before s is even started.
Fortunately there's an easy way to evaluate expressions on demand: functions. Instead of passing the result of f(a,b-1) to z, pass it a function that computes that result:
def s(x,y,z):
if x <= 0:
return y
return z() # z is a function now
def f(a,b):
return s(b, a+1, lambda:f(a,b-1)+1)
print(f(5,2)) # output: 8
I don't get the second function can someone help me what does the second function do I got this in solo learn Please explain to me in very basic way as I am a beginner and
def add(x, y):
return x + y
def do_twice(func, x, y):
return func(func(x, y), func(x, y))
a = 5
b = 10
print(do_twice(add, a, b))
Python supports higher order programming: you can pass a function as an argument (actually Python does not care about the type when you pass arguments).
So what happens if you call do_twice(add, a, b)? Well you call do_twice with function = add, x = 5 and y = 10. Now we inspect the body of do_twice:
return func(func(x,y),func(x,y))
The Python interpreter will interpret this statement, and first evaluate func(x,y) (the left one). So it calls add(5,10). I assume that you understand how the add function works, so that function returns 15. Next Python evaluates func(x,y) (the right one), so it again calls add(5,10) which evaluates in 15.
Finally it calls func(15,15), since func = add, it thus calls add(15,15) which will result in 30. This is the result that is returned.
If you would have called do_twice with a lambda expression like:
do_twice(lambda x,y: x+2*y,5,10)
the result will thus be: 75. Because (lambda x,y:x+2*y)(5,10) is 25 and (lambda x,y:x+2*y)(25,25) is 75.
You could also write your second function like this:
def do_twice(func, x, y):
val1 = func(x, y)
val2 = func(x, y)
val3 = func(val1 , val2)
return val3
That way you are basically just storing the result of each of the 3 calls to func in a temporary variable (val1, val2, val3).
Now if you call print(do_twice(add, a, b)) with your values 5 and 10 the following happens:
def do_twice(func, x, y):
# x = 5, b = 10
val1 = func(x, y)
# val1 = 5+10 = 15
val2 = func(x, y)
# val2 = 5+10 = 15
val3 = func(val1, val2)
# val3 = 15+15 = 30
return val3
The second simply takes the first function and applies the supplied inputs to it. Such that do_twice takes a function called func. func requires two positional arguments to work an example of a func is add() that requires x and y. so do_twice() takes add() and supplies x and y to it then returns the answer. do_twice is hence returning add(add(x, y), add(x, y))
So here is the the problem
def func_1(x):
print 'function'
def func_2(x,y):
print 'function2'
def func_3():
n=func_1(x)
m=func_2(x,y)
i have 2 functions and i have a third one which needs to use the first 2 , the problem is that i don't know how to make it work . I give the arguments of the first two functions and it gives me an error , tried giving the functions as an argument , but it gives me a syntax error
i also tried of getting rid of the first function , solving the problem with a while cycle like this
counter = 0
while counter<10:
n=func_1(x)
m=func_2(x,y)
but it tells me that tuple object is not callable
If someone could tell me how to do it without defining the first 2 functions inside the third one i would be grateful
You are not passing func_3() any arguments, and still expecting it to know x and y
Also func_1 () and func_2 doen't return anything, so there is no need to do value = func() at func_3()
Try this:
def func_1(x):
print "i'm func1"
print x
def func_2(x,y):
print "i'm func2"
print x, y
def func_3(x, y):
func_1(x)
func_2(x, y)
func_3(1, 2)
It's hard to tell from your question, but it sounds like you are trying to get func3 to use functions passed as arguments? Something like
def func1(x):
return 2*x
def func2(x, y):
return 3*x + 2*y
def func3(x, y, fn1, fn2):
return fn1(x) + fn2(x, y)
def main():
print(5, 8, func1, func2)
if __name__=="__main__":
main()