top | item 2331346

The worst program I ever worked on

147 points| bemmu | 15 years ago |jacquesmattheij.com

130 comments

order
[+] presidentender|15 years ago|reply
My instructor in the introductory programming course informed us that yes, the grader did indeed read our source code, and check to make sure we'd commented it meaningfully.

I decided to test this assertion.

The program in question was trivial - it was one of those contrived examples of how OOP works, a "Kennel" which had "Dog" objects which possessed various traits, and would bark() or wag(), stuff like that.

I obfuscated the code as much as I could - indentation all over the place, line breaks in inappropriate places, code hidden inside multi-line comments, and multiple dummy variables named one character off from the useful variables. The useful variables had names like "satrtrek," "maryppopins" and "pizza." The dummies were "startrek" and "marypoppins."

This exercise taught me nothing about writing code, but because my code gave the expected output, I still got an A. Source code comments from then on were made only as needed.

The next semester, I got an email from a friend of mine who just couldn't get his head around what was supposed to be going on. He asked whether I'd kept the source to one particular program, so that he could review it and see if he couldn't make sense of the assignment.

I had indeed kept it, and just sent the .java files to him without opening them for review. By coincidence, the program he was stuck on was the one I'd obfuscated. He switched his major to Math and Spanish for what I believe to be unrelated reasons.

[+] boyter|15 years ago|reply
Worst for me was something I was asked to maintain a little while ago. Was essentially Microsoft Reporting Services implemented in 80,000 lines of VB.NET.

The first thing I did was chuck it into VS2010 and run some code metrics on it. The results follow,

10 or so Methods had 2000+ lines of code. The maintainability index was 0 (number between 0 and 100 where 0 is unmaintainable). The worst function had a cyclomatic complexity of 2500 (the worst I have ever seen on a function before was 750 odd). It was full of nested inline dynamic SQL all of which refered to tables with 100+ columns, which had helpful names like sdf_324. There were about 5000 stored procedures of which most were 90% similar to other ones with a similar naming scheme. There were no foreign key constraints in the database. Every query including updates, inserts and deletes used NOLOCK (so no data integrity). It all lived in a single 80,000 line file, which crashed VS every time you tried to do a simple edit.

I essentially told my boss I would quit over it as there was no way I could support it without other aspects of work suffering. Thankfully it was put in the too hard basket and nobody else had to endure my pain.

I ended up peer reviewing the changes the guy made some time later and a single column update touched in the order of 500 lines of code.

EDIT - I forgot to mention, there was so much nested if code in methods you could hold down page down and it would look like the page was moving the other way, similar to how a wheel on tv looks like its spinning the other way.

[+] edw519|15 years ago|reply
I met the guy who wrote this bit that I had to maintain:

  for(a=0;a<NbrOfAs;a++){
   for(aa=0;aa<NbrOfAAs;aa++){
    for(aaa=0;aaa<NbrOfAAAs;aaa++){
     for(aaaa=0;aaaa<NbrOfAAAAs;aaaa++){
      for(aaaaa=0;aaaaa<NbrOfAAAAAs;aaaaa++){
       if(aaaaa==0)else{ExamineAAAAA()}
      }
     }
    }
   }
  }
What really pissed me off was that he was such a nice guy.

He still works a lot. Makes a lot of money. And his customers love him. (No, I don't think they review his code.)

[+] bhousel|15 years ago|reply
At least that code is indented properly..

Much of the code that I need to fix seems to be written by people who learned on day one of programming that "whitespace doesn't matter to a computer" and never looked back.

[+] brown9-2|15 years ago|reply
Did you ever ask this person why he wrote this code in this manner? Did he trot out the "job security" crap or was there a legit reason?
[+] arethuza|15 years ago|reply
Unless there is a lot of creative abuse of operator overloading or macros lurking in there that code really doesn't look too awful compared to some monstrosities I've had to work with.
[+] graywh|15 years ago|reply
Is this equivalent?

  for(a=1; a < (NbrOfAs*NbrOfAAs*NbrOfAAAs*NbrOfAAAAs*NbrOfAAAAAs); a++){
    ExamineAAAAA()
  }
Or do I need a nap?
[+] redredraider|15 years ago|reply
You really don't know bad programming until you have spent some time in a 50000 line cobol program. I'd post some crap I work on every day but I don't want to make anyone cry. Nevermind. Here's some random code I'm working on.

             MOVE SPACES TO LISTBAT-NAME.
             STRING WORK-FILES "LIST.BAT" DELIMITED BY "  "
             INTO    LISTBAT-NAME.
             OPEN OUTPUT LISTBAT.
             MOVE SPACES TO SCR-S.
             STRING "DIR /B " DATA-PREFIX " > " 
             WORK-FILES "TMPLIST" DELIMITED BY "  " 
             INTO  SCR-S.
             MOVE SCR-S TO LISTBAT-REC.
             WRITE LISTBAT-REC.
             CLOSE LISTBAT.
             CALL "C$system" USING LISTBAT-NAME, 96 
             GIVING STATUS-VAL.
             MOVE SPACES TO TMPLIST-NAME.
             STRING WORK-FILES "TMPLIST" DELIMITED BY "  " 
             INTO  TMPLIST-NAME.
             OPEN INPUT TMPLIST.
             MOVE LOW-VALUE TO LIST-NAME.
             PERFORM UNTIL 1 = 2
             READ TMPLIST
             INTO SCR-S
                AT END EXIT PERFORM
             END-READ
             ADD 1 TO PROGRESS-REC-CT
             INSPECT SCR-S CONVERTING LOWER-CASE-ALPHA TO 
              UPPER-CASE-ALPHA
              PERFORM VARYING SCR-X FROM 50 BY -1 UNTIL 
              SCR-X = 1
              IF SCR-S(SCR-X:1) = "."
              MOVE SPACES TO SCR-S(SCR-X:)
              EXIT PERFORM
              END-IF
             END-PERFORM
             CALL "CC/STRINGER" USING SCR-S, STRING-INFO
             MOVE SCR-S(1:STRING-INFO-LENGTH) TO TMP-RID
             PERFORM LOAD-RPT-FILE THRU END-LOAD-RPT-FILE
             END-PERFORM.
             CLOSE TMPLIST.

The newline on some of those lines is off because HN makes it wrap but you get the idea
[+] rorrr|15 years ago|reply
Note to self: do not learn COBOL.
[+] Stormbringer|15 years ago|reply
I worked on a piece of code that literally drove the guy who wrote it round the bend. He had a mental breakdown, ran away, and eventually ended up in a different state ~3000 miles away.

It wasn't so bad.

Now debugging code written by Chemistry Students... that's some scary stuff right there.

Which is not to go all elitist and put Comp Sci degrees up on a pedestal, one of the better coders I've had the pleasure of working with was a trained vet. He was very methodical.

Actually, now that I think about it, working with something that if you make it angry it will bite your hand off, is probably good preparation for dealing with a compiler...

[+] rwmj|15 years ago|reply
You should try working with code written by hardware engineers. Those guys are extremely smart when it comes to digital and analog electronics, but never ever let them write a device driver ...
[+] ladon86|15 years ago|reply
I worked with a guy (I won't name the company) who wrote Java code in one, huge, static class as much as possible. In fact, everything was largely in one function too.

He decided to name his fields alphabetically.

static int a

static int b

static String c

static float d

static int e...

What, I wondered, would happen when he ran out of letters? Scrolling down further I saw this:

static int aa

static float ab

static String ac

static int ad...

[+] Luyt|15 years ago|reply
I think the best way to guarantee job security is to solve hard problems for the company you work for, and make it visible (i.e., communicate about it). This will gain respect from your peers and give you a reputation of being useful and very worthy keeping around.

Writing some kind of obfuscated code is shooting yourself in the foot - after a while not even you can maintain it. Plus, your peers will notice and probably not like it. This notion will percolate up to management.

Another way to guarantee job security might be when you are the only person able (or willing) to maintain some old legacy system. This carries the risk that if that system is finally scrapped or replaced, your job is being scrapped too ;-)

edit: horrible grammar

[+] rahoulb|15 years ago|reply
Not a pleasant story, but true...

I used to work at a place where one of the guys wrote a horribly complicated piece of code that about half of the system depended on. He was also quite an unpleasant man who routinely mocked everyone else in the company for not being as clever as he was.

The company ran out of money and needed to halve its workforce - one of my friends overheard him boasting that there was no way that they could get rid of him, as no-one understood what he had written.

I was asked about his code - I said no-one but him could maintain it, but give me three months and I could rewrite it.

I don't like to revel in other's misfortunes but the look on his face as he left the office on the day of the redundancies was a picture.

In the end I kept half of his code (ring-fenced so it was effectively a black box that no-one touched) and rewrote the rest in about a month.

Personally, I work hard, make it visible (as Luyt says), own up to my failures and every now and then go beyond the call of duty. And I try very hard to be nice to people, even when they're acting like idiots.

[+] suppergenius|15 years ago|reply
The only place where the names made any immediate sense was 'main' and any C stdlib calls.

Any job worth doing is worth doing right. Contrariwise, any job worth fucking up is worth fucking up stupendously. He didn't go all the way.

  #define monkeymeat printf
  #define turtlescrotum malloc
  #define wolfnipplechips gets
  #define chipotlaway exit
  ...
[+] statictype|15 years ago|reply

    #define HEREWEGO {
    #define ENOUGHNOW }
[+] burgerbrain|15 years ago|reply

  #define wolfnipplechips gets
If you wanted to fuck it up proper, you should leave out this line. You don't want to dampen the horror people will have when they see you actually using gets.
[+] blntechie|15 years ago|reply
I've seen

#define true false

Think they do it just for fun sake. Evil.

[+] michael_dorfman|15 years ago|reply
Back in the day, I was an RPG programmer (on an AS/400), and I had a co-worker who insisted upon using geographical labels for all of his GOTO targets: GOTO BARCELONA, GOTO TOKYO, etc.

Needless to say, maintaining his code took some getting used to.

[+] Stormbringer|15 years ago|reply
That sounds kind of funny. Where do you go on error?

One time I had to debug this incredibly obfuscated Word Basic subroutine. It was such a mess of gotos (deliberately so) that the company that wrote it for us thought they had us over a barrel and could charge us like a wounded bull.

That is, until I showed my cow-orkers the superior technology of "paper, scissors and sticky tape".

[+] me2i81|15 years ago|reply
The thing about languages that require GOTOs is that there is often no inherent meaning in the label, such as in a control structure that we'd take for granted these days, and back in the day you were often limited by token size (in one assembler I used it was 5 characters) so people sometimes used schemes like "A0001", "A0002", etc. or sometimes "DOG", "PIG", "CAT", etc. though the former was preferable as it wasn't distracting.
[+] joelhaasnoot|15 years ago|reply
A project I worked at during an internship had an unmanaged C++ portion for rendering complex typography, which was written when every letter in a variable cost $10 (or so it seems). The result was that "pointer to a metadata character" became the variable "pmc", and that was just the beginning of it. I never quite did understand what the variable lpmnoics meant, and debugging the C++ was quite the drag and the task everybody avoided, and pushed off to the original developer of that code (who happened to be in a different geographic location).
[+] kragen|15 years ago|reply
That sort of thing is a lot easier to understand if you have the secret decoder key: http://www.joelonsoftware.com/articles/Wrong.html

But it's probably a defensible idea, in context. The idea is to supplement the type system of a low-level language with a manually-checked type system that helps you find semantic errors.

[+] Stormbringer|15 years ago|reply
lpmoics

a long pointer to a meta object in cthulhu studies...

... see also Hungarian notation as implemented by Miskatonic University

[+] gst|15 years ago|reply
It does not need to be that complicated :)

When a company I worked for was bought the new companies tried to lay of some (most) of the employees. At this time our team was working on a product that was to a large degree implemented in Scheme (because management didn't really care about the programming language). I quit at the company (for unrelated reasons) soon thereafter, but it seems that my colleague (with whom I've implemented the system) had quite a good job security at this time.

[+] mattdeboard|15 years ago|reply
I can't tell if the number of parentheticals in your post is a pun about using Scheme or not.
[+] mberning|15 years ago|reply
The legacy system that I'm working on now has about 20-30 distinct classes/data types that it needs to manage and persist to the database. The previous developer chose to implement all of these different data structures in one uber-table named 'object' and in the application code with one uber-class named 'Thing'. Relationships between 'Things', regardless of meaning or type, are simply dumped into a 'relationship' table. It wouldn't be so bad except for the meaning and nature of relationships is often inferred based on the order or 'direction' of the relationships in the database.

So pretend that I have a 'Thing' representing a table, and another 'Thing' representing a column. If the relationship was from the table to the column then that might indicate that the column simply belongs to the table. However, if the relationship is from the column to the table, then that might indicate that the column is a primary key.

There are also other gems deep within the bowels of the system. Many functions named things like 'doItForRealThisTime' and 'reallyDoIt'.

[+] nicpottier|15 years ago|reply
One of my favorite accessor method names I've run across is 'maybeGetCube()'.

The idea was that if it was cached, then it would return the cube, otherwise null. Cube was actually relatively aptly named, it was a big matrix of data BTW.

I guess really it wasn't THAT horrible, but the whole idea of 'maybe' doing something in code has always made me chuckle.

[+] xiaoma|15 years ago|reply
One of my former classmates names everything he can get his hands on after various obscure anime references-- database names, variables, servers, you name it. Once in a blue moon, I'd recognize a function name as being a character or item from one of the few animes I'd seen and after a bit of tortured logic based on the background it almost seemed like a reasonable choice.

Needless to say, he does better working on his own.

[+] travisglines|15 years ago|reply
Call me Captain Obvious, but I feel like quite often the time spent in obfuscating code in many cases might be a major component of why programmers that do this sort of thing get fired in the first place.

What goes on in someone's mind that says: "Maybe if I spend some time making my source code hard to understand I can better preserve my job." ?

In reality all it does is slow them down, waste their time and lead to the firing of the developer. (At which point we get to hear funny stories from people like jacquesmatteij)

If that time was spent improving/refactoring their code and working on new things, they'd actually have the job security they were so desperately seeking.

[+] danenania|15 years ago|reply
While this is true, there's a lot of space in between a model developer and a purposely-obfuscating twit. There's definitely a line that lazy developers can walk where they contribute just enough to make firing them more of a pain than putting up with them. I suppose the lesson for businesses is: be very careful about who you hire in the first place, because you may end up stuck with the person whether you like it or not.
[+] drzaiusapelord|15 years ago|reply
Yeah, it didn't save this guy from getting fired and it only made life harder on a another guy who he's never met. The whole "stick it to the man" mentality is childish and its shameful that this strategy is so common in software development.
[+] unknown|15 years ago|reply

[deleted]

[+] RiderOfGiraffes|15 years ago|reply
I've watched enough "programmers at play" and read enough code to happily believe that this guy was just letting his sense of humor have its day. I'm not at all convinced that things like this are deliberate obfuscation. Of course, I'm not the one who had to disentangle it all.

We've all read bad code with bad names that nonetheless "works" (except perhaps for the occasional minor glitch). This is perhaps just one that combines poor programming style with a mis-placed sense of humor.

[+] sp332|15 years ago|reply
True enough. In the 7th grade, I once divided some number by 100,000 by writing out the long division, and writing 03=0, 7-0=7, 07=0, etc. The teacher came by and was completely baffled where I had gone wrong in my education, but I was just bored :)
[+] Stormbringer|15 years ago|reply
I agree. Tomato and Pizza aren't any less silly than Foo, Baz and Bar, and certainly much less offensive than Fubar...

... It's not just programmers that do this either, also network admins name their computers R2D2 and C3PO, Shodan, Skynet etc.

[+] karamdeep|15 years ago|reply
I once took over some work that was previously the domain of our most highly paid ($150-200k a year) "architect"/contractor. Imagine my surprise when I actually examined his code and realized that it looked like it had been written by a student in an intro-level C101 class. At one point, I asked him what his approach to program design was...he replied "brute force and ignorance" and walked away laughing. We fired him shortly thereafter.
[+] scrrr|15 years ago|reply
This is off topic but I find it difficult to read the blog-articles from jaquesmattheij.com . Zooming doesn't help because the text doesn't wrap correctly. Just a suggestion for the author to change the layout of the page.
[+] edge17|15 years ago|reply
One semester I was TA'ing a certain course all electrical and computer engineering students are required to take.

One student named all his variables in phonetic chinese (using the utf8 character set of course).

Another student named all his variables after superheros.

[+] PakG1|15 years ago|reply
For the Chinese guy, I wonder if the code would have been way easy to maintain for the average Chinese developer. That would be an interesting analysis.
[+] jordw|15 years ago|reply
I worked with a guy a couple years ago who used the planets and nearby stars as a version numbering scheme. For example, the first revision of a file might be "Jupiter" and the second revision might have been called "Mars." (Of course, he didn't use the planets in their natural order)

He also refused to use real version control or even any kind of on network backup and insisted on using a Zip drive to back up all of the code he was working on. Needless to say, we had an intervention that involved hiding the Zip drive, and he quit in disgust shortly after.