Python: function arguments and return values - python

Say I have a function
def equals_to(x,y):
a + b = c
def some_function(something):
for i in something:
...
Is there a way to use c that was calculated by equals_to as a parameter for some_function like this
equals_to(1,2)
some_function(c)

You need to return the value of c from the function.
def equals_to(x,y):
c = x + y # c = x + y not a + b = c
return c # return the value of c
def some_function(something):
for i in something:
...
return
sum = equals_to(1,2) # set sum to the return value from the function
some_function(sum) # pass sum to some_function
Also the function signature of equals_to takes the arguments x,y but in the function you use a,b and your assignment was the wrong way round, c takes the value of x + y not a + b equals c.
Strongly recommend: http://docs.python.org/2/tutorial/

Related

How to pass a function as an argument

I would like to find an approximate value for the number pi = 3.14.. by using the Newton method. In order to use it also for some other purpose and thus other function than sin(x), the aim is to implement a generic function that will be passed over as an argument. I have an issue in passing a function as an argument into an other function. I also tried lambda in different variations. The code I am showing below produces the error message: IndexError: list index out of range. I will appreciate your help in solving this issue and eventually make any suggestion in the code which may not be correct. Thanks.
from sympy import *
import numpy as np
import math
x = Symbol('x')
# find the derivative of f
def deriv(f,x):
h = 1e-5
return (lambda x: (f(x+h)-f(x))/h)
def newton(x0,f,err):
A = [x0]
n = 1
while abs(A[n]-A[n-1])<=err:
if n == 1:
y = lambda x0: (math.f(x0))
b = x0-y(x0)/(deriv(y,x0))
A.append(b)
n += 1
else:
k = len(A)
xk = A[k]
y = lambda xk: (math.f(xk))
b = newton(A[k],y,err)-y(newton(A[k],y,err))/deriv(y,k)
A.append(b)
n += 1
return A, A[-1]
print(newton(3,math.sin(3),0.000001))
I don't know why you use sympy because I made it without Symbol
At the beginning you have to calculate second value and append it to list A and later you can calculate abs(A[n]-A[n-1]) (or the same without n: abs(A[-1] - A[-2])) because it needs two values from this list.
Other problem is that it has to check > instead of <=.
If you want to send function sin(x) then you have to use math.sin without () and arguments.
If you want to send function sin(3*x) then you would have to use lambda x: math.sin(3*x)
import math
def deriv(f, x, h=1e-5):
return (f(x+h) - f(x)) / h
def newton(x0, f, err):
A = [x0]
x = A[-1] # get last value
b = x - (f(x) / deriv(f, x)) # calculate new value
A.append(b) # add to list
while abs(A[-1] - A[-2]) > err: # it has to be `>` instead of `<=`
x = A[-1] # get last value
b = x - (f(x) / deriv(f, x)) # calculate new value
A.append(b) # add to list
return A, A[-1]
# sin(x)
print(newton(3, math.sin, 0.000001)) # it needs function's name without `()`
# sin(3*x)
print(newton(3, lambda x:math.sin(3*x), 0.000001))
# sin(3*x) # the same without `lambda`
def function(x):
return math.sin(3*x)
print(newton(3, function, 0.000001))
Result:
([3, 3.1425464414785056, 3.1415926532960112, 3.141592653589793], 3.141592653589793)
([3, 3.150770863559604, 3.1415903295877707, 3.1415926535897936, 3.141592653589793], 3.141592653589793)
EDIT:
You may write loop in newton in different way and it will need <=
def newton(x0, f, err):
A = [x0]
while True:
x = A[-1] # get last value
b = x - (f(x) / deriv(f, x)) # calculate new value
A.append(b) # add to list
if abs(A[-1] - A[-2]) <= err:
break
return A, A[-1]

How to find roots of an equation where a variable is an output from a function, having target variable as an argument itself?

I am trying to solve an equation for variable 'X' in python where some of the variables in the equation ('ABC, PQR') are output from a function 'calculations'. The problem is, in order to get an output from the function, I need to pass variable X as an argument itself. I am kind of stuck in a loop here. I tried two different approaches but didn't get any success. Is there a way I can solve the equation?
Any help/direction is really appreciated.
My first approach is to start with a small value and run a loop. I tried to use math.isclose() but receive 'math bound error' once the values go off the range and it runs into an infinite loop.
The second approach is to write the complete expression and use scipy.optimize fsolve() but I am unable to understand how to properly implement it.
# function
def calculations(X, a, b, c):
ABC = X*a*b + c
XYZ = X*b*c + a
PQR = X*a*c + b
return ABC, XYZ, PQR
# ABC, PQR is the output from a function which uses X as input
# solve for X
func = 2*ABC + sqrt(PQR*ABC) + X*100*0.5
# Approach 1
X = 0.001
step = 0.001
while True:
# function call
Var_ABC, Var_XYZ, Var_PQR = calculations(X, a, b, c)
func = 2*Var_ABC + math.sqrt(Var_PQR * Var_ABC) + X*100*0.5
if (math.isclose(func, 0.0, rel_tol=0.1) == True):
break
else:
X = X + step
# Approach 2
# Since I don't know the value of X, how can I get the output from the function and then solve it again?
func_output[0] = calculations(X, a, b, c) # ABC
func_output[2] = calculations(X, a, b, c) # PQR
func = 2* func_output[0] + math.sqrt (func_output[0] * func_output[2] ) + X*100*0.5
from scipy.optimize import fsolve
desired_output_X = fsolve(func, [0.01, 1])
This may help you getting started with fsolve:
# function of X
def func(X):
func_output = calculations(X, a, b, c)
func = 2* func_output[0] + math.sqrt (func_output[0] * func_output[2]) + X*100*0.5
return func
# extra arguments for calculations function, dummy values used: set them as desired
a,b,c = 1,2,6
# initiating X = 0.01 and solve for X
desired_output_X = fsolve(func, x0 = 0.01)

return function in python

I want to write script to calculate the volume. The first function calculates area of the base. The second takes this value and multiply it with the height. Then I'd like to write the value of the volume. Where is the mistake?
def base_area(a, b):
a = 2
b = 3
s = a * b
return s
def volume(s):
h = 7
V = h * s
print (V)
It doesn't make sense to pass a, b as parameters to base_area() function, because inside, you are assigning constant values to a and b. That method should look like:
def base_area(a, b):
s = a * b
return s
so you use the values passed. This function can be written in a more concise way:
def base_area(a, b):
return a * b
Then the volume() method should receive 3 parameters, a, b and h(height):
def volume(a, b, h):
return base_area(a, b) * h
Here, you are calling base_area() passing a and b. From this call, you get the area, so you multiply it by h and return it.
Test:
print volume(2, 3, 7)
>>> 42

how to set .__name__ in python?

I am trying to solve this exercise:
Return a function that represents the polynomial with these
coefficients.
For example, if coefs=(10, 20, 30), return the function of x that computes
30 * x**2 + 20 * x + 10. Also store the coefs on the .coefs attribute of
the function, and the str of the formula on the .__name__ attribute.
This is my solution:
def poly(coefs):
#write the string name
l=len(coefs)
coefs=reversed(coefs)
j=0
name=""
for i in coefs:
if j<l-2:
name=name+str(i)+" * x**"+str(l-j-1)+" + "
elif j==l-2:
name=name+str(i)+" * x + "
else:
name=name+str(i)
j=j+1
def calc(x):
name.replace("x",str(x))
calc.__name__=name
return eval(name)
return calc
It does not work very well.
>>> p=poly((1,2,3))
>>> p
<function calc at 0x3b99938> #the name of p is not what I want!!! (*)
>>> y=p(3)
>>> p
<function 3 * x**2 + 2 * x + 1 at 0x3b99938> # now this is right!
>>>
How can I have the right name also in the first call (*) ?
Set the name outside of the function object:
def calc(x):
newname = name.replace("x", str(x))
calc.__name__ = newname
return eval(name)
calc.__name__ = name
return calc
Note that str.replace() does not replace values in strings in-place. It returns the altered string, string values themselves are immutable.
Your initial name will have to use x, since the value of x is not known at the time you call poly(). I'd leave out filling in of x in the name however; the function will not return that exact calculation the next time you call it with a different x. Without replacing x in the name each time you call the function, calc() would simply be:
def calc(x):
return eval(name)
Together with adding name = '' at the top of your poly() function, with the namechange per call in place still, gives:
>>> p = poly((1,2,3))
>>> p
<function 3 * x**2 + 2 * x + 1 at 0x10ecf5488>
>>> p(3)
34
>>> p
<function 3 * 3**2 + 2 * 3 + 1 at 0x10ecf5488>

How can I use the result from a function in another function? [duplicate]

This question already has answers here:
How do I get a result (output) from a function? How can I use the result later?
(4 answers)
Closed 6 months ago.
Suppose I have a function like:
def eklid(p, a, b,):
x = [1, 0]
y = [0, 1]
r = [a, b]
q = [0]
n = 0
while r[n+1] != 0:
q.append(r[n] // r[n+1])
r.append(r[n] % r[n+1])
x.append(x[n] - x[n+1] * q[n+1])
y.append(y[n] - y[n+1] * q[n+1])
if p == 0:
print(r[n], "=", r[n+1], "*", q[n+1], "+", r[n+2])
elif p == 1: # extended print
print(r[n+2], "\t", x[n+2], "\t", y[n+2], "\t", r[n+2], "=", a, "*", x[n+2], "+", b, "*", y[n+2])
elif p == -1:
k =1
else:
print("wrong input")
n += 1
return x, y, r, q, n,
I want to use x and r from it in this function:
def cong_solv(x, r, b,):
result = x/r
int_result = int(result)
return int_result
How can I do that?
# Here, a=x, b=y, c=r, d=q, e=n
a, b, c, d, e = eklid(h, i, k)
# Assuming based on your function definitions you want the
# same value as the third argument
final_result = cong_solv(a, c, k)
You get the return values from eklid and save them into variables. You then use those variables to call the next function.
Of course, in a real code you should name your varialbes better than I did in this example. I deliberately did not call the variables the same names as inside the function to demonstrate that you don't have to.
One way would be to call the eklid() function from inside the cong_solv() function. Something like this should work:
def cong_solv(x, r, b):
p = "foo"
b = "bar"
x, y, r, q, n = eklid(p, a, b)
result = x/r
int_result = int(result)
return int_result
In python, when you return more than one variable, it returns a tuple.
You can retrieve the value by its index (returned_value[0], returned_value[1]) or unpack the tuple like Mike Driscoll said (a, b, c, d = eklid(h, i, k)).
Since I got two downvotes, I am going to give you better (I hope) explanation:
Everytime you return more than one value, it returns a tuple.
def my_function():
a = 10
b = 20
return a, b
print type(my_function()) # <type 'tuple'>
But if you return just one value:
def my_function():
a = 10
return a
print type(my_function()) # <type 'int'>
So if you want to use your value, you can:
Unpack tuple values like this
a, b = my_function()
This way you get your return values in the same order you return inside my_function.
Rewriting your code, you can simply do:
a, b, c = eklid(10, 20, 30) # it will return a tuple
And call your other function:
cong_solv(a, b, 20)
In my honest opinion I would return a dict. With dict you can be explicit because your values have key names.
Inside your eklid return function:
return d # d = {"what_x_means": x,
# "what_y_means": y,
# "what_r_means": r,
# "what_q_means": q,
# "what_n_means": n}
And retrieve for its key:
d["what_x_means"]
d["what_r_means"]
Similar to How do you return multiple values in Python?
Return as an tuple (x,y,r....) or an array and assign to tuple / array respectively.
Or assign them to class variables and access them

Categories

Resources