While writing my blogging software, there were several times when I wished that Python had an if-then-else expression à la PEP-308. I know that PEP-308 was thoroughly rejected for Python 2.4, but just in case discussion about it should ever surface again, I thought I’d examine my blogging software, Kangapy, to see what effect an if-then-else-expression would have on it.
I found that an if-then-else expression would reduce Kangapy’s lines of code count by 1.7%. This is small, but significant, and indicates to me that PEP-308, in some form would be worth proceeding with.
David A. Wheeler’s sloccount tells me that Kangapy has 3849 lines of code. A walkthrough of the code shows that 165 of those are ‘if’ statements. Examining each, I found 26 that could be replaced by an if-then-else expression, saving a total of 66 lines, or 1.7% of 3849 lines.
The rules I used for deciding which if statements could be replaced were fairly strict: the replacement had to be a semantically equivalent, readable, and fit on a single, 80 character line.
For example, I allowed this snippet:
if self.__isInclude:
op = ‘IN’
else:
op = ‘NOT IN’
to be rewritten as:
op = (if self.__isInclude: “IN” else: “NOT IN”)
As a counter example, I did not rewrite the following code with if-then-else, because the result would span multiple lines, and not be particularly readable:
if not isValidBlogDate(linkDate):
return None
return common.Link(
cls.MakeUrl(category, linkDate),
cls.MakeTitle(category, linkDate))
Given the ominous wording of PEP-308’s introductory paragraph I think I’d be pushing my luck to write two blog entries about it, so I’ll add this here.
The voting process for PEP-308 was fundamentally flawed. It is absolutely no surprise that a “community” of 400+ voters couldn’t settle on a single option out of a range of 20 similar ones, much less produce a “clear majority.” Duh. It’s called vote splitting and it’s the reason that Republicans cheer Ralph Nader, and that Australia is still a monarchy.
Short of using a preferential voting system A vote of this kind should be at least a two stage process – first decide whether a change is necessary, and only then choose amongst the options for change.
In PEP-308’s case, “the community” has indicated, by a “clear majority,” that they want a change. Further, the community has indicated four leading options. The results of the voting seem to say that “the community” would be happier with any one of those four forms of if-then-else than it would be with none at all.
If PEP-308 were ever to openned up again, the next step would be to hold a vote to choose from amongst those four options.
I’m happy to believe that Guido knew what he was doing when he rejected PEP-308, but I would have liked to have seen a bit more structure to the community consultation.
Comments
I certainly *hope* that adding a ternary operator operator isn't discussed again. It was by far the nastiest c.l.py thread I've ever seen.
Any road up, FWIW, I blogged my thoughts at the time: http://www.brunningonline.net/simon/blog/archives/000622.html
if self.__isInclude: op = 'IN' else: op = 'NOT IN'Can be rewritten as
if self.__isInclude: op = 'IN' else: op = 'NOT IN'Thus removing two lines immediately. Personally this is sufficient reason for me to *not* have the
if/then/else sytax.
Thankfully, I missed the c.l.py discussion. Maybe this has already been considered and dismissed, but doesn't this old standby still get the job done?
op = self.__include and 'IN' or 'OUT'Bryan,
That may work but it makes my eyes bleed. :-)
Anthony, Bryan,
I'm trying real hard to stop myself from pontificating - in great detail - about the options you each present, because I suspect that everything I would say was already said on c.l.py in early 2003 :)
a
So, it works OK with literals. But:
If doesn't always work with references - not if the first one might refer to a false value.
Besides, it's *rank*. ;-)
Psst... Simon: I editted your comment to make the code blocks be rendered in <pre> tags.
Ta.
If you're just choosing between two options, rather than relying on conditional evaluation, you can use:
def iif(condition, truepart falsepart): if condition: return truepart else: return falsepartOkay, I'm done now...
Was just bored and thought I would post
Thank you Bryn for a sensible solution in a baroque argument.
I am not (yet) pythonic. But I am beginning to translate 16
years worth of teaching/doing geometrical graphics from
C/GL into Python/GLUT. And not having the equivalent of
a?b:c is a nuisance.