Related
I created a function and make it usable in my Sympy expression like this:
def Unit(x):
if(x != 0):
return 0
else:
return 1
Unit = Function('Unit')
x = Symbol('x')
My expression:
fx = x ** 2 + Unit(x)
But when I run:
lam_f = lambdify(x, fx, modules=["sympy"])
print(lam_f(-1))
It said that my Unit is not defined?
Can anyone explain where i went wrong?
Function('Unit') returns an undefined function with name Unit. See this question. If you want to use your previously defined function Unit, remove the call to Function():
def Unit(x):
if(x != 0):
return 0
else:
return 1
x = Symbol('x')
fx = x**2 + Unit(x)
lam_f = lambdify(x, fx, modules=['sympy'])
print(lam_f(-1)) # prints 1
If I have a very simple (although possibly very complex) function generator in Python 2.7, like so:
def accumulator():
x = yield 0
while True:
x += yield x
Which can be used, like so:
>>> a = accumulator()
>>> a.send(None)
0
>>> a.send(1)
1
>>> a.send(2)
3
>>> a.send(3)
6
What would be a simple wrapper for another function generator that produces the same result, except multiplied by 2? The above function generator is simple, but please assume it is too complicated to copy-paste. I'm trying something, like:
def doubler():
a = accumulator()
a.send(None)
y = yield 0
while True:
y = 2 * a.send(yield y)
Or, imagining something simpler:
def doubler():
a = accumulator()
a.send = lambda v: 2 * super(self).send(v)
return a
Both of which are horribly broke, so I won't share the syntax errors, but it may illustrate what I'm trying to do.
Ideally, I would like to get something, like:
>>> d = doubler()
>>> d.send(None)
0
>>> d.send(1)
2
>>> d.send(2)
6
>>> d.send(3)
12
The results are the exact same as the original, except doubled.
I'm trying to avoid duplicating a very complicated function generator to create an identical result, except scaled by a known factor.
The second generator will ultimately have a different input stream, so I cannot just use the result from the first generator and double it. I need a second independent generator, wrapping the first.
The input stream is indeterminate, such that it is impossible to generate the entire sequence and then transform.
It seems I want to map or nest these function generators, but I'm not sure of the appropriate jargon, and so I'm getting nowhere in Google.
If you need to have the same interface as a coroutine (i.e. have a send method), then BrenBarn's solution is probably as simple as it gets.*
If you can have a slightly different interface, then a higher-order function is even simpler:
def factor_wrapper(coroutine, factor):
next(coroutine)
return lambda x, c=coroutine, f=factor: f * c.send(x)
You would use it as follows:
>>> a = accumulator()
>>> a2 = factor_wrapper(a, 2)
>>> print a2(1)
2
>>> print a2(2)
6
>>> print a2(3)
12
*Actually you can shave several lines off to make it 4 lines total, though not really reducing complexity much.
def doubler(a):
y = yield next(a)
while True:
y = yield (2 * a.send(y))
or even shorter...
def doubler(a, y=None):
while True:
y = yield 2 * a.send(y)
Either of the above can be used as follows:
>>> a = accumulator()
>>> a2 = doubler(a)
>>> print a2.send(None) # Alternatively next(a2)
0
>>> print a2.send(1)
2
>>> print a2.send(2)
6
>>> print a2.send(3)
12
I didn't tried this, but something along these lines:
class Doubler:
def __init__(self, g):
self.g = g()
def __next__(self):
return self.send(None)
def send(self, val):
return self.g.send(val)*2
Also, after Python 3.5, extending this from collections.abc.Container will eliminate the need of __next__, also will make this a proper generator(It currently doesn't support __throw__ etc., but they're just boilerplate).
Edit: Yes, this works:
In [1]: %paste
def accumulator():
x = yield 0
while True:
x += yield x
## -- End pasted text --
In [2]: %paste
class Doubler:
def __init__(self, g):
self.g = g()
def __next__(self):
return self.send(None)
def send(self, val):
return self.g.send(val)*2
## -- End pasted text --
In [3]: d = Doubler(accumulator)
In [4]: d.send(None)
Out[4]: 0
In [5]: d.send(1)
Out[5]: 2
In [6]: d.send(2)
Out[6]: 6
In [7]: d.send(3)
Out[7]: 12
You just need to move the yield outside the expression that passes y to a:
def doubler():
a = accumulator()
next(a)
y = yield 0
while True:
y = yield (2 * a.send(y))
Then:
>>> a = accumulator()
... d = doubler()
... next(a)
... next(d)
... for i in range(10):
... print(a.send(i), d.send(i))
0 0
1 2
3 6
6 12
10 20
15 30
21 42
28 56
36 72
45 90
I think this is what you want:
def doubler():
a = accumulator()
y = a.send(None)
x = yield 0
while True:
y = a.send(x)
x = yield 2 * y
This completely wraps the accumulator implementation but you could alternatively make that visible and pass it in as a parameter a to doubler.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Adding three variables through score function
How can I call my function? Here I want to add all three variables. Why doesn´t it show the output?
def score(x,y,z):
x == 1
y == 2
z == 3
return (x+y+z)
You're not assigning values, just checking a boolean.
And, even though you assign x,y,z in your function, make sure you're including arguments when calling it. However, your result will always be 6 no matter what arguments you pass, because you're changing their values in the function.
So, to use scores it should be:
def score(x,y,z):
return (x+y+z)
or, if you want a constant one:
def score():
x = 1
y = 2
z = 3
return(x+y+z)
In python, there's to use for the = character: if you use it alone, it is an assignment:
>>> a = 8
>>> print(a)
8
The other is a test, which returns a boolean, True or False: we use it to test if a variable equals another:
>>> 1 == 2
False
>>> 1 == 1
True
>>> a = 1 # Here, it's an asignment
>>> b = 1
>>> a == b
True
>>> b = 2
>>> a == b
False
In your code, you use the test: thus, the variables x, y, and z aren't modified. You must instead write:
def score(x, y, z):
x = 1
y = 2
z = 3
return (x + y + z)
if you want to assign 1, 2 and 3 to x, y and z. But please note that in this case, the three parameters are useless: this function is simply:
def score(x, y, z):
return (1 + 2 + 3)
You should define the parameters first:
def score(x,y,z):
return (x+y+z)
print(score(1, 5, 2))
Output: 7
If you want constant scores, you shouldn't even put any parameters in the first place. You used == instead of = too.
def score():
x = 1
y = 2
z = 3
return (x+y+z)
print(score())
Output: 6
It is x = 1... not ==, == is comparison = is assignment.
def score():
x = 1
y = 2
z = 3
return (x+y+z)
Then:
print(score()) # -> 6
If you want to pass the values:
def score(x,y,z):
return (x+y+z)
print(score(1,2,3)) # -> 6
If you wanted to test the values passed in were certain numbers you would use ==:
def score(x, y, z):
if x == 1 and y == 2 and z == 3:
return x + y + z
That tests if x is equal to 1 and y is equal to 2 and z is equal to 3
A more logical reason to assign values to x y and z would be to give x,y and z default values:
def score(x=1, y=2, z=3):
return x + y + z
So calling print(score(4)) would output 9 as x would be equal to 4 and the default values for y and z are used.
What is the difference between the following Python expressions:
# First:
x,y = y,x+y
# Second:
x = y
y = x+y
First gives different results than Second.
e.g.,
First:
>>> x = 1
>>> y = 2
>>> x,y = y,x+y
>>> x
2
>>> y
3
Second:
>>> x = 1
>>> y = 2
>>> x = y
>>> y = x+y
>>> x
2
>>> y
4
y is 3 in First and 4 in Second
In an assignment statement, the right-hand side is always evaluated fully before doing the actual setting of variables. So,
x, y = y, x + y
evaluates y (let's call the result ham), evaluates x + y (call that spam), then sets x to ham and y to spam. I.e., it's like
ham = y
spam = x + y
x = ham
y = spam
By contrast,
x = y
y = x + y
sets x to y, then sets y to x (which == y) plus y, so it's equivalent to
x = y
y = y + y
It is explained in the docs in the section entitled "Evaluation order":
... while evaluating an assignment, the right-hand side is evaluated
before the left-hand side.
The first expression:
Creates a temporary tuple with value y,x+y
Assigned in to another temporary tuple
Extract the tuple to variables x and y
The second statement is actually two expressions, without the tuple usage.
The surprise is, the first expression is actually:
temp=x
x=y
y=temp+y
You can learn more about the usage of comma in "Parenthesized forms".
An observation regarding the left-hand side as well: the order of assignments is guaranteed to be the order of their appearance, in other words:
a, b = c, d
is equivalent functionally to precisely (besides t creation):
t = (c, d)
a = t[0] # done before 'b' assignment
b = t[1] # done after 'a' assignment
This matters in cases like object attribute assignment, e.g.:
class dummy:
def __init__(self): self.x = 0
a = dummy(); a_save = a
a.x, a = 5, dummy()
print(a_save.x, a.x) # prints "5 0" because above is equivalent to "a = dummy(); a_save = a; t = (5, dummy()); a.x = t[0]; a = t[1]"
a = dummy(); a_save = a
a, a.x = dummy(), 5
print(a_save.x, a.x) # prints "0 5" because above is equivalent to "a = dummy(); a_save = a; t = (dummy(), 5); a = t[0]; a.x = t[1]"
This also implies that you can do things like object creation and access using one-liners, e.g.:
class dummy:
def __init__(self): self.x = 0
# Create a = dummy() and assign 5 to a.x
a, a.x = dummy(), 5
I've recently started using Python and this "feature" baffled me. Although there are many answers given, I'll post my understanding anyway.
If I want to swap the values of two variables, in JavaScipt, I'd do the following:
var a = 0;
var b = 1;
var temp = a;
a = b;
b = temp;
I'd need a third variable to temporarily hold one of the values. A very straightforward swap wouldn't work, because both of the variables would end up with the same value.
var a = 0;
var b = 1;
a = b; // b = 1 => a = 1
b = a; // a = 1 => b = 1
Imagine having two different (red and blue) buckets and having two different liquids (water and oil) in them, respectively. Now, try to swap the buckets/liquids (water in blue, and oil in red bucket). You can't do it unless you have an extra bucket.
Python deals with this with a "cleaner" way/solution: Tuple Assignment.
a = 0
b = 1
print(a, b) # 0 1
# temp = a
# a = b
# b = temp
a, b = b, a # values are swapped
print(a, b) # 1 0
I guess, this way Python is creating the "temp" variables automatically and we don't have to worry about them.
In the second case, you assign x+y to x
In the first case, the second result (x+y) is assigned to y
This is why you obtain different results.
After your edit
This happen because, in the statement
x,y = y,x+y
all variables at the right member are evaluated and, then, are stored in the left members. So first proceed with right member, and second with the left member.
In the second statement
x = y
y = x + y
yo first evaluated y and assign it to x; in that way, the sum of x+y is equivalent to a sum of y+y and not of x+x wich is the first case.
The first one is a tuple-like assignment:
x,y = y,x+y
Where x is the first element of the tuple, and y is the second element, thus what you are doing is:
x = y
y = x+y
Wheras the second is doing a straight assign:
x=y
x=x+y
Other answers have already explained how it works, but I want to add a really concrete example.
x = 1
y = 2
x, y = y, x+y
In the last line, first the names are dereferenced like this:
x, y = 2, 1+2
Then the expression is evaluated:
x, y = 2, 3
Then the tuples are expanded and then the assignment happens, equivalent to:
x = 2; y = 3
For newbies, I came across this example that can help explain this:
# Fibonacci series:
# the sum of two elements defines the next
a, b = 0, 1
while a < 10:
print(a)
a, b = b, a+b
With the multiple assignment, set initial values as a=0, b=1.
In the while loop, both elements are assigned new values (hence called 'multiple' assignment). View it as (a,b) = (b,a+b). So a = b, b = a+b at each iteration of the loop. This continues while a<10.
RESULTS:
0
1
1
2
3
5
8
Let's grok the difference.
x, y = y, x + y
It's x tuple xssignment, mexns (x, y) = (y, x + y), just like (x, y) = (y, x)
Stxrt from x quick example:
x, y = 0, 1
#equivxlent to
(x, y) = (0, 1)
#implement xs
x = 0
y = 1
When comes to (x, y) = (y, x + y)
ExFP, have x try directly
x, y = 0, 1
x = y #x=y=1
y = x + y #y=1+1
#output
In [87]: x
Out[87]: 1
In [88]: y
Out[88]: 2
However,
In [93]: x, y = y, x+y
In [94]: x
Out[94]: 3
In [95]: y
Out[95]: 5
The result is different from the first try.
Thx's because Python firstly evaluates the right-hand x+y
So it equivxlent to:
old_x = x
old_y = y
c = old_x + old_y
x = old_y
y = c
In summary, x, y = y, x+y means,
x exchanges to get old_value of y,
y exchanges to get the sum of old value x and old value y,
a, b = 0, 1
while b < 10:
print(b)
a, b = b, a+b
Output
1
1
2
3
5
8
the variables a and b simultaneously get the new values 0 and 1, the same a, b = b, a+b, a and b are assigned simultaneously.
What is the difference between the following Python expressions:
# First:
x,y = y,x+y
# Second:
x = y
y = x+y
First gives different results than Second.
e.g.,
First:
>>> x = 1
>>> y = 2
>>> x,y = y,x+y
>>> x
2
>>> y
3
Second:
>>> x = 1
>>> y = 2
>>> x = y
>>> y = x+y
>>> x
2
>>> y
4
y is 3 in First and 4 in Second
In an assignment statement, the right-hand side is always evaluated fully before doing the actual setting of variables. So,
x, y = y, x + y
evaluates y (let's call the result ham), evaluates x + y (call that spam), then sets x to ham and y to spam. I.e., it's like
ham = y
spam = x + y
x = ham
y = spam
By contrast,
x = y
y = x + y
sets x to y, then sets y to x (which == y) plus y, so it's equivalent to
x = y
y = y + y
It is explained in the docs in the section entitled "Evaluation order":
... while evaluating an assignment, the right-hand side is evaluated
before the left-hand side.
The first expression:
Creates a temporary tuple with value y,x+y
Assigned in to another temporary tuple
Extract the tuple to variables x and y
The second statement is actually two expressions, without the tuple usage.
The surprise is, the first expression is actually:
temp=x
x=y
y=temp+y
You can learn more about the usage of comma in "Parenthesized forms".
An observation regarding the left-hand side as well: the order of assignments is guaranteed to be the order of their appearance, in other words:
a, b = c, d
is equivalent functionally to precisely (besides t creation):
t = (c, d)
a = t[0] # done before 'b' assignment
b = t[1] # done after 'a' assignment
This matters in cases like object attribute assignment, e.g.:
class dummy:
def __init__(self): self.x = 0
a = dummy(); a_save = a
a.x, a = 5, dummy()
print(a_save.x, a.x) # prints "5 0" because above is equivalent to "a = dummy(); a_save = a; t = (5, dummy()); a.x = t[0]; a = t[1]"
a = dummy(); a_save = a
a, a.x = dummy(), 5
print(a_save.x, a.x) # prints "0 5" because above is equivalent to "a = dummy(); a_save = a; t = (dummy(), 5); a = t[0]; a.x = t[1]"
This also implies that you can do things like object creation and access using one-liners, e.g.:
class dummy:
def __init__(self): self.x = 0
# Create a = dummy() and assign 5 to a.x
a, a.x = dummy(), 5
I've recently started using Python and this "feature" baffled me. Although there are many answers given, I'll post my understanding anyway.
If I want to swap the values of two variables, in JavaScipt, I'd do the following:
var a = 0;
var b = 1;
var temp = a;
a = b;
b = temp;
I'd need a third variable to temporarily hold one of the values. A very straightforward swap wouldn't work, because both of the variables would end up with the same value.
var a = 0;
var b = 1;
a = b; // b = 1 => a = 1
b = a; // a = 1 => b = 1
Imagine having two different (red and blue) buckets and having two different liquids (water and oil) in them, respectively. Now, try to swap the buckets/liquids (water in blue, and oil in red bucket). You can't do it unless you have an extra bucket.
Python deals with this with a "cleaner" way/solution: Tuple Assignment.
a = 0
b = 1
print(a, b) # 0 1
# temp = a
# a = b
# b = temp
a, b = b, a # values are swapped
print(a, b) # 1 0
I guess, this way Python is creating the "temp" variables automatically and we don't have to worry about them.
In the second case, you assign x+y to x
In the first case, the second result (x+y) is assigned to y
This is why you obtain different results.
After your edit
This happen because, in the statement
x,y = y,x+y
all variables at the right member are evaluated and, then, are stored in the left members. So first proceed with right member, and second with the left member.
In the second statement
x = y
y = x + y
yo first evaluated y and assign it to x; in that way, the sum of x+y is equivalent to a sum of y+y and not of x+x wich is the first case.
The first one is a tuple-like assignment:
x,y = y,x+y
Where x is the first element of the tuple, and y is the second element, thus what you are doing is:
x = y
y = x+y
Wheras the second is doing a straight assign:
x=y
x=x+y
Other answers have already explained how it works, but I want to add a really concrete example.
x = 1
y = 2
x, y = y, x+y
In the last line, first the names are dereferenced like this:
x, y = 2, 1+2
Then the expression is evaluated:
x, y = 2, 3
Then the tuples are expanded and then the assignment happens, equivalent to:
x = 2; y = 3
For newbies, I came across this example that can help explain this:
# Fibonacci series:
# the sum of two elements defines the next
a, b = 0, 1
while a < 10:
print(a)
a, b = b, a+b
With the multiple assignment, set initial values as a=0, b=1.
In the while loop, both elements are assigned new values (hence called 'multiple' assignment). View it as (a,b) = (b,a+b). So a = b, b = a+b at each iteration of the loop. This continues while a<10.
RESULTS:
0
1
1
2
3
5
8
Let's grok the difference.
x, y = y, x + y
It's x tuple xssignment, mexns (x, y) = (y, x + y), just like (x, y) = (y, x)
Stxrt from x quick example:
x, y = 0, 1
#equivxlent to
(x, y) = (0, 1)
#implement xs
x = 0
y = 1
When comes to (x, y) = (y, x + y)
ExFP, have x try directly
x, y = 0, 1
x = y #x=y=1
y = x + y #y=1+1
#output
In [87]: x
Out[87]: 1
In [88]: y
Out[88]: 2
However,
In [93]: x, y = y, x+y
In [94]: x
Out[94]: 3
In [95]: y
Out[95]: 5
The result is different from the first try.
Thx's because Python firstly evaluates the right-hand x+y
So it equivxlent to:
old_x = x
old_y = y
c = old_x + old_y
x = old_y
y = c
In summary, x, y = y, x+y means,
x exchanges to get old_value of y,
y exchanges to get the sum of old value x and old value y,
a, b = 0, 1
while b < 10:
print(b)
a, b = b, a+b
Output
1
1
2
3
5
8
the variables a and b simultaneously get the new values 0 and 1, the same a, b = b, a+b, a and b are assigned simultaneously.