comments? storing a function in an object

Francesco Bochicchio bieffe62 at gmail.com
Mon Jul 20 13:44:16 EDT 2009


On Jul 20, 6:22 pm, Esmail <ebo... at 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





More information about the Python-list mailing list