Spot any errors? let me know, but Unleash your pedant politely please.

Tuesday 15 July 2014

PEP 20 > PEP 8

While trying to become a better Pythoneer, I'm struggling a little with PEP 8. I'm isolated, so I kind of don't care, but at some point I may have to learn to play well with others, so I should. I got a reminder of PEP 8 during a brief attempt to use PyCharm. I've only very briefly used an IDE with any success. That was with Eclipse and Java. That was only with help from people and online tutorials. PyCharm pointed out the myriad ways I was breaking PEP 8. It didn't tell me the ways I was conforming to PEP 20. Some code from PEP 8:
class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
                color == 'red' and emphasis == 'strong' or
                highlight > 100):
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)
 
And this is how I'd probably write it:
class Rectangle(Blob):

    def __init__(self,
                 width,
                 height,
                 color     = 'black',
                 emphasis  = None,
                 highlight = 0):
                 
        if  0 == width == height \
        and color == 'red'       \
        and emphasis == 'strong' \
        or  highlight > 100:
            raise ValueError("sorry, you lose")

        if  0 == width == height \
        and (color == 'red' or emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))

        Blob.__init__(self      = self,
                      width     = width,
                      height    = height,
                      color     = color,
                      emphasis  = emphasis,
                      highlight = highlight)
From PEP 20, my intention is to hit the following:
Beautiful is better than ugly. Explicit is better than implicit. Readability counts.
And from PEP 8, I'm playing the trump card:
When in doubt, use your best judgment.
Some preferences, like extra spaces here and there, are obviously subjective. Objectively, my experience of writing and maintaining code in Ada and Pascal tells me to always be explicit about using named actual parameters. It's probably even more important in a dynamically typed language. If Python didn't allow me to do this, I'd likely have rejected the language. That is has this feature in common with Ada and the indented scope of Occam (No braces, Yay!) made it a no-brainer for me. The main problem would appear to be that it's longer. Less code fits on-screen at once. I've never found that to be a problem even when I was editing in eve on VMS from a VT220. This wouldn't bother me much, even though I think it's less readable:
        Blob.__init__(self=self,
                      width=width,
                      height=height,
                      color=color,
                      emphasis=emphasis,
                      highlight=highlight)
But this drives me insane:
        Blob.__init__(self,
                      height,
                      width,
                      color,
                      emphasis,
                      highlight)
If you don't understand why, the deliberate mistake should be enough to persuade you that in the majority of cases, you really want to be be explicit about those parameter names. I'd only an the exception for functions that only take one parameter. Look, this is still fine even though the order deviated from the formal parameter list:
        Blob.__init__(self      = self,
                      height    = height,
                      width     = width,
                      color     = color,
                      emphasis  = emphasis,
                      highlight = highlight)
And this is impossible to do sober unless it's deliberate. It's also easy to spot in a review or when debugging:
        Blob.__init__(self      = self,
                      width     = height,
                      height    = width,
                      color     = color,
                      emphasis  = emphasis,
                      highlight = highlight)

No comments:

Post a Comment