On Jul 20, 6:22 pm, Esmail <ebo...@hotmail.com> wrote: > Hello all, > > I am trying to store a function and some associated information in an > object so that I can later have series of functions in a list that I can > evaluate one at a time. > > Right now I am only storing the function itself, the number of > arguments it expects and its string representation. I may add other > information such as the acceptable range for the parameters or other > characteristics such as maximum or minimum. > > I wonder if anyone could comment on my implementation and offer > suggestions or constructive criticisms? > > The 'loading' of the functions is a bit tedious and of course care > has to be taken to make sure the string representation corresponds to > the actual function computed. It would be nice if there was an > automatic way to convert the function to its string representation. > > Comments or problems with the approach I have taken? > > Thanks, > Esmail > > -- > > #!/usr/bin/env python > > # > # store and represent functions > # > > import math > > class FunctionException(Exception): > """ custom exception """ > def __init__(self, value): > self.parameter = value > > def __str__(self): > return repr(self.parameter) > > class Function(object): > """ class to represent a function """ > > def __init__(self, fn, fn_str, num_vars): > """ > the function, its string representation, and the number of variables > """ > self.fn = fn > self.fn_str = fn_str > self.num_vars = num_vars > > def eval_fn(self, variables): > """ size of variables should equal num_vars .. else problem """ > if len(variables) == self.num_vars: > result = self.fn(*variables) > return result > else: > raise FunctionException('invalid number of args provided - '+ > 'received %d, expected %d' > %(len(variables), self.num_vars)) > > def str(self): > """ return string representation of function """ > return self.fn_str > > def funct1(x): > ''' small test function ''' > return x * x > > def funct2(x, y): > ''' small test function ''' > return x + y > > def funct3(x): > ''' small test function ''' > return 1000 + (x*x + x) * math.cos(x) > > def main(): > """ main method """ > print 'in main' > > fn1 = Function(funct1, 'x * x', 1) > fn2 = Function(funct2, 'x + y', 2) > fn3 = Function(funct3, '1000 + (x*x + x) * cos(x)', 1) > > for i in range(-10, 10): > try: > > print 'f(', [i],') =', > print fn3.str(), ' => ', > print fn3.eval_fn([i]) > > except FunctionException, (ex): > print ex.parameter > > if __name__ == '__main__': > main()
I can offer some small suggestions: it is up to you to evaluate if they make sense for your app: 1. use __doc__ function standard attribute for function description (your fn_str); this meanst that you do not need fm_str in the constructor and you have to do e.g. : def funct2(x, y): ''' x + y ''' return x + y then funct2.__doc__ becomes the string you want to associate to the function 2. Use __call__ instead of eval_fn : this way, the instance of your Function became a 'callable' and can be used everywhere a function is needed. You can do: f = Function(...) f( some_args ) 3. If you call a python function with wrong number of arguments, it already raises a TypeError exception which contains - with different wording - the same information of your FunctionException : consider removing the check and using the python error instead HTH Ciao ------ FB -- http://mail.python.org/mailman/listinfo/python-list