comments? storing a function in an object
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Mon Jul 20 17:38:22 EDT 2009
En Mon, 20 Jul 2009 14:44:16 -0300, Francesco Bochicchio
<bieffe62 at gmail.com> escribió:
> 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
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
More information about the Python-list
mailing list