This is an amusing anecdote.
When I was working on my cross-check of shows and characters, I got everything working right except one thing. I noticed my count of ‘shows with death’ made a weird pie chart. You see, the number of shows was off by one compared to the total number of shows. I went back and forth, trying to figure out why it was doing that, and in the end I decided that I’d output the list and manually count to see what I was missing.
I counted, by hand, the shows that I got with the list of ‘all characters are dead’ and that number matched what the code output. Then I subtracted that from the number of ‘shows with any death’ to get the ‘some characters are dead’ count, and that too was okay. This meant that, for some reason, the list of shows where no one died was wrong. But it was subtraction! How could it be wrong!
Well as it turns out, I forgot that null and zero aren’t the same to a computer, but they tend to be to a human’s brain.
Now I know this! I know that zero is a number, it’s a value of the known quantity of zero. And I know that ‘null’ is a non value, meaning that it’s a data point that cannot yet be known.
You can’t math on null. And I knew this. Earlier in my code I’d written $foo = 0
outside of my loop where I check and, as needed, increment it with $foo++
specifically because you can’t add to null.
Nothing from nothing, carry the nothing…
But. In my calculations, I checked the following:
- If a show has been flagged with ‘death,’ count all the characters.
- For each character, if they’re dead, add 1 to the death count.
- If the number of characters is the same as the death count, add this show to the list of ‘kill ’em all.’
- If the number of characters is greater than the number of dead, and the value of either isn’t 0, add the show to the list of ‘kill some.’
Then, separately, I checked “If the show has not been flagged with death, add the show to the ‘kill none’ list, because that’s a 1/0 check. And when you don’t think too deeply about that, it sounds fine, right? If they aren’t marked with death they must kill none. And if they don’t kill them all, and they don’t kill some, then the number should be the same as the ‘kill none’ list.
The problem was that I had one show, just one, where all the characters were alive but it had been flagged with death. This was not an error. The show did kill off a character, but I’d not added the dead character yet. Which meant it ran through the checks like this:
- Flagged with death, we count all the characters (8).
- If the character is dead, add one to death count (death count is 0).
- If the number of characters (8) is the same as the dead (0), add to ‘kill them all’ (false).
- If the number of characters (8) is more than the dead (0) (true), add the value of either isn’t 0 (false), add them to ‘kill some.’ (false).
Which isn’t wrong at all. It just meant that the show didn’t get listed on ‘kill none’ because it was flagged with dead, and it didn’t get listed on ‘kill them all’ because 8 is more than 0, and it didn’t get listed on ‘kill some’ because while 8 is more than 0, dead was 0.
Oh silly me. The value of death characters was ‘null.’ They simply didn’t exist in a place where they should have.
The fix? I added the dead character to the site and everything was fixed. But code wise, could I prevent this? I certainly should, since I know better than many that you can’t predict what users are going to do. So it begs the question of why was I checking if character count and dead count were not 0 to begin with? It was, originally, because my ‘no deaths’ list was screwed up and I threw that check in to omit cases where a show was flagged as death but didn’t have death.
The accuracy of these things depends entirely on your data. Garbage in, garbage out. The best fix would be to check ‘if a show has death and it has no dead characters, adjust the dead count down by one’ but also ‘if a show has no death, but it has dead characters, adjust the live show count down by one.’ I haven’t done that yet. I will soon.
Comments
One response to “Null and Zero”
Good for you, Mika. Always initialize variables yourself because sometimes compilers or interpreters do it for you in unexpected ways. xxx