Dr. Dobb's Python-URL! - weekly Python news and links (Dec 7)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • bonono@gmail.com

    #16
    Re: lambda (and reduce) are valuable


    Paul Rubin wrote:[color=blue]
    > "Fredrik Lundh" <fredrik@python ware.com> writes:[color=green]
    > > a temporary factory function should be sufficient:
    > >
    > > def digit(label, x, y):
    > > def callback():
    > > # print "BUTTON PRESS", label # debug!
    > > user_pressed(in t(label))
    > > Button(label=la bel, command=callbac k).grid(column= x, row=y)[/color]
    >
    > Looking at the calculator program I wrote a while back (one of my
    > first Python programs, written just to play with tkinter), I see that
    > I actually did something like that for the buttons. However, it also
    > contained (in the other order):
    >
    > unops = {'sqrt': math.sqrt,
    > 'sin': math.sin,
    > 'cos': math.cos,
    > 'tan': math.tan,
    > 'ln': math.log,
    > 'log': lambda x: math.log(x)/math.log(10),
    > 'clr x': lambda x: 0
    > }
    >
    > binops = {'+': (lambda x,y: x+y),
    > '-': (lambda x,y: x-y),
    > '*': (lambda x,y: x*y),
    > '/': (lambda x,y: x/y),
    > '**': (lambda x,y: x**y)
    > }
    >
    > How would you refactor that, with no lambda?[/color]

    Or, why would you want to refactor that ? The lambdas were used as the
    quickest and the most straight forward way to have the solution back
    then I believe. Refactoring is an aftermath(perfo rmance, frequent
    change to the same module for feature changes etc.).
    Without lambda, even the first version would force the programmer to
    think more about how to factor it and it seems in this case, not
    necessary and waste of precious programmer time.

    Comment

    • Paul Rubin

      #17
      Re: lambda (and reduce) are valuable

      bonono@gmail.co m writes:[color=blue][color=green]
      > > How would you refactor that, with no lambda?[/color]
      > Or, why would you want to refactor that ?[/color]

      I like it the way it was written. I'm not the one saying lambda is bogus.

      Comment

      • Bengt Richter

        #18
        Re: lambda (and reduce) are valuable

        On Mon, 12 Dec 2005 09:15:38 +0100, "Fredrik Lundh" <fredrik@python ware.com> wrote:
        [color=blue]
        >Steven Bethard wrote:
        >[color=green][color=darkred]
        >> > I thought stuff like the following was idiomatic in GUI programming.
        >> > Do you really want separate names for all those callbacks?
        >> >
        >> > # generate calculator keypad buttons
        >> > Button(label='7 ', command=lambda: user_pressed(7) ).grid(column=1 , row=1)
        >> > Button(label='8 ', command=lambda: user_pressed(8) ).grid(column=2 , row=1)
        >> > Button(label='9 ', command=lambda: user_pressed(9) ).grid(column=3 , row=1)
        >> >
        >> > Button(label='4 ', command=lambda: user_pressed(4) ).grid(column=1 , row=2)
        >> > Button(label='5 ', command=lambda: user_pressed(5) ).grid(column=2 , row=2)
        >> > Button(label='6 ', command=lambda: user_pressed(6) ).grid(column=3 , row=2)
        >> > ...[/color]
        >>
        >> While I don't spend much time on GUIs, code like that would scream
        >> "refactor" to me, e.g. something like:
        >>
        >> class UserPressedButt on(Button):
        >> def __init__(self, i):
        >> def command():
        >> return user_pressed(i)
        >> Button.__init__ (self, label=str(i), command=command )
        >>
        >> Button(7).grid( column=1, row=1)
        >> Button(8).grid( column=2, row=1)
        >> Button(9).grid( column=3, row=1)
        >>
        >> Button(4).grid( column=1, row=2)
        >> Button(5).grid( column=2, row=2)
        >> Button(6).grid( column=3, row=2)[/color]
        >
        >a temporary factory function should be sufficient:
        >
        > def digit(label, x, y):
        > def callback():
        > # print "BUTTON PRESS", label # debug!
        > user_pressed(in t(label))
        > Button(label=la bel, command=callbac k).grid(column= x, row=y)
        >
        > # create numeric pad
        > digit("7", 1, 1); digit("8", 2, 1); digit("9", 3, 1)
        > digit("4", 1, 2); digit("5", 2, 2); digit("6", 3, 2)
        > digit("1", 1, 3); digit("2", 2, 3); digit("3", 3, 3)
        >
        >are people still missing that local functions are inexpensive in Python ?[/color]

        OTOH, (untested)

        for label, x, y in ((str(d+1), d%3+1, 3-d//3) for d in xrange(9)):
        Button(label=la bel, command=lambda d=int(label):us er_pressed(d)). grid(column=x, row=y)

        or

        for tup in ((str(d+1), d%3+1,3-d//3) for d in xrange(9)): digit(*tup)

        tweak 'til correct ;-)

        Regards,
        Bengt Richter

        Comment

        • Paul Rubin

          #19
          Re: lambda (and reduce) are valuable

          bokr@oz.net (Bengt Richter) writes:[color=blue]
          >
          > for tup in ((str(d+1), d%3+1,3-d//3) for d in xrange(9)): digit(*tup)
          >
          > tweak 'til correct ;-)[/color]

          GMTA. See:



          written a couple years ago. It uses:

          for i in xrange(1,10):
          add_button(5+2-(i-1)/3, (i-1)%3, str(i))

          Comment

          • Christopher Subich

            #20
            Re: lambda (and reduce) are valuable

            Chris Mellon wrote:[color=blue]
            > functions with real names is crucial to maintainable code. The only
            > reason to ever use a lamdba in Python is because you don't want to
            > give a function a name, and that is just not a compelling use case for
            > GUI events.[/color]

            Ah, but that neglects the sheer utility of delayed-evaluation
            expressions. Consider the key= parameter to list.sort, et. al:

            complicated_lis t.sort(key=lamb da x: x[3])

            Decorate-sort-undecorate is another way of doing this, but it's also
            boilerplate, involves list copies that have nothing to do with the flow
            of the program itself, and can possibly error (if done naively: key is
            comparable, but complex_list[i][0] isn't comparable, such as sorting a
            list of complex numbers by the real part, if two or more items have the
            same real).

            The key= parameter was implemented just to make this sort of thing
            clearer and easier (and, in an odd way, actually more semantically
            explicit). The utility of a full function for the key= is nice and
            necessary, but simultaneously a lot of the uses are going to be for
            one-off expressions (like item[3]). There, the idea of a named function
            seems conceptual overkill.

            The most significant problem with Python's lambda is that it's billed as
            an anonymous function, when it's really an encapsulated expression. My
            preferred solution is to replace lambda with something along the lines
            of an 'expression comprehension,' with similar syntax to list and
            generator comprehensions as-is:

            lambda param1, param2: stuff_with(para m2,param1) would become

            <(param1, param2): stuff_with(para m2, param1)>
            or, to become even more similar to comprehension syntax:
            <stuff_with(par am2, param1) with (param1, param2)>

            The only real problem, parsing-wise, with this syntax is that it can
            sometimes conflict with the << or >> operators if used without
            whitespace near comparisons.

            The scope of what can be contained in the expression comprehension
            (lambda currently) is exactly the same as what can be contained in a
            list/generator comprehension, so why not capitalize on the parallelism?

            Comment

            • Marc 'BlackJack' Rintsch

              #21
              Re: lambda (and reduce) are valuable

              In <dnmobd$5a0$1@r umours.uwaterlo o.ca>, Christopher Subich wrote:
              [color=blue]
              > Chris Mellon wrote:[color=green]
              >> functions with real names is crucial to maintainable code. The only
              >> reason to ever use a lamdba in Python is because you don't want to
              >> give a function a name, and that is just not a compelling use case for
              >> GUI events.[/color]
              >
              > Ah, but that neglects the sheer utility of delayed-evaluation
              > expressions. Consider the key= parameter to list.sort, et. al:
              >
              > complicated_lis t.sort(key=lamb da x: x[3])[/color]

              This can be written as::

              from operator import itemgetter
              complicated_lis t.sort(key=item getter(3))

              Ciao,
              Marc 'BlackJack' Rintsch

              Comment

              • bonono@gmail.com

                #22
                Re: lambda (and reduce) are valuable


                Marc 'BlackJack' Rintsch wrote:[color=blue]
                > In <dnmobd$5a0$1@r umours.uwaterlo o.ca>, Christopher Subich wrote:
                >[color=green]
                > > Chris Mellon wrote:[color=darkred]
                > >> functions with real names is crucial to maintainable code. The only
                > >> reason to ever use a lamdba in Python is because you don't want to
                > >> give a function a name, and that is just not a compelling use case for
                > >> GUI events.[/color]
                > >
                > > Ah, but that neglects the sheer utility of delayed-evaluation
                > > expressions. Consider the key= parameter to list.sort, et. al:
                > >
                > > complicated_lis t.sort(key=lamb da x: x[3])[/color]
                >
                > This can be written as::
                >
                > from operator import itemgetter
                > complicated_lis t.sort(key=item getter(3))
                >[/color]
                Though I find the lambda form easier for me to understand but
                itemgetter should be the preferred way as it should have some
                performance advantage and sort are those kind of functions that need
                it, in general.

                Comment

                • Cameron Laird

                  #23
                  Re: lambda (and reduce) are valuable

                  In article <mailman.1984.1 134375476.18701 .python-list@python.org >,
                  Fredrik Lundh <fredrik@python ware.com> wrote:

                  Comment

                  Working...