TJLMOM: Dealing with “rates”

I’ve seen a lot of code that handles “rates”[1] in such a way that if in some weird circumstance the denominator; we’ll call it “D”, here; one of 3 things happens:

  • the program either just crashes outright because of a DivideByZero error
  • the math runtime catches this and the display is NaN things/time
  • the math runtime doesn’t catch it, but you get some other weird output

None of these are user friendly, and all of them are, IMO, the wrong way to handle it.

When encountering these issues, most developers will check D to see if it’s zero and handle that, since it’s a DivideByZero issue, so we want to see if the thing that could be zero is or isn’t, right? I maintain this is the wrong approach.

Normal Human Program

For this type of application, I’m talking about a run of the mill application that isn’t specifically for math or science (those are treated below). These are apps where mathematical or program purity isn’t tantamount; you just want to show something to the user that isn’t incorrect, or weird. UX is very important here.

Given that, my preferred method here is to not check D, but rather check the numerator (N). Why? If you have zero “things / time unit”, it doesn’t matter what the time unit actually is, you have zero things per that unit. So just return 0. If D is zero but N is not, you still have SOME rate. You just don’t know what it is so returning 0 isn’t quite right, and you’re masking some other issue in your program.

Either data isn’t getting to your function correctly or D is actually zero; something’s happened that the time (et. al.) quantum couldn’t be measured.

For UX, I’d return some sentinel value to indicate to the caller that the rate couldn’t be calculated; have the display show “Unknown” or “N/A” or “Not Yet Ready” OR just not show it at all! Set its CSS display: none, for example.

Scientific/Math Program

For more rigorous mathematical apps, you can do the same thing as above, but in general these types of apps NEVER expect D to be zero, so something is definitely wrong with your program. If your program reaches this “impossible” state, it’s often best to just error and stop; you have bad data, or bad code, or both. Trying to valiantly continue on “defensively” just leads to a crippled program, and a crippled program does WAY MORE DAMAGE than a dead one, as a rule.

Another option would be to have the DISPLAY show that in huge red letters that THIS CALCULATION IS INVALID AND DON’T RELY ON IT.

TL;DR

Check the Numerator, not the Denominator, and handle that if it’s 0. Either use whatever logging/alerting system you have in place to let you know you have a problem so you can fix it, or error/exit if this “should never happen”.

But that’s like, just my opinion, man.

[1] Any time you have “some amount of things / some metric”. This metric is usually some sort of time quantum, so I’m talking about “bits/second”, “events/day”, type of thing. Doesn’t have to be time, but usually is.