Unsigned 8 bit integer vs human heights
🎚️

Unsigned 8 bit integer vs human heights

Tags
blog
Computer Science
Career
Startups
Software Development
Web Dev
The life of software engineering is full of adventures, as those in this field constantly realize. Let me share an interesting problem from a real-life story! (You will also understand why Problem Solving and DSA are necessary for every SWE job.)
So, a customer reported a strange bug. They claimed that their height (257 cm) was not being accepted as input in the user registration form. While it seems exaggerated (surely a bit too much, but we can't verify it, can we?), the form doesn't submit when entering the height. After much investigation, I found that when we were creating the User Entity in our user database, we had selected Unsigned 8-bit integer as the Field Type for height during normal circumstances. An Unsigned 8-bit integer can have values ranging from 0 (zero) to 255. Since height is never negative (Unsigned), and who knows, someone might be 8 feet 4.394 inches tall (255 cm), this type had been working fine without any issues and was the most optimal solution. But how do we register this new user now? Manually entering 257 cm in the database is not possible! At that point, I had two industry-standard options in my hands (ones that were used in other companies):
  1. Changing the Field Type of Height through Database Migration:
  1. Creating a New Table where abnormal values are entered. Set the height in the previous records to 0. Implement logic such that if the height is 0 in the new table, retrieve the data from there.
  1. For heights above 255 feet, apply the Ostrich Algorithm 😂
    1. In computer science, the ostrich algorithm is a strategy of ignoring potential problems on the basis that they may be exceedingly rare. It is named after the ostrich effect which is defined as "to stick one's head in the sand and pretend there is no problem". It is used when it is more cost-effective to allow the problem to occur than to attempt its prevention. - Wikipedia
The first fix was almost everyone's choice. If you don't want to deal with the hassle of database migration, the second option can also be considered. However, my supervisor explicitly stated,
"Sanjib, no way I can allow you to change the Database Schema. You can do every other thing except changing the Database schema."
Of course, he's not without fault! Changing the DB schema not only poses the fear of data loss but also the possibility of breaking many things in the backend. What to do... what to do... what to do... In this life, before even thinking about marriage, I find myself tangled in fixing these bugs. In such moments, the revolutionary idea came! As I sit down to work, fresh from the restroom:
Backend (Actually, Client-Side JavaScript does this):
height = height - 50;
Then, Form Submit Action.
And in the Frontend View: height = height + 50;
Did it go over your head? Let me explain it better:
  1. Assuming that it's still impossible for anyone under 16 to have a height below 50cm. As the record for the shortest person above 16 years of age is 54.6 cm.
  1. Assuming that it's still impossible for anyone over 16 to have a height above 300cm. As the record for the tallest person is about 272.03 cm.
  1. Since values below 0 and above 50 are not needed, I am reducing everyone's height by 50 in the frontend. For someone with a height of 152 cm, it will be saved as 102 cm in the database. For someone with 257 cm, it will be saved as 207 cm. No need to change the Database Schema!
  1. Later, in the frontend template, I am adding 50 to the height received from the backend to show the actual value.
  1. A strict comment is added beside the height field in the entity for future reviewers and coders. If a case like (height < 50 || height > 300) ever comes up, a warning log handler is needed.
This might not be considered standard, conventional, or even good code. However, considering our infrastructure, this was the only alternative. Solving this problem without touching the DB impressed the supervisor so much that day.
You can make this solution more convenient by using a abstraction layer or what we call is getter/setter function with this:
function getHeight(self):{ if (self.createdAt().toString() < new Date("12-02-2023").toString()) return self.height // After this date, all heights will be 50cm less than actual height return self.height as u16+50; // caste unsigned 8 bit to unsigned 16 bit integer, unsafe }
And,
function setHeight(self, height):{ if (height>300 || height < 50 ) return HeightOutOfBoundError("Height can not be below 50cm or above 300cm") self.height = height -50 as u8; // Caste unsigned 16 bit to unsigned 8 bit int, unsafe }
Now call these two functions whenever you need those.
💡
I could also use 35 as Difference Constant. Height range from 35cm to 290cm is more reasonable and future-proof than 50cm to 300cm range.
In software engineering life, I have solved various unique problems in such unusual ways. If interested, I'll share another story another day.