Zsolt Fabók

Practical ideas on kanban, lean, scrum, xp, java, programming…

The Currency Format Kata

in development

A couple of days ago, I needed a function which is capable of printing out a certain amount in Hungarian currency format. At that time I found the implementation of this function challenging, so I decided to implement it on my own, without googling for an existing solution. It was fun - as I expected - and I also realized that it would be a great Coding Kata exercise, because:

  • The exercise is quite simple

  • It can be finished in a short period of time

  • There are multiple choices on how to do it

The definition of the exercise:

Implement a functionality which shall receive a double number as string input. It shall format its input according to the Hungarian currency format, and it shall return the formatted value as string. In this particular format, the thousands are separated with spaces, and the decimal mark is a comma. You can assume that the input is always in the right format.

For example:

  • 100 -> 100

  • 1000 -> 1 000

  • 1000000.01 -> 1 000 000,01

I did the pilot Kata with my friend and colleague Tamás Győrfi in a pair programming session with TDD. we had a great time, and learnt new things even though we were unable to finish our implementation due to our time limit on the kata session. The following code demonstrates how far we got:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class HungarianCurrencyFormatter {
    public String format(String number) {
        if (isInteger(number)) {
            return insertThousandSeparator(number);
        } else {
            String integerValueOfTheNumber = number.split("\\.")[0];
            StringBuilder formattedNumber = new StringBuilder();
            formattedNumber.append(insertThousandSeparator(integerValueOfTheNumber));
            formattedNumber.append(",");
            formattedNumber.append(number.split("\\.")[1]);
            return formattedNumber.toString();
        }
    }

    private boolean isInteger(String number) {
        return !number.contains(".");
    }

    private String insertThousandSeparator(String number) {
        final StringBuilder formattedNumber = new StringBuilder(number);
        for (int i = 1; i <= (number.length() / 3); i++) {
            int position = number.length() - 3 * i;
            if (position != 0) {
                formattedNumber.insert(position, " ");
            }
        }
        return formattedNumber.toString();
    }
}

The code above could use some refactoring, because there are duplications in the code such as calling the String#split() method twice, and the inserThousandSeparator method is not self-explanatory.

I tried a different way using the NumberFormat.getCurrencyInstance(Locale) method. The returned formatted String had some extras in it like an ” Ft” suffix and a strange thousand separator:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class HungarianCurrencyFormatter {
    private static Locale HUN = new Locale("hu", "HU");

    public String format(String number) {
        NumberFormat currencyFormatter =
            NumberFormat.getCurrencyInstance(HUN);

        String currencyFormattedNumber =
            currencyFormatter.format(Double.parseDouble(number));

        String formattedNumberWithProperGroupSeparator =
            replaceLocaleSpecificGroupSeparatorWithSpace(currencyFormattedNumber);

        return removeFtSuffix(formattedNumberWithProperGroupSeparator);
    }

    private String removeFtSuffix(String number) {
        return number.substring(0, number.indexOf(" Ft"));
    }

    private String replaceLocaleSpecificGroupSeparatorWithSpace(String number) {
        char separator = DecimalFormatSymbols.getInstance(HUN).getGroupingSeparator();
        return number.replace(separator, ' ');
    }
}

The full source code is available on github.

The extras made the code a bit complicated, and I don’t feel that the second solution is much better than the first one. So I’ll keep exercising, maybe I found one which is much better than the versions above.

If the exercise is no longer challenging for you, you can do the following:

  • Accept any kind of string, and do proper error handling

Do the Kata with different constraints, like

Comments