This is the latest update.
Before the next earnings releases happen in July/August, I am going through refactoring my code yet again. Last time it was for fixing issues with scalability, this time I am fixing issues with type safety and performance.
The webpage has had a large update. The consolidated earnings results on the special page for every company can now display data for 1st Quarter, 2nd Quarter, 3rd Quarter, 4th Quarter, First Half, First Three Quarters and FY Cumulative.
This means you'll be able to check for new records every quarter. Will the 1st quarter for Nintendo FY3/2024 have a new record in net sales, operating income or net income? Who knows but now you'll have an easier time finding out.
You can now see the consolidated operating results from 1981 to 2003 for Nintendo in the Date by Fiscal Year section other than the Special Page:
That is all for the latest update.
Once again, it is going to take a long time refactoring a lot of things because it will have to be rewritten from the ground up. The main reason for this is dealing with all kinds of data, and it is often that you won't have data for every quarter such as the Nintendo earnings data above. My code before this update did not handle this well.
After learning about algebraic data types, I went and started this refactoring by changing the type system I have in place:
The type in the image at the top that says Earnings is the old type, EarningsV2 is the new type. EarningsV2 looks like a plain object, go to the second image and you will see the EarningsValue type, this is what is going to improve things. This type is structured using a "
discriminated union" in TypeScript.
To understand how this works, look at the type above it called Maybe. The Maybe type is a type that can result in a Just type containing a value of some type or it can result in the nothing type. Here is an example:
JavaScript:
type Nothing = { kind: "Nothing"}
type Just<T> = { kind: "Just", value: T}
type Maybe<T> =
| Just<T>
| Nothing
function divide(x: number, y: number): Maybe<number> {
if (y === 0) {
return { kind: "Nothing"}
} else {
return {
kind: "Just",
value: x/y
}
}
}
console.log(divide(3,0));
console.log(divide(3,6))
Code:
[LOG]: {
"kind": "Nothing"
}
[LOG]: {
"kind": "Just",
"value": 0.5
}
Using a function to divide numbers safely that makes use of the Maybe type with a number as input. In most languages, if you try to divide by zero, you'll get an error. Of course, in JavaScript if you divide by zero it will just return Infinity. Maybe you don't want a transaction to occur over the internet that will cost infinity dollars because JavaScript divided by zero in one of its computations, you might have an if condition where it keeps running the same result because the condition relies on a number being greater than infinity.
For this divide function being used, if "y" which is the divisor is equal to zero, then the function is going to return an object of the Nothing type. If the divisor is not equal to zero, then it will return an object of the Just type containing the value from the result.
If you look back at my EarningsValue type in the image, you'll see I have objects that are for different types of data, and they all hold different values. This provides better type safety compared to the old Earnings type I made because that old type did not have constraints for each different type of data. When you look at the EarningsValue type, you will see that each kind of object only knows what they know so TypeScript will prevent you from making a mistake if you are not inserting the correct data. The Nothing type inside the EarningsValue type deals with data I don't have, which can make things easier for handling undefined data.
The old Earnings type required using multiple objects placed into a list. When I needed to perform any computations, I could end up with lists of lists (nested lists) and they cannot be flattened.
With the new EarningsV2 type I made, I made one single object to have all the data needed which means nested lists are less likely to occur. Since my code involves making a lot of objects and since it will likely grow over time, I had to change the data structure being used. Creating regular JavaScript Objects are expensive because they take up a lot of memory (compared to other types) and also take longer to create. To solve this issue since I am using objects is to make use of the Map() function/data structure. It has already been implemented for the code that uses the EarningsV2 type. What this means is that over time as the data on the webpage grows, the performance from using Map() will be much better compared to lists holding objects when looking at Heap memory usage and time spent doing computations on objects i.e. adding, removing or modifying objects.
I know that right now, there isn't much of a performance problem yet however, I am saving myself time from doing this now instead of another major refactoring in the future.
While I did solve the issue regarding missing quarters such as in the image above which is from one of the Capcom fiscal years between 2001 to 2003, I noticed that I would also need to implement a function for subtracting from halves and not just quarters since the fourth quarter data isn't correct.
That is all for the latest update.