Divide and Validate

« Return to Article
  • Tomas 2013-01-07 08:04
    Well sounds very odd, yet it can return "what is your percentage of completeness"....
    I wouldnt do it by myself (mixing bools and ints and magin all the way) but I think I understand why this code came to mind of programmer .-)
  • Pino 2013-01-07 08:04
    That's pretty weird indeed.
  • daef 2013-01-07 08:05
    return "frist".Length / 0.0;
  • DonaldK 2013-01-07 08:05
    Take into consideration poor Piotr Kaminski, who got stuck with unmaintainable code, in the Twilight Zone...
  • Rob 2013-01-07 08:09
    Well if you want to tell the user how close their form is to completion, that'll work quite nicely. If all the fields are entered correctly it'll return 100; if only one is, you'll get 12 and so on. You can use the value to show a "Your application is now xx% complete" message.

    Not great, but not necessarily a WTF.
  • gallier2 2013-01-07 08:14
    It's actually quite clever. Of course it demands from the developer who reads that, some arithmetic and boolean skills.
    I know, it's asking a lot from people who actually are supposed to know how to crunch numbers. Transforming 100*ct/9.0 to ct/0.09 should be obvious to anyone, and if it isn't, pull down that keyboard and search for another job, more tuned to your skills (flipping burgers, collecting garbage or whatever).

    Not a WTF, in my opinion.
  • Paul 2013-01-07 08:18
    The bit I really don't like is adding BOOLs.

    I don't like the divide because it's not obvious, and not commented (and not self commenting), and there's also the issue that if you add another thing to check for, then the 'percentage complete' calculation would be wrong.

    So, if it was me, I'd:
    - change the 'adding BOOLs pattern' to using tertiary operators (slower, but for this type of check I can't see it being an issue)
    - change the final calcuation to "(ct / 9) * 100" to make it a bit more obvious
    - add a comment to say that if you change the number of checks, then change the calculation at the end

  • LoremIpsumDolorSitAmet 2013-01-07 08:23
    TRWTF is JavaScript, right? Coercing those booleans to be integers (0 or 1) is very cheeky at best - I didn't even know you could do that.

    If this were ported to VB it would be even more fun because TRUE would become -1, so you'd divide by -0.09.
  • QJo 2013-01-07 08:31
    It works, but is it portable?
  • Tragedian 2013-01-07 08:31
    It seems quite an unusual method for validation, but I can see some value in quantifying how far through the validation process you are as a decimal value, rather than the usual true/false/filenotfound.

    Then I got to the line:

    u.employerSharing && true);


    I can't even imagine what sort of person thinks "where [the] employer is sharing, and true" is a reasonable statement.
  • Ade 2013-01-07 08:31
    The WTF is that a % of completeness has been given for a form. On one hand a code maintainer would have to calculate the new number when adding and removing fields. On the other the user would get a percentage value of 'form completeness' which is nonsense.

    "7 out of 8 fields completed" is far more intuitive and meaningful.
  • QJo 2013-01-07 08:33
    But of course TRWTF is "&& true", amirite? Or is this just a smart-bottomed technique to force its type?
  • Anonymous 2013-01-07 08:38
    gallier2:
    Transforming 100*ct/9.0 to ct/0.09 should be obvious to anyone

    Possibly obvious, but also wrong: 0.09 can't be exactly represented in IEEE floating-point, so you may get a fractionally different result. It happens to work for 9 items, but not in general e.g.

    $ python -c 'import math; print math.ceil(57/0.57)'
    101
  • EpicEraser 2013-01-07 08:43
    The general trick for forcing types to booleans is !! (not-not)
    !!1 === true
    !!0 === false

    Whether it is smart to use this in everyday code, I don't know.
  • chris 2013-01-07 08:50
    LoremIpsumDolorSitAmet:
    TRWTF is JavaScript, right? Coercing those booleans to be integers (0 or 1) is very cheeky at best - I didn't even know you could do that.

    If this were ported to VB it would be even more fun because TRUE would become -1, so you'd divide by -0.09.

    Coercing booleans to integers comes from C, and I think since JS is loosely-typed and has C as its most obvious ancestor, you can reasonably expect it to work.

  • Tod 2013-01-07 09:02
    It's still shitty code. No need to repeat all that.

    ct=0;
    elementslist = [u.nickname, u.websiteUrl, u.linkedin, u.locationString, u.title, u.bio, u.imageUrl, u.resume]
    for element in elementslist:
    if typeof(element)=="string" and element.length>0: ct += 1
    if u.employerSharing: ct += 1
    return 100*ct/(len(elementslist)+1);

    Python syntax. I don't know if you can get rid of the "u." in elementslist easily.
  • LoremIpsumDolorSitAmet 2013-01-07 09:04
    Tragedian:
    It seems quite an unusual method for validation, but I can see some value in quantifying how far through the validation process you are as a decimal value, rather than the usual true/false/filenotfound.

    Then I got to the line:

    u.employerSharing && true);


    I can't even imagine what sort of person thinks "where [the] employer is sharing, and true" is a reasonable statement.

    QJo:
    But of course TRWTF is "&& true", amirite? Or is this just a smart-bottomed technique to force its type?

    This.

    u.employerSharing could be any type. The AND operation will coerce it to a boolean... which is then coerced to a number.
  • Doctor_of_Ineptitude 2013-01-07 09:06
    Paul:
    The bit I really don't like is adding BOOLs.

    I don't like the divide because it's not obvious, and not commented (and not self commenting), and there's also the issue that if you add another thing to check for, then the 'percentage complete' calculation would be wrong.

    So, if it was me, I'd:
    - change the 'adding BOOLs pattern' to using tertiary operators (slower, but for this type of check I can't see it being an issue)
    - change the final calcuation to "(ct / 9) * 100" to make it a bit more obvious
    - add a comment to say that if you change the number of checks, then change the calculation at the end



    You should also atleast add an XML layer, coupled with DAL and a backing database implementation. Sure it might be slower, but at least it will be obvious with the added benefit of flexibility.
  • savar 2013-01-07 09:11
    gallier2:
    It's actually quite clever. Of course it demands from the developer who reads that, some arithmetic and boolean skills.
    I know, it's asking a lot from people who actually are supposed to know how to crunch numbers. Transforming 100*ct/9.0 to ct/0.09 should be obvious to anyone, and if it isn't, pull down that keyboard and search for another job, more tuned to your skills (flipping burgers, collecting garbage or whatever).

    Not a WTF, in my opinion.


    Clever is a strong word. This is still very stupid code. (Hint: each field is hard coded, as is the constant 0.09.) But I agree its not exactly a WTF either. It's bad code that kinda works for what it was supposed to do.
  • MiffTheFox 2013-01-07 09:13
    chris:
    Coercing booleans to integers comes from C, and I think since JS is loosely-typed and has C as its most obvious ancestor, you can reasonably expect it to work.


    Let's face it, if this were PHP, nobody would be standing up for this code.

    The only real difference between JS and PHP is that when it comes to PHP you have alternatives.
  • ¯\(°_o)/¯ I DUNNO LOL 2013-01-07 09:27
    MiffTheFox:
    chris:
    Coercing booleans to integers comes from C, and I think since JS is loosely-typed and has C as its most obvious ancestor, you can reasonably expect it to work.
    Let's face it, if this were StackOverflow, nobody would be standing up for this code.
    FTFY. This is TDWTF and we love to ironically defend bad code.
  • anonymouse 2013-01-07 09:32
    Any value coming from a non-checkbox is a string, not sure why you would check the type every time. Also not sure why a function is being declared anonymously, that's irritating. Also not sure what's up withe the && true statement.

    function proFormComplete()
    
    {
    var props = ['websiteUrl', 'linkedin']; // etc.
    var ct = 0;
    var u = user.getUser();
    for(var s in props)
    {
    ct += u[s].length > 0;
    }
    ct += !!u.employerSharing;
    return (props.length+1*100)/9;
    }
  • chris 2013-01-07 09:34
    Doctor_of_Ineptitude:
    Paul:
    The bit I really don't like is adding BOOLs.

    I don't like the divide because it's not obvious, and not commented (and not self commenting), and there's also the issue that if you add another thing to check for, then the 'percentage complete' calculation would be wrong.

    So, if it was me, I'd:
    - change the 'adding BOOLs pattern' to using tertiary operators (slower, but for this type of check I can't see it being an issue)
    - change the final calcuation to "(ct / 9) * 100" to make it a bit more obvious
    - add a comment to say that if you change the number of checks, then change the calculation at the end



    You should also atleast add an XML layer, coupled with DAL and a backing database implementation. Sure it might be slower, but at least it will be obvious with the added benefit of flexibility.


    In JS, surely the way to do it is to maintain an array of functions as a property of a function to run them all and divide by the length of the array?
  • Doctor_of_Ineptitude 2013-01-07 09:47
    chris:
    Doctor_of_Ineptitude:
    Paul:
    The bit I really don't like is adding BOOLs.

    I don't like the divide because it's not obvious, and not commented (and not self commenting), and there's also the issue that if you add another thing to check for, then the 'percentage complete' calculation would be wrong.

    So, if it was me, I'd:
    - change the 'adding BOOLs pattern' to using tertiary operators (slower, but for this type of check I can't see it being an issue)
    - change the final calcuation to "(ct / 9) * 100" to make it a bit more obvious
    - add a comment to say that if you change the number of checks, then change the calculation at the end



    You should also atleast add an XML layer, coupled with DAL and a backing database implementation. Sure it might be slower, but at least it will be obvious with the added benefit of flexibility.


    In JS, surely the way to do it is to maintain an array of functions as a property of a function to run them all and divide by the length of the array?


    Nice. We should also add a round trip to server to check the results. That way we also get the opportunity to add a few more security holes and even slow down the system even more. Double win.
  • Shock Puppet 2013-01-07 09:56
    ¯\(°_o)/¯ I DUNNO LOL:
    MiffTheFox:
    chris:
    Coercing booleans to integers comes from C, and I think since JS is loosely-typed and has C as its most obvious ancestor, you can reasonably expect it to work.
    Let's face it, if this were StackOverflow, nobody would be standing up for this code.
    FTFY. This is TDWTF and we love to ironically defend bad code.


    I'm not entirely certain said defenders are aware of their irony...of course, maybe that makes your statement doubly ironic!

    captcha: ludus, as in, "The amount of crappy code people on TDWTF call clever is just ludus".
  • conquer 2013-01-07 09:57
    chris:

    Coercing booleans to integers comes from C, and I think since JS is loosely-typed and has C as its most obvious ancestor, you can reasonably expect it to work.


    I don't know of any booleans in C. I doubt it exists in C. (Dunno C++)
    So if you see this in C, it's not really because the programmer likes ints more, it's because their are no booleans.

    Seeing it in a language that knows booleans, that's probably just stupid.

  • operagost 2013-01-07 10:05
    That's "31337", or "1337". But in this case, it's definitely "14M3".
  • smilr 2013-01-07 10:05
    you never use the final result of the ct tally...

    perhaps you meant something more like:

    return (ct*100)/(props.length + 1);
  • Berend 2013-01-07 10:07
    Why give this function a global variable? For all it's cleverness that's just sloppy.
  • gallier2 2013-01-07 10:31
    The types
    _Bool
    and its alias
    bool
    are in the C language since the C99 standard (it was already in some compilers like gcc as extension long before that).


    bool b = 99;
    printf("Value of b=%d\n", b);


    will print
    Value of b=1
    
  • realmerlyn 2013-01-07 10:34
    When I have something like this, I use a series of checks, and return false when any check fails, and return true at the end of the subroutine. Why perform unneeded checks?
  • Snowrat 2013-01-07 10:46
    The real WTF is dividing by 0.09 and incurring a slow division instead of multiplying with 11.11
  • Zylon 2013-01-07 10:50
    Y'know, if you replace that last line with "return ct == 9;" you'd have a perfectly reasonable, if somewhat excessively clever, validation routine.
  • Anonymous Coward 2013-01-07 11:10
    I used to work with a guy who everyone considered a wizard, because he wrote undocumented "clever" code like this that still met its intended function. Pretty much your standard "job security through obfuscation." It was always a treat to come across a SQL statement that took 15 minutes of analysis to figure out it was checking if a certain type of record existed in a table.

    I always thought his code would have been TDWTF-worthy, if not that the WTFs therein were completely opaque to anyone without years of intimate knowledge of the DB schema.
  • chubertdev 2013-01-07 11:30
    LoremIpsumDolorSitAmet:
    TRWTF is JavaScript, right? Coercing those booleans to be integers (0 or 1) is very cheeky at best - I didn't even know you could do that.

    If this were ported to VB it would be even more fun because TRUE would become -1, so you'd divide by -0.09.


    It's odd that you get a code smell so strong from the language itself. If I were to create a language that forced users to type three equal signs in a row, I'd think, "maybe I'm doing something wrong."
  • Abico 2013-01-07 11:38
    realmerlyn:
    When I have something like this, I use a series of checks, and return false when any check fails, and return true at the end of the subroutine. Why perform unneeded checks?

    Many languages use short-circuit evaluation, So you can do:

    if (a bunch of things you expect to be true, ANDed together) {
    return true;
    }
    return false;

    Or simply:
    return (a bunch of things you expect to be true, ANDed together);

    As soon as one of the terms evaluates to false, it will stop evaluating.

    But all that aside, this isn't simply evaluating TRUE or FALSE, it's seeing how many things are TRUE or FALSE.
  • Abico 2013-01-07 11:40
    Abico:
    realmerlyn:
    When I have something like this, I use a series of checks, and return false when any check fails, and return true at the end of the subroutine. Why perform unneeded checks?

    Many languages use short-circuit evaluation, So you can do:

    if (a bunch of things you expect to be true, ANDed together) {
    return true;
    }
    return false;

    Or simply:
    return (a bunch of things you expect to be true, ANDed together);

    As soon as one of the terms evaluates to false, it will stop evaluating.

    But all that aside, this isn't simply evaluating TRUE or FALSE, it's seeing how many things are TRUE or FALSE.

    I should note that using short-circuit evaluation can make debugging really obnoxious.
  • Gary 2013-01-07 11:44
    anonymouse:
    Also not sure why a function is being declared anonymously, but that's awesome.

    FTFY. In this case, easier to attach to an event.

    Anonymous functions are the best thing about JS.
  • Coyne 2013-01-07 11:44
    gallier2:
    Transforming 100*ct/9.0 to ct/0.09 should be obvious to anyone, and if it isn't, pull down that keyboard and search for another job, more tuned to your skills (flipping burgers, collecting garbage or whatever.


    So, okay, given that this is clever and "obvious", then why no do the next clever step and change it to multiply by 11.111111? (Multiply being much more efficient than divide.)
  • Alexandros 2013-01-07 12:01
    TRWTF is not using AJAX to validate on the server:

    1. Server request sends parameters to a validation servlet.
    2. Server responds with true or false.
    3. If the server gave true, submit to the real server.
    4. Else, show error message.
  • Zecc 2013-01-07 12:04
    Berend:
    Why give this function a global variable? For all it's cleverness that's just sloppy.
    If it's 'user' you're talking about, then you can't be sure. It may be part of something like:


    function setup(){
    var myForm // This is how you should declare variables,
    , user // haven't you heard?
    , proFormSetNickname
    // ...
    , proFormComplete
    ;

    myForm = document.getElementById('theForm');
    user = {};

    proFormSetNickname = function(){
    user.nickname = myForm['nickname'].value;
    }
    // ...

    myForm['nickname'].onchange = proFormSetNickname;
    // ...
    myForm.onsubmit = proFormComplete;
    }

  • Zecc 2013-01-07 12:09
    Zecc:


    myForm.onsubmit = proFormComplete;
    Didn't think of how the return value is used, here.
    Oh well, wrap it in an anonymous function are compare it to 100 or something
  • F 2013-01-07 12:37
    Zylon:
    Y'know, if you replace that last line with "return ct == 9;" you'd have a perfectly reasonable, if somewhat excessively clever, validation routine.


    Except, of course, that it produces an incompatible result.
  • LordHighFixer 2013-01-07 13:12
    That's not so bad. Back in the old days before strict typing rules existed it used to be possible in some languages to do math on strings and get strings in return as a result (binary math on strings with strings can return some interesting, predictable, and hilarious results). Of few of the more enterprising of us figured how how to use this little fact to our advantage much to the chagrin of anyone who actually saw the code.
  • da Doctah 2013-01-07 13:17
    This is no more arcane than Zeller's Algorithm for calculating the day of the week (in which today's date in ISO form is 2012-13-07).
  • chubertdev 2013-01-07 13:20
    LordHighFixer:
    That's not so bad. Back in the old days before strict typing rules existed it used to be possible in some languages to do math on strings and get strings in return as a result (binary math on strings with strings can return some interesting, predictable, and hilarious results). Of few of the more enterprising of us figured how how to use this little fact to our advantage much to the chagrin of anyone who actually saw the code.


    I still can't believe that the plus sign can be used to concatenate strings in VB .NET. Talk about a huge WTF.
  • instigator 2013-01-07 13:35
    I'm not a javascript expert, but that might have something to do with manipulating the return type. Just as I expect the "0 +" at the beginning of the sum is likely for type casting. But does java not have an explicit cast operator?
  • booleans are booleans 2013-01-07 13:38
    I know why it works, but booleans should never have been equated to integers.

    From "The Elements of Programming Style" which should be required reading:
    "Write clearly - don't be too clever."
  • instigator 2013-01-07 13:45
    chubertdev:
    It's odd that you get a code smell so strong from the language itself. If I were to create a language that forced users to type three equal signs in a row, I'd think, "maybe I'm doing something wrong."


    Yes, but you also might be a pretentious prick.
  • instigator 2013-01-07 13:51
    chubertdev:
    I still can't believe that the plus sign can be used to concatenate strings in VB .NET. Talk about a huge WTF.


    Why is that a WTF? Its a feature available in many sane languages.
  • instigator 2013-01-07 13:56
    I'm guessing there is a validation check server side as well. But doing it on the client side saves a potential network traversal, server load, etc. This would be particularly advantageous if you are doing live validation.
  • Berend 2013-01-07 13:57
    Nah, I was talking about the function declaration which should be

    var proFormComplete = function(){...}

    but of course it could be part of a larger function like you suggested.
  • chubertdev 2013-01-07 14:01
    instigator:
    chubertdev:
    I still can't believe that the plus sign can be used to concatenate strings in VB .NET. Talk about a huge WTF.


    Why is that a WTF? Its a feature available in many sane languages.


    Take two seconds on Google to research it.
  • d.k.ALlen 2013-01-07 14:04
    chubertdev:
    instigator:
    chubertdev:
    I still can't believe that the plus sign can be used to concatenate strings in VB .NET. Talk about a huge WTF.


    Why is that a WTF? Its a feature available in many sane languages.


    Take two seconds on Google to research it.


    Relying on Google for judging the sanity of operator overloading is the real WTF.
  • eVil 2013-01-07 14:13
    chubertdev:
    instigator:
    chubertdev:
    I still can't believe that the plus sign can be used to concatenate strings in VB .NET. Talk about a huge WTF.


    Why is that a WTF? Its a feature available in many sane languages.


    You made the assertion, so the onus is yours to provide evidence (via google or otherwise) to support it. Simply stating something, and demanding that other people proove it to themselves

    Take two seconds on Google to research it.


    You made the assertion, so the onus is on you to provide evidence when challenged. Demanding that other people google something to prove your point is both lazy and foolish.
  • eVil 2013-01-07 14:15
    Trying to post that shit on a phone on a very wobbly train is TRWTF.
  • chubertdev 2013-01-07 14:16
    TRWTF is posting as different users :facepalm:
  • eVil 2013-01-07 14:20
    Indeed. Still you should really explain yourself if you want people to agree... Hardly anyone ever googles someone elses side of the argument.
  • Harrow 2013-01-07 15:05
    I like to think that if anyone ever asked me for a function that reported what percentage of a form was filled out correctly, I would write something a lot like this. Probably not as clear, though.

    WTF specifications deserve WTF code.

    -Harrow.
  • Capitalist 2013-01-07 15:15
    instigator:
    chubertdev:
    I still can't believe that the plus sign can be used to concatenate strings in VB .NET. Talk about a huge WTF.


    Why is that a WTF? Its a feature available in many sane languages.
    You said it already. Seriously, in weakly-typed languages, there is possible confusing with addition (when the strings can be converted to numbers). In strongly-typed languages, there is no problem. C++, Pascal and others have been doing it for decades.
  • Capitalist 2013-01-07 15:18
    QJo:
    But of course TRWTF is "&& true", amirite? Or is this just a smart-bottomed technique to force its type?
    That's what I assumed on first reading. Of course it's not very obvious. When supported (C++, C99, etc.) I'd use an explicit cast to bool, otherwise (C90 and older) I might use "!!foo", which is also not obvious the first time, but at least is a more or less common idiom used for no other purpose (unlike "&& true" which may be left over from a check removed, or a placeholder for a check to be added ...).
  • Capitalist 2013-01-07 15:27
    Paul:
    The bit I really don't like is adding BOOLs.

    I don't like the divide because it's not obvious, and not commented (and not self commenting), and there's also the issue that if you add another thing to check for, then the 'percentage complete' calculation would be wrong.

    So, if it was me, I'd:
    - change the 'adding BOOLs pattern' to using tertiary operators (slower, but for this type of check I can't see it being an issue)
    - change the final calcuation to "(ct / 9) * 100" to make it a bit more obvious
    - add a comment to say that if you change the number of checks, then change the calculation at the end

    1. Maybe, though I don't think it's demaning too much for other programmers to know some basic rules of their language, including ordinal values of booleans (if they're well-defined in the given language).

    2. At least that. Though, as others have pointed out, that kind of return value doesn't even give the caller a reliable way to check whether everything is valid (comparing against 100 is not always reliable), and a percentage is not very useful to the end-user either. So just the number of valid fields (and porobably the number of total fields, since this function is where the knowledge is how many fields there are to be validated).

    3. Programmers don't read comments. A self-explanatory variable name like "total_validation_fields" stands a slightly better chance to be noticed and maintained.

    If you expect maintenance often, maybe something like this, so copying/pasting a line of the validation code will keep track of the total:

    total = 0; valid = 0;

    total++; valid += typeof(u.nickname)==='string' && u.nickname.length>0;
    total++; valid += typeof(u.websiteUrl)==='string' && u.websiteUrl.length>0;
    [...]

    return make_pair (valid, total);
  • F 2013-01-07 15:53
    instigator:
    chubertdev:
    It's odd that you get a code smell so strong from the language itself. If I were to create a language that forced users to type three equal signs in a row, I'd think, "maybe I'm doing something wrong."


    Yes, but you also might be a pretentious prick.


    Why only "might"?
  • Maurits 2013-01-07 15:57
    I like that it considers 1-character résumés valid.
  • ¯\(°_o)/¯ I DUNNO LOL 2013-01-07 16:27
    chubertdev:
    I still can't believe that the plus sign can be used to concatenate strings in VB .NET. Talk about a huge WTF.
    Then I guess you don't know that dates back to the late '70s, when computers didn't even have enough RAM to contain this web page you're reading right now.
  • chubertdev 2013-01-07 17:10
    ¯\(°_o)/¯ I DUNNO LOL:
    chubertdev:
    I still can't believe that the plus sign can be used to concatenate strings in VB .NET. Talk about a huge WTF.
    Then I guess you don't know that dates back to the late '70s, when computers didn't even have enough RAM to contain this web page you're reading right now.


    I think you misunderstand me. I mean in addition to the ampersand operator. It would be like C# having both the plus sign and ampersand available for string concatenation.
  • luolimao 2013-01-07 17:29
    anonymouse:
    Any value coming from a non-checkbox is a string, not sure why you would check the type every time. Also not sure why a function is being declared anonymously, that's irritating. Also not sure what's up withe the && true statement.

    function proFormComplete()
    
    {
    var props = ['websiteUrl', 'linkedin']; // etc.
    var ct = 0;
    var u = user.getUser();
    for(var s in props)
    {
    ct += u[s].length > 0;
    }
    ct += !!u.employerSharing;
    return (props.length+1*100)/9;
    }


    That last line should be
    return 100*ct/(props.length+1)

    But as someone else mentioned, TRWTF is % completion.
  • Billy G 2013-01-07 17:37
    Tragedian:
    It seems quite an unusual method for validation, but I can see some value in quantifying how far through the validation process you are as a decimal value, rather than the usual true/false/filenotfound.

    Then I got to the line:

    u.employerSharing && true);


    I can't even imagine what sort of person thinks "where [the] employer is sharing, and true" is a reasonable statement.
    This was my first reaction 2 - forget the rest of it, what's the purpose of the "&& true"?
    Or is the problem that u.employerSharing might be any odd number (I think it would have to be odd.....)

    But yeah, as others have said, TRWTF is Javascript
  • Holly Molly 2013-01-07 17:49
    chris:
    LoremIpsumDolorSitAmet:
    TRWTF is JavaScript, right? Coercing those booleans to be integers (0 or 1) is very cheeky at best - I didn't even know you could do that.

    If this were ported to VB it would be even more fun because TRUE would become -1, so you'd divide by -0.09.

    Coercing booleans to integers comes from C, and I think since JS is loosely-typed and has C as its most obvious ancestor, you can reasonably expect it to work.

    No, No, no. C happened not to have a boolean, so people would use integers as booleans, however going the other way (and making an int from a boolean) is impossible, because the boolean type does not exist.

    The biggest problem with using the same integers we use as a boolean in C as integers is that true can be multiple values.
    The way C uses an integer in a boolean expression equates to something like:

    #define false (0)
    #define true (!false)

    What is the value of true? On many compilers, it's 1. More intuitively, it should probably be 0xff. But it can actually be a whole heap of things.


    int main()
    {
    int total=0;
    int x=3;
    if(x) printf("%d\n", x);
    printf("%d\n", !x);
    total+=x;
    printf("%d\n", total);
    return 0;
    }


    which on my compiler prints:
    3
    0
    3

    C does not have a (standard) boolean type, so coercing back to an integer isn't really coercing - it's using an integer for what it's meant for. That said, it is often dangerous to use an integer simultaneously in logical and arithmetic expressions (although I'll confess I do it to check pointers are non-null)....
  • Holly Molly 2013-01-07 17:55
    gallier2:
    The types
    _Bool
    and its alias
    bool
    are in the C language since the C99 standard (it was already in some compilers like gcc as extension long before that).


    bool b = 99;
    printf("Value of b=%d\n", b);


    will print
    Value of b=1
    
    OK - I stand corrected, I didn't know about _Bool, but bool gives me an "error: 'bool' undeclared", (both on gcc and it's windows friend mingw)

    In that case maybe people do coerce _Bool to int....I don't really think it's a very smart (or necessary) thing to do, but there ya go.....
  • Simon 2013-01-07 18:03
    instigator:
    I'm not a javascript expert, but that might have something to do with manipulating the return type. Just as I expect the "0 +" at the beginning of the sum is likely for type casting. But does java not have an explicit cast operator?


    Java does, yes. But this is javascript, a completely different beast.
  • bgodot 2013-01-07 18:06
    Whenever I write a piece of code, and I'm pleased with how clever it is; I rewrite it to be simpler.
  • gwhe ir 2013-01-07 18:13
    eVil:
    chubertdev:
    instigator:
    chubertdev:
    I still can't believe that the plus sign can be used to concatenate strings in VB .NET. Talk about a huge WTF.


    Why is that a WTF? Its a feature available in many sane languages.


    You made the assertion, so the onus is yours to provide evidence (via google or otherwise) to support it. Simply stating something, and demanding that other people proove it to themselves

    Take two seconds on Google to research it.


    You made the assertion, so the onus is on you to provide evidence when challenged. Demanding that other people google something to prove your point is both lazy and foolish.
    Children, please.
    Who gives a rat's left testicle....
  • mick 2013-01-07 18:19
    Harrow:
    I like to think that if anyone ever asked me for a function that reported what percentage of a form was filled out correctly, I would write something a lot like this. Probably not as clear, though.

    WTF specifications deserve WTF code.

    -Harrow.

    Why is everyone obsessed with %complete??? It's like those stupid progress bars that get slower and quicker.

    Is a field with no name equivalent to a field with no age (I have several letters in my name, and will probably never reach 3 digits in age).
    I sort of understand the "you have filled in 7 of 9 fields", but isn't it perhaps more useful to say "You need to put a name and surname in you fuckstick" - the user doesn't give a shit about random numbers relating to the form, they just wanna know why it keeps getting rejected.
  • Paul 2013-01-07 18:21
    Using http://www.codinghorror.com/blog/2008/07/spartan-programming.html spartan coding you should inline the local variable ct. That is all.
  • foo 2013-01-07 18:47
    Holly Molly:
    chris:
    LoremIpsumDolorSitAmet:
    TRWTF is JavaScript, right? Coercing those booleans to be integers (0 or 1) is very cheeky at best - I didn't even know you could do that.

    If this were ported to VB it would be even more fun because TRUE would become -1, so you'd divide by -0.09.

    Coercing booleans to integers comes from C, and I think since JS is loosely-typed and has C as its most obvious ancestor, you can reasonably expect it to work.

    No, No, no. C happened not to have a boolean, so people would use integers as booleans, however going the other way (and making an int from a boolean) is impossible, because the boolean type does not exist.

    The biggest problem with using the same integers we use as a boolean in C as integers is that true can be multiple values.
    The way C uses an integer in a boolean expression equates to something like:

    #define false (0)
    #define true (!false)

    What is the value of true? On many compilers, it's 1. More intuitively, it should probably be 0xff. But it can actually be a whole heap of things.


    int main()
    {
    int total=0;
    int x=3;
    if(x) printf("%d\n", x);
    printf("%d\n", !x);
    total+=x;
    printf("%d\n", total);
    return 0;
    }


    which on my compiler prints:
    3
    0
    3

    C does not have a (standard) boolean type, so coercing back to an integer isn't really coercing - it's using an integer for what it's meant for. That said, it is often dangerous to use an integer simultaneously in logical and arithmetic expressions (although I'll confess I do it to check pointers are non-null)....
    C (before C99) did not have a Boolean type, but well-defined Boolean values, 0 and 1. Each Boolean operator (&&, ||, !) returns 0 or 1. Not on "many compilers", but on all correct compilers. Certainly not 0xff, since the size of int is not specified, but usually larger than 8 bits (or 9 bits signed ;-). Also, I'd argue that 1 is more useful, since it can be used for counting (as in today's example -- that is not the WTF about it), whereas 0xff, -1 or any other value has little practical advantage.

    Your example uses just ints, so the results are what they are with ints, no surprise. The two places you use the value of x in Boolean contexts (if, !) don't change the value stored in x (why would they?), so of course total = x = 3.
  • Amakudari 2013-01-07 19:39
    Not even smart. For x && true, if x is falsy then it evaluates to x without an implicit cast.


    true && true // true
    false && true // false

    1 && true // true
    0 && true // 0

    "a" && true // true
    "" && true // ""


    The only case in which it "works" is if employerSharing can be false or truthy, which is chaotic evil.

    So in the remaining sane case, where employerSharing can only be false or true, the && true is just redundant and potentially confusing.
  • old timer 2013-01-07 23:39
    chris:

    Coercing booleans to integers comes from C, and I think since JS is loosely-typed and has C as its most obvious ancestor, you can reasonably expect it to work.



    The Bool type was only introduced in C99. And even now, it is defined as an integer type. I don't think that the idea of "coercing booleans to integers" comes from C...
    In spite of the obvious differences, the code is clear and intuitive in BASIC. Because BASIC did not have seperate logical and arithmetic operators, all boolean operations were arithmetic operations. That is why, unlike FORTRAN, BASIC evaluates all terms in a boolean/arithmetic expression, and that is why, unlike C, !0 = -1.

    This leads me to suspect that the original author had strong experience with some version of BASIC. To an experienced programmer, the code is obvious. To a C programmer, as indicated in the discussion, not so much.
  • pjt33 2013-01-08 03:05
    Tod:
    It's still shitty code. No need to repeat all that.

    ct=0;
    elementslist = [u.nickname, u.websiteUrl, u.linkedin, u.locationString, u.title, u.bio, u.imageUrl, u.resume]
    for element in elementslist:
    if typeof(element)=="string" and element.length>0: ct += 1
    if u.employerSharing: ct += 1
    return 100*ct/(len(elementslist)+1);

    Python syntax. I don't know if you can get rid of the "u." in elementslist easily.

    You can if you use strings and property indexing:


    var ct=0;
    var elementslist = ['nickname', 'websiteUrl', 'linkedin', 'locationString', 'title', 'bio', 'imageUrl', 'resume'];
    for (var i = 0; i < elementslist.length; i++) {
    var element = u[elementslist[i]];
    if (typeof(element)=="string" && element.length) ct++;
    }
  • gallier2 2013-01-08 03:55
    Holly Molly:
    gallier2:
    The types
    _Bool
    and its alias
    bool
    are in the C language since the C99 standard (it was already in some compilers like gcc as extension long before that).


    bool b = 99;
    printf("Value of b=%d\n", b);


    will print
    Value of b=1
    
    OK - I stand corrected, I didn't know about _Bool, but bool gives me an "error: 'bool' undeclared", (both on gcc and it's windows friend mingw)

    In that case maybe people do coerce _Bool to int....I don't really think it's a very smart (or necessary) thing to do, but there ya go.....


    You have to include stdbool.h to have the bool alias (required by the standard).
  • noland 2013-01-08 05:58
    Wow, let's build our own int, so we won't mix types:
    function getInt( n ) {
    
    var i = false + false;
    for (var k = 1; k <= n; k++) i += true;
    return i;
    }

    function getBootstrappedInt( n ) {
    return getInt( getInt( n ) );
    }

    Now we only need to add floating point arithmetics ...
  • John 2013-01-08 06:00
    Looks like someone didn't get the memo about readable code.
  • Canatella 2013-01-08 06:48
    Booleans are assimiled to int since ages, just look at power switch (1/0) or in electronic, the way a line with no signal which maps to a false has 0v. Bools also works as integers: commutative, transitive, etc if you map && to * and || to + mapping anything greater then 1 to 1 to stay within the boolean values. In fact a bool is just a bit 1 or 0 or in C a word (8, 16, 32 or 64 bits) artificially limited to 1 bit.

    For the implementation of the function, that's where I would use a map and a reduce (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/reduce)
  • Geoff 2013-01-08 07:52
    Accuracy and precision requirements very with use. I doubt there is a problem here. Its a display value to give the user some idea how much more agony they have ahead filling out answers to questions that at least to them and quite likely in general are asinine to their purpose.

    Yes 101% will look stupid but you won't show them that, when proFormComplete >= 100 you will simply move on to the next application screen. The rest of the time users won't know or care if you display 48% complete when its really 47% or whatever.
  • F 2013-01-08 07:54
    luolimao:

    ...
    But as someone else mentioned, TRWTF is % completion.


    Clearly you've never had to develop anything at the behest of a "marketing" department who, by definition, know what the customer / end-user wants.
  • jEDI 2013-01-08 08:11
    Maybe every one should be made to put up the code they would use, in their choice of language, before their comment. Then we could all safely ignore the rest of the comment if the code is obviously pants. That certainly would have saved me the time it took to read Capitalist's comment.
  • turist 2013-01-08 09:50
    TRWTF is actually requiring linkedin for application ...
  • gnasher729 2013-01-08 10:14
    Snowrat:
    The real WTF is dividing by 0.09 and incurring a slow division instead of multiplying with 11.11


    The problem is: I don't know if your remark is sarcastic or stupid. Let's just say that the form will never be 100% filled with that change.
  • Rootbeer 2013-01-08 10:28
    Canatella:
    in electronic, the way a line with no signal which maps to a false has 0v.


    It shouldn't be assumed in a digital circuit that voltage high is 'true' and voltage low is 'false'.
  • Ben 2013-01-08 10:52
    why .09, why not .10
  • dkf 2013-01-08 10:53
    Rootbeer:
    Canatella:
    in electronic, the way a line with no signal which maps to a false has 0v.
    It shouldn't be assumed in a digital circuit that voltage high is 'true' and voltage low is 'false'.
    Or, for that matter, vice versa. Some circuits go as far as toggling the voltage level on one line for 1 and another for 0. Really. Hardware designers are crazy…
  • PiisAWheeL 2013-01-08 13:32
    bgodot:
    Whenever I write a piece of code, and I'm pleased with how clever it is; I rewrite it to be simpler.
    Whenever I write a piece of code, and I'm pleased with how clever it is; I write a large paragraph above it explaining what it does.
  • PiisAWheeL 2013-01-08 13:47
    Ben:
    why .09, why not .10
    Because you are only validating against 9 fields.

    The math works like this:
    Number_of_fields_good / Total_Number_of_fields = %percentage of fields complete.

    So (for an example) 8 validated fields out of 9 would return .88(8888etc), which multiplied by 100, will return 88(.88+), which can be used as a percentage.

    What this particular developer here instead of multiplying by 100, was use the inverse; he divided the number of fields by 100, and then divided the total number of valid fields (8 in our example: 8/.09=88.88+) so that he would get 88.88+% without needing to do any more math. Then he runs ciel (rounds up to the nearest whole number) yielding 89%.
  • Tasty 2013-01-08 14:30
    LoremIpsumDolorSitAmet:
    TRWTF is JavaScript, right? Coercing those booleans to be integers (0 or 1) is very cheeky at best - I didn't even know you could do that.

    If this were ported to VB it would be even more fun because TRUE would become -1, so you'd divide by -0.09.


    When I define my next language, I'm making TRUE coerce to imaginary I. Then, it will never be less or more than anything.
  • Anon 2013-01-08 14:54
    I think it should be a little clever-er, so it can be like installation progress bars. You know, you fill in one field, "9% done!" Fill in two fields "18% done!" Fill in three fields "18% done!" Fill in four fields "18% done!" Fill in five fields "1% done!" Fill in six fields "98% done!" ...
  • Capitalist 2013-01-08 15:34
    jEDI:
    Maybe every one should be made to put up the code they would use, in their choice of language, before their comment. Then we could all safely ignore the rest of the comment if the code is obviously pants. That certainly would have saved me the time it took to read Capitalist's comment.
    How typical of you pussy programmers!

    Guys like you always talk about maintainability, but when someone proposes a solution that is actually maintainable (add a field: copy/paste one line and you get both counts correct), you get shocked when it doesn't conform to what you know. Two statements on a single line? Hell, how dare he! Seen it all too often. So next time, don't talk about maintainability, talk about not wanting to learn anything new because it bends your little mind.
  • leo 2013-01-08 16:34
    To me, transforming 100*ct/9 to ct/0.09 is what makes this snippet to go from "meh, not wtf" to "wtf is that dark magic ?" because you cannot tell easily what the programmer is trying to achieve.
    Of course using a comment or a descriptive name could have done it, ut neither of them can be found, so in my book this classifies as bad code.

    From this snippet this may not seem obvious, but the person that thinks it is better to write 0.09 than 9/100 is probably the same one that gave you this clusterfuck of code that reverses a matrix in 3 undecipherable lines but is not efficient at it and suffers a bug your boss asked you to remove.
  • JimFin 2013-01-09 03:38
    gallier2:
    It's actually quite clever. Of course it demands from the developer who reads that, some arithmetic and boolean skills.
    I know, it's asking a lot from people who actually are supposed to know how to crunch numbers. Transforming 100*ct/9.0 to ct/0.09 should be obvious to anyone, and if it isn't, pull down that keyboard and search for another job, more tuned to your skills (flipping burgers, collecting garbage or whatever).

    Not a WTF, in my opinion.

    Well, saying it's validation while it's percentage calculation combined with the fact that the actual percentage calculation is hidden is somewhat a WTF.

    Here you can find some WTFs that are not really WTFs but they are misunderstandings. When WTF is said not to be WTF, it should be a big red flashing <marquee> warning: some day you will miss a WTF that you made yourself and you will make your coworkers very angry.
  • Scripticious 2013-01-09 17:54
    Amakudari:
    Not even smart. For x && true, if x is falsy then it evaluates to x without an implicit cast.


    true && true // true
    false && true // false

    1 && true // true
    0 && true // 0

    "a" && true // true
    "" && true // ""


    The only case in which it "works" is if employerSharing can be false or truthy, which is chaotic evil.

    So in the remaining sane case, where employerSharing can only be false or true, the && true is just redundant and potentially confusing.


    Nice work, and completely correct. It's amazing that so many others missed this.

    To give those here who continue to claim that the code is well written some food for thought, here's a simpler example:

    [10:44:25.966] 1 + 2 + 3 + ("" && true) + 4
    [10:44:25.968] "64"

    Javascript has a nuance that other languages don't with regards to boolean operations: they will always return either the first falsy or last truthy operand in the statement - NOT necessarily a boolean.

    This is an extremely powerful feature and allows developers to create short and sweet validation statements. For example:

    var firstSurname = (isMarried && maidenName) || currentSurname;

    The above is rather a variation on a ternary expression, but you can see the potential for reducing many complex validation tasks down into a single simple step.
  • BitDreamer 2013-01-10 09:15
    Why do you think a TDWTF submission can have only one "the real WTF"? This one is a minor cornucopia of WTF.
    As hinted elsewhere, the overall WTF is that you CAN write code like this, and it works (insert frown 'smiley' here).
    If you want to identify the specific "real WTF", it's that apparently, u.employerSharing must be True to be valid.
    Another WTF, only hinted at, is why check the type of the variables? I don't mean because non-checkboxes will be strings. I mean the type is not a user input. An error there would be a program error (i.e. BUG), not an data validation issue.

    Why was "&&true" included with u.employerSharing you ask? Programmer OCD, obviously. All the other fields have 2 conditions tested.

    And lastly, regarding math on strings, in Perl you can't do true math on non-numeric strings, but you can do incrementing (++) on alpha-numeric strings, with results like "AA"++ = "AB" and "AZ"++ = "BA".
  • Gibbon1 2013-01-11 17:02
    savar:
    Clever is a strong word. This is still very stupid code. (Hint: each field is hard coded, as is the constant 0.09.) But I agree its not exactly a WTF either. It's bad code that kinda works for what it was supposed to do.


    I'm not sure an extra level of abstraction is going to improve things. At least here the wtf is contained
  • Some Damn Yank 2013-01-14 17:16
    Anonymous:
    gallier2:
    Transforming 100*ct/9.0 to ct/0.09 should be obvious to anyone

    Possibly obvious, but also wrong: 0.09 can't be exactly represented in IEEE floating-point, so you may get a fractionally different result. It happens to work for 9 items, but not in general e.g.

    $ python -c 'import math; print math.ceil(57/0.57)'
    101

    That's because you're using IEEE math instead of ASCII math.
  • Jimm 2013-01-17 21:06
    If this is supposed to get percentage complete, shouldn't it be 100 * ct/9, or 11.11 * ct?
  • Senji 2013-01-25 11:24
    In JS you could probably do:

    elementslist = [ "nickname", "websiteUrl", "linkedin", "locationString", "title", "bio", "imageUrl", "resume"]

    ..... if typeof( u[element] ) ....
  • anonymous 2013-06-26 13:19
    I found the following WTFs:

    - "proFormComplete" means... "procent form complete"?
    - there's an anonymous function for no apparent reason*
    - "user" is a global variable instead of an argument
    - "user" has a getter method that returns... itself?
    - two variable definition lines in a row, both with "var"**
    - "0 +" does absolutely nothing that the next "+" wouldn't do
    - typeof is not a function; the parentheses do nothing
    - why the need to check the types... they might not be strings?
    - the only thing equal to "string" is "string"; exact comparison is unnecessary
    - string.length > 0 instead of string > "" (when we know it's a String)
    - "value && true" instead of "!!value" (or just "value", if it's Boolean)
    - variable that holds a stupid intermediate value**
    - no comments whatsoever

    *it's not an event; the only other reason it would need to be done this way is if it's nested inside another function - in which case, that's another WTF.
    **this should be done when it helps improve readability; it doesn't, so why bother?

    Dividing by 0.09 is not a WTF. Yes, you could multiply by 11.1 instead. No, it wouldn't make any substantial difference.

    Without making it much less "clever", this is how the code should probably look:
    function percentFormComplete(u) {
    
    // Sums the number of values that aren't blank
    // and returns an integer between 0 and 100

    return Math.round(
    (
    (typeof u.nickname == "string" && u.nickname > "") +
    (typeof u.websiteUrl == "string" && u.websiteUrl > "") +
    (typeof u.linkedin == "string" && u.linkedin > "") +
    (typeof u.locationString == "string" && u.locationString > "") +
    (typeof u.title == "string" && u.title > "") +
    (typeof u.bio == "string" && u.bio > "") +
    (typeof u.imageUrl == "string" && u.imageUrl > "") +
    (typeof u.resume == "string" && u.resume > "") +
    !!u.employerSharing
    ) / 0.09);
    }