PEP308: Yet another syntax proposal

David Eppstein eppstein at ics.uci.edu
Mon Feb 10 18:39:44 EST 2003


On 2/10/03 11:28 PM +0100 holger krekel <pyth at devel.trillke.net> wrote:
>> It's a flag value to distinguish a "select all" menu item from the menu
>> items referring to individual columns.
>
> i see.
>
> When i had situations like this I rewrote it to get the special "select
> all"  value not interfere with usual list/tuple-index semantics.  E.g.
> using a  dummy-class for "select_all" rather than reusing an otherwise
> valid key index.
>
>> > This reinforces an earlier thought about PEP-308 alternatives,
>> > which might read as follows:
>> >
>> >     cols[i] except IndexError: None
>>
>> Again, not good, i==-1 doesn't cause the IndexError unless cols is empty.
>
> right. with my above "class select_all: pass" this would work nicely,
> though.

Cocoa NSPopUpButton's indexOfSelectedItem method doesn't return non-numeric 
values.

> Sure.  But I'd rather have my co-coders think about easier ways rather
> having to understand ternary operations often.  Had i seen your above
> code
>
>     cols[i] if i >= 0 else None
>
> just on its own i would be puzzled (which i was).  May i ask
> you to show the complete function where this came from?

Not that I make any claim of having polished this to jewel-like perfection, 
but here it is.  It's part of the controller for the Find dialog in a 
table-editing application.  The input data structures are:
self.doc.columns() -- a list of strings used as dict keys
self.doc.rows() -- a list of dicts keyed by the columns
contains, beginsWith, endsWith, exactMatch -- localized string compare 
routines
self.table -- the controller for the table display
self.column, self.match, self.text -- components of the Find dialog
Note that self.match and self.columns are both pop-up buttons, but accessed 
differently because one is static and the other has to be updated when the 
self.doc.columns() changes.

    def search(self, row, increment):
        def matches(row):
            if col is not None:
                return match(row.get(col, ''), target)
            for c in cols:
                if match(row.get(c, ''), target):
                    return 1
            return 0

        cols = self.doc.columns()
        col = self.column.indexOfSelectedItem() - 1
        if col < 0:
            col = None
        else:
            col = cols[col]

        match = self.match.selectedItem().tag()
        match = (contains, beginsWith, endsWith, exactMatch)[match]
        target = self.text.stringValue()
        rows = self.doc.rows()
        while 1:
            row += increment
            if row < 0 or row >= len(rows):
                return 0
            if matches(rows[row]):
                self.table.setSelectedLine_(row)
                return 1

Looking at it again, it is possible to simplify this, in a way that gets 
rid of the implicit ternary, allowing the subroutine to be more easily 
folded into the main routine:

    def search(self, row, increment):
        cols = self.doc.columns()
        col = self.column.indexOfSelectedItem() - 1
        if col >= 0:
            cols = [cols[col]]
        match = self.match.selectedItem().tag()
        match = (contains, beginsWith, endsWith, exactMatch)[match]
        target = self.text.stringValue()
        rows = self.doc.rows()
        while 1:
            row += increment
            if row < 0 or row >= len(rows):
                return 0
            for c in cols:
                if match(rows[row].get(c, ''), target):
                    self.table.setSelectedLine_(row)
                    return 1

But, clearly, the existence or nonexistence of a ternary operator had 
nothing to do with my ability to find this simplification -- I already had 
working code for this problem, so had little motivation to work harder on 
simplifying it until you asked me to post it.

--
David Eppstein       UC Irvine Dept. of Information & Computer Science
eppstein at ics.uci.edu http://www.ics.uci.edu/~eppstein/






More information about the Python-list mailing list