The BadProgrammer is the one who leaves a trail of destruction in his/her wake. Yes, this programmer has figured out how to make a three-hundred-line method called "get_stuff()" that has all sorts of nested try blocks, handles exceptions (all of them) by dropping them on the floor, and generally writes hard-to-understand BadCode. Whoever wrote the comment "Call this function after you do foo, bar, or baz" is a BadProgrammer. You've been called in to make "one minor change". This, of course, is unrealistic. You haven't read the entire program (it's 400 pages long) so you don't call this function after you did bar. It's not like there's a way to make this part of some API or calling convention; you would have the moral obligation to make everything use said API which is a monumental task. Anyway, add your experiences. ---- ''Bad programmer! No pizza for you!'' ---- '''Quotes''' : BadProgrammer''''''s will be BadProgrammer''''''s in any language. I have a friend who will take your beautiful PythonLanguage and make it his bitch. This is not a boast on my part - I'm actually rather disturbed. My point is that writing code in PythonLanguage will not magically make my friend write beautiful code. -- JohnBeppu : I once knew someone who could write PDP-8 assembly language in any language. -- AndrewKoenig ---- We've all met (sometimes only through their code) bad programmers who did things like: * iterate through a hash table to find the entry with a given key ''e.g. the X509 CRL in the IAIK JCE provider v. 2.51; 'fortunately' the application threw away the CRL after one search, so it didn't matter.'' * put N objects in a hash table using sequential integers [1..N] as their keys. ** TclLanguage makes you do this. LOL. ''no it doesn't, you can use lindex, or actually give your keys meaningful names, gasp!'' What I read about lindex reminded me about Tcl lists. Are they still strings these days, or have they (finally) implemented real arrays (in the 'vector' sense)? Maybe I was thinking of PhpLanguage, which also lacks real arrays, leading to kludges like ksort. I hate PHP. With a passion. -- TheerasakPhotha * cut and paste the same 10 methods on 12 different classes, generating about 40KLOC of extra code. Obviously never heard of templates. ''Or writing a new class, or library.'' * after hearing of templates, sprinkling liberal amounts of them all over their code - mostly without respect for or understanding of ''either'' genericity or polymorphism. * indent randomly. When asked about it, they respond "It doesn't matter - the compiler ignores whitespace." * exclusively use nouns as names of functions, and verbs as names of variables. Or just name all variables x, y, and z, or name them all after characters from LordOfTheRings. ** I knew a guy who wrote a piece of fortran with variables ikaren1 through ikaren78. His ex's name was Karen ... * call abort() whenever an error occurs, or even worst, ignore the error and keep going. ** Depending on the context, aborting on an error might be appropriate. *** But the context is never "whenever". * set up signal handlers so that if a SEGV occurs, the program just keeps running (because the program crashes once in a while, and they can't figure out why, but it can be "fixed" like this). ** BeenThereDoneThat. I was a mediocre programmer at the time, but I had inherited a nest of bugs, had neither the tools, talent, or time to fix them all, and the user couldn't just restart the program when it crashed. --RobMandeville * write their own versions of printf() and memcpy(), because they found a bug in a standard library once and decided that libraries are evil. ** AdvocatusDiaboli: What if their versions are cleaner, faster, safer? (maybe not memcpy, but most of the rest?) * write a value out to a temporary file, and later read the value back in from the file when they need it, because "global variables are bad". (And then, of course, neglect to delete the "temporary file" at shutdown.) * every module/class contains a lot of FixmeComment''''''s. * the error/log messages contain profanity (''this is one of my most favorite things to do''). ** Personal. Preference. Period. ** I've seen test cases that contain A LOT OF profanity! * write three large vaguely-named C++ classes and make them intimate friends of each other. (CPlusPlusLoveTriangleAntiPattern?) * declare global variables ''temp1'', ''temp2'', and ''temp3'' that are used as scratch variables by several unrelated subroutines (because declaring local variables is just too much work). * don't fix their own code that produces compiler warnings ("unreferenced local variable," etc.) because those aren't really bugs anyway. * only knows one data structure or design methodology, and uses them for everything, even when inappropriate, thinks the same solution fits every single problem. cf GoldenHammer. * Fortran programmer in C: Put an 'int' "array index" in each node of a circular doubly-linked list. Renumbered elements 'i+1 to N' when inserting nodes into the list, to keep the "array index" numbers sequential. Used the index numbers, instead of pointer comparisons, to determine when loops had traversed the whole list. {UNlearn arrays, oh FORTRAN programmer!!!) ---- A rather good programmer I know had once (while working on some parser, late at night) written the following piece of code: for i=1 to 3 switch on i case 1: ... break; case 2: ... break; case 3: ... break; end switch end for Generally, this programmer makes quite good code; it's just that sometimes he loses something, and this is what happens. I'm sure he would have caught it in the morning, if he'd seen it again. -- AvivEyal ---- What bugs me about this is that these people got jobs billing themselves as C++ programmers. '''And''' didn't get fired for massive incompetence. I can't imagine any other industry when people without even the most rudimentary, basic knowledge of their trade are allowed to practice and make disasters day after day after day. ''[Politicians, maybe?]'' -- AlainPicard ''Then your imagination is not as creative as reality. Quite a great number of people working in pretty much any field are pretty poor at it.'' : No, no, no ... there are no incompetent doctors, lawyers, judges, auto mechanics, waitresses, CEO's, or Wiki posters. ''You appear to be massively incompetent, Alain, on several levels. Here's a clue: inability to imagine P != not P.'' You must be being sarcastic...worked as a cook in college...there are many incompetent waitresses... ---- People naturally think that more experience means you are better at your job. This is not necessarily true in any job; in programming, the correlation is almost non-existent. PeopleWare empirically showed the weakness of this correlation. ''No it didn't.'' This should not be confused with the idea that experienced programmers are never better at their job. Experienced programmers can avoid traps that most rookies do. They are battle-scarred; they have found AntiPattern''''''s and dealt with them on their own; they have stories to share. The 'DotBomb cemetery' is full of bright but naive young programmers. You get experience when you are honest enough to interpret your failures. Too many programmers don't bother thinking about the reasons for a bug. "Bugs are just bad luck." Until the next bug correction in the production code, they just bury the facts under excuses. Reflection on our own work requires that we assess our limits, and it hurts. : There were 400 bugs reported. : ''It was good code.'' : Good code? How? : ''I got paid for it.'' ''"in programming, the correlation is almost non-existent" -- Only an incompetent moron would believe this.'' ---- ''I wonder HowToImproveProgrammingSkills?'' ---- There is the occasional "bad because it's easier" programmer. See BadGolfer. ''One of the best coders I ever knew was a notably BadProgrammer. We've all SeenThisPattern: he can write code faster than he can design it, so when he needs a the same operation done in fourteen different places, rather than write one function to handle all fourteen cases, he writes fourteen slightly different functions scattered about the code. Multiply this by the number of times he's done this and by the number of changes that have to be applied to each similar function, and you have a maintenance nightmare that can bring a project to its knees.'' ''Mind you, this was in MicrosoftAccess, which sort of encourages this nonsense by its heavy reliance on CodeBehindTheForm. - JayOsako'' ---- E''''''ngineersShouldTestTheirOwnCode. An engineer who relies upon QA, other engineers, or customers to test their code is a BadProgrammer. E''''''ngineersShouldHaveSomeoneElseTestTheirCode. An engineer who relies upon his own mistake-making brain to spot all of his mistakes, and considers it fully-tested if he doesn't happen to see any, is a BadProgrammer. Hence, PairProgramming, ContinuousIntegration, and CustomerTest''''''s... ---- Hey, It doesn't matter if I'm writing code or rewriting code. I get paid exactly the same! ---- ''Bugs are just bad luck. Until the next bug correction in the production code, they would just bury the facts under a lot of excuses.'' Why would they bother burying facts under excuses if facts just result from bad luck? Which ultimately is bad: programmer, code, luck? - Yes! I've found the bug: the report showed the same figures in 2001 and 2000 because the query object wasn't refreshed by a close, then open. - Ah. Now, maybe we should think about how we could have prevented this bug. - Impossible, testing wouldn't prevent this, because you must ask for the report for 2000, then for the report for 2001. This kind of request never happens. - You are telling me that this bug couldn't have been trapped because the test case is just too rare to be worth the pain of executing it. - Exactly. - But the users just found it, and they were not testing anything, just using the feature. - Yes, but if they use the report once in a session, then ''it works''. Such a repeated request for a report, year 2000, then 2001 with ''absolutely'' correct result is not a critical to them. - You seem to forget how they discovered the failure: they had to produce year reports because their dept is under an accounting audit. - ''well, yeah''... - ...so how could we try to prevent the failure? - Hmm, just by checking that every query object should be closed and re-opened before we use the results. Oh wait! We could put some code here: "if query.active then query.close;" and next, the "query.open". - Don't you think that the problem happened just because this query object is a global? - Uh? - Your report() routine use many local variables but one global query object... Then the discussion slips in generality and voilĂ : one hour spent in stupid arguments about "theory and practice", "here we're different" and so on. I don't think there are bad programmers. ''Then you're an idiot.'' There's bad code (peta-tons of), which programmers are both frustrated with and ashamed of and try to cover with defensive behaviour: arrogance, irrelevance, confidence, and so on. ---- The worst programmer I ever knew was a good programmer. ''More likely you're stupid and incompetent to judge.'' I mean, his code was good. What made him the worst programmer I ever knew was stubbornness. He wrote the wrong thing, and never, ever turned back. He had a particular task that was daunting, so he met it with a dauntingly complex solution. One aspect of this solution was a new BASIC-like programming language (compiled to C via lex and yacc) that knew how to undo all of its commands at any time. It could receive an interrupt from the user that caused it to reverse execution back through commands, up and down the call stack, undoing everything along the way, until it reached a "stop back tracking" command. He spent months alone on it and the fact that it worked as well as it did is a tribute to his brilliance. Unfortunately an exec saw it in an incomplete state and fell in love with it. Next thing he knew he had two weeks to deliver it. He tried his best to fix it up, but as soon as people started using it the bug reports started piling up. It had lots and lots of weird, non-deterministic bugs. They threw more people at it (that's when I came in), but in the end it drove him insane. He stopped coming to work, stopped answering his phone. No one heard from him for weeks. I spoke with him months later and he said he just quit being a programmer. I spent a month trying to fix/figure out what the code was doing. I looked everywhere I could think of for information about languages designed to reverse execution direction. (All I found was a mailing list devoted to hypothetical CPUs with an unused mirror CPU that does the opposite of what the used CPU does, all so they can use transistors that are like electron see-saws instead of electron cliff divers, which would result in virtually no power consumption or heat, but conjures the spooky image of an evil negaverse lurking in the CPU running MicrosoftWord's evil twin... - ''Wouldn't that be Word's good twin?'' - anyway, back to my story.) ''You must not have looked all that hard - see http://mindprod.com/article.html. Also, your friend sounds not so much like a good or bad programmer as a mentally disturbed programmer.'' In the end I gave up and talked to my boss, who was a great programmer. I told him it looked like a year to make it bug free, with a chance that it was mathematically impossible. We argued until we came up with a stunningly simple solution to the daunting task: five C++ classes that knew how to serialize their history on a common stack. We took about a week to write and test it. It was a big hit with the customers because C++ experience looks much better on a resume than JBMRL (Joe Blow's Magical Reversible Language). ''Whether something looks good on a resume is the determinant of good or bad programming'' I'm grateful for the lessons this episode taught me: Always argue, and when you hit a dead end, turn around. ''How about the lesson that your views on what is impossible and how long it will take to achieve something aren't reliable?'' See ReversibleLogic. ---- I once found the variable 'alanIsABastard' in code written by another. Unfortunately, I was quite clearly the Alan in question. ''Why is that unfortunate?'' ---- ''Or just name all variables x, y, and z, or name them all after characters from LordOfTheRings.'' I once had the pleasure of working with a guy who named all of his variables and functions after French towns. It wasn't a pretty sight. * A friend of mine in university, who wasn't too bad at getting algorithms to work, by student standards, had a similar horrid habit for a while, that made it impossible to help him debug his code when he had problems: he named all his variables and functions after ex-girlfriends. (The implication that he must've gone through girlfriends at a rapid pace in order to have enough such names is correct. :-) Slightly less bad, but still bad bad bad, and much too common: I worked with a programmer who abbreviated most variables to at most 4 characters. He chose them with purpose, but there's only so much you can do with 4 characters. So if he had a pointer, he'd call it ''p''. If a function was working on a data byte, he'd call it ''d'' or ''b''. A pointer to data might be ''pd'' or ''pb''. It was common to see expressions like ''ta = ps->ld.t1 - q.t''. When I had to call one of his functions, the API's of which were rarely documented, I'd stare at the 10 lines of it for about an hour. When I finally figured it out, I realized how graceful the logic was. He had a way of using simple, straightforward algorithms in powerful ways, the ways they were designed to be used. His code was like a great work of literature, written in ProtoSumerian. * Actually that's Proto-HungarianNotation, prior to the invention of the idea of adding a descriptive name following the encoded type. ;-) ** '''Actually''', omitting the name in local or temp variables is standard in Hungarian. *** '''Actually''', the little symbol there, ";-)" is a little humor-marker. It means, "you may have missed it on the first pass, but note, this is humor". You seem to have missed it on both passes. *** '''Actually''' #2, pretending there was no humor involved: you are claiming that HungarianNotation calls for using names only for global variables, which in turn implies an expectation of heavy use of global variables. I dislike HungarianNotation, but I don't believe that claim/implication. I never saw a description of it that recommended use of global variables. Omitting a (descriptive) name from temp variables '''only''', not from all locals, is frequent practice in both HungarianNotation and non-HungarianNotation. *** But it '''was''' humor, so this is all a silly digression. * That is possibly a consequence of over-involvement in programming contests, where output and time is much more important than readability ---- In a code review, I suggested to a colleague that his seven hundred line method should be broken up into smaller, easier-to-follow methods. He dutifully broke it up... into a chain of functions that called one another, passing a massive list of the function's local state as parameters to the next chunk of code, with sequential naming. doProcess -> doProcess2 -> doProcess3 -> doProcess4 -> doProcess5 -> (...). Even better, he didn't even return the values up the stack; all the results went into a global variable. This was in Python. ---- See BadCode, BadCodingStandards, WarningSignsOfBadProgramming, GruntProgrammer, BadGolfer, GoodProgrammer, GrandMasterProgrammer