At some point, Kyler Laird <Kyler at news.Lairds.org> wrote:
> Richie Hindle <richie at entrian.com> writes:>>[Cameron]>>> Whenever you feel like a lambda, define a named function; >>[Kyler]>>> How do you cleanly do that?>>> foo = range(-10, 10)>>> my_op = lambda x: float(x) / max(map(abs, foo))>>> bar = map(my_op, foo)>>>foo = range(-10, 10)>>def my_op(x):>> return float(x) / max(map(abs, foo))>>bar = map(my_op, foo)>>>...did I misunderstand?>> Well, your solution depends on a global variable. That's going to> get *really* ugly if we move beyond the trivial example given here.> There are other problems but they're apparently not obvious with > that example.
The lambda depends on a global variable too (or at least, a variable
up one scope).
> How 'bout some non-working code to shine some more light on it? (If> pressed, I should be able to come up with similar code that works!)>> def make_translation_function(GCPs, type, invert=False):> if type == 'LSF' and len(GCPs) < 12:> # Do lots of time-consuming magic to calculate A, B, ...> return(> lambda x, y: (> x * A + y * B +> x * y * C +> ...,> x * G + y * H +> x * y * I +> ...> )> )> elif ... # Repeat lots of times for variations.>> map_im = foo.open('map.tif')> map_translation = make_translation_function(map_im.get_GCPs, type='LSF')>> path_im = foo.open('path.tif')> path_translation_i = make_translation_function(path_im.get_GCPs, type='LSF', invert=True)>> # Mark all points on map that are red in path.> for (x, y) in all_red_pixels(path_im):> (lon, lat) = path_translation_i(x, y)> (x, y) = map_translation(lon, lat)> map_im.putpixel((x, y), mark_val)>> Now, let's pretend that this is part of a larger program that's doing lots> of things with, potentially, lots of images, and let's also say that we> allow user-defined/imported extensions to make_translation_function().> How are you going to make a *clean* solution using named functions?
Umm, easily? You don't have to refer to functions by their original
name; they are first-class objects.
def make_translation_function(GCPs, type, invert=False):
if type == 'LSF' and len(GCPs) < 12:
# Do lots of time-consuming magic to calculate A, B, ...
def LSF_function(x, y):
xy = x*y
lon = x*A + y*B + xy*C + ...
lat = x*G + y*H + xy*I + ...
return (lon, lat)
return LSF_function
elif ... # Repeat lots of times for variations.
I've even optimized by premultiplying x and y, which couldn't do in
the lambda, and made the code clearer by breaking up the calculation.
--
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca