• (cs)

    Where's the WTF? It's only a braindead method with quadratic time complexity.  At University we had an assignment to develop a resource-planning application, A co-student of mine wrote code that performed a task that required only a linear-time algorithm in O(n^5) time.  That is, use 10 times the amount of input data, and the time required to process it increases 10.000fold.

    If only I had known about thedailywtf.com at that time.

  • (cs) in reply to Alexis de Torquemada

    Blast! Should've been 100.000fold.

  • DZ-Jay (unregistered) in reply to Yaytay
    Anonymous:
    Anonymous:

    The extended version went one more step.  The entire issue is about Return On Investment (ROI).  One programmer will take 100% of the time to complete a project, a 3 week project takes 3 weeks. Two programmers does not cut the time in half to 1.5 weeks but rather reduces it to maybe 2 weeks.  In man-hours we increased the time (making him correct in theory) but in reality we reduced the time to market (making me correct in practice).  I stated that there will come a time where you start adding programmers and get a negative ROI but until such time you are shortening your time to market albiet with increased cost.

    Even with the addition of a second body I would expect the project to take longer to complete if it's a three week project - simply because it takes too long for bod number 2 to learn what bod number 1 is thinking.
    You will also end up with a less cohesive whole.

    Not that I'm agreeing with what you say Brooks said, you can reduce time to market by adding bods, but you have to bloody careful about how you do it - and I would argue that very few shops are.

    I'd also claim (with nothing but my own experience to back this up) that adding bods is considerably worse than starting off with more bods - and I mean right back at the planning stage.



    That is precisely the point in The Mythical Man Month:  not that adding *any* programmers to a project (i.e. more having more than one) is going to make it late, but that adding *new* programmers to a project which is already under way *is* going to necessarily delay it; because you need to get the new programmers up to speed on the design, implementation strategy, tools, etc., plus possibly introduce some communications problems and management complexity that weren't there before.  All this occuring *during* the software implementation.

    This is why "Brooks' Law" has usually been quoted as "adding manpower to a late software project makes it later".

    I could certainly see why entering into a semantics argument with Mr. Brooks about having 1+N programmers as opposed to just 1 programmer, would make him throw his arms in the air and dismiss the argument altogether.  It means you didn't get his point.

        -dZ.
  • (cs) in reply to Anymoose Jr
    Anonymous:

    public ArrayList GetRoles(){
        ArrayList roles;
        return null==roles=getRols()? roles : roles.Clone();
    }




    Why the hell would you try to assign "getRols() ? roles : roles.Clone()" (with roles being an uninitialized variable) to the rvalue "null == roles"?  If you were "clever", you would first get your operator precedence straight.  In this case, comparison > ternary conditional (?:) > assignment.

    GoatCheez:
    I came up with 2n+2.... It looks pretty linear to me...


    Yes, linear in the call to getRols().  Now if getRols() takes amortized constant time (i.e. if it caches the result), the total time complexity would be linear.  But that seems to be wishful thinking.

  • BugDozer (unregistered) in reply to Kodi
    Kodi:

    Anonymous:
    Anonymous:
    ...snip catch(Exception e) { throw e; }
    hey .Net Developer - please if you are going to rethrow an exception, just call throw, not throw e. This will lose the stack trace and you will never see the real eror.

    Not that is a real WTF. Why in the name of all that is pure and holy would you  just throw again!  The whole idea of the try / catch is to gracefully handle errors, or to "throw a more specific error  ie System.ArgumentNullException. But to catch an exception to only throw it again!



    Because the IDE won't let him proceed without doing something, but he has no idea what to do other than the default IDE stub.
  • (cs) in reply to First-time-poster

    I say three, three, three database calls for the price of one unnecessary wrapper function.  So it goes from what should be O(n) to O(n^3) for no good reason at all.  Scarry.

  • wavenger (unregistered) in reply to gadgetarms
    gadgetarms:

    This isn't actually as bad as it may seem.  getRols()  is probably a private getter method wrapping an instance variable, while GetRoles is the public equivalent and does nothing but clone the Roles returned by getRols().  Most likely, this is an attempt to keep external classes from adding/removing items from the Roles list (since ArrayList is not immutable).  Although the choice of method names and the fact that they didn't use roles.clone() leaves something to be desired, I've seen much worse.  Of course if I am wrong and getRols() makes a database call, then this code really sucks.



    getRols() does in fact make a database call:

    getRols(), as you may have guessed, also returned an ArrayList; but unlike GetRoles(), it went to the database to retreive the user's roles.


    I suppose you're one of those people who fell for the "Read the entire test before starting," trick (where the last page of the test says, "Put your name on the paper, turn it over and sit quietly until the end of the test"). :) But at least you recognize the potential for a performance problem (ergo, you would probably not make the same mistake yourself).

    I'll admit that I've been lazy and done something similar once or twice, but most of what I write is Python or Perl to help me spit out documentation faster. I'm a technical writer, not a programmer. And, holy shit, I've never been dumb enough to do it with a database.

    Also, what are the conventions like in C#? It seems pretty weird (coming from somebody who started with C++ and Java) to have a function that can either return an ArrayList or null, which necessitates sanity checking whenever you call it. And GetRols() is as dumb a function name as anybody could come up with. Would it really have been a problem to say GetRolesFromDatabase() instead? Perhaps if they'd used that instead, the programmer writing this function would've realized they're making a buttload of slow SQL queries.
  • (cs) in reply to impslayer
    impslayer:

    <!--StartFragment -->That's one of the great things with this site, and has been mentioned several times before... It's actually not impossible that Alex ('Alex') uses TDWTF as some sort of psychology experiment by presenting fabricated 'WTF stories' just to lure 'WTF people' into proving themselves to be just that. Perhaps some of us will even turn up in some academic papers, or even a book! Now THAT would be the real WTF?!?!?!?

    I think you're looking a little too far into this ...

  • (cs)

        Holy crap, this makes me want to cry. Imagining a whole application written like this makes me seriously depressed.

  • Anon Coward (unregistered)

    The real WTF is that a manager allows developers to write an application without a single comment in the code.  We are then left to guess what a particular method is supposed to accomplish by wading through the code and debating whether it's a failed cache mechanism, or really, really bad code.  If it's just really, really bad code, we are still left with guessing the original intent.  After the senior developer had re-written the code, I'd have fired the manager.

    To me, the best indication of a developer's worth is how well the code is documented with comments.  When I started programming, I was given some very good advice by a very good coder: for (just about) every line of code, there should be a comment.  If there aren't then I have a very low opinion of the developer.  His/her view is, no doubt, that if someone is unable to follow the uncommented code, then then that someone is an idiot.

    This reminds me of a book I had to read in college - on the way to my degrees in History and Philosophy.  It started out in English, then started to include long untranslated quotations from French and German writers.  This didn't seem too bad - I knew French and I had to do was find someone who knew German.  Then came the quotations in Latin, and I gave up when I got to the quotations in Greek.

    Nobody becomes a good programmer without being a bad programmer first.  And as we get better, we will come across our own code and wonder "WTF?".  The only thing that will help things along is good commenting.  I remember writing my first dll in C, and there were many, many comments.  Months later, we had to resolve a bug.  Another developer had to look at my code - his speciality was SQL, not C.  Instead of running to me, he was able to understand the code, and trace the problem to an incorrect ODBC setting on the server.

  • (cs) in reply to mjonhanson

    mjonhanson:
    I say three, three, three database calls for the price of one unnecessary wrapper function.  So it goes from what should be O(n) to O(n^3) for no good reason at all.  Scarry.

    No, it should be one.  One single call to the database is all that is required.  This wonderful function turns it into 2n+1 calls to the database, where n is the number of items returned by getRols.

    So, if there are 10 roles in the database, then this function makes 21 calls to the database when only 1 is necessary.  If there are 50 roles in the database the function makes 101 calls to the database when only one is necessary.  I mean what does the time it takes to loop through an array and populate another matter in the face of that?

  • some moron (unregistered) in reply to Anon Coward
    Anonymous:

    When I started programming, I was given some very good advice by a very good coder: for (just about) every line of code, there should be a comment.  If there aren't then I have a very low opinion of the developer.  His/her view is, no doubt, that if someone is unable to follow the uncommented code, then then that someone is an idiot.



    the trouble with comments is that they are often neglected as the code evolves... better to choose a verbose and self explanatory naming policy, to keep things short and to always remember that programmers are stupid and forgetful.

    Comments on every line tend to be a patronising duplication of the code itself.
  • chuck (unregistered)

    getROFL();

    (CAPTCHA: "genius")

    'nuff sed.

  • robot (unregistered)

    That's not a WTF. That's an OMFG.

  • (cs) in reply to KattMan
    Anonymous:
    He stated that adding programmers will slow down a project, end of story, finito.  I countered by saying that if that were the case no project would have more than one programmer but in reality, adding programmers will reduce the time to production.  He countered basically saying He was right and I was wrong and that was the way of the world.  This is where our published correspondence ended, of course he was the one controlling it.
    Are you sure that's what he said? If I remember correctly, one of his primary arguments is that the more programmers you have, the more lies of communication you need and the harder it is to keep everybody singing off the same sheet effectively. For instance, if your project has one person, you've no need for communication; two = one line; three = three lines; four = six lines; &c. The number of lines of communication grows exponentially each time you add somebody until the returns diminish completely and start becoming a burden.

    That's part of the reason for breaking big projects into smaller ones: that way, not as many lines of communication are required. Of course, that brings its own problems at integration time.
  • Sofayeti (unregistered) in reply to mjonhanson
    mjonhanson:
    I say three, three, three database calls for the price of one unnecessary wrapper function.  So it goes from what should be O(n) to O(n^3) for no good reason at all.  Scarry.


    No. No. No^3.
    The O function seems to be one of the most mightily abused concepts in this forum.
    Just for the sake of correctness, and as previously stated, the code in question has linear time complexity depending on the number of roles, assuming the database access takes approximately constant time (i.e, can be done in O(1)). As we all have learned, O(2n+1) = O(n).
    So the WTF is that she coded it in O(n) instead of O(1).

    And for sacrilegious misuse of the O function I suggest the term OTF (Oh the...)

    Sofayeti


  • Yariv (unregistered) in reply to Keith Gaughan
    Keith Gaughan:
    The number of lines of communication grows exponentially each time you add somebody until the returns diminish completely and start becoming a burden.

    Not exponentially, please. Its only O(n^2) (to be precise, n*(n-1)/2).
  • Philippe Boucher (unregistered) in reply to NT

    This is the perfect answer to this WTF.  I simply don't get it : we have a lot of comments of people who did not understand this simple WTF.  Go wonder why we need faster processors!

    I would work with you anytime!

    Philippe

  • (cs) in reply to Philippe Boucher
    Philippe:

    This is the perfect answer to this WTF.  I simply don't get it : we have a lot of comments of people who did not understand this simple WTF.  Go wonder why we need faster processors!

    I would work with you anytime!

    Philippe

    All Your Comment Are Belong To Us!

  • O (unregistered) in reply to Sofayeti
    Anonymous:
    mjonhanson:
    I say three, three, three database calls for the price of one unnecessary wrapper function.  So it goes from what should be O(n) to O(n^3) for no good reason at all.  Scarry.


    No. No. No^3.
    The O function seems to be one of the most mightily abused concepts in this forum.
    Just for the sake of correctness, and as previously stated, the code in question has linear time complexity depending on the number of roles, assuming the database access takes approximately constant time (i.e, can be done in O(1)). As we all have learned, O(2n+1) = O(n).
    So the WTF is that she coded it in O(n) instead of O(1).

    And for sacrilegious misuse of the O function I suggest the term OTF (Oh the...)

    Sofayeti




    But it's not O(1), getRols returns an array of some sort with the result set in it. Simply creating that array is O(n) where n is the number of items. Since we do it 2n+1 times that gives us O(n^2)

  • PurplePeopleEater (unregistered)

    The problem with the 10 junior developers is that they're not just junior, they're 10 of them and they all don't know what to do when with what..

    <sigh />

     

  • PurplePeopleEater (unregistered) in reply to someone

     

    But it's not O(1), getRols returns an array of some sort with the result set in it. Simply creating that array is O(n) where n is the number of items. Since we do it 2n+1 times that gives us O(n^2)

    now lets review O(n). it's not 2n^2+1 now is it?  you end up in a loop that is 2^n so you don't just get 25 lists you get 2^25 lists people.

  • (cs) in reply to PurplePeopleEater

     

  • (cs) in reply to GoatCheez

    Ok, it's +2!!! +2!!!! (not like that matters anyway because it gets taken out, but still!)

    getRols is called twice for each loop. It is also called once before, and once for the final not true loop check.

    Simple table:
    (assuming getRols has n Execution time (otherwise it's just too simple))

    of items.        # of calls to getRols          getRols execution time             total "time"

    2                              6                                        2                                   2^6 = 64
    4                              10                                       4                                 4^10 = 1048576
    10                           22                                      10                                10^22 = 1x 10^22 (lol)

    n^(2n+2)

    u can simplify if u want.


    #include <disclaimer>
    char GoatCheez[]="brillant!";
  • Luke (unregistered) in reply to Shizzle
    Anonymous:
    Anonymous:

    It's not just junior developers, i started work straight out of university working with someone with 3years in the business (not much but alot more than me). Here is an example of his code

    ArrayList al = new ArrayList();

    // al gets populated so has stuff in

    int count = 0;

    for (int i=0; i<al.Count; i++)
    {
       count++;
    }

    return count;

    And this guy was earning far more than me since he was contracting. I wondered why I even bothered sometimes. Not to mention the webpage he wrote that took approximately 30seconds to be generated. Once he left I rewrote it to take around 1second. And im still on my rubbish wage.


    This is *NOT* a WTF... anyone knows a sufficiently intelligent compiler would optimize the loop out of existence in the machine code.  Heh and LOL0rz.

    The C# compiler doesn't optimize the loop out of the generated IL (check it out for yourself). So in fact this is a WTF. In anycase why anyone would want to write the code like this, even if the compiler optimized it out, is beyond me.

  • Cerin (unregistered) in reply to Bitruder
    Bitruder:
    Would that ever not return null?
    Wait... wouldn't that be an infinite loop?

    I'm guessing you're one of the 10 programmers they let go...
  • (cs) in reply to PurplePeopleEater
    PurplePeopleEater:

    now lets review O(n). it's not 2n^2+1 now is it?  you end up in a loop that is 2^n so you don't just get 25 lists you get 2^25 lists people.



    Where is this 2^n loop? WTF?
  • Sofayeti (unregistered) in reply to O
    Anonymous:


    But it's not O(1), getRols returns an array of some sort with the result set in it. Simply creating that array is O(n) where n is the number of items. Since we do it 2n+1 times that gives us O(n^2)



    That is correct. If you want, you may say the WTF is that she coded it in O(n^2) instead of O(n).
    At least we know that it _could_ be done in about O(1), e.g. by caching the results in an immutable ArrayList (if such thing exists in C#).

    Sofayeti
  • Sofayeti (unregistered) in reply to GoatCheez
    GoatCheez:
    Ok, it's +2!!! +2!!!! (not like that matters anyway because it gets taken out, but still!)

    getRols is called twice for each loop. It is also called once before, and once for the final not true loop check.

    Simple table:
    (assuming getRols has n Execution time (otherwise it's just too simple))

    # of items.        # of calls to getRols          getRols execution time             total "time"
    2                              6                                        2                                   2^6 = 64
    4                              10                                       4                                 4^10 = 1048576
    10                           22                                      10                                10^22 = 1x 10^22 (lol)

    n^(2n+2)

    u can simplify if u want.



    You're right about the +2. Still I'd want to "simplify" to n*(2n+2).

    Sofayeti
  • (cs) in reply to Someone, Somewhere, outwhere

    Someone:
    so let's expand this function (translated into php for clarity), and include what it's calling
    function GetRoles()
    {
           // some stuff deleted
           while (1)
           {
                 $lengthRoles = getRols();
                 if (count($roles) >= count($lengthRoles))
                    break;
                 $fetchRoles = getRols();
                 $roles[] = $fetchRoles[count($roles)];
            }
           // some stuff deleted
    }

    Why did you feel the need to obfuscate the code?  The lack of types in PHP is compounded by your brilliant variable naming strategy, so I would expect lengthRoles to be an integer (the length / size of the array) and fetchRoles to perhaps be a function pointer (address of a function that fetches something)...  no, wait, they're both assigned the return value of getRols(), so they must both be arrays of roles...

    The code in the original post was at least easy to read, if not exactly optimized for performance...

  • YourMother (unregistered)

    This is what you get when you teach "premature optimization is the root of all evil."

    captch: stfu

  • Maldo (unregistered) in reply to NT

    getRols(...) is not by definition an abbreviation. Assuming that this code is written in The Netherlands (as the name of the believer suggests), the author of this code has used the dutch word for Role, namely Rol.
    However, it is of course quite a bad habit to mix up your languages. One should do it in all dutch, or in all English.
    Second however: Rols is not the plural form of Rol, the method name should have been getRollen(...).


    I'm not sure if this speaks for or against the author of this code ;-)

  • (cs) in reply to Anon Coward
    Anonymous:
    To me, the best indication of a developer's worth is how well the code is documented with comments.  When I started programming, I was given some very good advice by a very good coder: for (just about) every line of code, there should be a comment. If there aren't then I have a very low opinion of the developer.

    I have a very low opinion of a developer if there is a need "for (just about) every line of code" to have a comment. If they have to resort to explaining what (just about) every line does then something is fundamentally wrong with the way it is coded. As such, that advice from "a very good coder" was bollocks.

    His/her view is, no doubt, that if someone is unable to follow the uncommented code, then then that someone is an idiot.

    This reminds me of a book I had to read in college - on the way to my degrees in History and Philosophy.  It started out in English, then started to include long untranslated quotations from French and German writers.  This didn't seem too bad - I knew French and I had to do was find someone who knew German.  Then came the quotations in Latin, and I gave up when I got to the quotations in Greek.

    And this is relevant how? Comments are optional, whereas what you needed was an appendix, or at the very least a translation footnote for each quotation.
  • (cs) in reply to MrBester
    MrBester:

    I have a very low opinion of a developer if there is a need "for (just about) every line of code" to have a comment. If they have to resort to explaining what (just about) every line does then something is fundamentally wrong with the way it is coded. As such, that advice from "a very good coder" was bollocks.



    Exactly. An experienced programmer must be able to read well-written code without constant need for comments.

    Comments are usefull to explain uncommon circumstances, the reason why something is necessary, warn against pitfalls. JavaDoc-Style comments are obviously usefull to generate formal documentation. The last thing I want in my code are redundant comments like

    i++; // increase i by 1


Leave a comment on “The Juniors' Whopper”

Log In or post as a guest

Replying to comment #:

« Return to Article