WebCalc iteration 3 - formatting and cleanup in calculator module

Welcome to the third iteration of WebCalc implementation. Previously I managed to get only basic operations working, namely addition and subtraction. This time I want to go further and add multiplication and division. Whereas multiplication should be pretty straightforward, I’m expecting issues with the division. Once I get these things working, I’ll see if I can improve the design of calculator itself and the tests. To IDE then.

Multiplication is, indeed, straightforward. I copy subtraction test (which still bothers me, but I don’t see a better solution yet) and modify it accordingly, like so:

Implementation is a tiny bit more complicated because I need to replace an if there with something else. Well, I could use ‘else if’, but instead I’ll use a switchover strings, never done that before honestly. Everything else is obvious:

I’m adding a few more test cases, just for completeness sake.

No surprises here, implementation is correct.

Division starts fairly simple. Yet another copy of tests and I have:

So far the implementation can look like this:

Works for now. Now it will get trickier because I want to leave a world of integers. I’m adding a simple test case:

It failed because of the decimal point. I’m from Poland, currently living in Germany, and in both those countries, we’re using comma as a decimal point, not a dot. Java, when converting BigDecimals to strings, is always using the dot. If I want to get a coma in string representation, I need to format the numbers using NumberFormat, like so:

Now I have a coma. Next problem to solve is rounding. The division is the first operation, that can produce infinite expansion, but I need a finite number of digits to return. I don’t know if that’s a good idea, but I’ll add to the Calculator a possibility of setting max fraction digits.

Digression, in hindsight, it’s a bad idea and I’ll have to fix it later, at the beginning of 4th iteration probably. Although I’ve found it out after writing the code and during writing this article, I decided not to go back, fix it immediately and hide my failure from everybody. It happens to me all the time, and not only to me. We’re all making mistakes, we just need to reflect on them and learn from them. It is a very important part of software engineering.

Back to code, merely adding a test case will not be enough this time, I’ll need to change a bit more. This is the moment, where all test methods stop looking exactly the same way, so making a copy for a division was a good decision. Now my test looks like this:

Calculator needs to get its setMaxFractionDigits:

So far it works. As usual, I’m adding a few test cases to find out if I’ve covered all cases:

Funny enough I didn’t. Although I was limiting max fraction digits in the division, printing number out, just by accident, was also using maximum 2 fraction digits. In the end, I didn’t notice, that I’ve missed something. When I asked for higher (or lower) precision, I didn’t get what I wanted. Fix is simple:

I’m looking at the Calculator and I think that the eval method has grown beyond my liking. Especially this big switch is bothering me. Luckily Java has something like BinaryOperator, that I can use, so I’m extracting a method finding out what kind of function needs to be applied to two values.

I think the Calculator itself is now more complete, I don’t yet see any applicable improvements. Parsing string looks like a candidate, but it would change once I start dealing with more than one operation on two numbers, so I’m leaving it like it is. Also looking at calculator tests I still cannot figure out if I should merge adding, subtracting and multiplicating together. They seem very similar, but operations are different after all. I’ll probably stop tormenting myself with that and leave it be. I can always return here later on and merge if that would make sense.

It’s time to see if something needs to be changed from the REST interface perspective. Indeed, setting max fraction digits is not handled at all, and I should probably also test division from outside, as it is quite different from all other operations implemented so far. My new test hitting the application from outside looks like this:

Fixing the controller is straightforward:

That will be all this time. Next time I’ll start by fixing handling of max fraction digits. I’ll also stick to Calculator itself and add a possibility of doing some more complex calculations. See you next time!