I agree with all twelve of Damien Katz’s Signs You’re a Crappy Programmer (and don’t know it). I’d even add two more signs:
- You want to reinvent the wheel.
You look forward to implementing all the building blocks of your program without first checking for libraries and packages that can do most of the job for you. You are so excited about building an object-oriented email-sending library that you don’t even notice that the language you’re using already has all the email-sending functions you’ll ever need in its standard library. This is a failure to focus on getting the task at hand done, and it’s also a variation of talking just to hear the sound of your own voice. Get over it.
- You use language constructs without really understanding what they are for.
You use multiple inheritance from a large set of empty classes, or multiple empty interfaces, as configuration “flags” for your classes, and then test for the flag’s presence with
issubclass(). Or you encapsulate related data into an object, and then write a function that takes that object as an argument and operates on it, instead of a method on the object. Or you buffer input and output between short strings and regular expression operations. You are just like those annoying people who simultaneously overuse and misuse some big word like obsequious or audacious. Get a manual, and learn the language you’re speaking.
I’ve worked with people in the past who’ve been guilty of eleven of Katz’s twelve offenses. The one holdout? I’ve never worked with a UML fan-boy. If they’re half as bad as the people who use Excel for everything, I wouldn’t want to.
I’ve even committed some of them myself. I tend to get suspicious of long, complex functions/methods, but, as Ken Thompson is quoted as saying in the first comment, it’s more the levels of indentation and the number of function-local variables that should drive you to split up big functions. I also like to keep the number of return points in a method down as much as possible, especially in long, complex functions (see previous sentence) but there are cases where multiple return points are the best (available) way to structure a function.
I even agree with one of What I Hate About Your Programming Language‘s complaints about Python: the singleton-tuple syntax is a major gotcha. I don’t buy the last, though, whitespace has never been a problem for me. And the middle one I disagree with too:
Half-hearted closure support means that enclosed lexicals cannot be modified. I could emulate real closure support with objects, but sometimes the functional solution feels more natural.
I don’t see the use case for this (thanks to Greg for explaining it). If you really have two functions that need to operate on the same namespace, they should be children methods of the same object. Or pass the variables that the inner function needs to modify as arguments, or return the new value of from the inner function. These all make it clear what’s happening to the value in the affected lexical variable.
The kind of closures he wants are way more side-effecty and it’s harder to understand what the scope of a variable is and where’s it’s being modified. Lots of people seem to want more powerful scoping in Python, but I’ve never needed it.