PEP 308: more use cases

Dan Schmidt dfan at dfan.org
Sun Feb 9 12:06:43 EST 2003


Here are some places in another person's code where he used the and/or
trick because of the lack of a ternary operator.  The script is 413
lines long and there are 8 uses of the and/or trick (I realize that
that's a lot more frequent than it would be for most programs).

The program was not intended to be great code (I assume); it was
written to get the job done, so I don't want to pick on it too much.
My main point is that when the readable alternative does not exist,
people often do pick the less readable alternative rather than write
things out explicitly with a temporary variable the 'nice' way.  This
code would have been more clear, not less clear, if the ternary
operator had existed, given the programmer's insistence on finding
some way to fake it if a real way didn't exist.

Personally, despite my wishes for a ternary conditional operator, I
write everything out explicitly instead of using the and/or or
array-indexed-by-bool tricks, both of which I consider insufficiently
perspicuous.  When I rewrote this code in a form I could more clearly
understand, I 'defactored' out all of these expressions to if/else
assignments (to temporary variables when necessary).

For each of the examples I will provide what the code would have
looked like if the original programmer had access to a ternary
conditional operator.

old:
    lines = (inFile and open(inFile) or sys.stdin).readlines()
new:
    lines = (inFile if open(inFile) else sys.stdin).readlines()

old:
    where, section = word[1] == 'OF' and 5 or 2, word[0][0]
new:
    where, section = (5 if word[1] == 'OF' else 2), word[0][0]

old:
    self.adj[power] = [word[1][0] == 'B' and 'BUILDS ' or 'REMOVES']
new:
    self.adj[power] = ['BUILDS ' if word[1][0] == 'B' else 'REMOVES']


old:
    self.outFile.write("\t%d %d %s\n" % (si['x'], si['y'],
                                         unit == 'A' and "DrawArmy" or "DrawFleet"))
new:
    self.outFile.write("\t%d %d %s\n" % (si['x'], si['y'],
                                         "DrawArmy" if unit == 'A' else "DrawFleet"))

old:
    graphics.append('%s%d %d %s%s' % (msg and 'FailedOrder ' or '',
                                      si['x'], si['y'], graph,
                                      msg and ' OkOrder' or ''))
new:
    graphics.append('%s%d %d %s%s' % ('FailedOrder ' if msg else '',
                                      si['x'], si['y'], graph,
                                      ' OkOrder' if msg else ''))

old:
    self.outFile.write((time and '(%s) WriteOrder\n' or '%s\n') % power)
new:
    self.outFile.write(('(%s) WriteOrder\n' if time else '%s\n') % power)

old:
    self.outFile.write('\t%d %d %s\n' % (unit['loc']['x'], unit['loc']['y'],
                                         unit['type'] == 'A' and
                                         'DrawArmy' or 'DrawFleet'))
new:
    self.outFile.write('\t%d %d %s\n' % (unit['loc']['x'], unit['loc']['y'],
                                         'DrawArmy' if unit['type'] == 'A' else 'DrawFleet'))

old:
    status = power == 'UNOWNED' and ' ' or ('(%d/%d)' % (len(self.units.get(power, [])),
                                                         len(self.owner.get(power, []))))
new:
    status = ' ' if power == 'UNOWNED' else ('(%d/%d)' % (len(self.units.get(power, [])),
                                                          len(self.owner.get(power, []))))

Dan

-- 
http://www.dfan.org




More information about the Python-list mailing list