Problem with Lexical Scope

Bengt Richter bokr at oz.net
Mon Dec 12 15:32:00 EST 2005


On 12 Dec 2005 01:23:48 -0800, "jslowery at gmail.com" <jslowery at gmail.com> wrote:

>Thanks for the example code. Definately provided a few different ways
>of doing the construction.
>
>Actually, the status variable was the only thing that mattered for the
>inner function.  The first code post had a bug b/c I was first just
>trying to use reduce. However, I realized that the boolean reducer
>ended up using the boolean result instead of the next field for
>subsequent operations.
>
>The effect I was going for was was a logical AND of all the returned
>values from reducer. However the inner function is supposed to use the
>same type algorithm as the built-in reduce function.
>
>reducer does have no side effects so I suppose short-circuting it would
>be the best thing. I think the only thing about the last example is
>that it starts things off with a zero. I think that would boink it.
>
>The way that this thing works is it's a general algorithm for boolean
>operations that are applied to fields in a dict.
>
>def lt(*fields):
>    return collect(fields, lambda x, y: x < y)
>
>data = {
>  'birth_date' : 19740201,
>  'hire_date' : 19840721,
>  'fire_date' :   19850123
>}
>
>rule = lt('birth_date', 'hire_date')
>assert rule(data) == True
>
I suspect you are trying to win an obfuscation contest ;-)
It appears that in this case you want lt to have the same effect
as if it were written

 >>> def lt(*fields):
 ...     def _(dct):
 ...         return dct[fields[0]] < dct[fields[1]]
 ...     return _
 ...
 >>> data = {
 ...   'birth_date' : 19740201,
 ...   'hire_date' : 19840721,
 ...   'fire_date' :   19850123
 ... }
 >>>
 >>> rule = lt('birth_date', 'hire_date')
 >>> rule
 <function _ at 0x02F986BC>
 >>> rule(data)
 True
 >>> assert rule(data)
 >>> assert rule(data) == True

But why do you need to "collect" with reduce and all that cryptic cruft?
I think we need a use case where you have other than two fields to operate on.
but in that case, what would reduce do? Something seems bogus with that.

I'm guessing you want to loop through a bunch of "records" that are extracted from
a database in the form of dicts, and you want to check them in various ways.
So you want to extract fields in given order and apply various checks, something like (untested)

    for data in dbrecordsupply:
        for fields, check, msg in record_supply_checklist:
            assert check(*[data[field] for field in fields]), msg

where record_supply_checklist is something like (untested) (and eschewing lambdas for a change ;-)

    def before(x, y): return x<y
    def before_now(x): return x < time.time()
    def during_company_existence(x): return company_founding_time <= x < time.time()

    record_supply_checklist = [
        (['birth_date', 'hire_date'], before, 'born at or after hire),
        (['birth_date'], before_now, 'not yet born'),
        (['hire_date'], during_company_existence, 'bogus hire date')
        # etc ...
    ]

I suppose different checklists would go with different recordsupply's.
Is this too simple? Or have I misread between the lines? ;-)
(Of course you might want to log stuff instead of blowing up on the first assert.)

Regards,
Bengt Richter



More information about the Python-list mailing list