Reputation: 21
I have a function involves a double integration from -10 to 10 in x and -10 to 10 in y, and I am using the built in quadrature function in SciPy to do this. However, the exact function that needs to be integrated needs user input.
The function is A*cos(x+y), where A needs to be a user input function.
For example, sometimes the function is a constant, and A is 2. So the integral will be of 2*cos(x+y) from -10 to 10 in both x and y. I want the user to input 2 when prompted for A.
But sometimes, the user may want A to be sin(x). So the integral will be of sin(x)*cos(x+y) from -10 to 10 again. I want the user to input np.sin(x) when prompted for A.
Or maybe the user might need A to be np.pi*y*e^(x/3).
A is a string when user inputs value. How do I get it to become a piece of code such that if the user inputs np.sin(x), then later on in the code at the quadrature, Python reads it as np.sin(x)*np.cos(x+y)?
I'm okay if the user inputs wrongly (say, he misspells np.sin as np.siin) and an error is returned.
What I have written is below:
import numpy as np
from scipy.integrate import dblquad
A = input('Enter your function here: ')
def function(x,y):
return A*(np.cos(x+y))
integral = dblquad(function, -10, 10, lambda x:-10, lambda x:10)
print integral
Appreciate any help given.
Upvotes: 2
Views: 3012
Reputation: 174624
I would suggest the following approach, its not foolproof, but should catch the majority of cases:
Apply the following rules on the user's input:
int
, if this fails:.
in the input, split on this .
.
is not a module, then its invalid input..
and then trim it down to the last (
partials
to call it, and then chain the rest of your formula..
, check if it contains a (
, and trim to this (
.partials
to call it.Here is some code:
import functools
import re
i = 'math.sin(12)'
try:
i = int(i)
except ValueError:
bits = i.split('.')
if len(bits) > 1:
module = bits[0]
callable = bits[1][:bits[1].rfind('(')]
args = re.search(r'\((.*?)\)', i).groups()[0]
if hasattr(module, callable):
f = functools.partial(getattr(module, callable), args)
After this point, f
will be the function that you can call. There are some issues with this code though:
It doesn't account for all cases, most prominently if a user enters a function without a module, you'll have to handle this part.
It doesn't handle complex nested function calls.
Hopefully though, you can build on this for your specific use case.
Upvotes: 2
Reputation: 621
I am pretty sure you can archieve this using the "eval" function. https://docs.python.org/2/library/functions.html#eval
Careful though, this function executes user input and this can be a security risk.
Edit: In your function replace the A variable by eval(A). Assuming this is a valid function this should work.
Upvotes: 0