1

my code is :

from sympy import symbols

x = symbols ('x')

def f(x):
    y = input("what is your function?")
    return y
print (f(1))

But if I put x**2 + 3 as an input and run the code then it prints x**2 +3 Why this happens?

I think the builtin function input does not take 'x' as a variable.

How can I fix it?

user88914
  • 123
  • 6

2 Answers2

1

As you want to use a variable name in expression, you cannot directly use ast.litteral_eval which is a secure alternative to (the evil) eval.

At least you can try to remove builtins from the global context:

def f(x):
    y = input("Function:")
    return eval(y, {'__builtins__': {}}, {'x': x})

But beware, even with builtins removed eval may not be safe

You could also use the variant proposed by Steven:

def g(**args):
    y = input("Function:")
    return eval(y, {'__builtins__': {}}, args)
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

You could do something like this to get an expression formatted with any arguments that match. Although it doesn't work if you have for example xs and x as variables since x will replace x in xs since I didn't handle that in this example, so be aware of that.

def get_exp(**kwargs):
    print(kwargs) # left in to show how kwargs looks
    inp = input('--> ')
    for k, v in kwargs.items():
        inp = inp.replace(k, str(v))
    return inp

# Use
>>> exp = get_exp(x = 5, y = 10)
{'x': 5, 'y': 10}
--> x ** 5 + (y - 2)
>>> exp
'5 ** 5 + (10 - 2)'
>>> exp = get_exp(x = 5, y = 10)
{'x': 5, 'y': 10}
--> z + x
>>> exp
'z + 5'

As for evaluating the expression look to here on safely evaluating input using ast module or here for pyparsing.

If you want to use the sympy module then here has an example on use. However be aware the sympy isn't considered safe.

Community
  • 1
  • 1
Steven Summers
  • 5,079
  • 2
  • 20
  • 31