Magical For Loop



  • I used to work for a large aerospace company, writing automated test software for avionics systems. The hiring managers there were absolutely clueless about anything software-related, so we ended up with way more than our fair share of incompetent programmers. In fact, the incompetent programmers vastly outnumbered the competent ones, which meant that the relatively few competent programmers ended up having to do double-duty - getting their own assignments done while simultaneously having to take responsibility for fixing all the awful code that the incompetent programmers wrote.

     Luckily, I managed to fall in with a small niche of very smart, capable programmers. We had a small (4-5 people) group, that went largely unnoticed by management, because we worked on relatively small side projects, whereas the vast majority of the 200 or so programmers at our company were busy working on the avionics flight software. Still, every now and then, when work got scarce, some bean counter manager would reassign one or two programmers to our group, just as a way of keeping them around until more work came in. Over the years, a dozen or so of these "extras" cycled in and out of our group, and most of them were more of a burden than a help.

    One guy in particular - let's call him Todd - was constantly writing such terrible code that the rest of us basically had to take turns rewriting his code for him. Every other day or so, he'd ask one of us to help him "troubleshoot" some problem he was having with his code, and whichever one of us got stuck with the dreadful task would follow him back to his cubicle and fix his code for him.

    This one time in particular, Todd came looking for help, and the other guys had conveniently slipped off to some meeting somewhere, so I got stuck helping Todd with his code. He'd been given a task to write a small text parser to read data from a log file and dump it into a format that the systems engineers could import into Excel. It was a ridiculously simple log file. One row of data per line, with every line containing the same N data items as the next, with the exception of a roughly 100-line header that contained all sorts of comments and meta-data.

    When I asked him what the problem was, he said his parser kept reading the 100-line header every time, even though he'd written it in such a way that he was sure the first 100 lines were being skipped. When I saw his code, I was speechless:

     

    FILE *fp = fopen(argv[1], "r");
    char line[100];
    int i;
    

    for (i=100;i<99999;i++)
    {
    if (fgets(line, 100, fp) != NULL)
    {
    ...
    }
    }

    I spent the next 30 minutes trying to explain why fgets doesn't magically know what the value of your loop counter is, and why he shouldn't be using a for loop anyway.

     

     



  • Was this a long time ago? Why would you even think of using C of all languages for that?



  • Whats wrong with using C for something as simple as this?



  • Because most languages have a string type that supports operations like 'split' without resorting to strtok?



  • Yes, this was quite a while ago, although not that long ago - probably about 10 years ago.

    As for choice of language, most aerospace environments aren't exactly on the cutting edge of programming tools. We were up to our necks in C code, but we were happy to be doing C, as lots of our coworkers were stuck writing in languages like JOVIAL, Ada, and Fortran.

    As far as whether or not C is appropriate for something like this, well, I suppose if you're proficient in another language that has built-in string-splitting, associative arrays, etc, you could write such a program faster than doing it in C, but for such a small, simple program, the time savings would be on the order of maybe 5 minutes or less. So, in this case, there was no compelling reason not to just go ahead and use C.

    However, the choice of language is really beside the point. This guy would have just as surely written terrible code in Perl or Python, or whatever language you threw at him. His problem wasn't his inability to grasp the complexities of the C language (which, let's be honest, isn't really a difficult language unless you're either a total noob or a complete moron). His problem was his inability to grasp even the simplest programming concepts. He was basically programming with the same level of understanding with which my grandma uses a TV remote. She doesn't know how it works - it's basically just magic to her - but she knows if she presses 1 - 3 - Enter, it changes the TV to channel 13. That's basically what this guy was doing. He wasn't visualizing chunks of memory, stack frames, pointers, etc, as he typed.  He just knew that if he cut and pasted the right lines from someone else's old code, and tweaked a few variable names, he could (at least sometimes) get it to do what he wanted, even though he didn't really understand what he was doing.

    The sad part is, this wasn't some junior programmer that was fresh out of college, although even a junior programmer ought not the be making mistakes this dumb. This guy had been at the company for about 5 or 6 years. And not only did he write the bad code in the first place, but he was pulling his hair out while stepping through it in the debugger, clueless as to why it wasn't doing what he expected.


  • Discourse touched me in a no-no place

    @arty said:

    Because most languages have a string type that supports operations like 'split' without resorting to strtok?
    Given the description in the OP, sscanf() would have been perfectly adequate. Providing you bothered to check the return value that is...



  •  You were being far too nice to the idiots. I helped them along, sure, but I didn't really care about the quality of there code or how they wrote it (thats upto them, afterall), plus I always wanted to get back to my own projects.

    In this case, I probably would have gone "Fine. Ok. for (i = 0; i < 100; i++) fgets (line, 100, fp);". Why spend longer explaining everything to them? They are not going to take it in anyway, and you'll get dragged into a meeting explaining why your project is behind schedule.I admit I did it at the beginning, but after explaining everything 5 times and basically doing there entire project for them, I got bored of that game. 



  • Er...

    <font face="Courier New">tail -n +100 myLogFile</font> ?


  • @joemck said:

    Er...

    <font face="Courier New">tail -n +100 myLogFile</font> ?

    From the OPs post, I'd imagine there is at least some processing to be done after those first 100 nuisance lines were removed, so your solution wouldn't work.

    Plus, I'd also guess that you really should find the end of the header section, rather than guess its exactly 100 lines worth.



  • You guys are all missing the point completely. I don't need help figuring out how to parse a text file, nor is this some kind of contest to see who can come up with the most clever, compact way to perform this simple task. Frankly, I find that a bit pedantic and pointless. There are probably about a million different ways to get the job done, but really, who gives a crap? This is just a story from 10 years ago (!) about some guy who thought he could magically skip past 100 lines in a file just by initializing i to 100.



  • @BitBeetle said:

    You guys are all missing the point completely.

    Welcome to TDWTF. That's the favourite sport here.

    This is just a story from 10 years ago (!) about some guy who thought he could magically skip past 100 lines in a file just by initializing i to 100.
     

    And I laughed. Thanks for sharing it.



  • At least he did remember that fgets read n-1 characters from the input, to leave room for the null terminator. A lot of people forget that and wonder why copying a 5 byte string into a 5 byte array causes strange things to happen.



  • @Mole said:

    At least he did remember that fgets read n-1 characters from the input, to leave room for the null terminator. A lot of people forget that and wonder why copying a 5 byte string into a 5 byte array causes strange things to happen.

     

    You're giving him way too much credit. I doubt he even knew what a null terminator is. The code snippet I quoted was just my own rough sketch from memory. It's not as if I've been carrying around a copy of his crappy code all these years, just waiting for the day I could cut and paste it into a forum post about incompetent programmers. Except for the "for (i=100;" part, I don't really remember much about what the rest of his code looked like, so I just gave him the benefit of the doubt on the other bits. (Well, sort of, anyway - there are still lots of dumb things you could point out in my snippet, like assuming argv[1] is non-null, assuming no more than 99999 lines, etc - but I wrote the snippet that way mostly just to simplify it, as opposed to trying to mimic his bad coding style).



  • @Mole said:

    At least he did remember that fgets read n-1 characters from the input, to leave room for the null terminator. A lot of people forget that and wonder why copying a 5 byte string into a 5 byte array causes strange things to happen.

    There's nothing wrong with copying a 5 byte string into a 5 byte array - as long as when you say "5 byte string" you really did count all the bytes...

Log in to reply