Sanity Check

« Return to Article
  • Crazy Dutch Bastard 2012-05-17 09:02
    I must be insane.

    Captcha: secundum - comes after fristum
  • Vamp 2012-05-17 09:09
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later. Maybe it was something similar for those 2 values :)
  • Turd Blossom 2012-05-17 09:13
    const maxVolume = 10 + 1;
  • Christian 2012-05-17 09:16
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
  • portablejim 2012-05-17 09:17
    At least you have the magic values in one place instead of spread out inside the class.
  • Other Nagesh 2012-05-17 09:19
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.


    Or you could use multiple random number generators and randomly select the one to use for enhanced super-randomness.
  • AGray 2012-05-17 09:21
    Constants in a class may or may not be a WTF - I'd honestly rather deal with a constant defined at the class level (preferably, in a Constants region) where I can easily find, identify, and maintain it, than have to sift through a bunch of code to find a method-level constant.

    The value of that constant though...I think that's TRWTF.

    Captcha: enim - must be Eminem's little brother.
  • Severity One 2012-05-17 09:23
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
  • CT 2012-05-17 09:25
    probably some serious backstory to that 199 + 6. I have some humorous (to me anyway) code like that for managers who are decidedly NOT developers and have weird ideas about what is right.
  • Testing Troll 2012-05-17 09:25
    Or... you could do the sane thing and seed the PRNG with a constant when you're unit testing, and let it be seeded with the system time for normal operations...


    CAPTCHA: conventio... if you follow the conventio you won't produce WTF-ridden code.
  • Andrew 2012-05-17 09:26
    "I don't even want to know why a constant is declared inside a class...
    Because that's the way it's done in Java? Yes, I know that this is probably .NET/C#, but the guy might not be thinking that way.

    Captcha: veniam. That's the way we coded in Ve'niam.
  • zelmak 2012-05-17 09:31
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?

    Similar to this method for having a fake clock.
  • Tony 2012-05-17 09:31
    Here's a couple:

    1) Using random numbers for a short wait time so a server doesn't get hit with a lot of requests (ala ethernet collsion algorithm) - You might want to have a non random number to see how the server behaves when it does get hit simultaneously

    2) Boundary checking - you might expect random numbers to be in a certain range, but for testing purposes, you could simulate numbers at the boundary or across the boundary
  • Fool 2012-05-17 09:37
    I do things like 199+6 isntead of 205 on occasion.

    2 reasons:
    1) I am often doing math where I might look at the code one day and say, why the heck did I put 205 there? But looking around I see the numbers 195 and 6 somewhere else in the code.

    2) 199+6 compiles to 205 so it should be equivilent to 205 in the binary file that is generated.
  • Mike 2012-05-17 09:37
    Other Nagesh:

    Or you could use multiple random number generators and randomly select the one to use for enhanced super-randomness.


    But which random number generator would you use to select which random number generator to use for your super random number generator?
  • DonaldK 2012-05-17 09:38
    CT:
    probably some serious backstory to that 199 + 6


    If you walk the version control commit history might get something like:


    [Source change 382]
    const int expected_length = 199;
    [Comment block]
    Should be fine for all cases


    [Source change 383]
    const int expected_length = 199 + 1;
    [Comment block]
    I'm sure it was some zero based issue


    [Source change 384]
    const int expected_length = 199 + 2;
    [Comment block]
    Wierd. +1 should have worked


    [Source change 385]
    const int expected_length = 199 + 3;
    [Comment block]
    Makes sense now... it's 2 UNICODE char's -1 (since it's zero based)


    [Source change 386]
    const int expected_length = 199 + 4;
    [Comment block]
    Still didn't work... +4 should be OK I'm sure


    [Source change 387]
    const int expected_length = 199 + 5;
    [Comment block]
    Still crashing! We really need to look at this logic


    [Source change 388]
    const int expected_length = 199 + 6;
    [Comment block]
    Praying this will be enough for all cases

  • Nagesh 2012-05-17 09:41
    In java, ain't declared quite the seme. Writen like this:

    public static final int EXPECTED_LENGTH = 199 + 5;


    Constant declared in class for purpose of scope. Concretion values being used for purpose of showing how result is being found. Unfortunate after meking us wating a day, Alex provide code semples that is not being WTF. :(
  • Tyler 2012-05-17 09:42
    Looks like a normal thing to do. He has a fixed length string of 199 characters that has 6 chars appended to the end.

    As for "within a class" sounds good, better than global, I've even done such things as:

    //Tightly-Scope
    {
    int bPtr=0,ePtr=0;
    ...
    }
    (No if statement/while block etc. to set off the block).
  • Nick 2012-05-17 09:42
    199 - clearly they are zero based arrays, and the max line length is 200 chars.

    Now if that line is sent elsewhere, then it is going to be bundled into a buffer. You will need an overhead for the message type, and the length of the text being sent. I would suggest that is 2 bytes for the message, and 4 bytes for the length. Or 4 and 2.

    Hence the 6.

    Would be better if that was a constant in its own right.

    e.g

    max_line = 199
    protocol_size = 6
    message_size = max_line + protocolsize
  • C-Octothorpe 2012-05-17 09:51
    // We need to give 110% here...
    
    const double MAX_EFFORT = 1D + 0.1D;
  • Gazzonyx 2012-05-17 09:53
    TRWTF is that there isn't a comment on the magic numbers there. Not that there is anything wrong with something like this, but it should be documented. For instance, this is one of my commits to Samba :

    [...]
    + /* domain/username%password */
    + const int max = MAX_DOMAIN_SIZE +
    + MAX_USERNAME_SIZE +
    + MOUNT_PASSWD_SIZE + 2;
    [...]
  • snoofle 2012-05-17 09:54
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
  • Nagesh 2012-05-17 10:01
    Tyler:
    As for "within a class" sounds good, better than global

    Agreed. TOS ain't understanding scope is TRWTF.
  • Matthew 2012-05-17 10:12
    Repeatability testing.

    If I'm testing a simulation program, I may want to run the simulation under the same set of constraints repeatedly for testing, but use random numbers in production.
  • ZPedro 2012-05-17 10:15
    You don't get it. This is like an encounter in a Cthulhu mythos RPG, where you have to roll a dice to know if you are staying sane. Same here, the original coder put an unfathomable expression to force any future reader of the code into insanity if he wasn't sane enough already, thus avoiding borderline cases from going any further - and he helpfully documented he was doing this. Think of it as an assert on the maintenance programmer, forcing him to exit with insanity if he fails the check.
  • concerned citizen 2012-05-17 10:20
    Yeah, I gotta say, I don't see a WTF here except for maybe not having a comment explaining where the 199 and 6 came from. And like hell if I'm going to throw stones in that glass house!! :p
  • Lockwood 2012-05-17 10:25
    [Insert xkcd random number thing here.]

    199+6? Simple explanation time?
    Expected length used to be 199. There was some reason deep in the logic or spec that said "We need it to be 6 longer".
    They did 199 + 6 rather than 205, expecting it to be respecced and it being easier that way.

    (I've got code that is now sadly barely maintainable because the spec and calculation to use was being changed hourly, so it has loads of commented versions littered all over the place, "Change it to this. It should be *2 not *3. Change it back to the original. *3 again. No, wait. *2)
  • Dave 2012-05-17 10:32
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.


    I tend to agree, but that's a very different case to that mentioned in the article:

    The Article:
    solely to duplicate the behavior
  • Xeromal 2012-05-17 10:34
    University all over again. :(

    Cogo, I had fun in the Cogo line today.
  • Not sure if Fry or just Philip 2012-05-17 10:46
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.
  • airdrik 2012-05-17 10:55
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.


    Oh, now that makes perfect sense, thanks!
  • Playoffs? 2012-05-17 10:57
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.


    Magic Number = T - W - L

    where
    T is the total number of games in the season
    A is the number of games won by the team for which you are trying to calculate the magic number.
    B is the number of games lost by the team for which you are trying to calculate the magic number against.

    Source 1
    Source 2

    That being said, it's way to early to start talking playoffs
  • operagost 2012-05-17 10:59
    I am not a real programmer, so I don't work in C/C++ and didn't realize that this was legal in any languages. The last time I tried this it wouldn't compile. It was probably something esoteric like DEC BASIC.
  • WhiskeyJack 2012-05-17 11:01
    Nick:
    199 - clearly they are zero based arrays, and the max line length is 200 chars.

    Now if that line is sent elsewhere, then it is going to be bundled into a buffer. You will need an overhead for the message type, and the length of the text being sent. I would suggest that is 2 bytes for the message, and 4 bytes for the length. Or 4 and 2.

    Hence the 6.

    Would be better if that was a constant in its own right.

    e.g

    max_line = 199
    protocol_size = 6
    message_size = max_line + protocolsize


    You beat me to it, I was just thinking that's probably how I would see it appear in my code if it were to appear at all.

    But a better approach would be to declare a struct for the particular message type including the header block (message type, message length) and then do a sizeof() to calculate the size instead of hard-coding it to 205.
  • cellocgw 2012-05-17 11:07
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;


    Which reminds me of a MatLab WTF: everybody, including me, uses _foo_ and _bar_ as throwaway variables. Well, just try that in MatLab, and then try to call their function to draw a bar plot, which is named, you guessed it, "bar" . Hilarious subscript errors ensue.
  • Karl 2012-05-17 11:12
    C'mon guys it is staring you right in the face! How come nobody got it yet?

    // Sanity check

    If you are a sane person, when you look at the next line of code you will immediately delete it. Nobody has yet, therefore you and all your peers are insane.
  • Frank 2012-05-17 11:20
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.
  • DaveK 2012-05-17 11:38
    Gazzonyx:
    TRWTF is that there isn't a comment on the magic numbers there. Not that there is anything wrong with something like this, but it should be documented. For instance, this is one of my commits to Samba :
    Good stuff. Here's your next one:

    [...]
    /* domain/username%password */
    const int max = MAX_DOMAIN_SIZE +
    MAX_USERNAME_SIZE +
    - MOUNT_PASSWD_SIZE + 2;
    + /* Oops. CVE2012-xxx-yyy */
    + MOUNT_PASSWD_SIZE + 3;
    [...]
  • DaveK 2012-05-17 11:42
    DaveK:
    Gazzonyx:
    TRWTF is that there isn't a comment on the magic numbers there. Not that there is anything wrong with something like this, but it should be documented. For instance, this is one of my commits to Samba :
    Good stuff. Here's your next one:

    [...]
    /* domain/username%password */
    const int max = MAX_DOMAIN_SIZE +
    MAX_USERNAME_SIZE +
    - MOUNT_PASSWD_SIZE + 2;
    + /* Oops. CVE2012-xxx-yyy */
    + MOUNT_PASSWD_SIZE + 3;
    [...]
    Oh, don't bother, I see someone already caught it for you. Heh.

    (I also see it's not directly used to size a buffer anyway.)
  • Loren Pechtel 2012-05-17 11:45
    AGray:
    Constants in a class may or may not be a WTF - I'd honestly rather deal with a constant defined at the class level (preferably, in a Constants region) where I can easily find, identify, and maintain it, than have to sift through a bunch of code to find a method-level constant.

    The value of that constant though...I think that's TRWTF.

    Captcha: enim - must be Eminem's little brother.


    Yup. I've declared plenty of constants in classes. They're not applicable outside the class but a constant is much better than a magic number in the code.

    Nick:
    199 - clearly they are zero based arrays, and the max line length is 200 chars.

    Now if that line is sent elsewhere, then it is going to be bundled into a buffer. You will need an overhead for the message type, and the length of the text being sent. I would suggest that is 2 bytes for the message, and 4 bytes for the length. Or 4 and 2.

    Hence the 6.

    Would be better if that was a constant in its own right.

    e.g

    max_line = 199
    protocol_size = 6
    message_size = max_line + protocolsize


    Agreed. If the reason for the math isn't self-evident you should do something like this.

  • Not sure if Fry or just Philip 2012-05-17 11:56
    airdrik:
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.


    Oh, now that makes perfect sense, thanks!
    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const.
    On the other hand, generic variables like "foo" and "bar" are the most evil variable names ever. While they're perfectly acceptable in short and meaningless examples, they should never, ever appear in production code. Except when they mean something, like spacebar or meter bar.
  • WordCrawler 2012-05-17 12:08
    Not sure if Fry or just Philip:
    airdrik:
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.


    Oh, now that makes perfect sense, thanks!
    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const.
    On the other hand, generic variables like "foo" and "bar" are the most evil variable names ever. While they're perfectly acceptable in short and meaningless examples, they should never, ever appear in production code. Except when they mean something, like spacebar or meter bar.


    Oh yeah, and don't forget to maintain that comment when you change the number from 205 to 206!

    CAPTCHA: damnum = damn number
  • Jack 2012-05-17 12:10
    Dave:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.


    I tend to agree, but that's a very different case to that mentioned in the article:

    The Article:
    solely to duplicate the behavior, but with tons of bugs


    FIFY (if history is any indicator)
  • Calli Arcale 2012-05-17 12:10
    Frank:
    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".


    Well, that's what you *hope* to do. More often, you'll find that although the bug was fixed, it has now broken something else. Or it is only fixed in condition A, but in condition B it remains broken. Or the bug didn't break anything else at all, but you've stumbled upon something broken that nobody had noticed yet, possibly because the bug you fixed was concealing it.

    I actually get a little worried when regression testing always passes. I find myself wondering whether or not the testing is adequate.
  • Dan Minjoc 2012-05-17 12:12
    Not sure if Fry or just Philip:
    airdrik:
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.


    Oh, now that makes perfect sense, thanks!
    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const.
    On the other hand, generic variables like "foo" and "bar" are the most evil variable names ever. While they're perfectly acceptable in short and meaningless examples, they should never, ever appear in production code. Except when they mean something, like spacebar or meter bar.


    Disagree. The compiler will automatically evaluate the expressions. Why decrease code readability for no benefit?

    Which would you rather have?

    const uint32 NUM_SEC_IN_DAY = 60 * 60 * 24;
    const unit32 NUM_SEC_IN_DAY = 86400;

    Both are correct, but the first one shows exactly where the calculation is coming from.
  • Jack 2012-05-17 12:13
    Not sure if Fry or just Philip:
    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const.


    I tend to disagree. I trust the compiler's math way more than most developers'.
  • Harrow 2012-05-17 12:16
    operagost:
    I am not a real programmer, so I don't work in C/C++ and didn't realize that this was legal in any languages. The last time I tried this it wouldn't compile. It was probably something esoteric like DEC BASIC.
    Ah yes, I recall whiling away many happy hours writing DEC BASIC. In fact, I give DEC BASIC full credit for making me the person I have become today. I would explain more but Doctor says I'm not supposed to even use the computer at all while I'm in here.

    -Harrow.
  • C-Octothorpe 2012-05-17 12:18
    Frank (Captain Obvious):
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.
    Wow, ground-breaking stuff you got there... So, you're telling me that when I fix a bug, I need to make sure I don't break everything else? Thank goodness you were here to tell everyone in such a condescending tone...
  • Joe 2012-05-17 12:28
    Frank:
    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    You run the test 10 billion times so that you know you're testing every random 32-bit number (to within 5%) that might come up in production.

    This also gives the advantage of never finding another problem during your career, and/or inflating the "number of tests passed" metric that you get a bonus on.

    --Joe
  • Zylon 2012-05-17 12:28
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?
  • QJo 2012-05-17 12:29
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.


    Maybe not so perfect. So, in your unit tests, and other automatic regression tests, you've got a little flag which tells the app whether it's being run in "test" mode. If it is, then path A is negotiated. If not, then path B.

    The predictable happens, and there's a bug in path B. It's your job now to go and explain to the boss why was this not caught by the regression tests.

    Not so unusual. This happened once, on my watch, to mine and my team's acute embarrassment. It's a common mistake to make. Only this week a colleague suggested that we embark on a similar strategy. My suggestion is that if you have designed an application which can not be tested, then it needs to be re-engineered so that it can.

    Ultimately it's an engineering decision: do we spend extra effort on making it bulletproof, or do we risk something coming burrowing out of the woodwork later to bite us on the ankles? Your call.
  • G 2012-05-17 12:31

    like the System.Environment.Exit calls peppered throughout library code that causes the app to inexplicably exit.


    I'm no .NET expert, but it seems to me exits caused by a function called "Exit" seem perfectly explicable to me...
  • Matt Westwood 2012-05-17 12:35
    Gazzonyx:
    TRWTF is that there isn't a comment on the magic numbers there. Not that there is anything wrong with something like this, but it should be documented. For instance, this is one of my commits to Samba :

    [...]
    + /* domain/username%password */
    + const int max = MAX_DOMAIN_SIZE +
    + MAX_USERNAME_SIZE +
    + MOUNT_PASSWD_SIZE + 2;
    [...]


    So what's the fucking 2 for, you stupid prick?
  • Meep 2012-05-17 12:39
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?


    this way you can replace this component with one that returns a "random" number which you can control in your unit-tests
  • Meep 2012-05-17 12:40
    Tyler:
    Looks like a normal thing to do. He has a fixed length string of 199 characters that has 6 chars appended to the end.

    As for "within a class" sounds good, better than global, I've even done such things as:

    //Tightly-Scope
    {
    int bPtr=0,ePtr=0;
    ...
    }
    (No if statement/while block etc. to set off the block).


    Yup, not even remotely a WTF.
  • QJo 2012-05-17 12:42
    Not sure if Fry or just Philip:
    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const.


    Certainly not.

    The whole point of using the compiler to do your arithmetic is so that if one of the terms in your calculation changes you just have to change it in that one place.

    This is particularly important where one of the numbers is used in more than one place, and there is a multiplicity of constants which depend on its value. And if that is not the case now, then it may possibly be the case in the future.
  • Jay 2012-05-17 12:51
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?


    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=4*60*60". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.
  • Matt Westwood 2012-05-17 12:57
    Jay:
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?


    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=4*60*60". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.


    Almost there - CACHE_TIMEOUT_SECONDS would be better. Then the obviousness is even more blinding.
  • wbrianwhite 2012-05-17 13:09
    Matthew:
    Repeatability testing.

    If I'm testing a simulation program, I may want to run the simulation under the same set of constraints repeatedly for testing, but use random numbers in production.


    So you don't want to test your production code, got it.
  • James 2012-05-17 13:12
    Any procedurally generated content. A good example is Perlin Noise. It's best to have a random number generator that's repeatable (so no physical sources such as various forms of radiation) so you can recreate the object, image, etc. at a later date.
  • Jay 2012-05-17 13:13
    "I don't even want to know why a constant is declared inside a class"

    Umm ... maybe so that the constant is associated with the class that it relates to? I thought that was one of the key ideas of object-oriented programming: Group related code and data together.

    Suppose I have, let us say, an "Integer" object. And I want to have a constant for the maximum value that can be stored in an Integer. Where should I logically put this constant? In some grab-bag place that includes hundreds of other constants used all over the system? Or in the Integer class?

    If I put it in the Integer class, then anyone looking at the Integer class has a good chance of finding it. If we adopt this as a general practice, than anyone looking for constants related to Integers knows exactly where to look. Anyone who notices this constant in the Integer class can reasonably expect that it relates to Integers and not to something else, and furthermore that it relates to Integers in general, and not to a particular Integer used in some other class or set of classes.

    If I put the constant in a grab-bag of globals, none of the above is true. With all constants in there, there's no easy way to tell what constants relate to what classes. I suppose we could establish a naming convention, like all constants must have names beginning with the class name that they are related to. But you know that people will forget or ignore such a rule. Having unrelated things in one place makes anything harder to find. Etc etc.

    Oh, and by the way, in modern languages, putting constants in the class they relate to gives an extra bit of self-documentation. If I see code that says, say, "if (x==READ) ...", I might well wonder if this means that we are presently reading, that a file is readable, that the last action was a read, etc. But if I see "if (x==Permissions.READ) ...", that gives me a much better idea what's going on.
  • wbrianwhite 2012-05-17 13:14
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time.
    Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?
  • wbrianwhite 2012-05-17 13:17
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?


    No. So that you can redefine two minutes to 1 minute. It makes your application twice as fast of course.
  • Jay 2012-05-17 13:24
    QJo:
    Not sure if Fry or just Philip:
    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const.


    Certainly not.

    The whole point of using the compiler to do your arithmetic is so that if one of the terms in your calculation changes you just have to change it in that one place.

    This is particularly important where one of the numbers is used in more than one place, and there is a multiplicity of constants which depend on its value. And if that is not the case now, then it may possibly be the case in the future.


    And, I might add, to make it easier to track down errors.

    Suppose I see

    // max lifetime is 4 hours
    public final static int LIFETIME_SECONDS = 4 * 60 * 50;

    It's pretty likely that the "50" is a typo and should have been "60".

    But suppose instead it says

    // max lifetime is 4 hours
    public final static int LIFETIME_SECONS = 12000;

    Well, 4 hours is not 12,000 seconds. But is the error that the programmer made an arithmetic mistake? Or that the time limit changed and no one updated the comment?

    Sure, just writing "expectedlength = 199 + 6" is cryptic because I have no clue where those numbers came from. But

    // length = data + header
    public final static int EXPECTED_LENGTH = 199 + 6;

    is excellent coding style. I see exactly what's happenning, and if one of those numbers changes, you just change the thing that changed and let the compiler re-do the calculation. Sure, with just two numbers it's not a big deal, but I've had times when I've had things more like:

    // length = header length + number of packets * packet length + trailer length
    public final static int LEN = 22 + 4 * 80 + 40;

    Now if we up the number of packets to 5, we just change the 4 to a 5. We don't redo any manual arithmetic and introduce the possibility of an arithmetic error. We don't have to update the comment to keep it synchronized with the code. Lots of good things.
  • KattMan 2012-05-17 13:31
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?
  • KattMan 2012-05-17 13:36
    Jay:
    // length = header length + number of packets * packet length + trailer length
    public final static int LEN = 22 + 4 * 80 + 40;

    Now if we up the number of packets to 5, we just change the 4 to a 5. We don't redo any manual arithmetic and introduce the possibility of an arithmetic error. We don't have to update the comment to keep it synchronized with the code. Lots of good things.


    I would argue for more constants:

    public final static int header_length = 22;
    public final static int number_of_packets = 4;
    public final static int packet_length = 80;
    public final static int trailer_length = 40;

    public final static int LEN = header_length + number_of_packets * packet_length + trailer_length;

    better documentation and if any of these values are used elsewhere you only change one place. Also if any are not to be constant the values are easily changed without changing other code.
  • Anna Moose 2012-05-17 13:42
    [quote user="KattMan"][quote user="Jay"] // length =

    I would argue for more constants:

    public final static int header_length = 22;
    public final static int number_of_packets = 4;
    public final static int packet_length = 80;
    public final static int trailer_length = 40;

    public final static int LEN = header_length + number_of_packets * packet_length + trailer_length;

    better documentation and if any of these values are used elsewhere you only change one place. Also if any are not to be constant the values are easily changed without changing other code.
    [/quote]

    Nope. You've got to serialize all your constants in an XML file.

    The tricky part is to reference the file without using any string literals. So we need another XML file that contains the filename of our configuration XML file. Which means we'll need yet another XML file...
  • Jack 2012-05-17 13:43
    QJo:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.

    My suggestion is that if you have designed an application which can not be tested, then it needs to be re-engineered so that it can.

    He did that. He made a wrapper for his random number generator that could choose between pseudo-random numbers, or a predetermined sequence. (Why the original comment has very little to do with the article has already been addressed.)

    And by the way, there's no reason to call the predetermined sequence "test" mode. Some tests would use it, but some should use the pseudo-random number generator. They just test different things.
  • KattMan 2012-05-17 13:45
    Anna Moose:

    The tricky part is to reference the file without using any string literals. So we need another XML file that contains the filename of our configuration XML file. Which means we'll need yet another XML file...


    Hell yeah, employeed for life and never finishing, sounds like the perfect setup for this economy.
  • dkf 2012-05-17 13:45
    Vamp:
    I have done that with constants before. For example timeouts or similar:
    const int TWO_MINUTE_CONSTANT = 2 * 60;
    Makes it easier to read for me later. Maybe it was something similar for those 2 values :)
    Plus all the bonus fun you get when some manager decides that the timeout now has to be 5 minutes, so you update that to read:
    const int TWO_MINUTE_CONSTANT = 5 * 60;
    The moral is “use the meaning in names, not the value”…
  • The Great Lobachevsky 2012-05-17 13:49
    Speakign of sanity - am I the only one whose page up and page down keys inexplicably aren't working on this site anymore? (granted, I'm forced to use IE7, which causes all sorts of weird things)
  • Jack 2012-05-17 13:58
    dkf:
    Vamp:
    I have done that with constants before. For example timeouts or similar:
    const int TWO_MINUTE_CONSTANT = 2 * 60;
    Makes it easier to read for me later. Maybe it was something similar for those 2 values :)
    Plus all the bonus fun you get when some manager decides that the timeout now has to be 5 minutes, so you update that to read:
    const int TWO_MINUTE_CONSTANT = 5 * 60;
    The moral is “use the meaning in names, not the value”…

    Who ever said we were using it directly as a timeout?

    const int TWO_MINUTE_CONSTANT = 2 * 60;
    const int FIVE_MINUTE_CONSTANT = 5 * 60;
    ...
    int currentTimeout = FIVE_MINUTE_CONSTANT;
  • Dave 2012-05-17 14:09
    enim is Latin for "truly"
  • Rohan 2012-05-17 14:16
    Dan Minjoc:
    Which would you rather have?

    const uint32 NUM_SEC_IN_DAY = 60 * 60 * 24;
    const unit32 NUM_SEC_IN_DAY = 86400;

    Both are correct, but the first one shows exactly where the calculation is coming from.


    I agree with you, but this an unfortunate example. Some days have 23 hours, other days have 25.

    That fact has bit me often enough that I've made a point of watching out for it. :/
  • shadowman 2012-05-17 14:17
    Jack:
    dkf:
    Vamp:
    I have done that with constants before. For example timeouts or similar:
    const int TWO_MINUTE_CONSTANT = 2 * 60;
    Makes it easier to read for me later. Maybe it was something similar for those 2 values :)
    Plus all the bonus fun you get when some manager decides that the timeout now has to be 5 minutes, so you update that to read:
    const int TWO_MINUTE_CONSTANT = 5 * 60;
    The moral is “use the meaning in names, not the value”…

    Who ever said we were using it directly as a timeout?

    const int TWO_MINUTE_CONSTANT = 2 * 60;
    const int FIVE_MINUTE_CONSTANT = 5 * 60;
    ...
    int currentTimeout = FIVE_MINUTE_CONSTANT;

    I re-factored this for you to make it more readable:


    #define TIMES(A,B) A*B

    const int ONE = 1;
    const int TWO = 2;
    .
    .
    .

    const int SECONDS_IN_MINUTE = 60;
    const int ONE_MINUTE_CONSTANT = TIMES(ONE,SECONDS_IN_MINUTE);
    const int TWO_MINUTE_CONSTANT = TIMES(TWO,SECONDS_IN_MINUTE);

  • Speakerphone Dude 2012-05-17 14:29
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?


    Typically for testing boundary conditions (such as 0).
  • Speakerphone Dude 2012-05-17 14:30
    The Great Lobachevsky:
    Speakign of sanity - am I the only one whose page up and page down keys inexplicably aren't working on this site anymore? (granted, I'm forced to use IE7, which causes all sorts of weird things)


    Did this problem appeared before or after you spilled your coffee on the keyboard?
  • Speakerphone Dude 2012-05-17 14:32
    Anna Moose:

    The tricky part is to reference the file without using any string literals. So we need another XML file that contains the filename of our configuration XML file. Which means we'll need yet another XML file...


    Duh, this is why God created environment variables
  • Jesus is just alright with me 2012-05-17 14:37
    Speakerphone Dude:
    Anna Moose:

    The tricky part is to reference the file without using any string literals. So we need another XML file that contains the filename of our configuration XML file. Which means we'll need yet another XML file...


    Duh, this is why God created environment variables
    I think it's fairly obvious from this reading of The Book of Bullshidia 3:14 that The Lord doesn't believe in your amoral "thinking machines".

    And the man did flail his fists
    And the keyboard keys did fly
    And the Lord did grin
    And he said unto his prophet
    "Burn all such devices
    lest they drive your people
    to madness and damnation"
  • wbrianwhite 2012-05-17 14:41
    KattMan:
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?


    So if you're testing an online poker bot, the best way to test it is with a series of games where the other players always have the exact same hands? Seems like an excellent way to introduce algorithm errors where the algorithm works well in those specific cases but would fail elsewhere. If you want to say that is integration testing's job that is fine, but not many shops have a formal integration testing suite that is actually separate from unit tests. I could write unit tests for my code where my code would work on 4, 9, and 67 and put those in as the test values, but my could could just blow up on 5, 10, and 68 and that test suite would detect no problem.

    Also, please define "tested to be sure it generates a good level of randomness". How would you measure this? What is 80% random versus 85% random? If this was actually a quantifiable event, computers wouldn't be stuck with pseudo-random number generators. Generally all you can do is use a PRNG from a crypto library in preference to the universally flawed RAND built in language functions.
  • Tayrtahn 2012-05-17 14:49
    Jay:
    "I don't even want to know why a constant is declared inside a class"

    Umm ... maybe so that the constant is associated with the class that it relates to? I thought that was one of the key ideas of object-oriented programming: Group related code and data together.

    Suppose I have, let us say, an "Integer" object. And I want to have a constant for the maximum value that can be stored in an Integer. Where should I logically put this constant? In some grab-bag place that includes hundreds of other constants used all over the system? Or in the Integer class?

    If I put it in the Integer class, then anyone looking at the Integer class has a good chance of finding it. If we adopt this as a general practice, than anyone looking for constants related to Integers knows exactly where to look. Anyone who notices this constant in the Integer class can reasonably expect that it relates to Integers and not to something else, and furthermore that it relates to Integers in general, and not to a particular Integer used in some other class or set of classes.

    If I put the constant in a grab-bag of globals, none of the above is true. With all constants in there, there's no easy way to tell what constants relate to what classes. I suppose we could establish a naming convention, like all constants must have names beginning with the class name that they are related to. But you know that people will forget or ignore such a rule. Having unrelated things in one place makes anything harder to find. Etc etc.

    Oh, and by the way, in modern languages, putting constants in the class they relate to gives an extra bit of self-documentation. If I see code that says, say, "if (x==READ) ...", I might well wonder if this means that we are presently reading, that a file is readable, that the last action was a read, etc. But if I see "if (x==Permissions.READ) ...", that gives me a much better idea what's going on.


    I'm pretty sure the original post is just poorly worded. Constants in a class are fine and dandy... but the post states that this gem was found inside a class methods. So, it would only be in the scope of that one method, not usuable from the rest of the class or outside. Important distinction.
  • ochrist 2012-05-17 14:57
    Sanity Clause...

    I don't believe in no Sanity Clause!
  • F. 2012-05-17 15:01
    Ok... I did read it at least five times and still fail to see what's the WTF here.

    It only seems to be a matter of personal preferences of the programmer. Nothing wrong with it.
  • AN AMAZING CODER 2012-05-17 15:13
    Dan Minjoc:
    Not sure if Fry or just Philip:
    airdrik:
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.


    Oh, now that makes perfect sense, thanks!
    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const.
    On the other hand, generic variables like "foo" and "bar" are the most evil variable names ever. While they're perfectly acceptable in short and meaningless examples, they should never, ever appear in production code. Except when they mean something, like spacebar or meter bar.


    Disagree. The compiler will automatically evaluate the expressions. Why decrease code readability for no benefit?

    Which would you rather have?

    const uint32 NUM_SEC_IN_DAY = 60 * 60 * 24;
    const unit32 NUM_SEC_IN_DAY = 86400;

    Both are correct, but the first one shows exactly where the calculation is coming from.


    I agree with this wholeheartedly. It's also easier to catch errors when the math is spelled out like this.


    This would _probably_ be caught easily by anyone that's used to seeing the correct number:
    const unit32 NUM_SEC_IN_DAY = 85400;


    this would _certainly_ be caught by anyone with half a brain:
    const uint32 NUM_SEC_IN_DAY = 60 * 60 * 23;



    Write your code so it's easier to spot problems. Your brain can do way more work at once when it doesn't have to concentrate as hard on the simplest things.

  • Lurch 2012-05-17 15:33
    Says Joe:

    "You run the test 10 billion times so that you know you're testing every random 32-bit number (to within 5%) that might come up in production.

    This also gives the advantage of never finding another problem during your career, and/or inflating the "number of tests passed" metric that you get a bonus on."


    10 billion times? But there are only 4 billion 32 bit numbers (float or integer, doesn't matter, we are counting bit patterns)! So, you get OVER 200% coverage.
  • Lurch 2012-05-17 15:41
    wbrianwhite:
    KattMan:
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?


    So if you're testing an online poker bot, the best way to test it is with a series of games where the other players always have the exact same hands? Seems like an excellent way to introduce algorithm errors where the algorithm works well in those specific cases but would fail elsewhere. If you want to say that is integration testing's job that is fine, but not many shops have a formal integration testing suite that is actually separate from unit tests. I could write unit tests for my code where my code would work on 4, 9, and 67 and put those in as the test values, but my could could just blow up on 5, 10, and 68 and that test suite would detect no problem.

    Also, please define "tested to be sure it generates a good level of randomness". How would you measure this? What is 80% random versus 85% random? If this was actually a quantifiable event, computers wouldn't be stuck with pseudo-random number generators. Generally all you can do is use a PRNG from a crypto library in preference to the universally flawed RAND built in language functions.


    Firstly, there are ways of testing random numbers. Second, you have a very poor understanding of regression testing. Third, I don't think you understand the concept of "universal". And, how would you know the quality of the "PRNG for a crypto library" anyway? (given you don't know how to test random number sequences). Indeed, (and this IS meant to be insulting), your comment is the real WTF here.

  • big picture thinker 2012-05-17 15:45
    Say you want to document the number of seconds in a day:


    #define SECONDS_IN_MINUTE 60
    #define MINUTES_IN_HOUR = 60
    #define HOURS_IN_DAY 12



    #define DAY_AS_SECONDS SECONDS_IN_MINUTE * MINUTES_IN_HOUR * HOURS_IN_DAY
  • Lurch 2012-05-17 15:51
    wbrianwhite:
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time.
    Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?


    mbrianwhite, you and kattman could conceivably both give me apoplexy. That is, if I EVER had to work with you.

    Sure, TLS. There are standard vectors for testing. You could test (real) random vectors for the next hundred years, and still not have any real confidence. Put that stawman away.

    And, I suspect that, since you (probably) can't crack the code, you would simply run the encrypted material through your decryptor, match the results and call it good?

    Here is where I hit you in the head with a heavy object.
  • Meep 2012-05-17 15:52
    wbrianwhite:
    KattMan:
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?


    So if you're testing an online poker bot, the best way to test it is with a series of games where the other players always have the exact same hands? Seems like an excellent way to introduce algorithm errors where the algorithm works well in those specific cases but would fail elsewhere.


    I was about to say, "that's only really an issue if developers are deliberately coding by kludge to pass tests" but then I realized that part of our team has recently declared that they're going to do exactly that. :-(
  • Lurch 2012-05-17 15:56
    Kattman

    I misread a quote sequence, and I declared that it would give me apoplexy to work with you. I am sorry, that comment should not have been directed to you.

    Lurch
  • Yazeran 2012-05-17 15:59
    Rohan:
    Dan Minjoc:
    Which would you rather have?

    const uint32 NUM_SEC_IN_DAY = 60 * 60 * 24;
    const unit32 NUM_SEC_IN_DAY = 86400;

    Both are correct, but the first one shows exactly where the calculation is coming from.


    I agree with you, but this an unfortunate example. Some days have 23 hours, other days have 25.

    That fact has bit me often enough that I've made a point of watching out for it. :/



    Yea, I too hate daylight savings time.....

    I have tred for years to make management accept that all servers used for data logging (large government/university lab) run on only UTC, but the response has always been: 'But when I see that X happened at 12.30 on the graph, it should be at 12.on my watch too..'

    I have given up and now have 2 timestamps in each data line, one unixtime (for mee to work with in data processing) and one localtime (with all the hilarity that entails in spring and fall) for data display...

    Yazeran

    Plan: To go to Mars one day with a hammer
  • Gazzonyx 2012-05-17 16:22
    matt westwood:
    gazzonyx:

    TRWTF is that there isn't a comment on the magic numbers there. Not that there is anything wrong with something like this, but it should be documented. For instance, this is one of my commits to Samba :

    [...]
    + /* domain/username%password */
    + const int max = MAX_DOMAIN_SIZE +
    + MAX_USERNAME_SIZE +
    + MOUNT_PASSWD_SIZE + 2;
    [...]

    So what's the fucking 2 for, you stupid prick?

    The 2 is for the '/' and '%' in the formatted string.
  • Jack 2012-05-17 16:28
    Lurch:
    wbrianwhite:
    KattMan:
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?


    So if you're testing an online poker bot, the best way to test it is with a series of games where the other players always have the exact same hands? Seems like an excellent way to introduce algorithm errors where the algorithm works well in those specific cases but would fail elsewhere. If you want to say that is integration testing's job that is fine, but not many shops have a formal integration testing suite that is actually separate from unit tests. I could write unit tests for my code where my code would work on 4, 9, and 67 and put those in as the test values, but my could could just blow up on 5, 10, and 68 and that test suite would detect no problem.

    Also, please define "tested to be sure it generates a good level of randomness". How would you measure this? What is 80% random versus 85% random? If this was actually a quantifiable event, computers wouldn't be stuck with pseudo-random number generators. Generally all you can do is use a PRNG from a crypto library in preference to the universally flawed RAND built in language functions.


    Firstly, there are ways of testing random numbers. Second, you have a very poor understanding of regression testing. Third, I don't think you understand the concept of "universal". And, how would you know the quality of the "PRNG for a crypto library" anyway? (given you don't know how to test random number sequences). Indeed, (and this IS meant to be insulting), your comment is the real WTF here.


    And the reason computers are "stuck with pseudo-random number generators" is because computers are, by design, deterministic, and not random.

    But that only means you're stuck with psuedo-RNGs as long as you're using a purely software solution. There are devices that can generate true random numbers.

    http://www.idquantique.com/true-random-number-generator/products-overview.html
  • KattMan 2012-05-17 17:00
    Jack:
    And the reason computers are "stuck with pseudo-random number generators" is because computers are, by design, deterministic, and not random.

    But that only means you're stuck with psuedo-RNGs as long as you're using a purely software solution. There are devices that can generate true random numbers.

    http://www.idquantique.com/true-random-number-generator/products-overview.html


    Exactly, you know this, I know this, Lurch knows this, Brian seems to miss it. You are expecting a reasonable facsimili of randomness. How do you measure it? Well your specs should tell you how. Let's say you have a generator to give you a number between 1 and 100, if you get 100 different numbers you aren't random, you are picking from a pool and that pool is getting smaller each time. If you get 100 6's once again you aren't random, if you get the same 10 numbers, you aren't random. Should you expect 85% of the numbers with some duplication? Hell I don't know what is "good enough" for the situation at hand, there are people better then me that write those things so I don't try to write my own, but if I had to I would expect something along the lines of 85% with duplicagtion and the duplicated numbers perhaps 90% of those are different, or something like that.

    As for the online poker bot, no, you don't need to check for a fully random sequence, you look at the hands possible, 4 of a kind, 3 of a kind, etc.compare that to other possible hands, with only 13 variances in some of those hands. you check variances against each other, not full deterministic sets, because the algorythym isn't going for if he has X I need to have Y, if you are, why even build an algorythym beyond that?
    Let's say high card, every other hand beats it so no further checks, high card is one of 13 values, easy variance to test against here, and your algorythym test can basically see if it has anything more then a single high card it is winning, only when it has a single high card does the algorythym need to work out what to toss and how many cards to get. quick test passing in not a random number, but high card pairs to check itself against.
  • wbrianwhite 2012-05-17 17:06
    Lurch:
    wbrianwhite:
    KattMan:
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?


    So if you're testing an online poker bot, the best way to test it is with a series of games where the other players always have the exact same hands? Seems like an excellent way to introduce algorithm errors where the algorithm works well in those specific cases but would fail elsewhere. If you want to say that is integration testing's job that is fine, but not many shops have a formal integration testing suite that is actually separate from unit tests. I could write unit tests for my code where my code would work on 4, 9, and 67 and put those in as the test values, but my could could just blow up on 5, 10, and 68 and that test suite would detect no problem.

    Also, please define "tested to be sure it generates a good level of randomness". How would you measure this? What is 80% random versus 85% random? If this was actually a quantifiable event, computers wouldn't be stuck with pseudo-random number generators. Generally all you can do is use a PRNG from a crypto library in preference to the universally flawed RAND built in language functions.


    Firstly, there are ways of testing random numbers. Second, you have a very poor understanding of regression testing. Third, I don't think you understand the concept of "universal". And, how would you know the quality of the "PRNG for a crypto library" anyway? (given you don't know how to test random number sequences). Indeed, (and this IS meant to be insulting), your comment is the real WTF here.



    Are we talking unit testing, regression testing, or integration testing? All different. All potentially handled by entirely different toolsets. But I think most devs would create a unit test that actually ran N iterations of the code using real random numbers, since that provides a measure of testing what your code is actually supposed to do.

    "And, how would you know the quality of the "PRNG for a crypto library" anyway?" - You're right, I'm relying on computer science teachers who tell me that they are better than RAND. I have not actually sat down and run 10 billion iterations and then looked for patterns myself. Please tell me the ways of testing random numbers. And then tell me why I would want to do so, rather than simply using the PRNG from whatever crypto library I am using? To me the real WTF is some unit test trying to test that a crypto PRNG is "random enough". Like you need to test that every month to make sure that the quality of the randomness hasn't declined? And what if you RANDOMLY got a series of numbers that looked non-random? You would raise a red flag on the status of the product? That's absurd.
  • wbrianwhite 2012-05-17 17:10
    KattMan:
    Jack:
    And the reason computers are "stuck with pseudo-random number generators" is because computers are, by design, deterministic, and not random.

    But that only means you're stuck with psuedo-RNGs as long as you're using a purely software solution. There are devices that can generate true random numbers.

    http://www.idquantique.com/true-random-number-generator/products-overview.html


    Exactly, you know this, I know this, Lurch knows this, Brian seems to miss it. You are expecting a reasonable facsimili of randomness. How do you measure it? Well your specs should tell you how. Let's say you have a generator to give you a number between 1 and 100, if you get 100 different numbers you aren't random, you are picking from a pool and that pool is getting smaller each time. If you get 100 6's once again you aren't random, if you get the same 10 numbers, you aren't random. Should you expect 85% of the numbers with some duplication? Hell I don't know what is "good enough" for the situation at hand, there are people better then me that write those things so I don't try to write my own, but if I had to I would expect something along the lines of 85% with duplicagtion and the duplicated numbers perhaps 90% of those are different, or something like that.

    As for the online poker bot, no, you don't need to check for a fully random sequence, you look at the hands possible, 4 of a kind, 3 of a kind, etc.compare that to other possible hands, with only 13 variances in some of those hands. you check variances against each other, not full deterministic sets, because the algorythym isn't going for if he has X I need to have Y, if you are, why even build an algorythym beyond that?
    Let's say high card, every other hand beats it so no further checks, high card is one of 13 values, easy variance to test against here, and your algorythym test can basically see if it has anything more then a single high card it is winning, only when it has a single high card does the algorythym need to work out what to toss and how many cards to get. quick test passing in not a random number, but high card pairs to check itself against.


    99.9% of software uses PRNGs. Yes there are random number generators out there. My favorite being a web cam that takes pictures of a lava lamp. But I have never heard of them being used.

    "but if I had to I would expect something along the lines of 85% with duplicagtion and the duplicated numbers perhaps 90% of those are different, or something like that. "
    Yes, you would expect that but humans are terrible at random. Teachers often give their students an assignment of "flip a coin x times and write the results". The students who make it up are easily distinguished because they try to make it random, and end up making very clear patterns.
  • wbrianwhite 2012-05-17 17:19
    Lurch:
    wbrianwhite:
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time.
    Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?


    mbrianwhite, you and kattman could conceivably both give me apoplexy. That is, if I EVER had to work with you.

    Sure, TLS. There are standard vectors for testing. You could test (real) random vectors for the next hundred years, and still not have any real confidence. Put that stawman away.

    And, I suspect that, since you (probably) can't crack the code, you would simply run the encrypted material through your decryptor, match the results and call it good?

    Here is where I hit you in the head with a heavy object.


    You could test real random vectors, and be testing the actual protocol. Or you could test using the same number every time, and be testing something that was almost TLS, except that it is 100% susceptible to replay attacks which is one of the primary things TLS is designed to protect against. Or you can do both. I would expect to see both done. In the predetermined sequence you know the calculated key you expect to get back using the server's public key and can validate that is correct. In the random sequence you just test that the protocol works and that you establish a shared key, and that at least tests the actual protocol.

    I have seen errors caused when using the repository pattern where the unit test for the code passes, but the actual repository doesn't work. So I always like to see the actual code being exercised.

    Am I really so annoying that people want to insult me and hit me in the head? If so, please at least state reasons you think I'm wrong.
  • Flink 2012-05-17 17:28
    It's a code obfuscation technique....makes it more difficult for someone who is specifically searching for 205 in a binary...not much more difficult, perhaps, but more difficult all the same.
  • wbrianwhite 2012-05-17 17:30
    http://en.wikipedia.org/wiki/Randomness_tests
    Ah yes, good old Kolmogorov complexity. The shortest program to generate the sequence of numbers should look like print('...the sequence of numbers'). I forgot about that. I don't know how you would implement that in a unit test. The http://en.wikipedia.org/wiki/Diehard_tests look like you could definitely unit test. But it still seems like unit testing that opening a database connection returns a database connection. It's plumbing that you need to use but is generally trusted. And if you did test it it would be a one time test, not a unit test you ran every build.
  • FFS 2012-05-17 17:30
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    He just did - when you're testing and you want to test how something relying on the generator acts for a specific value (that is, when you're testing code that relies on the Random Number, not the generation of the Random Number itself....
  • AGray 2012-05-17 17:36
    I am a .NET developer, but I don't see why you would want to kill the application unless the user has kindly asked the app to stop running.

    If they're there as a defensive measure, then this becomes TRWTF; Exceptions/Try/Catch/Finally can take care of that.

    CAPTCHA: Sagaciter - One who quotes sagas, I would guess...
  • Jim boi 2012-05-17 17:36
    Dave:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.


    I tend to agree, but that's a very different case to that mentioned in the article:

    The Article:
    solely to duplicate the behavior
    Ya but that be çause the poster didn't know why it was like that. When testing, the class is substituted for one that returns predictables results. Often easier to substitute one of your own classes than one you might rely on (possibly for someit else) elsewhere
  • Manic 2012-05-17 17:43
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.

    I would comment as you did, but then still do = 199 + 6. In this example it's trivial, but you don't want to make a calculation mistake (one that would be more noticeable if the code is not consistent with the comment).

    TBH (as many others have sadi before me), I think I'd generally split it into several constants:
    [code]
    /* Message = Header (sender, msg ID 10 char) + 100 for body (although most messages will be 50, we support sending 2 Customers in one message) + Footer (for whatever reason the protocol requires two byte tail) */
    public final static int MSG_HEADER_LEN = 10;
    public final static int MAX_MSG_BODY_LEN = 100;
    public final static int MSG_FOOTER_LEN = 2;
    public final static int MAX_MESSAGE_LEN = MSG_HEADER_LEN + MAX_MSG_BODY_LEN + MSG_FOOTER_LEN;
    [code]
    It costs little or nothing, and is clear why we set message length to a particular value (without the developer having to think about what the specific value is).
  • aeryh 2012-05-17 17:51
    Not sure if Fry or just Philip:
    airdrik:
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.


    Oh, now that makes perfect sense, thanks!
    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const.
    On the other hand, generic variables like "foo" and "bar" are the most evil variable names ever. While they're perfectly acceptable in short and meaningless examples, they should never, ever appear in production code. Except when they mean something, like spacebar or meter bar.

    Wha? So the compiler is more likely to make a mistake than the dev?
    Why wouldn't you rely on the compiler to do the math - you are, after all, (likely) relying on the compiler to correctly create instructions to do other more complicated math.

    Sure your name didn't used to be geoffery?
  • Dongle 2012-05-17 17:58
    Matt Westwood:
    Jay:
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?


    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=4*60*60". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.


    Almost there - CACHE_TIMEOUT_SECONDS would be better. Then the obviousness is even more blinding.

    CACHE_TIMEOUT_SECS
  • JJ 2012-05-17 17:59
    Flink:
    It's a code obfuscation technique....makes it more difficult for someone who is specifically searching for 205 in a binary...not much more difficult, perhaps, but more difficult all the same.

    ...

    If you're a troll, You're Doin' It Right(TM). If you're serious, step away from the computer and never program again.
  • Dongle 2012-05-17 17:59
    Dongle:
    Matt Westwood:
    Jay:
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?


    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=4*60*60". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.


    Almost there - CACHE_TIMEOUT_SECONDS would be better. Then the obviousness is even more blinding.

    CACHE_TIMEOUT_SECS

    With a comment above explaining it is currently set to 4 hrs...eg:
    [code]
    // Timeout = 4hrs
    #define CACHE_TIMEOUT_SECS 4*60*60
  • Matt Westwood 2012-05-17 18:07
    Dongle:
    Matt Westwood:
    Jay:
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?


    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=4*60*60". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.


    Almost there - CACHE_TIMEOUT_SECONDS would be better. Then the obviousness is even more blinding.

    CACHE_TIMEOUT_SECS

    (*snigger*) he said SECS
  • Matt Westwood 2012-05-17 18:10
    Dongle:
    Dongle:
    Matt Westwood:
    Jay:
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?


    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=4*60*60". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.


    Almost there - CACHE_TIMEOUT_SECONDS would be better. Then the obviousness is even more blinding.

    CACHE_TIMEOUT_SECS

    With a comment above explaining it is currently set to 4 hrs...eg:

    // Timeout = 4hrs
    #define CACHE_TIMEOUT_SECS 4*60*60


    Actually what you might want to do to be *really* bleedin' obvious is:

    [code]
    #define CACHE_TIMEOUT_HRS 4
    #define HRS_TO_SECS 60 * 60
    #define CACHE_TIMEOUT_SECS (CACHE_TIMEOUT_HRS * HRS_TO_SECS)

    ... or some such buggery. It's neater in some other languages.
  • Fer 2012-05-17 18:11
    I don't know, but the random generator that will random generate it, good random generator will be!
  • picka 2012-05-17 18:29
    wbrianwhite:
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time.
    Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?
    Reading comprehension not your forte'?

    What Ol' Frank is saying is that you FIRST test that the specific issue reported is fixed (this might be checking that the issue with 12321232 is fixed). THEN you test to make sure everything else still appears to work - this would include the normal testing of edge cases (0, Max valid value, max valid value+1, etc) as well as (probably seeing as we use Random Numbers) some testing to satisfy yourselves that with Random Numbers things still work (and although I agree with some people who say it's not the Random Number Generation that we're testing, I think at least some testing with the real random Number generation is worthwhile if nothing else to maximise the chance of catching a hitherto unthought of error)
  • Cynic 2012-05-17 18:30
    KattMan:
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?
    Because they are developers not testers - and let's face it, even many testers are crap
  • Oh dear 2012-05-17 18:32
    Dave:
    enim is Latin for "truly"
    I thought it was short for enema
  • Ryan (Original Poster) 2012-05-17 18:38
    The constant in question is actually defined at method level, which to me was a WTF for sure, especially when you sprinkle in the magic number.

    Further, the 199 + 6 magic number was not commented to explain anything about it.

    Captcha: erat - e-rat?
  • Oh dear 2012-05-17 18:46
    Jack:
    Lurch:
    wbrianwhite:
    KattMan:
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?


    So if you're testing an online poker bot, the best way to test it is with a series of games where the other players always have the exact same hands? Seems like an excellent way to introduce algorithm errors where the algorithm works well in those specific cases but would fail elsewhere. If you want to say that is integration testing's job that is fine, but not many shops have a formal integration testing suite that is actually separate from unit tests. I could write unit tests for my code where my code would work on 4, 9, and 67 and put those in as the test values, but my could could just blow up on 5, 10, and 68 and that test suite would detect no problem.

    Also, please define "tested to be sure it generates a good level of randomness". How would you measure this? What is 80% random versus 85% random? If this was actually a quantifiable event, computers wouldn't be stuck with pseudo-random number generators. Generally all you can do is use a PRNG from a crypto library in preference to the universally flawed RAND built in language functions.


    Firstly, there are ways of testing random numbers. Second, you have a very poor understanding of regression testing. Third, I don't think you understand the concept of "universal". And, how would you know the quality of the "PRNG for a crypto library" anyway? (given you don't know how to test random number sequences). Indeed, (and this IS meant to be insulting), your comment is the real WTF here.


    And the reason computers are "stuck with pseudo-random number generators" is because computers are, by design, deterministic, and not random.

    But that only means you're stuck with psuedo-RNGs as long as you're using a purely software solution. There are devices that can generate true random numbers.

    http://www.idquantique.com/true-random-number-generator/products-overview.html
    Maybe there's no such thing as a truly random number.

    Weather phenomena and the like may be unpredictable because we don't fully understand all the factors that go into causing a particular event, not because there's some higher being rolling 14 sided dice...

    Perhaps a clearer example is traffic. Traffic is caused by coincidence, not randomness. A number of people make decisions that result in them being on the same transport infrastructure at the same time. Meanwhile, decisions dictating traffic light sequences (and other factors come into play).

    So what if "Random" is just our way of saying "inexplicable with our knowledge"? What if there is no random? What if Chaos Theory is the only truth? Sierpinski's Sieve is certainly an example of how even random events can be used to create predictable patterns. Even lotteries are not random (in fact I think they rarely even have "Random Distributions"), although I guess that movie's already been made....

    Short: Pillosophical - What is Random? If Random is simply "unpredictable" then perhaps there comes a time when more is understood and random ceases to exist.
  • Luiz Felipe 2012-05-17 18:49
    Other Nagesh:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.


    Or you could use multiple random number generators and randomly select the one to use for enhanced super-randomness.


    Dont do that, this will skew the statistics, and will not produce an perfect s-curve.
  • Luiz Felipe 2012-05-17 18:56
    Karl:
    C'mon guys it is staring you right in the face! How come nobody got it yet?

    // Sanity check

    If you are a sane person, when you look at the next line of code you will immediately delete it. Nobody has yet, therefore you and all your peers are insane.


    No programmer is a sane people
  • Jim 2012-05-17 18:56
    AGray:
    I am a .NET developer, but I don't see why you would want to kill the application unless the user has kindly asked the app to stop running.

    If they're there as a defensive measure, then this becomes TRWTF; Exceptions/Try/Catch/Finally can take care of that.

    CAPTCHA: Sagaciter - One who quotes sagas, I would guess...

    admittedly I'm mainly fmiliar with C so this new-fnagled exception type stuff might be a bit beyond me, however....

    One of the probelms (as I see it) with Exceptions is that some programmers decide (rather than shutting cleanly, and perhaps displaying a quasi-useful explanation for Tech Staff) they think they should try to recover the irrecoverable.

    We recently had an incident where a (fairly critical) database error occured (corrupt data file, I think). Whoever had written our code (thankfully about 12 years before me, so it wasn't I) had a check in place to break out of a loop on a Database (or any) error. Unfortunately, this meant that we exited the loop and assumed life was normal (ie DB transactions had successfully) and a whole lot of mess ensued.

    Granted, an Exception in the Java/C# sense might have meant that this was caught rather than ignored, however one way or another the behaviour has to be to do no more processing - even if that means the system doesn't work for the user!! If something is broke, then make it break for the user, don't try to pretend the world is happy...

    That said, not all errors/exceptions are (or should be) fatal, but I think there are times when you want them to be.
  • blowhole 2012-05-17 18:58
    AGray:
    Constants in a class may or may not be a WTF - I'd honestly rather deal with a constant defined at the class level (preferably, in a Constants region) where I can easily find, identify, and maintain it, than have to sift through a bunch of code to find a method-level constant.

    The value of that constant though...I think that's TRWTF.

    Captcha: enim - must be Eminem's little brother.


    A constant in a class is standard procedure. In a non-static context though, well that would be silly.
  • blowhole 2012-05-17 19:32
    Jim:
    AGray:
    I am a .NET developer, but I don't see why you would want to kill the application unless the user has kindly asked the app to stop running.

    If they're there as a defensive measure, then this becomes TRWTF; Exceptions/Try/Catch/Finally can take care of that.

    CAPTCHA: Sagaciter - One who quotes sagas, I would guess...

    admittedly I'm mainly fmiliar with C so this new-fnagled exception type stuff might be a bit beyond me, however....

    One of the probelms (as I see it) with Exceptions is that some programmers decide (rather than shutting cleanly, and perhaps displaying a quasi-useful explanation for Tech Staff) they think they should try to recover the irrecoverable.

    We recently had an incident where a (fairly critical) database error occured (corrupt data file, I think). Whoever had written our code (thankfully about 12 years before me, so it wasn't I) had a check in place to break out of a loop on a Database (or any) error. Unfortunately, this meant that we exited the loop and assumed life was normal (ie DB transactions had successfully) and a whole lot of mess ensued.

    Granted, an Exception in the Java/C# sense might have meant that this was caught rather than ignored, however one way or another the behaviour has to be to do no more processing - even if that means the system doesn't work for the user!! If something is broke, then make it break for the user, don't try to pretend the world is happy...

    That said, not all errors/exceptions are (or should be) fatal, but I think there are times when you want them to be.


    I like exceptions and find them useful. As a programming feature, they do make sense. Primarily because it deals with the problem that based on what you're returning, it might be hard to have a consistent way of reporting errors (no error channel). In a strongly typed traditional language it makes the most sense. In a weakly typed language you could return an error object instead of the normal return type ultimately to the same effect.

    If you think that it means no more processing can be done or that the program should just crash I have to disagree with that. Some things can be recovered, or more likely ignored. Especially in the context of where you are doing things in parallel and a failure somewhere shouldn't bring down the entire program (as it wouldn't affect anything else). When it comes to programming people are more often at fault than their tools. Don't make the mistake of blaming tools because they can't fight back.

    There's really nothing wrong with handling errors, no matter the criticality, as long as you are actually handling them. However it is something that can be horribly abused.

    Probably the most common abuse:


    try do_everything_under_sun();
    catch(Exception) do_one_thing_irrespective_of_error_details();


    An ambiguous abuse:

    try do_something();
    catch(Exception) do_nothing();


    This isn't always an abuse, remember that throw is like an extra return channel and sometimes you just aren't always interested everything that gets returned. However, sometimes people ignore what is being returned hen you really shouldn't. A more common mistake is being too unspecific about the type of Exception that you want to ignore. To give an example of where you may want to reasonably ignore a throw, when closing a socket.

    The most fubar thing I ever saw was where someone had apparently used every error handling system under the sun.


    method x() {
    try {
    y = ob.do_something();

    if(y == -1) throw new Exception();

    z = ob.do_some_more();

    if(z.isError) throw new Exception();
    }
    catch(Exception ex) {
    this.isError = true;
    this.errorMsg = "Blah blah.";
    return -1;
    }
    }


    It's been a while now since I was working with that but it was something like the above but probably worse. You could never be too sure in any instant what you had to do to detect an error. Some things would let it be throw up the stack, some not. Being in a high level language made things even worse. I'm sure someone once thought this was a clever pattern but the net result was having to implement error checking at every level from the callee up through every caller when not having to do that is one of the key benefits of throwing exceptions.

    I have since decided that I would rather spend the rest of my life on the dole and only program for personal enjoyment.
  • blowhole 2012-05-17 19:52
    G:

    like the System.Environment.Exit calls peppered throughout library code that causes the app to inexplicably exit.


    I'm no .NET expert, but it seems to me exits caused by a function called "Exit" seem perfectly explicable to me...


    I think he means without any explanation. A very common malpractice. Something went wrong? Go with the bare minimum exit strategy.

    Considerate programmers have the common decency to in the very least have a print() before exit() or use a procedure to the effect of printThenExit(message).
  • Major DoucheBag 2012-05-17 21:06
    KattMan:

    Exactly, you know this, I know this, Lurch knows this, Brian seems to miss it. You are expecting a reasonable facsimili of randomness. How do you measure it? Well your specs should tell you how. Let's say you have a generator to give you a number between 1 and 100, if you get 100 different numbers you aren't random, you are picking from a pool and that pool is getting smaller each time. If you get 100 6's once again you aren't random, if you get the same 10 numbers, you aren't random.


    It's good to know that you have no concept of what random is.
  • fs 2012-05-17 22:12
    Major DoucheBag:
    KattMan:

    Exactly, you know this, I know this, Lurch knows this, Brian seems to miss it. You are expecting a reasonable facsimili of randomness. How do you measure it? Well your specs should tell you how. Let's say you have a generator to give you a number between 1 and 100, if you get 100 different numbers you aren't random, you are picking from a pool and that pool is getting smaller each time. If you get 100 6's once again you aren't random, if you get the same 10 numbers, you aren't random.


    It's good to know that you have no concept of what random is.
    I agree - to a point.

    All of those results could be randomd (unlikely, perhaps, but possible). If you always got those result I'd start to worry, but still could be random....

    I don't knwo whether you're (@kattman not MDB) aware of this, but people do actually win the lottery occasionally. Some people win it multiple times. It would be possible to win it with the integers from 1 to n (where n= the number of numbers required to win).
  • wbrianwhite 2012-05-18 00:44
    picka:
    wbrianwhite:
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time.
    Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?
    Reading comprehension not your forte'?

    What Ol' Frank is saying is that you FIRST test that the specific issue reported is fixed (this might be checking that the issue with 12321232 is fixed). THEN you test to make sure everything else still appears to work - this would include the normal testing of edge cases (0, Max valid value, max valid value+1, etc) as well as (probably seeing as we use Random Numbers) some testing to satisfy yourselves that with Random Numbers things still work (and although I agree with some people who say it's not the Random Number Generation that we're testing, I think at least some testing with the real random Number generation is worthwhile if nothing else to maximise the chance of catching a hitherto unthought of error)


    The part I was objecting to was:
    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    Which seemed to forbid testing with random numbers and insist on using a fixed set of predetermined numbers

    Addendum (2012-05-18 00:50):
    picka:
    wbrianwhite:
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time.
    Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?
    Reading comprehension not your forte'?

    What Ol' Frank is saying is that you FIRST test that the specific issue reported is fixed (this might be checking that the issue with 12321232 is fixed). THEN you test to make sure everything else still appears to work - this would include the normal testing of edge cases (0, Max valid value, max valid value+1, etc) as well as (probably seeing as we use Random Numbers) some testing to satisfy yourselves that with Random Numbers things still work (and although I agree with some people who say it's not the Random Number Generation that we're testing, I think at least some testing with the real random Number generation is worthwhile if nothing else to maximise the chance of catching a hitherto unthought of error)


    The part I was objecting to was:
    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    Which seemed to forbid testing with random numbers and insist on using a fixed set of predetermined numbers. And testing with ACTUAL random numbers should be part of the regression.
  • wbrianwhite 2012-05-18 00:50
    Damn this site code
  • hikari 2012-05-18 03:41
    I do that sometimes, when the individual numbers have some meaning to them. Although generally I'd leave a comment saying that too.

    I guess more correctly you should define the two numbers as constants with meaningful names in their own right, and then define the third as a compound...
  • d 2012-05-18 03:48
    I'm not necessarily seeing a WTF here. While 205 may be just as good as 199+6, it's not as readable - say 6 is a header size, 199 is the data size and such.

    As for constants in a class: Why not?
  • QJo 2012-05-18 06:04
    d:
    I'm not necessarily seeing a WTF here. While 205 may be just as good as 199+6, it's not as readable - say 6 is a header size, 199 is the data size and such.

    As for constants in a class: Why not?


    The main WTF is that nowhere in this class is a message explaining exactly what these numbers actually mean. Unexplained magic numbers are a major WTF in my book, all the worse for being so common, the result of a programmer too lazy or impatient to exercise basic human politeness.
  • DanDan 2012-05-18 06:07
    It should be selected at random.
  • Steve The Cynic 2012-05-18 06:16
    Dan Minjoc:
    Which would you rather have?

    const uint32 NUM_SEC_IN_DAY = 60 * 60 * 24;
    const unit32 NUM_SEC_IN_DAY = 86400;

    Both are correct, but the first one shows exactly where the calculation is coming from.

    In C / C++ on a 16-bit system, the first is wrong, because it says a day is 20864 seconds long.

    (Hint: undecorated integer constants have type int if possible, and int is allowed to be 16 bits in C and C++. The promotion to uint32 is done after the multiplication. Fix it as 60L*60L*24L, then do something to fix the dumb compiler's loss-of-precision warning on a system with 64-bit longs...)
  • Vamp 2012-05-18 07:21
    dkf:
    Vamp:
    I have done that with constants before. For example timeouts or similar:
    const int TWO_MINUTE_CONSTANT = 2 * 60;
    Makes it easier to read for me later. Maybe it was something similar for those 2 values :)
    Plus all the bonus fun you get when some manager decides that the timeout now has to be 5 minutes, so you update that to read:
    const int TWO_MINUTE_CONSTANT = 5 * 60;
    The moral is “use the meaning in names, not the value”…


    Oh wow, didn't think people here would take my sample so literally :P of course I don't name my consts that way in real code. I just named it like that so it would be clear why I used 2 * 60 and not 120. I guess i should've written SOME_RANDOM_CONSTANT_FROM_CODE, maybe then it would be clear.
  • BlackKnight 2012-05-18 08:21
    The Great Lobachevsky:
    Speakign of sanity - am I the only one whose page up and page down keys inexplicably aren't working on this site anymore? (granted, I'm forced to use IE7, which causes all sorts of weird things)


    Working fine for me, but I'm using IE 8. Time you got a modern browser.
  • KattMan 2012-05-18 08:59
    fs:
    Major DoucheBag:
    KattMan:

    Exactly, you know this, I know this, Lurch knows this, Brian seems to miss it. You are expecting a reasonable facsimili of randomness. How do you measure it? Well your specs should tell you how. Let's say you have a generator to give you a number between 1 and 100, if you get 100 different numbers you aren't random, you are picking from a pool and that pool is getting smaller each time. If you get 100 6's once again you aren't random, if you get the same 10 numbers, you aren't random.


    It's good to know that you have no concept of what random is.
    I agree - to a point.

    All of those results could be randomd (unlikely, perhaps, but possible). If you always got those result I'd start to worry, but still could be random....

    I don't knwo whether you're (@kattman not MDB) aware of this, but people do actually win the lottery occasionally. Some people win it multiple times. It would be possible to win it with the integers from 1 to n (where n= the number of numbers required to win).


    Wow is this captian douchbag and Fapper Sidkick? Yes these results all the time would not be random, even getting them once should throw a red flag for testing, but that does not mesn I have no idea what random is, it actually makes me think I know it more than you based off of a very small sample set, that set being the last posts by the two of you.
  • LittleChild 2012-05-18 09:10
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?

    At some point in the future there'll be a Ministry of Love to remind us all about the 2 minutes.

    //sanity dump
    int ROOM = 101;
  • AGray 2012-05-18 09:10
    Jim:
    AGray:
    I am a .NET developer, but I don't see why you would want to kill the application unless the user has kindly asked the app to stop running.

    If they're there as a defensive measure, then this becomes TRWTF; Exceptions/Try/Catch/Finally can take care of that.

    CAPTCHA: Sagaciter - One who quotes sagas, I would guess...

    admittedly I'm mainly fmiliar with C so this new-fnagled exception type stuff might be a bit beyond me, however....

    One of the probelms (as I see it) with Exceptions is that some programmers decide (rather than shutting cleanly, and perhaps displaying a quasi-useful explanation for Tech Staff) they think they should try to recover the irrecoverable.

    We recently had an incident where a (fairly critical) database error occured (corrupt data file, I think). Whoever had written our code (thankfully about 12 years before me, so it wasn't I) had a check in place to break out of a loop on a Database (or any) error. Unfortunately, this meant that we exited the loop and assumed life was normal (ie DB transactions had successfully) and a whole lot of mess ensued.

    Granted, an Exception in the Java/C# sense might have meant that this was caught rather than ignored, however one way or another the behaviour has to be to do no more processing - even if that means the system doesn't work for the user!! If something is broke, then make it break for the user, don't try to pretend the world is happy...

    That said, not all errors/exceptions are (or should be) fatal, but I think there are times when you want them to be.


    I can agree to that.

    In the context of the story, though, when the app 'inexplicably' exits, that sounds to me like evidence of overuse of exiting the application.

    I can add that I think when an app enters an unrecoverable state, before it exits it should tell the user that the world is no longer happy and the app cannot continue operating. Inexplicable exits cause the user/customer huge WTF moments, which translate into those irritating 3 in the morning irate calls.

    CAPTCHA: Appellatio - the Harry Potter spell for turning naughty coders into apples!
  • Joe 2012-05-18 09:21
    Lurch:
    Says Joe:

    "You run the test 10 billion times so that you know you're testing every random 32-bit number (to within 5%) that might come up in production.

    This also gives the advantage of never finding another problem during your career, and/or inflating the "number of tests passed" metric that you get a bonus on."


    10 billion times? But there are only 4 billion 32 bit numbers (float or integer, doesn't matter, we are counting bit patterns)! So, you get OVER 200% coverage.


    Learn something about randomness.

    With only 65000 randomly-selected 32-bit numbers, you have over 50% probability of a duplicate. The probability of getting all 4 billion different values by selecting only 4 billion samples is quite small.

    --Joe
  • rpl 2012-05-18 09:49
    Joe:


    Learn something about randomness.

    With only 65000 randomly-selected 32-bit numbers, you have over 50% probability of a duplicate. The probability of getting all 4 billion different values by selecting only 4 billion samples is quite small.



    Learn something about random number generators. The output of a PRNG is a deterministic function of its state vector. Therefore, a PRNG with a 32-bit state vector must generate every value it is capable of generating within 2^32 iterations (possibly far less, if the generator is a crappy one). This is undoubtedly what Lurch was referring to.

    On the other hand, Lurch might want to bear in mind that just because a PRNG outputs 32-bit values doesn't mean it has a 32-bit state vector. In fact, a 32-bit state would result in a very poor generator, since it will start failing tests for correlation within a few hundred million iterations, which is well within the range of normal usage.

  • Marc 2012-05-18 10:42
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.


    Especially if you have a large application that contains bits written in a mix of languages. Having a random generator that can be called with a fixed seed might not be enough. You may run into situations where you need a random generator that behaves identical, regardless of the language a snippet of code was written in. Unfortunately, you can't rely on system libraries across languages to have the same implementation.
  • 7eggert 2012-05-18 11:19
    Mike:
    Other Nagesh:

    Or you could use multiple random number generators and randomly select the one to use for enhanced super-randomness.


    But which random number generator would you use to select which random number generator to use for your super random number generator?


    You'd use The One RNG.
  • Jack 2012-05-18 11:52
    Oh dear:
    Maybe there's no such thing as a truly random number.

    Weather phenomena and the like may be unpredictable because we don't fully understand all the factors that go into causing a particular event, not because there's some higher being rolling 14 sided dice...

    Perhaps a clearer example is traffic. Traffic is caused by coincidence, not randomness. A number of people make decisions that result in them being on the same transport infrastructure at the same time. Meanwhile, decisions dictating traffic light sequences (and other factors come into play).

    So what if "Random" is just our way of saying "inexplicable with our knowledge"? What if there is no random? What if Chaos Theory is the only truth? Sierpinski's Sieve is certainly an example of how even random events can be used to create predictable patterns. Even lotteries are not random (in fact I think they rarely even have "Random Distributions"), although I guess that movie's already been made....

    Short: Pillosophical - What is Random? If Random is simply "unpredictable" then perhaps there comes a time when more is understood and random ceases to exist.

    Maybe nothing is truly random. But all the best evidence at the moment is that quantum mechanics is: it is impossible to have any information before the event that will enable you to accurately predict the outcome.
  • DaveK 2012-05-18 11:56
    Steve The Cynic:
    Dan Minjoc:
    Which would you rather have?

    const uint32 NUM_SEC_IN_DAY = 60 * 60 * 24;
    const unit32 NUM_SEC_IN_DAY = 86400;

    Both are correct, but the first one shows exactly where the calculation is coming from.

    In C / C++ on a 16-bit system, the first is wrong, because it says a day is 20864 seconds long.

    (Hint: undecorated integer constants have type int if possible, and int is allowed to be 16 bits in C and C++. The promotion to uint32 is done after the multiplication.
    Well in that case, the second one will also be truncated, won't it?
  • DaveK 2012-05-18 11:57
    Turd Blossom:
    const maxVolume = 10 + 1;
    (That's ridiculous. It's not even funny.)
  • Lacrymology 2012-05-18 12:42
    well, no.. but you can do

    const int TIMEOUT_SECONDS = 2 * 60;

    because your API takes the timeout in seconds, and you want anyone who happens to read the code to know you're setting up 2min without having to do the math.

    Personally, I always initialize a double-buffered 32bit screen memory like so:

    buf = (byte *)alloc(640 * 480 * 4 * 2);
  • wbrianwhite 2012-05-18 15:36
    Jack:
    Oh dear:
    Maybe there's no such thing as a truly random number.

    Weather phenomena and the like may be unpredictable because we don't fully understand all the factors that go into causing a particular event, not because there's some higher being rolling 14 sided dice...

    Perhaps a clearer example is traffic. Traffic is caused by coincidence, not randomness. A number of people make decisions that result in them being on the same transport infrastructure at the same time. Meanwhile, decisions dictating traffic light sequences (and other factors come into play).

    So what if "Random" is just our way of saying "inexplicable with our knowledge"? What if there is no random? What if Chaos Theory is the only truth? Sierpinski's Sieve is certainly an example of how even random events can be used to create predictable patterns. Even lotteries are not random (in fact I think they rarely even have "Random Distributions"), although I guess that movie's already been made....

    Short: Pillosophical - What is Random? If Random is simply "unpredictable" then perhaps there comes a time when more is understood and random ceases to exist.

    Maybe nothing is truly random. But all the best evidence at the moment is that quantum mechanics is: it is impossible to have any information before the event that will enable you to accurately predict the outcome.


    Quantum mechanics is probabilistic. You know that there is about a 25% the the electron will be in orbit x, or other such statement about a physical system. Probabilistic isn't the opposite of random but it's still pretty far away.
  • Ragnax 2012-05-18 15:56
    blowhole:
    G:

    like the System.Environment.Exit calls peppered throughout library code that causes the app to inexplicably exit.


    I'm no .NET expert, but it seems to me exits caused by a function called "Exit" seem perfectly explicable to me...


    I think he means without any explanation. A very common malpractice. Something went wrong? Go with the bare minimum exit strategy.

    Considerate programmers have the common decency to in the very least have a print() before exit() or use a procedure to the effect of printThenExit(message).


    Even then you should never ever use System.Environment.Exit directly unless you are dealing with the simplest of all terminal programs. The fact that the user account that is running the program requires SecurityPermissionFlag.UnmanagedCode to call Environment.Exit should tell you plenty about the nature of the problems surrounding it:

    Calling Exit does not shut down the process's application domain cleanly. It doesn't terminate processes started from your process, kills managed threads, doesn't call Dispose or run finalizers to take care of unmanaged resources and doesn't run code in finally blocks. It stops everything stone cold and can potentially leak a lot of system resources (Like file handles, window handles, sockets, memory from various types of in-memory stream, etc.)
  • token_woman 2012-05-18 16:47
    Zylon:
    So, in case at some point in the future you forget what "TWO MINUTES" means?


    Must be ... since that is so much more likely than forgetting what "2*60" represented in that particular case.

    Sarcasm aside, there is something to be said for going even further and embracing seemingly over-engineered DSL-ish typesafing stuff. Like, this is a minute, and by definition it has 60 seconds. Rather than just chucking integers about (which is still what you are doing even if you define them as constants). Not something I've had much experience of but seems like it does what the constant-mongers are trying to do, but with more success.
  • Barf 4eva 2012-05-18 17:39
    Not sure if Fry or just Philip:
    airdrik:
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar)
    public final static or whatever length = 205;

    Even better, use javadoc.


    Oh, now that makes perfect sense, thanks!
    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const.
    On the other hand, generic variables like "foo" and "bar" are the most evil variable names ever. While they're perfectly acceptable in short and meaningless examples, they should never, ever appear in production code. Except when they mean something, like spacebar or meter bar.


    Or if you are writing production code for helping people with introductory software books...
  • SG_01 2012-05-18 18:09
    Pfft, this one is too obvious. The code is obviously there to check the programmer's sanity. If you're too sane you will be hung up on this line too much.
  • Friedrice the Great 2012-05-18 18:18
    BlackKnight:
    The Great Lobachevsky:
    Speakign of sanity - am I the only one whose page up and page down keys inexplicably aren't working on this site anymore? (granted, I'm forced to use IE7, which causes all sorts of weird things)


    Working fine for me, but I'm using IE 8. Time you got a modern browser.

    My employer just upgraded us from IE6 to IE7 ...
  • Friedrice the Great 2012-05-18 20:04
    DaveK:
    Turd Blossom:
    const maxVolume = 10 + 1;
    (That's ridiculous. It's not even funny.)

    "But MY amp goes to 11." - Spinal Tap
  • Pramod 2012-05-18 23:52
    You're being racist. Can you please stop?
  • Lurch 2012-05-19 13:37
    wbrianwhite:
    Lurch:
    wbrianwhite:
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.


    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time.
    Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?


    mbrianwhite, you and kattman could conceivably both give me apoplexy. That is, if I EVER had to work with you.

    Sure, TLS. There are standard vectors for testing. You could test (real) random vectors for the next hundred years, and still not have any real confidence. Put that stawman away.

    And, I suspect that, since you (probably) can't crack the code, you would simply run the encrypted material through your decryptor, match the results and call it good?

    Here is where I hit you in the head with a heavy object.


    You could test real random vectors, and be testing the actual protocol. Or you could test using the same number every time, and be testing something that was almost TLS, except that it is 100% susceptible to replay attacks which is one of the primary things TLS is designed to protect against. Or you can do both. I would expect to see both done. In the predetermined sequence you know the calculated key you expect to get back using the server's public key and can validate that is correct. In the random sequence you just test that the protocol works and that you establish a shared key, and that at least tests the actual protocol.

    I have seen errors caused when using the repository pattern where the unit test for the code passes, but the actual repository doesn't work. So I always like to see the actual code being exercised.

    Am I really so annoying that people want to insult me and hit me in the head? If so, please at least state reasons you think I'm wrong.


    Given:

    - The encryption phase is harnessed for testing.
    - The decryption phase is harnessed for testing.

    And, assuming (typical) development:

    - The product provides both encryption and decryption
    - You use an RNG *also* under test harness
    - You send a message through the entire stack.

    Let us look at some failure cases:

    - The key vector is computed incorrectly. In this case, the entire stack appears to work fine. The data may even appear "random". Of course, an entropy calculation filter on the actual stream would highlight the problem.

    - Everything has been done as above. Except that the decryption component has been replaced by another implementation, with a simple "pass/fail". Again, the RNG or key computation is incorrect. Message are "brute forcible". (Actually happened with Debian SSH). Can only be detected by proper analysis of the key path.

    Once the key path is confirmed, it must be "boxed away" (the Debian fiasco occurred because a packaging dev "opened" the box to get rid of some valgrind warnings).

    The testing of a crypto component in particular is difficult. Very, very difficult. It starts with known vectors. Followed by code path and data analysis. "Random" tests are really not at all useful, and mostly just hurt because they install a false sense of security. Aside from a "smoke test", but that is done more usefully with known vectors as well. Simply because, if the "smoke test" doesn't work, it needs to be replicated anyway.

    (FWIW: FIPS 140 validation involves code analysis, and known test vectors. I have never needed "random" tests. However random testing for customer demonstration, along with a entropy analyzer is useful for sales purposes)

    If random vectors *are* used in a smoke test, they would need to be stored along with the results (just in case of failure).

  • Lurch 2012-05-19 13:48
    Joe:
    Lurch:
    Says Joe:

    "You run the test 10 billion times so that you know you're testing every random 32-bit number (to within 5%) that might come up in production.

    This also gives the advantage of never finding another problem during your career, and/or inflating the "number of tests passed" metric that you get a bonus on."


    10 billion times? But there are only 4 billion 32 bit numbers (float or integer, doesn't matter, we are counting bit patterns)! So, you get OVER 200% coverage.


    Learn something about randomness.

    With only 65000 randomly-selected 32-bit numbers, you have over 50% probability of a duplicate. The probability of getting all 4 billion different values by selecting only 4 billion samples is quite small.

    --Joe


    Joe

    If someone does 10 billion random tests for 4 billion possible cases -- that's, um... a serious WTF.

    Just do 4 billion directed tests and guarantee 100% coverage.

    That's all I meant to say.
  • Scarlet Manuka 2012-05-20 23:46
    Severity One:
    Would you mind giving an example where a non-random random number makes sense?
    I'm sure SpectateSwamp would find a use for it.
  • peter 2012-05-21 04:50
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?


    Sure. Sometimes, a randomizer is used with a seed, which will make it return a consistent, rather than a random, result.

    Randomizers used in this way are a nice tool in encrypting.

    Seeing how the product is called 'legacy', the randomizer may be there to not exactly duplicate the behavior of the .NET randomizer, but an different one... for instance, the VB6 randomizer.

    Been there, done that. Burnt the T-shirt.

    peter

    Captcha: quibus -- strangely enough, that is a (misspelled) Dutch colloquial word for a nutcase (kwibus).
  • Steve The Cynic 2012-05-21 08:41
    DaveK:
    Steve The Cynic:
    In C / C++ on a 16-bit system, the first is wrong, because it says a day is 20864 seconds long.

    (Hint: undecorated integer constants have type int if possible, and int is allowed to be 16 bits in C and C++. The promotion to uint32 is done after the multiplication.
    Well in that case, the second one will also be truncated, won't it?

    No, because the "defaults to int" behaviour is only if it can be an int with the value given. ("undecorated integer constants have type int if possible")

    So on a 16-bit system:

    * 32767 is an int
    * -32768 is an int
    * 32768 is an unsigned int
    * 65535 is an unsigned int
    * 65536 is a long.
    * Perhaps most relevantly, 86400 is a long.
    * But 24*60*60 is three ints multiplied together and the rules say that int*int is an int so 24*60*60 is also an int, and clips to 20864...
  • JimTheJam 2012-05-21 14:42

    "Don't rely on the compiler to do your math."
    by "Not sure if Fry or just Philip"

    That has to be the Dumbest
    or
    the Funniest phrase
    I've ever seen on The Daily WTF! (or both!)

    ROFL,
    Jim

    There are 10 types who have programming jobs:
    1) Those who can program,
    10) Those who can't.
  • JimTheJam 2012-05-21 15:10
    Lurch:

    If someone does 10 billion random tests for 4 billion possible cases -- that's, um... a serious WTF.

    Just do 4 billion directed tests and guarantee 100% coverage.

    That's all I meant to say.


    Nope. That assumes that the PRNG is only called once per transaction (or whatever the main loop is doing). If it is called twice you need to square that (trice and **3, etc). And even then you might miss problems caused by leftover values from one iteration affecting the next.

    Example (though not of a PRNG): One of my employer's computers had a bug where if a Procedure Exit instruction was preceded by one particular innocuous instruction, the exit would, well, not exit properly. No amount of individual instruction testing would have caught the bug. Some machine state was left weird, and it only affected the Procedure Exit instruction.

    A PRNG example: a friend of mine was using a PRNG to initially place stars in a volume of space for a simulation of galaxy evolution. The PRNG was highly thought of, and passed many tests with flying colors (die, dice, poker hands, and other tests). When he took a stereoscopic picture of the resulting array he got what he called a "cosmic potato chip" instead of a spherical structure. It turned out that that PRNG had a known - but undocumented -- weakness -- sets of triplet values did have a non-random behavior. But it was fine for anything else! (or so they said).

    An excellent PRNG is hard to find. Bad ones are easy and common.

    Jim
    - and just who's opinions did you think these were?
  • validus 2012-05-21 18:25
    Fool:
    I do things like 199+6 isntead of 205 on occasion.

    2 reasons:
    1) I am often doing math where I might look at the code one day and say, why the heck did I put 205 there? But looking around I see the numbers 195 and 6 somewhere else in the code.

    2) 199+6 compiles to 205 so it should be equivilent to 205 in the binary file that is generated.


    I'll also write "1000 * 60 * 10" to define 10 minutes in milliseconds, rather than "600000".

    "199 + 6" could have been a left-over of some test code that ended up being kept, or it could relate to something that Mr. smart-ass Ryan failed to mention.

    Ryan, honey, is that seriously the worst piece in that whole codebase that you were able to find, and you absolutely and desperately just had to find something to ridicule? Dumb-ass...
  • Ryan (Original Poster) 2012-05-23 14:11
    There's a HUGE difference between an "199 + 6" (*with nothing other than "Sanity Check" as a comment, and "1000 * 60 * 10" with a comment indicating something like "ten minutes, in ms".

    The latter is clear and understandable, the former is not.

    And there's no need to resort to name calling - While I freely admit to being a smart-ass, I don't particularly appreciate being called "honey" or "dumb-ass".

    So lay off, if you will. There was plenty in the code base that was questionable, but that was a single line of code (2 with the comment) that made me bust out laughing in a slightly incredulous "This makes me so sad that I can only laugh to keep my sanity" type of laugh.

    Captcha: nisl (National Institute of Silly Lexicon"