This is how we get TDWTF style code.



  • Right, so I finally stopped procrastinating my programming homework, and opened up the book to find this snippet of example code (with minor syntax fixes applied, since the purpose of the corresponding exercise was to fix those):

    void taxCalculations(num income)
        num count, tax
        const num NUMBRKTS = 5
        num brackets[NUMBRKTS] = 15000, 22000, 40000, 70000, 100000
        num rates[NUMBRKTS] = 0, 0.15, 0.18, 0.22, 0.28, 0.30
        while count < NUMBRKTS and income > brackets[count]
            count = count + 1
        endwhile
        tax = income * rates[count]
    return tax

    I'm still not sure exactly how that while loop works, but I translated it into Python and it appears to have the intended effect. Other WTFs, most present throughout the book: using completely ridiculous names for constants complying with an arbitrary law restricting variable names to one vowel; blithely ignoring the (important) difference between int and float; reusing the counter variable of a loop outside of that loop; and camel case (I know, not really a WTF but I personally can't stand it). (Side note: Java's println() is cited as an example of camel case. Fail.)

     

    And these students (all 6 of us, the rest dropped the class) will someday be allowed to actually touch code?



  • It's not really that bad. I imagine the original code were javascript or a similary language which only have floatingpoints.

    The purpose of the loop is to find out which bracket the given income is in. When the loop terminates count is the correct bracket. No magic there, and quite easy to understand. But yes, count is a bad name for that variable, should have been userBracket or something similary. (Well, it really should have been its own function, but I disgress).

     ps: I think you miss a count=0; before the loop.

     



  • I understand *what* the loop does, I just had to stare at it way too long to figure out *how* it does it. I would have broken it out into a set of if statements. Just as efficient as a loop and a lot clearer (well, at the expense of a few bytes of space.)


    (And the book is semi-written for C++ - there's a smaller book that goes with it containing C++ code for all this that I've been too {scared,lazy} to open until this point. It doesn't seem as bad as the pseudocode, but still contains minor WTFs such as a constant called NUM_LOOPS (loops != iterations!) and saying the string "Chicago" (as a std::string) will take up exactly 7 bytes of memory (but "may be different on your system"). They're not major but a resource intended for learning shouldn't contain things like that.



  •  TRWTF is that tax brackets don't work that way.



  • @scgtrp said:

    saying the string "Chicago" (as a std::string) will take up exactly 7 bytes of memory (but "may be different on your system"). They're not major but a resource intended for learning shouldn't contain things like that.

    Not counting the overhead of the std::string object itself (which is likely 3*sizeof(pointer)) or memory allocation, it can very well take exactly 7 bytes. std::string does not depend on a terminating nil character, and may contain embedded nils. It generally works by storing pointers to the beginning and end of allocated area as well as the end of actual data (the standard does not actually mandate this internal structure, but strongly hints towards it).

    So, there's no factual WTF there, although I can't quite decide whether the statement is too vague (no mention of the overhead) or gives too much details (this is intended for relative beginners after all).



  • @scgtrp said:

    void taxCalculations(num income)
        num count, tax
        const num NUMBRKTS = 5
        num brackets[NUMBRKTS] = 15000, 22000, 40000, 70000, 100000
        num rates[NUMBRKTS] = 0, 0.15, 0.18, 0.22, 0.28, 0.30
        while count < NUMBRKTS and income > brackets[count]
            count = count + 1
        endwhile
        tax = income * rates[count]
    return tax

    1. Function is declared void but returns a value
    2. count is not initialized (some languages zero-initialize everything by default)
    3. rates is declared to be the same size as brackets, but contains one more value
    4. If income falls outside the highest bracket, the rates array is accessed past its declared size
    5. The tax variable is only assigned once just before returning its value - the expression could have been returned directly instead
    6. Using apparent floating-point values for monetary calculations
    7. Using a variable of an apparent non-integer type to declare array sizes
    8. Tax calculation does not work that way

    Did I miss anything?



  • @scgtrp said:

     I would have broken it out into a set of if statements. Just as efficient as a loop and a lot clearer (well, at the expense of a few bytes of space.)

     

    But now you need to understand the code and change the if-else ladder if you add or remove a tax bracket.



  • @scgtrp said:

    I understand *what* the loop does, I just had to stare at it way too long to figure out *how* it does it.

     

    I put it to you that there are two possible places for the problem to reside in this scenario, and only one of them is the code.

    Though I do agree that an if/else chain would be preferable here.

    The real WTF though is hard-coding tax brackets in a program.  Don't they know they're going to change regularly?  Those should be in a database, and then you can just use a very simple SQL statement to pull out the relevant figure without obfuscation or fragility.


  • @Iago said:


    Though I do agree that an if/else chain would be preferable here.

    The real WTF though is hard-coding tax brackets in a program.  Don't they know they're going to change regularly?  Those should be in a database, and then you can just use a very simple SQL statement to pull out the relevant figure without obfuscation or fragility.

    I wonder what your if/else chain would look like when the values are loaded from a database.


  • Discourse touched me in a no-no place

    @tdb said:

    @Iago said:

    Though I do agree that an if/else chain would be preferable here.

    The real WTF though is hard-coding tax brackets in a program.  Don't they know they're going to change regularly?  Those should be in a database, and then you can just use a very simple SQL statement to pull out the relevant figure without obfuscation or fragility.

    I wonder what your if/else chain would look like when the values are loaded from a database.

    http://thedailywtf.com/articles/soft_coding.aspx ?


  • What language is this anyway?

    @scgtrp said:

    num rates[NUMBRKTS] = 0, 0.15, 0.18, 0.22, 0.28, 0.30

    Writing a beginner course in programming in a language that allows discrepancies like this is a WTF in itself



  • @tdb said:

    @scgtrp said:

    void taxCalculations(num income)
        num count, tax
        const num NUMBRKTS = 5
        num brackets[NUMBRKTS] = 15000, 22000, 40000, 70000, 100000
        num rates[NUMBRKTS] = 0, 0.15, 0.18, 0.22, 0.28, 0.30
        while count < NUMBRKTS and income > brackets[count]
            count = count + 1
        endwhile
        tax = income * rates[count]
    return tax

    1. Function is declared void but returns a value
    2. count is not initialized (some languages zero-initialize everything by default)
    3. rates is declared to be the same size as brackets, but contains one more value
    4. If income falls outside the highest bracket, the rates array is accessed past its declared size
    5. The tax variable is only assigned once just before returning its value - the expression could have been returned directly instead
    6. Using apparent floating-point values for monetary calculations
    7. Using a variable of an apparent non-integer type to declare array sizes
    8. Tax calculation does not work that way

    Did I miss anything?

    Doesn't 'count < NUMBRKTS' take care of the fourth item in your list?



  • @Adriano said:

    @tdb said:
    @scgtrp said:

    void taxCalculations(num income)
        num count, tax
        const num NUMBRKTS = 5
        num brackets[NUMBRKTS] = 15000, 22000, 40000, 70000, 100000
        num rates[NUMBRKTS] = 0, 0.15, 0.18, 0.22, 0.28, 0.30
        while count < NUMBRKTS and income > brackets[count]
            count = count + 1
        endwhile
        tax = income * rates[count]
    return tax

    1. Function is declared void but returns a value
    2. count is not initialized (some languages zero-initialize everything by default)
    3. rates is declared to be the same size as brackets, but contains one more value
    4. If income falls outside the highest bracket, the rates array is accessed past its declared size
    5. The tax variable is only assigned once just before returning its value - the expression could have been returned directly instead
    6. Using apparent floating-point values for monetary calculations
    7. Using a variable of an apparent non-integer type to declare array sizes
    8. Tax calculation does not work that way

    Did I miss anything?

    Doesn't 'count < NUMBRKTS' take care of the fourth item in your list?

     

    Not exactly. The last iteration through the loop, count will start off as 4, which is less than NUMBRKTS. The code in the loop will set count to 5.

    Then, the assignment to tax will reference rates[5]. So, it depends on which part of the broken declaration of rates you believe. It's declared as an array of size 5, but is initialized with 6 elements.



  • @levbor said:

    What language is this anyway?

    @scgtrp said:

    num rates[NUMBRKTS] = 0, 0.15, 0.18, 0.22, 0.28, 0.30

    Writing a beginner course in programming in a language that allows discrepancies like this is a WTF in itself

    I'm betting pseudocode. The author of the OP did mention in some post that there was a companion book containing C++ translations of the examples.



  • It is pseudocode. TRWTF seems to be my bug finding skills when I'm up late doing homework due the next day. Plenty of stuff there I missed :/

    I still think it would have been better to write the textbook in a real language so students can actually try the code. I always debug my code by actually compiling it and testing it, instead of just staring at it until bugs pop out at me. (The C++ companion book only contains language-specific stuff for the main text, not the exercises like this one.)



  • @scgtrp said:

    It is pseudocode. TRWTF seems to be my bug finding skills when I'm up late doing homework due the next day. Plenty of stuff there I missed :/

    I still think it would have been better to write the textbook in a real language so students can actually try the code. I always debug my code by actually compiling it and testing it, instead of just staring at it until bugs pop out at me. (The C++ companion book only contains language-specific stuff for the main text, not the exercises like this one.)

    you could always just try writing it in C/C++ and testing it that way.  The idea of debugging pseudocode has always struck me as silly. 



  • @DescentJS said:

    @scgtrp said:

    It is pseudocode. TRWTF seems to be my bug finding skills when I'm up late doing homework due the next day. Plenty of stuff there I missed :/

    I still think it would have been better to write the textbook in a real language so students can actually try the code. I always debug my code by actually compiling it and testing it, instead of just staring at it until bugs pop out at me. (The C++ companion book only contains language-specific stuff for the main text, not the exercises like this one.)

    you could always just try writing it in C/C++ and testing it that way.  The idea of debugging pseudocode has always struck me as silly. 

    Even more, the task was to correct the syntax errors in the pseudocode. 


  • @morbiuswilters said:

     TRWTF is that tax brackets don't work that way.

     

    Yah, whatever prof or TA wrote this example is in for a fun time with the IRS, come April 15th.



  • @blakeyrat said:

    @morbiuswilters said:

     TRWTF is that tax brackets don't work that way.

     

    Yah, whatever prof or TA wrote this example is in for a fun time with the IRS, come April 15th.

    Why would the IRS care? The error is in their favor. The way the brackets really work is that the first X dollars are taxed at rate 1, the next Y dollars at rate 2, the next Z dollars at rate 3. Taxing the entire amount at rate 3 would be grossly OVER-taxed.

    If tax brackets worked the way they do in this "program," then it would be possible to actually end up with a SMALLER paycheck when your boss gives you a RAISE (because you've bumped into a higher bracket). Obviously, people would overthrow the government if it worked like that.



  • [QUOTE] it would be possible to actually end up with a SMALLER paycheck when your boss gives you a RAISE (because you've bumped into a higher bracket).[/QUOTE]

    I've had this happen. The jerk bumped me just over the tax line. from just under it. Wise-ass found out the meaning of tax bracket pretty fast at my next pay check.


  • Discourse touched me in a no-no place

    @morbiuswilters said:

     TRWTF is that tax brackets don't work that way.

    Only in the more enlightened parts of tax codes.

    UK Stamp Duty Land Tax (a percentage tax on the value of land or buildings bought) works the way the program works. Go £1 into the next band up, and you get charged the percentage in that band on the whole price, not just the marginal bit.

    Naturally this constricts prices to below the band limits in cases where normally they'd be a certain amount above them.

    Income tax works on marginal rates, so the whole tax code isn't completely barking. At least not in that way.



  • @belgariontheking said:

    Even more, the task was to correct the syntax errors in the pseudocode. 

    Ding, ding, ding! Gentlemen, we have a winner. Pseudocode has no defined syntax. Its sole purpose is to allow you to document your logic in a human-readable way without having to worry about any particular syntax.


  • @joelkatz said:

    @belgariontheking said:

    Even more, the task was to correct the syntax errors in the pseudocode. 

    Ding, ding, ding! Gentlemen, we have a winner. Pseudocode has no defined syntax. Its sole purpose is to allow you to document your logic in a human-readable way without having to worry about any particular syntax.

    Not entirely true, I have a textbook that uses a pseudocode with a definined syntax. It's more that the code is not compilable and may use odd symbols.  Such as what the textbook uses for variable assignment "<FONT size=4>←</FONT>" 



  • @DescentJS said:

    the textbook uses for variable assignment "<font size="4">←</font>" 
     

    What the fuck.



  • @DescentJS said:

    Such as what the textbook uses for variable assignment "<font size="4">←</font>"
     

    Sounds like an early sign of APL Syndrome. Burn it quickly before it infects something else.



  • @Someone You Know said:

    @DescentJS said:

    Such as what the textbook uses for variable assignment "<font size="4">←</font>"
     

    Sounds like an early sign of APL Syndrome. Burn it quickly before it infects something else.

     

    Too late. That's what wikipedia pseudocode uses for variable assignment, too.



  •  @dhromed said:

    @DescentJS said:

    the textbook uses for variable assignment "<font size="4">←</font>" 
     

    What the fuck.

     Eh, Knuth?



  • @Obfuscator said:

     @dhromed said:

    @DescentJS said:

    the textbook uses for variable assignment "<font size="4">←</font>" 
     

    What the fuck.

     Eh, Knuth?

    Gesundheit!


Log in to reply