Jump to content

SoK/2021/StatusReport/Rohan Asokan

From KDE Community Wiki

Adding features to Kalk - A SoK Project

What is Kalk?

Kalk is a clean cross-platform calculator written using the Kirigami Framework. It consisted of a simple calculator with common trigonometric functions with history capabilities and a conversion module. It did not have infinite precision and relied on C++ data types to represent floating point numbers. The calculator is in itself very straightforward and runs a lexical parser in the background to perform calculations.

Its already amazing!! What did I want to do?

I wanted to add a few more commonly used scientific functions to the calculator, albeit that was already under some development so I was only able to add a few of them.

A completely new binary calculation module which will be able to handle binary calculations. Binary calculators are an important thing for many embedded systems developers and security analysts (they might have better tools :)).

I also want to add a date calculation module using which difference between two dates, and other commonly used date based calculations. The motive for this module is that, for most people (including myself) date calculation is extremely hard and time consuming. A calculator module for this will make the date calculation process easier.

The kind person who wanted to mentor me through implementing the above idea

Han Young

Find More about Kalk

https://invent.kde.org/plasma-mobile/kalk (Official Repository) https://invent.kde.org/arenagrenade/kalk (My Fork of the Repo)

The actual work

Phase 1 / Scientific Functions

The time I had applied, there was already some scientific functions being added. So, I wanted to add a few more functions to it. Further, as quite a bit of it was already done and to add a new functionality to this required me to go through quite a lot of code, I felt this was a nice way to get familiar with the code base. I found that "abs()", the absolute value function, was not present and started to dig around in the code and add that functionality. And after a bit of tinkering and some help from previous commits I figured the code out and submitted my first MR, https://invent.kde.org/plasma-mobile/kalk/-/merge_requests/14. Obviously I did not follow good git practices in terms of commits and useless files :), and it was squashed and merged manually by Han.

Phase 2 / Binary Calculator or Programmer Mode

This was a completely new mode and I had to write quite a bit of code to create a new page - which I did not understand the workings of. Kirigami and Qt were very new to me. I was used to the way most javascript frameworks handle display and processing - side-by-side in the same place. But I soon learnt it is good practice in Qt to seperate the processing part and the display part. This allowed me to take a different perspective and start working. But, another hiccup - I did not fully understand how to use a parser. Kalk uses Flex and Bison for that task. I kept thinking it was quite trivial and it was wrong to elevate to Han. But, search I may I found nothing. Finally, I just asked Han about it and she explained things very well. I had two courses of action - create a new parser for the binary mode or just use `QRegularExpression` to make a two number calculator, after all binary calculator its a trivial mode. So after a bit of discussion on the use of the mode, we decided to go ahead with the regular expression path. Till then I had completed the UI of the calculator - it was crude and different than the final one (https://invent.kde.org/plasma-mobile/kalk/-/merge_requests/16).

Once I understood what the workflow should be I got to work really fast and finished most of it really quickly. But, then came another major change - we were porting to KNumber from the c++ float we were using. This was to obtain infinite precision calculations. All of this, I kept adding to the above MR until completion - I felt it was better to keep the TODO and everything in a single thread. Porting to KNumber was not very hard once I had the basic classes in place.

As part of this I had also created a KNumber wrapper to handle Binary numbers and strings as it did not do so at that time.

Phase 3 / Date Calculation (Planned) vs. Port to KNumber (Done)

A date calculation module was initially planned, but was decided is a very trivial feature and Kalk being a very simplistic calculator, Han felt it was right to not add it. Further, there was no simple way to do dates with Kirigami, we had to style everything manually. Kirigami has this feature coming up soon, which only pointed to delaying this Date calculation module. I had made some work with the UI, just to see if it is at all possible to have this in a simple way, which could be found at https://invent.kde.org/arenagrenade/kalk/-/tree/date-calc. As this was stopped, I took up another important change for a release - porting to KNumber.

While, working with the binary calculator, I developed an idea of how data is being transferred inside the application and my task was to update this data flow to handle KNumber instances instead of Qstring, which was the case then. I just traced the path around and figured a best way to handle this change. There were two classes that were singly and directly connected in the data flow, which meant I could make the change from KNumber to QString in either of these classes. To elaborate, displaying something can only be done with QString and not KNumber - there was one class handling this `InputManager` from which we get the number string from. For parsing the math expression and returning a result, there is another class `MathEngine`. We can either change to string at the parsing lever or at the display level. I decided to keep the conversion at the display level as the `InputManager` class had other functionality that depended on the values being a string. This in itself was very straightforward to implement.

Now, the binary calculator module had additional functionality - display a conversion of the result in different bases - binary, decimal, hexadecimal. This meant I had to convert a string that we have at the display stage in binary to the other bases. This might be quite redundant as KNumber already has functionality for this as we have extended it earlier. This meant that I had to store it in the `InputManager` class with additional variables which only got filled whenever the binary mode is active. It is a very straightforward and elegant solution to handling the processing.

So how does it look now?

Binary Calculator mode Visible in the Menu
The basic UI for the mode
Simple input showing the conversion capabilities
Simple addition operation applied on two numbers inside the Binary Calculator
Bit wise Left Shift operator being applied to show the robustness of the calculator

Some UI suggested for the Date Calculator, but later removed in view of the upcoming Kirigami updates

Date Calculation as a menu item
The Combo Box for selection of the operation to be performed
Dynamically updating UI based on active operation
Date choosing calender popup for the inputs to the Date Calculator

Blog

https://planet.kde.org/page/14/#3