简体   繁体   中英

Create a function that accepts an expression as an input in python

I am busy just doing some code on the bisection method. It is easy of course to just write the script and run it. However, the trick comes in when I want to define a function that will take an expression such as x**2 as an input. I've scrapped something together though. It sort of gets the job done but then at my first if statement it complains about not being able to multiply a function by a function. How would I solve this problem as well? I really tried doing my homework on this problem before asking and unfortunately cannot find the solution. I would just love to know how to do this though.

from sympy.abc import x

def bisect(f, a, b):
    f = lambda x: f
    f_a, f_b = f(a), f(b)
    tol = 1e-4 
    count = 0
    print '\t'.join( ['Step' , 'a', 'b', 'c', 'f(c) ' , '(b-a)/2)'])
    while (b-a)/float(2) > tol:
        c = (a+b)/2
        f_c = f(c)
        print '\t'.join( [str(count) , str(a) , str(b) , str(c), str((b-a)/float(2) )])
        if f_a*f_c < 0:
            b = c
            f_b = f_c
        else:
            a = c
            f_a = f_c
        count = count + 1

Is this what you need to know?

>>> def demo(func):
...   for i in range(5):
...     print func( float(i))
... 
>>> demo( lambda x: x**2 + 2*x - 5 )
-5.0
-2.0
3.0
10.0
19.0

You can also pass in a function created with def as well as a one-liner defined with lambda . the above is the same as

def foo(x):
    return x**2 + 2*x - 5 

demo( foo) 

The other thing you might want to know is that

definition = "x**2 + 2*x - 5" # or read it from the user as text input
demo( eval( "lambda x: " + definition))

works ...

obligatory warning , "eval is evil", accepting Python code from a user and executing it is generally regarded as a security no-no-NO! However, if this code is run by the same user who is experimenting with plotting mathematical forms, no great harm can come of it. He can't do anything worse than what he could do with python at the command line. If you were to do anything like this in a web-server or suchlike, I would fear for your employment and future prospects thereof!

Let's assume you have created an expression for function f using sympy :

f = x**2-0.1

Your bisect function will work if you change the lambda definition:

def bisect(fexpr, a, b):
    f = lambda xval: fexpr.subs(x,xval)
    f_a, f_b = f(a), f(b)
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM