The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Are there ALWAYS 60 seconds in a minute?

I was told to make "60" a constant in this line of code:

  int minutes = seconds * 60;

Why?  Is the number of seconds in a minute going to change?  What do you think?  Am I alone in thinking this is stupid?
Caffeinated Send private email
Thursday, April 14, 2005
 
 
No, I think that would be stupid also.  You replace that '60' with a #define MAX_SECS_MINUTE which then is placed in some .H several subdirectories away.

Then it's not immediately obvious that MAX_SECS_MINUTE is seconds PER minute, nor is it obvious that it's only referred to in one place.  It becomes MORE difficult to maintain and understand than the 'magic number' is.

The 'rule' against 'magic numbers' is supposed to make maintenance EASIER, not harder.  It is supposed to make understanding what the program does and how EASIER.

Thus you don't hard-code the max length of strings, max size of arrays, etc., you put them in #defines (or const declarations).  Because these things can change quite often.

But the number of seconds in a minute will never change, so putting it in a .H somewhere just obfuscates the code for no good reason.
AllanL5
Thursday, April 14, 2005
 
 
You are correct in thinking that is stupid.

I cannot stand that kind of crap.
hoser Send private email
Thursday, April 14, 2005
 
 
There are always 60 seconds in a minute, by definition.

Changing our time unit is possible (since it is only a convention) but it would require us to revise our measuring system and all of physical constants. The costs of this type of change are prohibitive.
Dino Send private email
Thursday, April 14, 2005
 
 
Well, thre are minutes with leap seconds in them, so it's not entirely a constant.

But hell, nobody is ever going to write non-time-synchronization related software that cares about that, so ignore it.
Ryan Anderson Send private email
Thursday, April 14, 2005
 
 
#define SIXTY 60

int minutes = seconds * SIXTY;
Rosco
Thursday, April 14, 2005
 
 
Your math is backwards.  It should be

int minutes = seconds / 60;
Cowboy coder
Thursday, April 14, 2005
 
 
Also, I don't feel obligated to make a constant out of every magic number I use in a program.  If I know the number is never going to change, then I just annotate where the number came from in a comment.  I reserve declaring constants for values that change or are used multiple times in the code.  Otherwise, it just pedantics.
Cowboy coder
Thursday, April 14, 2005
 
 
"Your math is backwards.  It should be
int minutes = seconds / 60; "


Damn!  No wonder that never worked right!
Caffeinated Send private email
Thursday, April 14, 2005
 
 
Ryan is right, every few years there is a minute with 61 seconds in it, by definition. By definition the second a fixed period time measured with atomic clocks. A minute is 1/(24*60) of the mean solar day. Due to the slowing down of the rotation of the earth, there will be more and more seconds in a day.

So it is a constant that usually equals 60, sometimes 61.

However, for most practical purposes it is acceptable to have an internal clock that accumulates an error of a second every few years with wall time. If you use Windows you can correct this error every time your system is rebooted (-8.
Karel Thönissen Send private email
Thursday, April 14, 2005
 
 
In _my_ world there is ALWAYS 60 seconds in a minute.  In reality, not always.  I like my world better.
bpd
Thursday, April 14, 2005
 
 
I *hate* everyone participating in this thread; it exemplifies everything that is *wrong* about our industry.
Playa Hatah
Thursday, April 14, 2005
 
 
I will be the contrary opinion. Constants are not just for ease of maintenance / readability for items that may change later, they are also used for well... constants. Like PI or the number of meters in a mile. Having constants defined ensures no hard to spot typos creep into your code.

For instance:

Int minutes = seconds / 6;  vs Int minutes = seconds / 60;

Having a constant prevents the typo:

Int minutes = seconds / SECS_PER_MINUTE;

The key is to name them properly. MAX_SECS_MINUTE and SIXTY are confusing or meaningless.

Just my TWO_CENTS
DJ
Thursday, April 14, 2005
 
 
"I *hate* everyone participating in this thread; it exemplifies everything that is *wrong* about our industry.
Playa Hatah"

Self-hatred is so sad.
Aaron F Stanton Send private email
Thursday, April 14, 2005
 
 
Unable to locate file: <commonsense.h>
TWO_CENTS is not defined

---------------------- Done ----------------------

    Build: 0 succeeded, 1 failed, 0 skipped
Peter
Thursday, April 14, 2005
 
 
The point isn't that the number of seconds in a minute might change. The point is that "x * SECONDS_PER_MINUTE" tells the reader much more than "x * 60".
Russell Borogove Send private email
Thursday, April 14, 2005
 
 
Russell is right in that it's not about the constantness of 60. It's about the readability. And I find 60 to be more readable that SECS_PER_MIN. But I don't think it's stupid either way. Just do what you're told on the job, and write 60 in your pet project.
Simon Perreault Send private email
Thursday, April 14, 2005
 
 
"Your math is backwards. It should be int minutes = seconds / 60;"

And right there is a good example of why this should be a function. 'minutes = sec_to_min(seconds)" is not much longer, but it's harder to make a stupid mistake.

I was doing some similar conversions, and, after puzzling a few times about whether to multiply or divide, just made a function, so the code is now much easier to read and write.
masharpe
Thursday, April 14, 2005
 
 
use a function for that, which always return 60, in case you need to sell it to nasa, you can add leap seconds to that.

eg:

seconds()
{
 if (something special == true)
 {
  return x;
 }
 else
 {
  return 60;
 }
}

Thursday, April 14, 2005
 
 
and while you are at it, make it a public web service so that when i need to convert seconds to minutes i can just call your code and not worry about whether to use a constant or not . . .  :-)
bw
Thursday, April 14, 2005
 
 
"Your math is backwards.  It should be int minutes = seconds / 60; "

Aha! NOW I know where Air Canada got their flight scheduling software from!
NetFreak Send private email
Thursday, April 14, 2005
 
 
It was a rule while I was an undergrad that all numbers other than 0 and 1, and in rare cases 2, had to be defined as named constants.

It's a good rule for teaching.  It does not always hold in the real world, of course, but far too many people liberally sprinkle their code with magic numbers and it becomes hard to maintain.  So, you teach that you shouldn't use magic numbers, when people feel they have to make a conscious decision to break the rule.

The end result is generally better code.  Not always, but generally.
Chris in Edmonton Send private email
Thursday, April 14, 2005
 
 
Alrighty then...

Some people will find any excuse, any excuse at all, to litter their code with #define.

Here is a simple function that in fact is from our code base:

bool isLeapYear( unsigned int year )
{
return (year % 4 == 0) &&
  (year % 100 != 0 || year % 400 == 0);
}

What would be proper coding etiquette for eliminating the magic numbers 0, 4, 100 and 400?
hoser Send private email
Thursday, April 14, 2005
 
 
I thought the general goal of "no magic numbers" applied if you are using the number in more than one place.

If you are only using this conversion in ONE place, then I'd say use 60.

If you're using this conversion in MORE than one place then, as someone noted, it should be a function.

Then, if you ever need to change it (or have a bug) you only have it in ONE place.

Remember: keep it DRY: Don't Repeat Yourself.
Mr. Analogy (uISV owner} Send private email
Thursday, April 14, 2005
 
 
You can say that again! :)
sgf
Thursday, April 14, 2005
 
 
"You can say that again! :) "

It took me a full minute to GET that joke! LOL
Mr. Analogy (uISV owner} Send private email
Friday, April 15, 2005
 
 
Megic numbers. HMMM

Oneo f our developers created a code where the 0 (zero number) is replaced with ZERO constant.

In the IT there should be 3 number only: 0, 1, many.
Otto Takacs Send private email
Friday, April 15, 2005
 
 
>> What would be proper coding etiquette for eliminating the magic numbers 0, 4, 100 and 400?

One just side-steps that issue. A constant is set to 365.242375 and work out the code from that. ;-)
KayJay Send private email
Friday, April 15, 2005
 
 
David Aldridge Send private email
Friday, April 15, 2005
 
 
Perhaps a better example is the number of seconds in a day.
i.e. if you're from a unix date time then you to a VB/COM Date time then pick which one of these you'd prefer:

Function UnixToCOM(UTime as long) as Date
  UnixToCOM=UTime/86400+25569
End function

Function UnixToCOM(UTime as long) as Date
  UnixToCOM=UTime/(60*60*24)+#1/1/1970#
End function

Function UnixToCOM(UTime as long) as Date
  UnixToCOM=UTime/SECONDS_IN_DAY+UNIX_EPOCH_OFFSET
End Function

DO NOT use this code in production with checking:
a) That I have the unix epoch right
b) It probably needs half a day adding or subtracting.
Peter Ibbotson
Friday, April 15, 2005
 
 
One advantage of using a symbolic constant is that a constant can link uses of 60 in seconds-per-minute and distinguish this use from other uses of 60 (eg, minutes in an hour).
someone else
Friday, April 15, 2005
 
 
One thing to note:

Sixty seconds per minute is constant BUT

Not every minute has 60 seconds do to "leap seconds". It turns out the Earth's rotation is such that a day is longer than 86400 seconds. Thus leap seconds are added every so often so that the standard day and the sun's position don't drift apart.

So, the actual number of seconds since 00:00:00 1-January-1970 and right now doesn't match what the customary timekeeping library calls expect. This is mostly of interest to astronomers, GPS people, and the like.

On the main forum, there is a thread on Daylight Savings Time. Remember that causes some days to have 23 hours, some to have 25.

Except in Indiana (an American state), which is in two time zones, and most, but not all, of the state does not observe Daylight Time. Leading to indescribable confusion.
confused
Friday, April 15, 2005
 
 
>60 (eg, minutes in an hour)

Or speed limits, or the base of Babylonian calendars (actually that's where the 60 comes from in minutes and seconds).

Another example: 12. There are 12 months in a year, and 12 inches in a foot. So if we see

M = N * 12;

are we going from feet to inches, or years to months, or (old currency) pounds to shillings, etc etc.

But if we see

M = N * INCHES_IN_A_FOOT;

we are not confused about what conversion is taking place.

You might say, that will never happen that you don't know what M and N stand for, but if this code were buried in the middle of a 1,500 line function called do_everything_in_a_giant_while_loop(), it could help.
confused
Friday, April 15, 2005
 
 
I started this article thinking it was stupid to make 60 a constant but now I agree that doing so improves readability so it should be done.

Glad I read this. Always a note to not react to quickly to what immediately appears stupid.
me
Friday, April 15, 2005
 
 
If you're converting between different units, you should probably have a type for each different kind of measurement. That way, you don't have to divide your pounds into shillings, but can just run GetShillings() on a Money value (or whatever -- I think Money is a mass noun, but there you go) and have it magically work. Store the value as a number of ha'pennies and the maths becomes easier, and you avoid an expensive floating point divide.

This also helps prevent any mismatch of types. Use one of the oft-reviled statically typed languages, and the compiler will even check this without your having to run the program. One might have a distance type, to which one cannot add a weight, but can add more distance. (This distance can then be converted into poles and chains, just as the weight goes into troy ounces and grains.)

This removes all unsightly constant numbers from the code. However, one is still left with the unsightly constant names -- I've never considered this a problem, but on the code I'm working on at the moment this kind of thing is abstracted away through careful use of 4 steps of #define.
Tom_
Friday, April 15, 2005
 
 
>> I started this article thinking it was stupid to make 60 a constant but now I agree that doing so improves readability so it should be done.

In addition to readability, you have the advantage of having a variable whose scope is project wise. Months_per_Year will change if you change Calenders.
KayJay Send private email
Saturday, April 16, 2005
 
 
I saw a program with a set of numeric constants named ZERO, ONE, ... up to TEN.  Of course, seeing x*NINE in the code did nothing to improve readability or maintainability.

Constant names should reflect their *meaning*, not their value.
T. Norman
Sunday, April 17, 2005
 
 
To add another twist.

When working on older languages, on occasion what might seem to be a number wasn't, or perhaps it was different.

you could for instance say 6=7 and now the variable which used to be 6 is now actualy holding 7.  Love Cobol.

If you where writing a generalised class of any sort, one would regularly expect to be able to convert information in 2 directions, minutes=>seconds=>minutes, at which point any value used in conversion is likely to be used at least twice, and could therfore be expected to be a constant.
 
As commented we calculate small time based on our big time of how long it takes for the planet to rotate.  Will we have the same units of time when we move to other planets (if we ever do), will the number of seconds in a minute be the same on the moon?
gorf Send private email
Monday, April 18, 2005
 
 
I'd just like to add that it bugs me almost as much to see magic booleans floating around in code. Something like this...

Rectangle r = new Rectangle(true, false, false);

...really bugs me. In my opinion, this code is much better...

boolean drawBorders = true;
boolean drawFill = false;
boolean drawHoverState = false;
Rectangle r = new Rectangle(
  drawBorders,
  drawFill,
  drawHoverState
);
BenjiSmith Send private email
Monday, April 18, 2005
 
 
Yeah, in a line like:

int minutes = seconds / 60;

it's pretty redundant, but if you're using the same constant in multiple places or using it in an conditional expression it becomes more worthwhile. Ultimately, it's about meaning, 60 doesn't mean anything, doing

const int secs_per_minute = 60; // no #defines please people, this is the 21st century, you know.

becomes more worthwhile because then the expression actually means something.
Mr Jack
Tuesday, April 19, 2005
 
 
The coding standards at my previous employer required us to define constant variables for any constants besides zero and one. For our weekly progress reports, we ran a program that counted the number of coding standard violations and reported the results.

I ended up defining silly constants like
  #define FOUR 4

I was already behind schedule and working long hours, and I wanted to conform to coding standards as quickly as possible.
Julian
Wednesday, April 20, 2005
 
 
What is wrong with using #define?
Steven Send private email
Wednesday, April 20, 2005
 
 
I still hate everyone participating in this thread . . . hate, hate, hate.
Playa Hatah
Wednesday, April 20, 2005
 
 
>  What is wrong with using #define?

You can't define the scope of a '#define VALUE 2' statement to public or private:
Class Mars {
private const int Seconds_Per_Minute_On_Mars = 45 // We on earth don't care about the relative time rate on Mars
...
}

Elsewhere in Venus.h :
// wait. a comment on a #define? comments aren't parsed by a pre-processor... imagine there was a statement directly after this. the comment might get grouped with that.
#define Minutes_Per_Hour_On_Venus 30
...

If you can write code which doesn't require the extra step of a pre-processor, why wouldn't you? Things could compile faster, less dependencies on the underlying compilation regime. Also, Compile time checking of values might also become unavailable in the IDE. Not all IDE's support the tracing, debugging and/or analysis of defined constants at the level of coded constants.
Roman likes gravity at a nice consistent 9.8 Send private email
Thursday, April 21, 2005
 
 
Not to mention the fact that the preprocessor doesn't perform any kind of syntax validation on the replacement tokens. It just copies whatever string you've #define'ed all over the place in your source code.

I'm not opposed to the notion of preprocessing. I just thik the notion of a purely lexical preprocessor is phenomenally out-dated. I'd love to see a type-aware preprocessor capable of syntax-checking and semantic analysis.
Benji Smith Send private email
Thursday, April 21, 2005
 
 
But then it's no longer a PRE-processor. :)

Thursday, April 21, 2005
 
 
Ummmmm. Sure it is.

If it performs its analysis and replacements BEFORE the regular compiler, then it would still be a PREprocessor.
Benji Smith Send private email
Thursday, April 21, 2005
 
 
>  boolean drawBorders = true;
>  boolean drawFill = false;
>  boolean drawHoverState = false;
>  Rectangle r = new Rectangle(
>    drawBorders,
>    drawFill,
>    drawHoverState
>  );

How about this:

Rectangle r = new Rectangle(
  Rectangle::drawBorders,
  Rectangle::noFill,
  Rectangle::noHoverState
);

A few less lines, no dummy variables (although the compiler *should* be able to optimise them away), no confusion about what the arguments mean, and a compile time error if the arguments were a different way around.  (hmm, ok, your code looks like Java, if I recall correctly Java is stupid and wouldn't help quite as much with the type safety. Sheesh, what idiot wants a language that's worse than C++ ?)


> I was already behind schedule and working long hours, and I wanted to conform to coding standards as quickly as possible.

If you worked in the next cubical to me, there would have been constants such as JULIAN_IS_A_DUMBASS all over the place.

Well, either that or I'ld start having "#define THREE 5" all over the place, but particularly in code that I knew you'ld be working on. Actually, I think there is something to your attitude - you might be a fun victim, er, cow orker.

Idiots who're obsessed with "conforming to coding standards" instead of writing code that's readable in the first place are the reason we have this damn problem. If a number is worth using, it's worth giving a meaningful name. Every time someone acts confused about what value name to give to a constant, it's because they don't know what that constant is actually for.


> I still hate everyone participating in this thread . . . hate, hate, hate.

Quite a few of them deserve it. Keep up the good work.

Monday, April 25, 2005
 
 
I had to respond to this last post. Julian wrote, "For our weekly progress reports, we ran a program that counted the number of coding standard violations and reported the results." He wasn't *obsessed*, he was picking his battles.

That being said, whatever Playa Hatah says, I found this thread very amusing.
EKB Send private email
Wednesday, April 27, 2005
 
 
> Rectangle r = new Rectangle(
>  Rectangle::drawBorders,
>  Rectangle::noFill,
>  Rectangle::noHoverState
> );

Ah, yes, good point. If I have control over the classes (and I'm not just an API consumer), then I much much prefer using the named static fields from the class.

Unfortunately, at my current company, I've been brought into a project that already has several years (and nearly a million lines of code) in its history. I see stuff like this all the time:

int theValue = fetch_the_value(true, true, 1, false, 17, "purple", someObject, someOtherObject, "stylesheet.css");

It makes me want to poke out my eyes.
Benji Smith Send private email
Thursday, April 28, 2005
 
 
Late to the game, so maybe everybody has gone home, but...

Did anybody else (probably those of you familiar with Barton and Nackman) find themselves scratching their head wondering why minutes is an int?
Danil
Saturday, April 30, 2005
 
 
,,, Good to read  replies on this topic "Are there ALWAYS 60 seconds in a minute?".
i think there r 59 sec ,, the only think you have to do is to start counting from 0. thats why "0" is in between L0L.
Tarik Bin Ziyad Send private email
Monday, May 02, 2005
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz