I'm trying to use an equation that I've generated using sympy.Eq(func, var)
in a lambda. It seems to be returning a list of 'Add' objects, which I'm not sure how to use. I tried typecasting to astr
before using eval
, and i tried from sympy import I
, which i think has something to do with the problem.
Here's the code, and the error message:
py solid.py -v y = (x-1.0)(x-3.0)*2 1.0 3.0 -axis y --method disk
Here is a running example:
import sys
import argparse
import math
from scipy import integrate
from sympy import Symbol, Eq, solve, I
import numpy
import pylab
parser = argparse.ArgumentParser(description='Find the volume of the solid of rotation defined. Use * for multiplication and ** to raise a power. Bounds are set equal to the implicit variable. Trailing .0\'s must be used for constants, and parentheses must be escaped ( e.g. \(x-2\) ). Answers are accurate to 6 decimals')
parser.add_argument('var', choices='xy', help='x|y')
parser.add_argument('=', metavar='=', choices='=')
parser.add_argument('equation', help='continous function')
parser.add_argument('a', type=float, help='bound \'a\'')
parser.add_argument('b', type=float, help='bound \'b\'')
parser.add_argument('-axis', choices='xy', help='axis of revolution (default == x)')
parser.add_argument('-m', choices='ds', help='method (disk/shell)')
parser.add_argument('-g', action='store_true', help='show graph')
parser.add_argument('-v', action='store_true', help='verbose (for debugging)')
args = parser.parse_args()
y = Symbol('y')
x = Symbol('x')
def solve_for_implicit(func, var):
if var == 'x':
equation = Eq(eval(func), x)
func = solve(equation, y)
else:
equation = Eq(eval(func), y)
func = solve(equation, x)
return func
def volume(var, func, a, b, axis=None, method=None):
if axis == None: axis = 'x'
if method == 's': method = 'shell'
if method == 'd': method = 'disk'
if var == axis and axis == 'x':
if args.v: print 'x = y about x'
if not method == 'disk':
pass
else:
pass
elif var == axis and axis == 'y':
# SHELL METHOD
if args.v: print 'y = x about y'
if not method == 'disk':
# this is what should be used for y = x about y
if args.v: print 'using SHELL method'
func = eval('lambda x: ' + 'x*(' + func + ')')
integral = integrate.quad(func, a, b)
if args.v: print 'integral from', a, 'to', b, '=', integral[0]
answer = 2 * math.pi * integral[0]
if args.v: print '2*pi*', integral[0], '=', answer
else:
func = solve_for_implicit(func, var)
print func[0]
func = eval('lambda y: ' + '(' + str(func[0]) + ')**2')
integral = integrate.quad(func, a, b)
if args.v: print 'integral=', integral[0]
answer = math.pi * integral[0]
elif not var == axis and axis == 'y':
# DISK METHOD
if args.v: print 'x = y about y -- '
if not method == 'shell':
pass
else:
pass
elif not var == axis and axis == 'x':
# DISK
if args.v: print 'y = x about x --',
if not method == 'shell':
pass
else:
pass
return answer
print volume(args.var, args.equation, args.a, args.b, args.axis, args.m)
if args.g: graph(args.equation, args.a, args.b)
Traceback (most recent call last):
File "solid.py", line 136, in print volume(args.var, args.equation, args.a, args.b, args.axis, args.m) File "solid.py", line 75, in volume func = eval('lambda y: ' + '(' + func[0] + ')**2') TypeError: cannot concatenate 'str' and 'Add' objects
and when I try typecasting it to a str() first i get this:
File "solid.py", line 136, in print volume(args.var, args.equation, args.a, args.b, args.axis, args.m) File "solid.py", line 76, in volume integral = integrate.quad(func, a, b) File "/usr/lib/python2.6/dist-packages/scipy/integrate/quadpack.py", line 185, in quad retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points) File "/usr/lib/python2.6/dist-packages/scipy/integrate/quadpack.py", line 249, in _quad 开发者_运维技巧return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit) quadpack.error: Supplied function does not return a valid float.
also, print func[0]
gives:
2.33333333333333 + (0.296296296296298 - y/2 + (-0.0877914951989024 + (0.592592592592595 - y)2/4)(1/2))(1/3)*(1/2 - I*3(1/2)/2) + 0.444444444444444/((1/2 - I*3*(1/2)/2)(0.296296296296298 - y/2 + (-0.0877914951989024 + (0.592592592592595 - y)2/4)(1/2))**(1/3))
thanks for your help everyone, sorry for not providing a complete script before.
"I tried typecasting to astr before using eval, and i tried from sympy import I, which i think has something to do with the problem"
Yes, without a doubt that's exactly the problem. I'm sure Numpy has docuemntation on how to use the Add objects. Converting them to strings and then evaluating them definitely is not the right solution.
Except reading the documentation, you can also inspect the objects with dir(func) to see what functions and attributes it has. In the interpreter there is also a nifty help function, so you can type help(func) and get information.
精彩评论