0
myList = ['100', 'sin(x)', '0', '1']

I read these strings from a text file. I now want to execute the function call sin(x) from that string -- I want this to be a general interpretation of the string for any function expression.

I have tried the following with no success.

myList[1].replace("'", "")

I guess what I am asking is how to pull a string from a list and use it's 'raw text' so to speak.

The end goal is to get this function, where myList[1] should turn to sin(x)

from math import sin
def f(x):
    return myList[1]

Thus f(x) will give the computed value of sin(x) from this list.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • 2
    `eval`, but be damn sure that you actually need to solve this problem. `eval` is dangerous if misused. This strikes me as a XY problem. – Carcigenicate Mar 29 '17 at 18:43
  • Your comment on my answer fits better up here. It's still a narrow scope. Are you trying to program some sort of expression evaluator? What is the overall project? – Prune Mar 29 '17 at 18:55
  • @Prune: From his previous post, there is a text file with a task list "N function_string a b" and the goal is numerical integration of each task over the interval `[a,b]` with a subdivision in `N` sub-intervals. – Lutz Lehmann Mar 29 '17 at 18:59
  • Thanks; in SO, each question is supposed stand on its own, or at least include a link to the SO context. – Prune Mar 29 '17 at 19:01
  • See also http://stackoverflow.com/a/5936822/3088138, http://stackoverflow.com/a/25437733/3088138 and the other answers around these. – Lutz Lehmann Mar 29 '17 at 20:06
  • Possible duplicate of [Math operations from a list](http://stackoverflow.com/questions/43099916/math-operations-from-a-list) – Foon Mar 29 '17 at 23:44

5 Answers5

3

use dict and you archive it

from math import sin
myList = ['100', 'sin(x)', '0', '1']
options = { 'sin(x)':sin }
options[myList[1]](1)
0.8414709848078965
galaxyan
  • 5,944
  • 2
  • 19
  • 43
2

You're confusing a string value with executable code. Two basic points:

  1. You can do this with the eval function, which evaluates a string as Python code.
  2. Don't. Really; eval is a loaded gun pointed at your foot, and usually indicates a poor system design.

What is it that you're trying to do overall? If you want to trigger the trig functions with text input, you're better heeled to do it with enumerated checks, such as:

choice = myList[1]
if choice == "sin":
    return sin(x)
elif choice == "cos":
    return cos(x)
...
Prune
  • 76,765
  • 14
  • 60
  • 81
  • I am trying to get f(x) to return the functions given in myList[1]. Not only trig functions, could be log(x), x**2, .... – Jack Malrock Mar 29 '17 at 18:47
1

The safest way I can see to do this is to store the expected functions in a dictionary like this:

math_dict = {'sin(x)':sin, 'cos(x)':cos}

then you can call sin from the list like this:

def f(x):
    return math_dict[myList[1]](x)

I just added cos(x) to show you can do this with any arbitrary function. You could then do something like this to generalize it:

def f(x):
    return math_dict[x] if x in math_dict else None
Outis
  • 150
  • 7
1

Sin function is part of math library, you can get it like:

import math
getattr(math, 'sin')

That is same for all non-builtin libraries. Just split the string to get function name:

function_name = myList[1].split('(')[0]
function = getattr(math, function_name)
function(value for x)

For builtin functions like round:

getattr(globals()['__builtins__'], 'round')
Emin Mastizada
  • 1,375
  • 2
  • 15
  • 30
0

With sympy.sympify and highlighting the warning

Warning : sympify uses eval. Don’t use it on unsanitized input.

you can solve this as

myList = ['100', 'sin(x)', '0', '1']

from sympy.abc import x
from sympy import sympify

N, expr, a,b = myList

# convert strings to objects
N=int(N); a=float(a); b=float(b);
expr = sympify(expr)

# define user function
def f(xval): return expr.subs(x,xval)

or for multi-point evaluation replace the last line with

from sympy import lambdify
f = lambdify(x, expr, "numpy")

# integrate as left Riemann sum (order 1)
from numpy import linspace
xlist = linspace(a,b,N)

integral = sum(f(xlist))*(b-a)/N
Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51