- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
As in, "One hopes the guy who wrote this will have his day of reckoning?"
Admin
I'm not allowed to write self-documenting code.
Well I am, but I have to comment it too.
I had to change:
To:
I wish I was joking.
Admin
Yes, that's right give all constants near meaningless names, but put a comment near the declaration. That's the way to go.
Admin
Can I be the first to ask "What the F" is this amount of time being used for?
Because all of the variable names and options I've seen so far suck hard balls.
What about something closer to (assuming the variable is used to time the delay between automatic saves) the variable's intent rather than a description of its contents.
final autosaveDelay = 5 * 60 * 1000;
Admin
You should use
It doesn't matter here, but it would if you had to use a longer period of time.
won't work, because the product is of ints, and overflows.
Admin
Admin
You're both wrong.
const int c_MILLSEC_PER_SEC = 1000; const int c_MILLISEC_PER_MINUTE = c_MILLISEC_PER_SEC * 60;
final long ms = 5 * c_MILLISEC_PER_MINUTE;
Relying on comments to make a line even remotely understandable is wrong, ok?
Admin
You are all wrong. Considering the fact that when you use UTC clock not all your minutes are equally long (some are longer or shorter than others), the number of seconds in a minute/day/year changes.
And just because of that some days are actually one second longer (or shorter)!
As the number of seconds in a minute changes, you should obviously create a macro that calculates it and not a #defined constant.
You are all the same self-centered bastards as the bunch that does: #define DAYS_IN_YEAR 365
Admin
I prefer the 5 * 60 * 1000 route. Any compiler (yes, even java) will insert 300000 into the reulting code.
Verified by decompiling a class ;)
k
Admin
[quote user="Matt R"][quote user="Markp"]
Or gasp you could use a comment! Then you can remove the assumption that the moron who will be reading/maintaining your code will see the "obvious".
final long ms = 300000; /* 5 minutes worth of milliseconds */[/quote] Or better yet, name the little buggers. final long SECOND_IN_MS = 1000; final long MINUTE_IN_MS = 60 * SECOND_IN_MS; final long ms = 5 * MINUTE_IN_MS
Admin
Right, and then when the moron updates the code, but not the comment you'll have something like this:
final long ms = 3000000 /* 5 minutes worth of milliseconds */
instead of
final long ms = 50601000;
Yeah, definitely better to use comments to convey meaning than make the actual code self documenting.
As for the original one liner, I think the developer was smoking crack when they wrote it.
Admin
I think this is a fairly obvious one.
It used to be:
patno -= 40 + 10;
Then some idiot went a did a global replace of 10 ==> VERSION_CODE
and for some reason adding 1 every year fixes the problem, so it evolves into:
patno -= ((((((((((((((((40+1)+1)+1)+1)+1)+1)+1)+1)+1)+1)+10)+1)+('Z'-'A'))+1)+1)+1);
Admin
You jest but I saw this in code just last week (to be fair it was ONE, TWO, THREE.... TEN).
The way I to it is:
final long WAIT_PERIOD = 5 * MINUTES_TO_MILLISECONDS;
Admin
Have read this a few times here and I don't understand the logic. Seconds per minute, e, pi, are all things that will never change but I'll set you on fire if you don't use a constant for them.
indeed.
Admin
It's a matter of clarity.
You see final_time = 5000 and you don't know what it means. Even if you saw final_time = 5 * 1000 you still don't know what it means.
Is the fundamental clock unit milliseconds or something even smaller?
Sure, in the final_time = 5 * 60 * 1000 there's no question because we recognize there is only one set of conversion factors that would make this make sense. Just because you can reasonably get away with it once doesn't mean you should, though--simply get in the habit of always using descriptive constants and you won't get burned.
The clearer the code the less trouble it's going to be down the road. I've still got a year or so of supporting stuff I started 20 years ago.
Admin
And when you need to change it's value you gasp have to write a program to help you calculate the new value in milliseconds. I would first check the oxygen level in your cubicle...
Simon
Admin
That's fine until it becomes
final long ms = 600000; /* 5 minutes worth of milliseconds */
Joe
Admin
What are comments? What possible use could something like this have??
Admin
Unnecessarily complex.
The GP is right, this is better: final long xxx = 5 * 60 * 1000; // ms
Admin
except then it's more difficult to change the number of minutes....
Admin
That has only one serious drawback: When someone changes the constant without changing the comment... It'll confuse the heck out of the next one to come across it (I do a lot of jump-in-and-fix-it, so I've seens this embarrasingly often...)
My personal favourite way to write something like this is: final long SESSION_TIMEOUT = 5 * 60 * 1000; // specified in ms
Where I have: a) descriptive variable name b) upper case variable name, so it's obviously a constant (depends on your style guidelines and language, of course) c) one place to change the value, which is presented in a readable way (and any compiler will optimize this away, so nothing to worry there) d) comment that tells me what order of magnitude to expect here.
Admin
If this was Java code then it would be inefficient, you want to use StringBuilder then convert it to string buffer.
Admin
I see a lot of people trying to add even more WTFness, but on the serious side the cleanest solution is this:
const int millisecond = 1; const int second = 1000millisecond; const int minute = 60second; // etc. Perhaps use double instead of int.
// All code using times must explicitly state the unit, e.g. const int some_delay = 5*minute;
After all, we're dealing with units. It's pointless to have seconds_in_milliseconds etc., because then you will still need to know which of seconds and milliseconds is the fundamental unit (i.e. the one used internally).
Admin
That will never work on a site like this.
Admin
I'd guess this was part of a default password, and he was going for a 'Y', not 89.
Admin
I would say this is wrong. If you change the time, you have to recompute the milliseconds. Also duplication of information is bad, you are likely to change the value and forget to change the comment.
Requires no such comment (or a comment could simply be /* in milliseconds */, and is easy to change the number of minutes.
Admin
Hahaha, look at the brackets go as you scroll down.
Admin
If patno isn't an int, the operators + and - could be overloaded to do something else(like add or remove to/from a collection) and return the math result.
Admin
ROTFLMAO. What were ya smoking? Here's LISP:
Looks nothing like the abomination you posted above. I guess clueless posts are never out of fashion.
(Disclaimer: I'm a LISP clueless-post fascist. So what.)
Admin
Ekhm, why complicate things so much?
Addition (and other common operators) take multiple arguments, so there's no reason to manually apply increment (1+) so many times.
List constants can be written in 3 characters less.
Using char-int (or even char-code) twice would take way less space than as you have done with apply and mapcar.
Lyle
Admin
..and then what if you later need to change it to 6 minutes worth? 5 * 60 * 1000 is easier to change, no?
Admin
Writing 5601000 is better than writing 300000 and commenting why it is 300000. If you write a comment and change the number later, you may forget to update the comment. The next person looking at your code may not be sure if the comment or the code are supposed to be correct.
Admin
i'd personally rather do it the OP's way and spell it out so to speak. You might as well have it calculate it itself and it makes changing the number of minutes much easier since you only have to change the 5. If you had to use 4.389 minutes or something, writing 4.389601000 is less prone to error than manually writing 263340 /* 4.389 mins of ms*/
i think anyway :)
Admin
Yes, because it's so much easier once you're told to increase that time by one minute. Instead of changing one number, you have to change one number and a comment, and you have to calculate in your head. 300000 is easy, but what about 13 hours in seconds? Easy - yes, but why bother? Besides, sooner or later someone's going to ignore the comment while changing the constant.
final long delay = 46800; /* 14 hours worth of seconds */
Good luck finding this bug. It's actually better to use both self-documenting constants and comments or even just the constants exactly because of the moron who will be maintaining your code..
Admin
Admin
I was immensely entertained by the number of people who consider changing 5 minutes in milliseconds to 6 minutes in milliseconds a difficult challenge prone to errors.
Thank you for that.
Admin
Rubbish. Real lispers know about n-arity functions and would write this:
Admin
Many years ago, i worked with a C compiler for the Infineon E-GOLD chipset that would have loved the code in the article.
After many weeks of debugging weird behavior it turned out that it only evaluated the first 2 variables during variable declaration, so :
int a = 1 + 2 + 3;
would equal 3.
Of course you always "skip" through variable assignments while debugging and go straight for the breakpoints :(
Admin
It's a lot easier to change when someone wants 6 minutes instead of 5 if it's using Markp's method. Saves having to use a calculator every time you need to change it. You could add a comment as well though.
Admin
Cept you wouldn't want to use /* */ on a single line comment in case someone needed to comment out the block later :p.
Admin
Or: final long MILLISECONDS_IN_5_MINUTES = 300000; Of course, someone else would have gone for : final long MILLISECONDS_PER_SECOND = 1000; final long SECONDS_PER_MINUTE = 60; final long MINUTES_TO_CALCULATE = 5; final long I_AM_ANAL_RETENTIVE = MILLISECONDS_PER_SECOND * SECONDS_PER_MINUTE * MINUTES_TO_CALCULATE;
Admin
Really, you guys don't know lisp.
+
isnt restricted to two arguments.(+ 1 1 1 1 1 ... 1 1 1 (- \Z \A) 1 1 ... )
Admin
Admin
Admin
heh. Greetings from Australia. And actually I think it should be "I Þink ðe Queen". Or we could get even more phonetic and use the IPA, but I can't be bothered to be more of a smarty pants than this
Admin
#define CRAZY_CONSTANT 89 /My special number/
patno -= CRAZY_CONSTANT
Admin
Then you've got 2 things to update every time you change it and you have the possibility of the 2 getting out of sync.
I'd rather see Markp's solution, provided that you're using an optimizer that reduces the expression into a constant. It's also nice to define constants for conversion like MS_PER_MINUTE.
Admin
I thought that too at first, but then remembered that Þ was used in "the". That's how we ended up with "ye" as in "Ye Olde Tea Shoppe" - printers didn't have Þ in their typefaces, so used "y" instead (although I don't know why they didn't use "p", which would have been closer in appearance). Now you can impress all your friends by telling them that "ye" (meaning "the") is pronounced the same as "the"!
Admin
89 is used for the seed of a very secret algorithm. And of course no one should be able to read the compiled source ;-)
Admin
There's always the possibility of stupid, but..
I'd be willing to bet the only thing REALLY wrong with the code is that they didn't use constants and/or better naming conventions for all the conditions they're correcting for...
It may or may not be the case that encoding the whole thing as a single constant is compatible with the rest of the code. If there are lots of modules with different numbers of off-by-one issues, it may be time to refactor the whole program, but you aren't going to fix it by writing this function better.