En Mon, 20 Jul 2009 14:44:16 -0300, Francesco Bochicchio <bieff...@gmail.com> escribió:

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

If you follow the above suggestions, you'll see that your Function class becomes almost useless: a normal function already IS an object, so you don't have to wrap it inside ANOTHER object unless you need very special features.

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to