function name as parameter

I'm trying to write an implementation of the amoeba function from numerical recipes and need to be able to pass a function name and parameter list to be called from within the amoeba function. Simply passing the name as a string doesn't work since python doesn't know it is a function and throws a typeerror. Is there something similar to IDL's 'call_function' routine in python/numpy or a pythonic/numpy means of passing function names? -- Thomas K. Gamble Research Technologist, System/Network Administrator Chemical Diagnostics and Engineering (C-CDE) Los Alamos National Laboratory MS-E543,p:505-665-4323 f:505-665-4267 There cannot be a crisis next week. My schedule is already full. Henry Kissinger

I'm trying to write an implementation of the amoeba function from numerical recipes and need to be able to pass a function name and parameter list to be called from within the amoeba function. Simply passing the name as a string doesn't work since python doesn't know it is a function and throws a typeerror. Is there something similar to IDL's 'call_function' routine in python/numpy or a pythonic/numpy means of passing function names?
Just pass the function itself! For example: def foo(): print 6 def call_function_repeatedly(func, count): for i in range(count): func() call_function_repeatedly(foo, 2) # calls foo twice bar = foo bar() # still calls foo... we've just assigned the function to a different name In python, functions (and classes, and everything else) are first- class objects and can be assigned to variables, passed around, etc, etc, just as anything else. However, note that scipy.optimize.fmin implements the Nelder-Mead simplex algorithm, which is (I think) the same as the "amoeba" optimizer. Also you might be interested in the openopt package, which implements more optimizers a bit more consistently than scipy.optimize. Zach

On Wed, Oct 20, 2010 at 9:46 AM, Zachary Pincus <zachary.pincus@yale.edu> wrote:
I'm trying to write an implementation of the amoeba function from numerical recipes and need to be able to pass a function name and parameter list to be called from within the amoeba function. Simply passing the name as a string doesn't work since python doesn't know it is a function and throws a typeerror. Is there something similar to IDL's 'call_function' routine in python/numpy or a pythonic/numpy means of passing function names?
Just pass the function itself! For example:
def foo(): print 6
def call_function_repeatedly(func, count): for i in range(count): func()
call_function_repeatedly(foo, 2) # calls foo twice
bar = foo bar() # still calls foo... we've just assigned the function to a different name
In python, functions (and classes, and everything else) are first- class objects and can be assigned to variables, passed around, etc, etc, just as anything else.
This is the best way, but if you want to pass the function name as string, then you need to get the function with getattr for example, scipy has code like this def func(distname, args): distfn = getattr(scipy.stats, distname) distfn.rvs(args) func('norm') Josef
However, note that scipy.optimize.fmin implements the Nelder-Mead simplex algorithm, which is (I think) the same as the "amoeba" optimizer. Also you might be interested in the openopt package, which implements more optimizers a bit more consistently than scipy.optimize.
Zach _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

If you really need to pass the function name : In [3]: def my_func(x): ...: return 2*x In [4]: def caller(fname,x): ...: return eval("%s(%f)"%(fname,x)) In [5]: caller("my_func",2) Out[5]: 4.0 On 10/20/2010 03:46 PM, Zachary Pincus wrote:
I'm trying to write an implementation of the amoeba function from numerical recipes and need to be able to pass a function name and parameter list to be called from within the amoeba function. Simply passing the name as a string doesn't work since python doesn't know it is a function and throws a typeerror. Is there something similar to IDL's 'call_function' routine in python/numpy or a pythonic/numpy means of passing function names?
Just pass the function itself! For example:
def foo(): print 6
def call_function_repeatedly(func, count): for i in range(count): func()
call_function_repeatedly(foo, 2) # calls foo twice
bar = foo bar() # still calls foo... we've just assigned the function to a different name
In python, functions (and classes, and everything else) are first- class objects and can be assigned to variables, passed around, etc, etc, just as anything else.
However, note that scipy.optimize.fmin implements the Nelder-Mead simplex algorithm, which is (I think) the same as the "amoeba" optimizer. Also you might be interested in the openopt package, which implements more optimizers a bit more consistently than scipy.optimize.
Zach _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Wed, Oct 20, 2010 at 6:51 AM, Johann Cohen-Tanugi <cohen@lpta.in2p3.fr> wrote:
If you really need to pass the function name : In [3]: def my_func(x): ...: return 2*x
In [4]: def caller(fname,x): ...: return eval("%s(%f)"%(fname,x))
In [5]: caller("my_func",2) Out[5]: 4.0
The better way to do this is: import inspect def call_this(fname, x): caller_frame = inspect.currentframe().f_back f = caller_frame.f_locals.get(fname, caller_frame.f_globals.get(fname)) return f(x) IMPORTANT USAGE NOTE: never do this :-) -- Nathaniel

On 10/20/2010 10:35 PM, Nathaniel Smith wrote:
On Wed, Oct 20, 2010 at 6:51 AM, Johann Cohen-Tanugi <cohen@lpta.in2p3.fr> wrote:
If you really need to pass the function name : In [3]: def my_func(x): ...: return 2*x
In [4]: def caller(fname,x): ...: return eval("%s(%f)"%(fname,x))
In [5]: caller("my_func",2) Out[5]: 4.0
The better way to do this is:
import inspect def call_this(fname, x): caller_frame = inspect.currentframe().f_back f = caller_frame.f_locals.get(fname, caller_frame.f_globals.get(fname)) return f(x)
thanks for this probably safer way to do this (I guess safer, as I know nothing about inspect module, but can imagine the value of being explicit as to frames and namespaces)
IMPORTANT USAGE NOTE: never do this :-)
What would you recommand? I do encounter situations where I need instantiation based on the name of the thing to instantiate, typically passed as an argument by the client code/user..... thanks in advance, Johann
-- Nathaniel _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Wed, Oct 20, 2010 at 15:58, Johann Cohen-Tanugi <cohen@lpta.in2p3.fr> wrote:
On 10/20/2010 10:35 PM, Nathaniel Smith wrote:
IMPORTANT USAGE NOTE: never do this :-)
What would you recommand? I do encounter situations where I need instantiation based on the name of the thing to instantiate, typically passed as an argument by the client code/user.....
Example? -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco

On 10/20/2010 11:10 PM, Robert Kern wrote:
On Wed, Oct 20, 2010 at 15:58, Johann Cohen-Tanugi<cohen@lpta.in2p3.fr> wrote:
On 10/20/2010 10:35 PM, Nathaniel Smith wrote:
IMPORTANT USAGE NOTE: never do this :-)
What would you recommand? I do encounter situations where I need instantiation based on the name of the thing to instantiate, typically passed as an argument by the client code/user.....
Example?
Hi Robert, so in a big data analysis framework, that is essentially written in C++, exposed to python with SWIG, plus dedicated python modules, the user performs an analysis choosing some given modules by name,as in : myOpt="foo" my_analyse.perform(use_optimizer=myOpt) The attribute use_optimizer is then checked to perform the right calls/instantiations of python but also C++ objects..... and the actual crunching number is in the C++ part. But then I realize that I need to tweak this optimizer's state, and the optimizer object is accessible from a library pyOpt that has been swigified from a C++ library. Then I access the object by calling optObject = eval("pyOpt.%s(some_args)"%myOpt) where myOpt would be "foo" in this particular analysis. This is because what the attribute use_optimizer expects is also the object name in the library, of course. It goes without saying that I could do : if myOpt=="foo": optObject=pyOpt.foo(some_args) else: .... and if you guys tell me it is way safer, I will do that instead of the use of eval that I liked because of the compactness..... As to Nathaniel's last point : yes of course the type changing of 'x' in my code would be unacceptable if x becomes complicated enough. This was not meant to be used in *any* situation. cheers, Johann

Hi Robert, so in a big data analysis framework, that is essentially written in C ++, exposed to python with SWIG, plus dedicated python modules, the user performs an analysis choosing some given modules by name,as in : myOpt="foo" my_analyse.perform(use_optimizer=myOpt)
The attribute use_optimizer is then checked to perform the right calls/instantiations of python but also C++ objects..... and the actual crunching number is in the C++ part. But then I realize that I need to tweak this optimizer's state, and the optimizer object is accessible from a library pyOpt that has been swigified from a C++ library. Then I access the object by calling optObject = eval("pyOpt.%s(some_args)"%myOpt) where myOpt would be "foo" in this particular analysis. This is because what the attribute use_optimizer expects is also the object name in the library, of course. It goes without saying that I could do : if myOpt=="foo": optObject=pyOpt.foo(some_args) else: .... and if you guys tell me it is way safer, I will do that instead of the use of eval that I liked because of the compactness.....
Well, optObject=getattr(pyOpt, myOpt) is a bit nicer and marginally more likely to return sane error messages than optObject=eval("pyOpt. %s"%myOpt). Then you could do result=optObject(some_args)... But why not have the user just pass in the relevant optObject from the pyOpt namespace (or some restricted namespace that just has the relevant functions exposed)? E.g. my_analysis.perform(optimizer=pyOpt.Amoeba) rather than my_analysis.perform(optimizer='Amoeba') This lets users do introspection on the pyOpt namespace to see what functions they can choose from, which is rather friendlier in an interactive environment. Zach

On Wed, Oct 20, 2010 at 16:49, Zachary Pincus <zachary.pincus@yale.edu> wrote:
But why not have the user just pass in the relevant optObject from the pyOpt namespace (or some restricted namespace that just has the relevant functions exposed)? E.g. my_analysis.perform(optimizer=pyOpt.Amoeba) rather than my_analysis.perform(optimizer='Amoeba')
+11ty-billion
This lets users do introspection on the pyOpt namespace to see what functions they can choose from, which is rather friendlier in an interactive environment.
Or implement their own without having to modify pyOpt. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco

On 10/20/2010 11:49 PM, Zachary Pincus wrote:
Hi Robert, so in a big data analysis framework, that is essentially written in C ++, exposed to python with SWIG, plus dedicated python modules, the user performs an analysis choosing some given modules by name,as in : myOpt="foo" my_analyse.perform(use_optimizer=myOpt)
The attribute use_optimizer is then checked to perform the right calls/instantiations of python but also C++ objects..... and the actual crunching number is in the C++ part. But then I realize that I need to tweak this optimizer's state, and the optimizer object is accessible from a library pyOpt that has been swigified from a C++ library. Then I access the object by calling optObject = eval("pyOpt.%s(some_args)"%myOpt) where myOpt would be "foo" in this particular analysis. This is because what the attribute use_optimizer expects is also the object name in the library, of course. It goes without saying that I could do : if myOpt=="foo": optObject=pyOpt.foo(some_args) else: .... and if you guys tell me it is way safer, I will do that instead of the use of eval that I liked because of the compactness.....
Well, optObject=getattr(pyOpt, myOpt) is a bit nicer and marginally more likely to return sane error messages than optObject=eval("pyOpt. %s"%myOpt). Then you could do result=optObject(some_args)...
ok I definitely like that better than eval.
But why not have the user just pass in the relevant optObject from the pyOpt namespace (or some restricted namespace that just has the relevant functions exposed)? E.g. my_analysis.perform(optimizer=pyOpt.Amoeba) rather than my_analysis.perform(optimizer='Amoeba')
Well, that means that the user now needs to know about the underlying C++ library, etc.... Just requiring from the user that he knows the *name* of the optimizer was the primary driver. But I understand that it easily drives to a dead-end. my_analysis.perform(optimizer=pyOpt.Amoeba) is definitely allowed in the code as well, and that is what I do after I have fiddle with the optimizer object. Thanks to all for the tips and advices! Johann
This lets users do introspection on the pyOpt namespace to see what functions they can choose from, which is rather friendlier in an interactive environment.
Zach _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

Johann Cohen-Tanugi wrote:
On 10/20/2010 11:10 PM, Robert Kern wrote:
On Wed, Oct 20, 2010 at 15:58, Johann Cohen-Tanugi<cohen@lpta.in2p3.fr> wrote:
On 10/20/2010 10:35 PM, Nathaniel Smith wrote:
IMPORTANT USAGE NOTE: never do this :-)
What would you recommand? I do encounter situations where I need instantiation based on the name of the thing to instantiate, typically passed as an argument by the client code/user.....
Example?
Hi Robert, so in a big data analysis framework, that is essentially written in C++, exposed to python with SWIG, plus dedicated python modules, the user performs an analysis choosing some given modules by name,as in : myOpt="foo" my_analyse.perform(use_optimizer=myOpt)
The attribute use_optimizer is then checked to perform the right calls/instantiations of python but also C++ objects..... and the actual crunching number is in the C++ part. But then I realize that I need to tweak this optimizer's state, and the optimizer object is accessible from a library pyOpt that has been swigified from a C++ library. Then I access the object by calling optObject = eval("pyOpt.%s(some_args)"%myOpt) where myOpt would be "foo" in this particular analysis. This is because what the attribute use_optimizer expects is also the object name in the library, of course. It goes without saying that I could do : if myOpt=="foo": optObject=pyOpt.foo(some_args) else: .... and if you guys tell me it is way safer, I will do that instead of the use of eval that I liked because of the compactness.....
In this case getattr fits... in general, in cases where one could do if action == 'a': a() elif action == 'b': b() the nice (proper?) way of doing it is usually to populate a dictionary: actions['a'] = a actions['b'] = b # automatically populate etc... actions[action]() And on the subject of passing strings around and eval-ing them: http://cache.gawkerassets.com/assets/images/4/2010/03/for_traffic_cameras.jp... Dag Sverre

On Wed, Oct 20, 2010 at 1:58 PM, Johann Cohen-Tanugi <cohen@lpta.in2p3.fr> wrote:
On 10/20/2010 10:35 PM, Nathaniel Smith wrote:
The better way to do this is:
import inspect def call_this(fname, x): caller_frame = inspect.currentframe().f_back f = caller_frame.f_locals.get(fname, caller_frame.f_globals.get(fname)) return f(x)
thanks for this probably safer way to do this (I guess safer, as I know nothing about inspect module, but can imagine the value of being explicit as to frames and namespaces)
Right, there are two big advantages: (1) it looks up the name in the *caller*'s namespace, so it works even if the function is called from another module, (2) you don't have to rely on 'x' going float->string->back to float. (Which probably doesn't make much difference if you just have a single float argument, but for anything more complicated you can avoid a lot of hassle.)
IMPORTANT USAGE NOTE: never do this :-)
What would you recommand? I do encounter situations where I need instantiation based on the name of the thing to instantiate, typically passed as an argument by the client code/user..... thanks in advance,
Really, the recommendation is to define your API differently, so that people pass in actual objects (or whatever makes sense) instead of strings. But if you need to do this ugly thing for some reason (I've only needed it once, in a *very* exotic situation way outside what any normal scientific programmer would run into), then 'inspect' is probably the best way to accomplish it. -- Nathaniel

On Wed, 2010-10-20 at 09:46 -0400, Zachary Pincus wrote:
I'm trying to write an implementation of the amoeba function from numerical recipes and need to be able to pass a function name and parameter list to be called from within the amoeba function. Simply passing the name as a string doesn't work since python doesn't know it is a function and throws a typeerror. Is there something similar to IDL's 'call_function' routine in python/numpy or a pythonic/numpy means of passing function names?
Just pass the function itself! For example:
def foo(): print 6
def call_function_repeatedly(func, count): for i in range(count): func()
call_function_repeatedly(foo, 2) # calls foo twice
bar = foo bar() # still calls foo... we've just assigned the function to a different name
This works fine. Too obvious to see, I guess.
In python, functions (and classes, and everything else) are first- class objects and can be assigned to variables, passed around, etc, etc, just as anything else.
However, note that scipy.optimize.fmin implements the Nelder-Mead simplex algorithm, which is (I think) the same as the "amoeba" optimizer. Also you might be interested in the openopt package, which implements more optimizers a bit more consistently than scipy.optimize.
I try this and compare performance. I had looked for an 'amoeba' function, but couldn't find anything by that name. I should have broadened my search a bit. ;-)
Zach _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
-- Thomas K. Gamble Research Technologist, System/Network Administrator Chemical Diagnostics and Engineering (C-CDE) Los Alamos National Laboratory MS-E543,p:505-665-4323 f:505-665-4267 There cannot be a crisis next week. My schedule is already full. Henry Kissinger

On 10/20/2010 9:42 AM, Thomas Kirk Gamble wrote:
I'm trying to write an implementation of the amoeba function from numerical recipes and need to be able to pass a function name and parameter list to be called from within the amoeba function.
1. Have you checked whether this might already be in OpenOpt? 2. Here is a GAUSS version, that might (?) be easier to follow. http://www1.american.edu/academic.depts/cas/econ/gaussres/optimize/honore.sr... Alan Isaac

On Wed, 2010-10-20 at 13:18 -0400, Alan G Isaac wrote:
On 10/20/2010 9:42 AM, Thomas Kirk Gamble wrote:
I'm trying to write an implementation of the amoeba function from numerical recipes and need to be able to pass a function name and parameter list to be called from within the amoeba function.
1. Have you checked whether this might already be in OpenOpt? 2. Here is a GAUSS version, that might (?) be easier to follow. http://www1.american.edu/academic.depts/cas/econ/gaussres/optimize/honore.sr...
Yes, Zachary already pointed out a version in the scipy.optimize module. Thanks anyway for the reference. I tend to prefer evaluating multiple options rather than just taking the first one that seems to work.
Alan Isaac
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
-- Thomas K. Gamble Research Technologist, System/Network Administrator Chemical Diagnostics and Engineering (C-CDE) Los Alamos National Laboratory MS-E543,p:505-665-4323 f:505-665-4267 There cannot be a crisis next week. My schedule is already full. Henry Kissinger
participants (8)
-
Alan G Isaac
-
Dag Sverre Seljebotn
-
Johann Cohen-Tanugi
-
josef.pktd@gmail.com
-
Nathaniel Smith
-
Robert Kern
-
Thomas Kirk Gamble
-
Zachary Pincus