Simple question on how to link (or string together) multiple functions that depend on each other. I have the following example function (in Jupyter):
### First function
def function_one():
## process one
a = "one" + "two"
print(a)
## process two
b = "red" + "blue"
print(b)
## process three
c = "this" + "sucks"
print(c)
return a, b, c
### Second function
def function_two(a, b, c):
## process four
d = a + b
print(d)
## process five
e = b + c
print(e)
## process six
f = a + c
print(f)
return d, e, f
### Third function
def function_three():
g = a + b + c + d + e + f
print(g)
return g
### Calling functions
initial = function_one()
second = function_two(initial)
third = ... #I can't get past the following error to even link this function in
The first function works when called, but when I try to send that data downstream to the second function, I get this error:
onetwo
redblue
thissucks
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-7c5562b97c86> in <module>
1 initial = function_one()
----> 2 second = function_two(initial)
TypeError: function_two() missing 2 required positional arguments: 'b' and 'c'
How do I remedy this?
When returning multiple objects, you are actually returning a tuple. Ex:
>>> def foo():
>>> return 1, 2, 3
>>> type(foo())
<class 'tuple'>
So, right now the whole tuple is treated as argument a and hence b and c are missing. In order to pass that on as 3 separate arguments, you need to unpack that tuple:
initial = function_one()
second = function_two(*initial)
third = function_three(*initial, *second)
Assign the return values to variables then pass it to the second function:
a, b, c = function_one()
function_two(a, b, c)
For your third function you need it to accept parameters as well
def function_three(a, b, c, d, e, f):
g = a + b + c + d + e + f
print(g)
return g
Then putting it all together:
a, b, c = function_one()
d, e, f = function_two(a, b, c)
g = function_three(a, b, c, d, e, f)
Related
I'm trying to implement the multivariate chain rule using python, when I try to substitute one of the elements using the built-in sympy function expr.subs() I won't get an answer.
The exercise goes as follows:
Compute df/dx of the following function using the chain rule:
a = x^2
b = exp(a)
c = a + b
d = log(c)
e = sin(c)
f = d + e
And this is the code:
a, b, c, d, e, f = sym.symbols('a b c d e f')
f = d + e
dfd = sym.diff(f, d)
dfe = sym.diff(f, e)
df = sym.Matrix([[dfd, dfe]])
d = sym.log(c)
e = sym.sin(c)
ddc = sym.diff(d)
dde = sym.diff(e)
dd = sym.Matrix([[ddc],[dde]])
dfdd = df#dd
c = a + b
dca = sym.diff(c, a)
dcb = sym.diff(c, b)
dc = sym. Matrix([[dca, dcb]])
dfdc = dfdd#dc
a = x**2
b = sym.exp(a)
result = dfdc.subs(c, (a + b))
result
The result the function .subs() doesn't substitute anything and I don't know why, I tried substituting it using other ways to write the function, like:
dfdc.subs({c : (a + b)})
dfdc.subs(c, a + b)
And even tried to just substitute it for an integer to see it that would work and neither does it.
What am I doing wrong?
The c in your dfdc expression was created before you set c=a+b. So it still appears as c in dfdc. However, by the time you want to do your subs, the c symbol is declared as c=a+b, and so your substitute really reads
dfdc.subs(a+b, a+b)
And that does nothing.
In order to really use c there, do
dfdc.subs(sym.Symbol('c'), a+b)
How do I only access one of the values:
my code:
def test():
a = 4
b = 5
c = 6
return a, b, c
a = test().a # only want "a" from the function
You can ignore the other values by using a placeholder _
def test():
a = 4
b = 5
c = 6
return a, b, c
#Ignore b and c
a, _, _ = test()
print(a)
#4
Or you could return a dictionary of values and access a from the dictionary
def test():
a = 4
b = 5
c = 6
return locals()
print(test()['a'])
#4
Or you could just use indexing to find the first element of the returned tuple, given you know a is the first element, as per Tim's Answer above
def test():
a = 4
b = 5
c = 6
return a, b, c
print(test()[0])
#a
The function test() returns a tuple so in order to access a you would have to use the following code:
a = test()[0]
You could return a dictionary instead:
def test():
a = 4
b = 5
c = 6
return {"a":a, "b":b, "c":c}
print(test()["a"])
4
If you want to stick with your current approach, then the best you might be able to do would be to just print the first element from the tuple returned:
print(test()[0])
But this of course means that the caller would have to know that a happens to coincide with the first value.
There are a few ways to do this.
a, b, c = test() # ignore b and c
a, *_ = test() # ignore _ which captures b and c
a = test()[0]
a = test()
a[0] # which is equal to the 'a' inside the test function.
I am making a script where you can input a, b and c into the quadratic formula and it will give you the answer.
It says that b is not defined when I run it.
from cmath import sqrt
qf = lambda a, b, c: (-b-cmath.sqrt((b**2) - (4*a*c)))/(2*a), (-b+cmath.sqrt((b**2) - (4*a*c)))/(2*a)
a, b, c = input('Enter a, b and c with spaces in between the values \n').split()
a = float(a) ; b = float(b) ; c = float(c)
Print(qf(a, b,c)
Traceback (most recent call last):
File "/storage/emulated/0/Download/.last_tmp.py", line 2, in
qf = lambda a, b, c: (-b-cmath.sqrt((b2) - (4*a*c)))/(2*a), (-b+cmath.sqrt((b2) - (4*a*c)))/(2*a)
NameError: name 'b' is not defined
Check this out:
from math import sqrt
def get_roots(a, b, c):
if a == 0:
raise ZeroDivisionError('Not a quadratic equation')
val = b ** 2 - 4 * a * c
if val < 0:
raise Exception('Imaginary Roots')
val = sqrt(val)
root1 = (-b - val) / (2 * a)
root2 = (-b + val) / (2 * a)
return root1, root2
a, b, c = input('Enter a, b and c with spaces in between the values \n').split()
a, b, c = float(a), float(b), float(c)
print(get_roots(a,b,c))
Lambda functions can only return one thing so you need to group your outputs into either a tuple or a list by adding an enclosing () or []. The python parser is getting to:
qf = lambda a, b, c: (-b-sqrt((b**2) - (4*a*c)))/(2*a)
and assuming the lambda function is over. It then begins reading:
, (-b+sqrt((b**2) - (4*a*c)))/(2*a)
and tries to interpret -b in the global scope (where it doesn't exist) this gives you your name error. If you were to get rid of all the variables and for a moment pretend the second result of the quadratic formula was always 0, you'd get a tuple with the first element being a lambda function and the second being the integer 0
>>>qf = lambda a, b, c: [(-b-sqrt((b**2) - (4*a*c)))/(2*a),0
>>>qf
(<function <lambda> at 0x000002B44EF72F28>, 0)
This doesn't quite get what you're after, because you want a single function rather than a tuple of two separate functions to compute each root separately.
Here's what it'd look like if you want the lambda to return a list:
qf = lambda a, b, c: [(-b-sqrt((b**2) - (4*a*c)))/(2*a), (-b+sqrt((b**2) - (4*a*c)))/(2*a)]
This question already has answers here:
Multiple assignment and evaluation order in Python
(11 answers)
Closed 9 years ago.
2 questions...
1) I am trying to wrap my brain around this...
I am to understand that variables can take values using such code syntax as this:
a ,b = 2, 3
and that this would be the same as coding:
a = 2
b = 3
I hope this is correct.
So here is my puzzlement. I have the following code using a generator:
def fibonacci_generator() :
a = b = 1
while True :
yield a
a , b = b , a + b
fib = fibonacci_generator()
for i in fib :
if i > 100 :
break
else :
print ('Generated: ', i)
print (next(fib))
(yes this is code from a python learning book)
If I were to rewrite this code and instead assign my a and b variables like so:
yield a
a = b
b = a + b
then I get different returns for a.
I am not understanding why this is??? Super frustrated about it!
2) When I run the code as written the first time above, I get the number 233 printed at the end. I also cannot figure out why??!!
In this code:
a, b = b, a + b
a is set to b, and b is set to a+b.
In this code:
a = b
b = a + b
a is set to b, and b is afterwards set to a+b. But since a is already set to b, then b is in fact set to b+b.
a , b = b , a + b
is not the same as
a = b
b = a + b
Because, when you say
a, b = b, a + b
It will first prepare the values on the right side b, a + b and assign them to the variables on the left.
Python computes the right hand side first and then assigns the value (or unpacks it) on the left hand side. So, in the example:
a, b = b, a+b
compared to:
a = b
b = a + b
You have different values for a when you go to compute a + b. In the second example, when you compute a + b it is equivalent to computing b + b!
You are probably missing the flow of data.
a = b ...eqI
b = a+b ...eqII
here, before executing b eqII, a has already stored bas a value of itself. Now when yow try execute b of eqII it comes like b=b+b. Because after executing eqI when it comes to eqII, a is bnow.
But in python you can avoid this conflict if you try a, b = b, a+b.
For your second question:
I am not sure about your code but this one will work fine in the sense of your code...
a = b = 1
while True :
a , b = b , a + b
if a and b > 100:
break
else: print a, b
try it !!
In an assignment statement, the right-hand side is always evaluated fully before doing the actual setting of variables. Because that you get different results
a, b = b, a+b
This line computes b and a+b before performing any assignment. Strictly speaking, it computes a tuple (b, a+b) and then unpacks the elements of the tuple to assign them to a and b.
a = b
b = a+b
This assigns a, then computes a+b using the new value of a.
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