Is there an alternative to exec in python? - python

So I'm making an integrator program with the simpson 1/3 method and I want the user to give me a function and interval of integration, and then return the result. I figure that I can use exec to make dynamic code, so I use it to create the function. This is my code:
from math import *
class CreaFormula:
def __init__(self,formula):
self.fun = "def f(x):\n return %s" % formula
class Integrador:
def __init__(self,f):
#integration interval
a = 0
b = 1
n = 600
h = (b-a)/n
#method
self.s = f(a) + f(b)
for i in range(1,n):
if i%2 == 0:
self.s = self.s + 2*f(a+i*h)
else:
self.s = self.s + 4*f(a+i*h)
self.s = self.s*(h/3)
vr = -cos(1) + e
self.er = abs((vr -self.s) /vr)
formula = input()
MiFo = CreaFormula(formula)
f1 = MiFo.fun
exec(f1)
MyInt = Integrador(f)
a = MyInt.s
b = MyInt.er
print(a)
So basically I want to put everything that is at the end of the code inside a class, so I can call it later by another code, but if I do that it shows an error that f is not defined, because it is created with exec. So is there a way to not use exec but still create a function from user's input?
Thanks in advance

If the question is just how to construct a function object that can evaluate a user-supplied expression, you'll probably have an easier time using eval than exec:
def create_function_from_formula(formula):
def user_function(x):
return eval(formula, globals(), {'x': x})
return user_function
Of course, even with eval, if someone provides a malicious formula, it can do anything, up to and including executing any other program included on the computer. So only do this if you trust the person providing the formula to essentially take over your computer. In particular, you should never do this if formula can come from a user who is not physically logged in to your computer already.

Related

Increment function name in Python

I apologise if there is already an answer to my question, I've searched stack overflow for a while but found nothing that I could use.
I'm learning how to create classes at the moment and I've constructed classes for the explicit Runge-Kutta methods 1-4. The names of the classes are 'RK_1', 'RK_2', 'RK_3' and 'RK_4'. In order to test my code, I decided to solve the Legendre differential equation, which I also created a class for called 'Legendre'.
Now I wanted to solve the problem, so I wrote a function that uses a particular RK scheme and solves the Legendre problem. I wanted to do this for each one of my RK schemes, so I wrote the same function 4 times i.e
def solve_Legendre_1(p,Tmax,init,dt=0.001):
f = Legendre(p)
solver = RK_1(init,f)
while solver.now() < Tmax:
solver(dt)
return solver.state()
def solve_Legendre_2(p,Tmax,init,dt=0.001):
f = Legendre(p)
solver = RK_2(init,f)
while solver.now() < Tmax:
solver(dt)
return solver.state()
def solve_Legendre_3(p,Tmax,init,dt=0.001):
f = Legendre(p)
solver = RK_3(init,f)
while solver.now() < Tmax:
solver(dt)
return solver.state()
def solve_Legendre_4(p,Tmax,init,dt=0.001):
f = Legendre(p)
solver = RK_4(init,f)
while solver.now() < Tmax:
solver(dt)
return solver.state()
However, I realised there must be an easier way to do this. So I thought I might be able to use a loop and str.format() to change the name of the function and get it to take in its corresponding RK scheme, something like
for j in range(4):
def solve_Legendre_%s(p,Tmax,init,dt=0.001) % (j+1):
f = Legendre(p)
solver = RK_%s(init,f) % (j+1)
while solver.now() < Tmax:
solver(dt)
return solver.state()
but obviously this won't work. Does anyone know how I should approach this?
Thanks for your help.
You can simply pass the RK_n() function in as a parameter to avoid duplicating the other function:
def solve_Legendre(p,Tmax,init,dt=0.001, RK=RK_1):
f = Legendre(p)
solver = RK(init,f)
while solver.now() < Tmax:
solver(dt)
return solver.state()
and if you want you can bind that last parameter in advance:
import functools
solve_Legendre_1 = functools.partial(solve_Legendre, RK=RK_1)
solve_Legendre_2 = functools.partial(solve_Legendre, RK=RK_2)
...
You can use arguments not only to give "usual" things, like numbers, lists or strings to a function, you can also use functions themselves as parameters:
>>> def test1():
print(1)
>>> def test2():
print(2)
>>> def solve_with_func(funcname):
funcname()
>>> solve_with_func(test1)
1
>>> solve_with_func(test2)
2
This way you can use the same logic in solve_with_func and simply swap out the function that is executed.
This can of course be extended to lists of functions:
>>> def execute_all(funclist):
for f in funclist:
f()
>>> execute_all([test1, test2])
1
2
Your functions differ only by RK_x function, which you can simply pass by additional variable. This will minimize code redundancy:
def solve_Legendre(RK_func, p,Tmax,init,dt=0.001):
f = Legendre(p)
solver = RK_func(init,f)
while solver.now() < Tmax:
solver(dt)
return solver.state()
Now to your question - you can query globals for this. globals() function will return map with every object defined at global scope keyed by identifier. So you could write (using my previous function):
for j in range(4):
globals()['solve_Legendre_%d' % (j + 1)] = lambda *args, **kw_args: solve_Legendre(globals()['RK_%d' % (j + 1)], *args, **kw_args)
You should add a parameter to you function. So you have one function to solve all your schemes :
def solve_Legendre(p,Tmax,init,dt=0.001, RK):
f = Legendre(p)
solver = RK(init,f)
while solver.now() < Tmax:
solver(dt)
return solver.state()
You can set a default value for RK if you want :
def solve_Legendre(p,Tmax,init,dt=0.001, RK=RK_1):

How to use different functions in for loop in each iteration without using exec?

I am creating a program which fits various curves to data. I am creating a number of functions which define a fit by doing the following:
for i in range(len(Funcs2)):
func = "+".join(Funcs2[i])
func = func.format("[0:3]","[3:6]")
exec('def Trial1{0}(x,coeffs): return {1}'.format(i, func))
exec('def Trial1{0}_res(coeffs, x, y): return y - Trial1{0}
(x,coeffs)'.format(i))
How do I then call each function of these created functions in turn. At the moment i am doing the following:
for i in range(len(Funcs2)):
exec('Trial1{0}_coeffs,Trial1{0}_cov,Trial1{0}_infodict,Trial1{0}_
mesg,Trial1{0}_flag =
scipy.optimize.leastsq(Trial1{0}_res,x02, args=(x, y),
full_output = True)'.format(i))
In this loop, each created function is called in each iteration of the loop.The problem is that i have to keep using exec() to do want I want to do. This is probably bad practice and there must be another way to do it.
Also, i cannot use libraries other than numpy,scipy and matplotlib
Sorry for the bad formatting. The box can only take lines of code that are so long.
Functions are first-class objects in python! You can put them in containers like lists or tuples, iterate through them, and then call them. exec() or eval() are not required.
To work with functions as objects instead of calling them, omit the parentheses.
EG:
def plus_two(x):
return x+2
def squared(x):
return x**2
def negative(x):
return -x
functions = (plus_two, squared, negative)
for i in range(1, 5):
for func in functions:
result = func(i)
print('%s(%s) = %s' % (func.__name__, i, result))
--> OUTPUT
plus_two(1) = 3
squared(1) = 1
negative(1) = -1
plus_two(2) = 4
squared(2) = 4
negative(2) = -2
plus_two(3) = 5
squared(3) = 9
negative(3) = -3
plus_two(4) = 6
squared(4) = 16
negative(4) = -4

Python returning variables from various functions

from __future__ import division
import math
def main():
the_discriminant = discrim(1,0,-4)
print the_discriminant
the_rest(discrim,b,a)
def discrim(a,b,c):
discriminant = math.sqrt(math.pow(b,2)-4*a*c)
return discriminant, b,a
def the_rest(discrim,b,a):
x = ((-b + discriminant) / 2*a)
y = ((-b - discriminant) / 2*a)
print x,y
if __name__ == '__main__':
main()
I am fairly new to Python, and I'm playing with writing functions and returning variables, I'm a little confused on how to correct the code. I am writing a quadratic solver program, but I need to use the discriminant and a,b,c values in "the rest" function. (which does the rest of the equation.) I'm kind of confused on how to return the values and use them in another function. Thanks!
the_rest(*the_discriminant)
or (and I prefer this method):
d, b, a = discrim(1, 0, -4)
the_rest(d, b, a)
I believe this is what you're trying to do. your discrim function returns a tuple (similar to an array). Then when you call the_rest using a * indicates that you want to send the elements of the tuple, rather than the tuple itself as one argument
from __future__ import division
import math
def main():
the_discriminant = discrim(1,0,-4)
print the_discriminant
the_rest(*the_discriminant)
def discrim(a,b,c):
discriminant = math.sqrt(math.pow(b,2)-4*a*c)
return discriminant, b,a
def the_rest(discrim,b,a):
x = (-b + discrim) / (2*a)
y = (-b - discrim) / (2*a)
return x, y
if __name__ == '__main__':
main()
while jamylak's answer is correct, it can also be much more maintainable to return a simple class. Then if you ever change your function/return values/representation, the calling code:
is name/identifier-based; it is very flexible to change; its not order dependent, or tuple length dependent. It is also saves you typing and unnecessary duplication of ordering implied rules throughout your code.
if there IS a breaking change the interpreter will error on module load instead of at runtime, so you are not going to miss the error. This is because you are trying to access named members, and are not relying on some "hidden" or "implied" rule like tuple ordering that is not formalised anywhere in the code.
For a larger project this is definitely the way to go.
There's nothing wrong with returning tuples like in your version of discrim. But the code just doesn't make as much sense (IMO) that way.
Try it like so:
#!/usr/bin/env python
from __future__ import division
import math
def main():
a = 1
b = 0
c = -4
the_discriminant = discrim(a, b, c)
print the_discriminant
x, y = the_rest(the_discriminant,b,a)
print x, y
def discrim(a,b,c):
discriminant = math.sqrt(math.pow(b,2)-4*a*c)
return discriminant
def the_rest(d, b,a):
x = ((-b + d) / 2*a)
y = ((-b - d) / 2*a)
return x,y
if __name__ == '__main__':
main()

Python: exec "function()"

I'm coding a simple test program in python as part of my greater program, but i would l like to pass a sub function name into the main function, so the main function can run the subfunction.
eg:
import datetime;
def cronjob(repeat, interval, task):
if (str(repeat) == 'inf'):
repeat = 99999999999999999999;
position = 0;
interval = datetime.timedelta(seconds=interval);
x = datetime.datetime.now()
while not (position >= repeat):
while (datetime.datetime.now() - x < interval):
pass;
x = datetime.datetime.now();
position += 1;
exec task;
def test():
print "hello";
cronjob(10, 0.1, 'test');
EDIT: Already fixed this, but since nothing is listed here, let me show you how to do it in case someone else needs it.
I fiddled with eval() and exec, and tried just eval(task). that didn't throw an error, so I tried print eval(task) and sure enough, it listed the function's memory address [that is, test()]. finally, I have used eval(task); to then call that function. below is the code fixing this:
import datetime;
def cronjob(repeat, interval, task):
if (str(repeat) == 'inf'):
repeat = 99999999999999999999;
position = 0;
interval = datetime.timedelta(seconds=interval);
x = datetime.datetime.now()
while not (position >= repeat):
while (datetime.datetime.now() - x < interval):
pass;
x = datetime.datetime.now();
position += 1;
eval(task);
def test():
print "hello";
cronjob(10, 0.1, 'test()');
Why not pass the function object itself to the scheduler ?
test is an object and can be used as an argument too!
def test():
print "test"
def exe(func):
func()
exe(test)
I believe since functions are objects, you can just pass one in to the "controlling" function by name, so you don't need the exec call (which is usually used for dynamic code execution).
e.g.
def foo(a_number, a_function):
print a_number
a_number += 1
a_function(a_number)
def bar(another_number):
print another_number
foo(5, bar)
should produce the output:
5
6
In case if you're absolutely sure you want to derive a function from a string, you may want to use a dict as a mapping from strings to functions like follows:
dispatcher = {'dothis': module1.do_this,
'dothat': module2.to_that}
def foo(fun):
fun(arg1, arg2)
def bar(action):
fun = dispatcher.get(action)
if fun:
foo(fun)
This will be much more secure (as action is likely to come from the outside) and provide better decoupling of internal code structure from the external API.

Implementation of functions with very basic scripting

I've been playing around with python for some time and decided to better my generalized understanding of programming languages by writing a custom script handler in python. I have so far successfully implemented a basic memory handler and hooked a memory address ordinate to printing to the screen. My question can be posed as:
How can functions be implemented here? A goto statement is too easy, I would like to try something more difficult. (edit) Eventually i want to be able to do:
f0(x, y, z):=ax^by^cz
...in a shell that runs a script that runs this module (silly, eh?)
# notes: separate addresses from data lest the loop of doom cometh
class Interpreter:
def __init__(self):
self.memory = { }
self.dictionary = {"mov" : self.mov,
"put" : self.put,
"add" : self.add,
"sub" : self.sub,
"clr" : self.clr,
"cpy" : self.cpy,
"ref" : self.ref }
self.hooks = {self.val("0") : self.out }
def interpret(self, line):
x = line.split(" ")
vals = tuple(self.val(y) for y in x[1:])
dereferenced = []
keys_only = tuple(key for key in self.memory)
for val in vals:
while val in self.memory: val = self.memory[val]
dereferenced.append(val)
vals = tuple(y for y in dereferenced)
self.dictionary[x[0]](vals)
def val(self, x):
return tuple(int(y) for y in str(x).split("."))
def mov(self, value):
self.ptr = value[0]
def put(self, value):
self.memory[self.ptr] = value[0]
def clr(self, value):
if self.ptr in self.hooks and self.ptr in self.memory:
x = self.hooks[self.ptr]
y = self.memory[self.ptr]
for z in y: x(z)
del self.memory[self.ptr]
def add(self, values):
self.put(self.mat(values, lambda x, y: x + y))
def sub(self, values):
self.put(self.mat(values, lambda x, y: x - y))
def mat(self, values, op):
a, b = self.memory[values[0]], self.memory[values[1]]
if len(a) > len(b): a, b = b, a
c = [op(a[x], b[x]) for x in xrange(len(b))] + [x for x in a[len(a):]]
return [tuple(x for x in c)]
def cpy(self, value):
self.put(value)
def out(self, x):
print chr(x),
def ref(self, x):
self.put(x)
interp = Interpreter()
for x in file(__file__.split('/')[-1].split(".")[-2] + ".why"):
interp.interpret(x.strip())
a sample script:
mov 1
put 104.101.108.108.111.10
mov 0
ref 1
clr 0
(EDIT) I've made the decision to use this attempt as inspiration and start from scratch on this project. (Hopefully I'll find some real time to sit down and code before classes start up again.) I intend to award the best answer in a few days. I hope that that information fails to dissuade potential contributors from submitting anything they feel to be helpful for this sort of coding problem.
I am struggling a bit to understand what you are asking. Where is your function definition to be given? In the script handler or in the script?
If it is in the script handler, the obvious solution would be to use the lambda expression. Using the example you used in the question f0(x, y, z):=x^2 would translate in:
>>> f0 = lambda x, y, z : x**2
>>> f0(2,3,4)
4
If the function definitions are to be placed in the script itself, you could get away with a combination of lambda and eval expressions. Here's a quick example that I just hammered together to illustrate the idea.
class ScriptParser(object):
# See 'to_python' to check out what this does
mapping = {'^':'**', '!':' not ', '&':' and '}
def to_python(self, calc):
'''
Parse the calculation syntax from the script grammar to the python one.
This could be grown to a more complex parser, if needed. For now it will
simply assume any operator as defined in the grammar used for the script
has an equivalent in python.
'''
for k, v in self.mapping.items():
calc = calc.replace(k, v)
return calc
def feed(self, lfs):
'''
Parse a line of the script containing a function defintion
'''
signature, calc = lfs.split(':=')
funcname, variables = [s.strip() for s in signature.split('(')]
# as we stripped the strings, it's now safe to do...'
variables = variables[:-1]
setattr(self, funcname,
eval('lambda ' + variables + ' : ' + self.to_python(calc)))
def main():
lines = ['f0(x, y, z) := x^2',
'f1(x) := x**2 + x**3 + x*1000']
sp = ScriptParser()
for line in lines:
sp.feed(line)
print('Script definition : %s' % line)
for i in range(5):
res0 = sp.f0(i, None, None)
res1 = sp.f1(i)
print('f0(%d) = %d' % (i, res0))
print('f1(%d) = %d' % (i, res1))
print('--------')
if __name__ == '__main__':
main()
Running this program outputs:
Script definition : f0(x, y, z) := x^2
Script definition : f1(x) := x**2 + x**3 + x*1000
f0(0) = 0
f1(0) = 0
--------
f0(1) = 1
f1(1) = 1002
--------
f0(2) = 4
f1(2) = 2012
--------
f0(3) = 9
f1(3) = 3036
--------
f0(4) = 16
f1(4) = 4080
--------
Keep in mind though that:
Using eval has security implications that you should be aware of.
Writing your own grammar parser is a truly cool learning experience!! :)
HTH,
Mac.
If you go to a compiler manual, it will advise to use stacks when calling methods. That will allow you to create recursive functions, a function that calls other functions, and also keep you variables in proper scope.
So you use a stack to stack up your variables for each function call, and yes, use goto to go to the address of the function. Then use your stack to get the return address of the function, and the state of the variables when the function was called. That's it.
Good luck!
Not sure if I'm understanding you right, but if your goal is to be able to define a function by doing f0(x):=mov x and other complex syntaxes, then it sounds to me like the big components you're missing are some sort of lexical analysis and a grammar parser. Once you get away from the concept of "first symbol on the line defines what the line does", then your method of line.split(" ") is no longer sufficient. These are pretty complex tools, and every language more complex than assembly requires these tools (though they may be built by hand, depending on the language and compiler/interpreter).
Most parse their inputs in two primary steps:
1) Lexical Analysis -- This step takes "x+1/5" and translates it into meaningful symbols like "VARIABLE OPERATOR NUMBER OPERATOR NUMBER". The output from this step is used as the input to the grammar parser
2) Grammar parsing -- This is more complex, and there's a large amount of theory on the best ways to do grammar parsing. This will take the above input and parse it into a tree that can be evaluated. Like:
Operator+
| |
| ----Variable x
Operator/
| |
1 5
I don't have any experience with either of these types of tools in Python. In C++, the only tools I've used are called flex, and bison. I'm sure someone else here has used tools like these before in python, and could point you to some links. Looks like this question has some: Efficient Context-Free Grammar parser, preferably Python-friendly
I tried searching for some tutorials for ya on the concepts, but came up blank. My googling skills are not turned on tonight, for some reason.
Consider using pyparsing to define your grammar. There are lots of examples on its wiki, such as an interactive calculator.

Categories