From a897f0faf98b215763f5daf94a002d8f03f7e049 Mon Sep 17 00:00:00 2001 From: fatosmorina Date: Fri, 9 Feb 2018 09:53:20 +0100 Subject: [PATCH 01/11] Add tradukisto library --- algorithms/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/algorithms/pom.xml b/algorithms/pom.xml index e972f3949472..65e199bbc85f 100644 --- a/algorithms/pom.xml +++ b/algorithms/pom.xml @@ -39,6 +39,11 @@ jgrapht-core 1.0.1 + + pl.allegro.finance + tradukisto + 0.5.1 + From 2186ea3e65df0fcba599b77f6e4aca55ae4f01af Mon Sep 17 00:00:00 2001 From: fatosmorina Date: Fri, 9 Feb 2018 09:53:41 +0100 Subject: [PATCH 02/11] Implement MoneyIntoWords --- .../algorithms/moneywords/MoneyIntoWords.java | 148 ++++++++++++++++++ .../moneywords/MoneyIntoWordsTest.java | 42 +++++ 2 files changed, 190 insertions(+) create mode 100644 algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java create mode 100644 algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWordsTest.java diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java new file mode 100644 index 000000000000..76a191ec3bf4 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java @@ -0,0 +1,148 @@ +package com.baeldung.algorithms.moneywords; + +import java.math.BigDecimal; +import java.text.DecimalFormat; + +import pl.allegro.finance.tradukisto.MoneyConverters; + +public class MoneyIntoWords { + + private final String[] tens = { "", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" }; + + private final String[] ones = { "", " one", " two", " three", " four", " five", " six", " seven", " eight", " nine", " ten", " eleven", " twelve", " thirteen", " fourteen", " fifteen", " sixteen", " seventeen", " eighteen", " nineteen" }; + + public String getMoneyIntoWords(String input) { + MoneyConverters converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE; + return converter.asWords(new BigDecimal(input)); + } + + public String getMoneyIntoWords(double money) { + StringBuilder result = new StringBuilder(""); + if (money < 0) { + return result.toString(); + } + if (money == 0) { + return result.append("zero dollars") + .toString(); + } + long dollars = (long) money; + long cents = (long) (money * 100 - dollars * 100); + return addDollarsCentsWords(result, dollars, cents); + } + + private String addDollarsCentsWords(StringBuilder result, long dollars, long cents) { + long[] values = { dollars, cents }; + for (int i = 0; i < values.length; i++) { + if (values[i] != 0) { + if (result.length() != 0 && i == 1) { + result.append(" and "); + } + result.append(convert(values[i])); + if (i == 0) { + if (dollars == 1) { + result.append(" dollar"); + } else { + result.append(" dollars"); + } + } else { + if (cents == 1) { + result.append(" cent"); + } else { + result.append(" cents"); + } + } + } + } + return result.toString() + .trim(); + } + + private String convert(long number) { + // 0 to 999 999 999 999 + if (number == 0) { + return "zero"; + } + + String snumber = Long.toString(number); + + // pad with "0" + String mask = "000000000000"; + DecimalFormat df = new DecimalFormat(mask); + snumber = df.format(number); + + // XXXnnnnnnnnn + int billions = Integer.parseInt(snumber.substring(0, 3)); + // nnnXXXnnnnnn + int millions = Integer.parseInt(snumber.substring(3, 6)); + // nnnnnnXXXnnn + int hundredThousands = Integer.parseInt(snumber.substring(6, 9)); + // nnnnnnnnnXXX + int thousands = Integer.parseInt(snumber.substring(9, 12)); + + String tradBillions; + switch (billions) { + case 0: + tradBillions = ""; + break; + case 1: + tradBillions = convertLessThanOneThousand(billions) + " billion "; + break; + default: + tradBillions = convertLessThanOneThousand(billions) + " billion "; + } + String result = tradBillions; + + String tradMillions; + switch (millions) { + case 0: + tradMillions = ""; + break; + case 1: + tradMillions = convertLessThanOneThousand(millions) + " million "; + break; + default: + tradMillions = convertLessThanOneThousand(millions) + " million "; + } + result = result + tradMillions; + + String tradHundredThousands; + switch (hundredThousands) { + case 0: + tradHundredThousands = ""; + break; + case 1: + tradHundredThousands = "one thousand "; + break; + default: + tradHundredThousands = convertLessThanOneThousand(hundredThousands) + " thousand "; + } + result = result + tradHundredThousands; + + String tradThousand; + tradThousand = convertLessThanOneThousand(thousands); + result = result + tradThousand; + + // remove extra spaces + return result.replaceAll("^\\s+", "") + .replaceAll("\\b\\s{2,}\\b", " "); + } + + private String convertLessThanOneThousand(int number) { + String soFar; + + if (number % 100 < 20) { + soFar = ones[number % 100]; + number /= 100; + } else { + soFar = ones[number % 10]; + number /= 10; + + soFar = tens[number % 10] + soFar; + number /= 10; + } + if (number == 0) + return soFar; + return ones[number] + " hundred" + soFar; + } + +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWordsTest.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWordsTest.java new file mode 100644 index 000000000000..4fcf92546b35 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWordsTest.java @@ -0,0 +1,42 @@ +package com.baeldung.algorithms.moneywords; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class MoneyIntoWordsTest { + + private final MoneyIntoWords moneyIntoWords = new MoneyIntoWords(); + + @Test + public void whenMoneyNegative_thenReturnEmptyString() { + assertEquals((moneyIntoWords.getMoneyIntoWords(-13)), ""); + } + + @Test + public void whenZeroDollarsGiven_thenReturnZero() { + assertEquals((moneyIntoWords.getMoneyIntoWords(0)), "zero dollars"); + } + + @Test + public void whenOnlyDollarsGiven_thenReturnWords() { + assertEquals((moneyIntoWords.getMoneyIntoWords(1)), "one dollar"); + } + + @Test + public void whenOnlyCentsGiven_thenReturnWords() { + assertEquals((moneyIntoWords.getMoneyIntoWords(0.6)), "sixty cents"); + } + + @Test + public void whenGivenDollarsAndCents_thenReturnWords() { + String expectedResult = "nine hundred twenty four dollars and sixty cents"; + assertEquals((moneyIntoWords.getMoneyIntoWords(924.6)), expectedResult); + } + + @Test + public void whenGivenDollarsAndCents_thenReturnWordsVersionTwo() { + assertEquals((moneyIntoWords.getMoneyIntoWords("310")), "three hundred ten £ 00/100"); + } + +} From c0d53f1267b4a8b003997cb2fa952a10bedc5ce1 Mon Sep 17 00:00:00 2001 From: fatosmorina Date: Sun, 11 Feb 2018 16:05:32 +0100 Subject: [PATCH 03/11] Update the version of tradukisto library --- algorithms/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/algorithms/pom.xml b/algorithms/pom.xml index 65e199bbc85f..5c6d99ad88bb 100644 --- a/algorithms/pom.xml +++ b/algorithms/pom.xml @@ -40,9 +40,9 @@ 1.0.1 - pl.allegro.finance - tradukisto - 0.5.1 + pl.allegro.finance + tradukisto + 1.0.1 From 95799f6d6756be97137ddaf8e33ecd420bbc94c2 Mon Sep 17 00:00:00 2001 From: Fatos Morina Date: Tue, 20 Feb 2018 20:41:53 +0100 Subject: [PATCH 04/11] Refactor MoneyIntoWords --- .../algorithms/moneywords/MoneyIntoWords.java | 146 +++++++++++++++++ .../algorithms/moneywords/MoneyIntoWords.java | 148 ------------------ 2 files changed, 146 insertions(+), 148 deletions(-) create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java delete mode 100644 algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java diff --git a/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java b/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java new file mode 100644 index 000000000000..08a7bcbe6c24 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java @@ -0,0 +1,146 @@ +package com.baeldung.algorithms.moneywords; + +import java.math.BigDecimal; +import java.text.DecimalFormat; + +import pl.allegro.finance.tradukisto.MoneyConverters; + +public class MoneyIntoWords { + + private final String[] tens = { "", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" }; + + private final String[] ones = { "", " one", " two", " three", " four", " five", " six", " seven", " eight", " nine", " ten", " eleven", " twelve", " thirteen", " fourteen", " fifteen", " sixteen", " seventeen", " eighteen", " nineteen" }; + + public String getMoneyIntoWords(String input) { + MoneyConverters converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE; + return converter.asWords(new BigDecimal(input)); + } + + public String getMoneyIntoWords(double money) { + StringBuilder result = new StringBuilder(""); + if (money < 0) { + return result.toString(); + } + if (money == 0) { + return result.append("zero dollars") + .toString(); + } + long dollars = (long) money; + long cents = (long) (money * 100 - dollars * 100); + return addDollarsCentsWords(result, dollars, cents); + } + + private String addDollarsCentsWords(StringBuilder result, long dollars, long cents) { + long[] values = { dollars, cents }; + for (int i = 0; i < values.length; i++) { + if (values[i] != 0) { + if (result.length() != 0 && i == 1) { + result.append(" and "); + } + result.append(convert(values[i])); + if (i == 0) { + if (dollars == 1) { + result.append(" dollar"); + } else { + result.append(" dollars"); + } + } else { + if (cents == 1) { + result.append(" cent"); + } else { + result.append(" cents"); + } + } + } + } + return result.toString() + .trim(); + } + + private String convert(long number) { + // 0 to 999 999 999 999 + if (number == 0) { + return "zero"; + } + + String stringNumber = Long.toString(number); + + // Pad with "0" and avoid string exceptions if the number is smaller than a billion + String mask = "000000000000"; + DecimalFormat decimalFormat = new DecimalFormat(mask); + stringNumber = decimalFormat.format(number); + + // Get the number of billions from the format: XXXnnnnnnnnn + int billions = Integer.parseInt(stringNumber.substring(0, 3)); + + // Get the number of millions from the format: nnnXXXnnnnnn + int millions = Integer.parseInt(stringNumber.substring(3, 6)); + + // Get the number of hundred of thousands from the format: // nnnnnnXXXnnn + int hundredThousands = Integer.parseInt(stringNumber.substring(6, 9)); + + // Get the number of thousands from the format: // nnnnnnnnnXXX + int thousands = Integer.parseInt(stringNumber.substring(9, 12)); + + // We are adding billion term where needed + String formattedBillions = formatExpression(billions, "billion"); + + // We are adding million term where needed + String formattedMillions = formatExpression(millions, "million"); + + // We are adding thousand term where needed + String formattedHundredThousand = formatExpression(hundredThousands, "thousand"); + + String tradThousand = convertLessThanOneThousand(thousands); + + String result = formattedBillions + formattedMillions + formattedHundredThousand + tradThousand; + + return result.trim(); + } + + private String formatExpression(int number, String type) { + String expression; + switch (number) { + case 0: + expression = ""; + break; + case 1: + if (type == "thousand") { + expression = "one thousand "; + } else { + expression = convertLessThanOneThousand(number) + " " + type + " "; + } + break; + default: + expression = convertLessThanOneThousand(number) + " " + type + " "; + } + return expression; + } + + private String convertLessThanOneThousand(int number) { + String result; + // If the number given divided by 100 is greater than 20, then we need to + if (number % 100 >= 20) { + // get the number of ones as words + result = ones[number % 10]; + // remove the last digit + number /= 10; + // get the number of tens as words + result = tens[number % 10] + result; + // remove the last digit + number /= 10; + } else { + // get the number of ones as words + result = ones[number % 100]; + // remove the last two digits + number /= 100; + } + if (number == 0) { + // return the result if number given is zero + return result; + } + // return the number of hundreds + return ones[number] + " hundred" + result; + } + +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java deleted file mode 100644 index 76a191ec3bf4..000000000000 --- a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.baeldung.algorithms.moneywords; - -import java.math.BigDecimal; -import java.text.DecimalFormat; - -import pl.allegro.finance.tradukisto.MoneyConverters; - -public class MoneyIntoWords { - - private final String[] tens = { "", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" }; - - private final String[] ones = { "", " one", " two", " three", " four", " five", " six", " seven", " eight", " nine", " ten", " eleven", " twelve", " thirteen", " fourteen", " fifteen", " sixteen", " seventeen", " eighteen", " nineteen" }; - - public String getMoneyIntoWords(String input) { - MoneyConverters converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE; - return converter.asWords(new BigDecimal(input)); - } - - public String getMoneyIntoWords(double money) { - StringBuilder result = new StringBuilder(""); - if (money < 0) { - return result.toString(); - } - if (money == 0) { - return result.append("zero dollars") - .toString(); - } - long dollars = (long) money; - long cents = (long) (money * 100 - dollars * 100); - return addDollarsCentsWords(result, dollars, cents); - } - - private String addDollarsCentsWords(StringBuilder result, long dollars, long cents) { - long[] values = { dollars, cents }; - for (int i = 0; i < values.length; i++) { - if (values[i] != 0) { - if (result.length() != 0 && i == 1) { - result.append(" and "); - } - result.append(convert(values[i])); - if (i == 0) { - if (dollars == 1) { - result.append(" dollar"); - } else { - result.append(" dollars"); - } - } else { - if (cents == 1) { - result.append(" cent"); - } else { - result.append(" cents"); - } - } - } - } - return result.toString() - .trim(); - } - - private String convert(long number) { - // 0 to 999 999 999 999 - if (number == 0) { - return "zero"; - } - - String snumber = Long.toString(number); - - // pad with "0" - String mask = "000000000000"; - DecimalFormat df = new DecimalFormat(mask); - snumber = df.format(number); - - // XXXnnnnnnnnn - int billions = Integer.parseInt(snumber.substring(0, 3)); - // nnnXXXnnnnnn - int millions = Integer.parseInt(snumber.substring(3, 6)); - // nnnnnnXXXnnn - int hundredThousands = Integer.parseInt(snumber.substring(6, 9)); - // nnnnnnnnnXXX - int thousands = Integer.parseInt(snumber.substring(9, 12)); - - String tradBillions; - switch (billions) { - case 0: - tradBillions = ""; - break; - case 1: - tradBillions = convertLessThanOneThousand(billions) + " billion "; - break; - default: - tradBillions = convertLessThanOneThousand(billions) + " billion "; - } - String result = tradBillions; - - String tradMillions; - switch (millions) { - case 0: - tradMillions = ""; - break; - case 1: - tradMillions = convertLessThanOneThousand(millions) + " million "; - break; - default: - tradMillions = convertLessThanOneThousand(millions) + " million "; - } - result = result + tradMillions; - - String tradHundredThousands; - switch (hundredThousands) { - case 0: - tradHundredThousands = ""; - break; - case 1: - tradHundredThousands = "one thousand "; - break; - default: - tradHundredThousands = convertLessThanOneThousand(hundredThousands) + " thousand "; - } - result = result + tradHundredThousands; - - String tradThousand; - tradThousand = convertLessThanOneThousand(thousands); - result = result + tradThousand; - - // remove extra spaces - return result.replaceAll("^\\s+", "") - .replaceAll("\\b\\s{2,}\\b", " "); - } - - private String convertLessThanOneThousand(int number) { - String soFar; - - if (number % 100 < 20) { - soFar = ones[number % 100]; - number /= 100; - } else { - soFar = ones[number % 10]; - number /= 10; - - soFar = tens[number % 10] + soFar; - number /= 10; - } - if (number == 0) - return soFar; - return ones[number] + " hundred" + soFar; - } - -} From 0855c54bca3c5183c4df5b844868bf8049f5eb50 Mon Sep 17 00:00:00 2001 From: Fatos Morina Date: Wed, 28 Feb 2018 20:59:23 +0100 Subject: [PATCH 05/11] Refactor --- .../algorithms/moneywords/MoneyIntoWords.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java b/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java index 08a7bcbe6c24..402a534f9daf 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java @@ -73,22 +73,19 @@ private String convert(long number) { // Get the number of billions from the format: XXXnnnnnnnnn int billions = Integer.parseInt(stringNumber.substring(0, 3)); - // Get the number of millions from the format: nnnXXXnnnnnn + // nnnXXXnnnnnn int millions = Integer.parseInt(stringNumber.substring(3, 6)); - // Get the number of hundred of thousands from the format: // nnnnnnXXXnnn + // nnnnnnXXXnnn int hundredThousands = Integer.parseInt(stringNumber.substring(6, 9)); - // Get the number of thousands from the format: // nnnnnnnnnXXX + // nnnnnnnnnXXX int thousands = Integer.parseInt(stringNumber.substring(9, 12)); - // We are adding billion term where needed String formattedBillions = formatExpression(billions, "billion"); - // We are adding million term where needed String formattedMillions = formatExpression(millions, "million"); - // We are adding thousand term where needed String formattedHundredThousand = formatExpression(hundredThousands, "thousand"); String tradThousand = convertLessThanOneThousand(thousands); @@ -119,7 +116,6 @@ private String formatExpression(int number, String type) { private String convertLessThanOneThousand(int number) { String result; - // If the number given divided by 100 is greater than 20, then we need to if (number % 100 >= 20) { // get the number of ones as words result = ones[number % 10]; @@ -136,7 +132,6 @@ private String convertLessThanOneThousand(int number) { number /= 100; } if (number == 0) { - // return the result if number given is zero return result; } // return the number of hundreds From 81c85dffaba676dc54e6b510e1d29db4cd31538e Mon Sep 17 00:00:00 2001 From: Fatos Morina Date: Sun, 4 Mar 2018 06:54:18 +0100 Subject: [PATCH 06/11] Refactor pom.xml --- algorithms/pom.xml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/algorithms/pom.xml b/algorithms/pom.xml index 5c6d99ad88bb..6831a6a94712 100644 --- a/algorithms/pom.xml +++ b/algorithms/pom.xml @@ -16,7 +16,6 @@ parent-modules 1.0.0-SNAPSHOT - org.apache.commons @@ -43,9 +42,14 @@ pl.allegro.finance tradukisto 1.0.1 - + + + org.assertj + assertj-core + 3.9.0 + test + - @@ -76,4 +80,4 @@ - + \ No newline at end of file From 991610b2a48da0f130d2c6df3d2dc6d77b3b6e76 Mon Sep 17 00:00:00 2001 From: Fatos Morina Date: Sun, 4 Mar 2018 07:00:12 +0100 Subject: [PATCH 07/11] Refactor pom.xml --- algorithms/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/algorithms/pom.xml b/algorithms/pom.xml index 6831a6a94712..a18c9fdfd651 100644 --- a/algorithms/pom.xml +++ b/algorithms/pom.xml @@ -16,6 +16,7 @@ parent-modules 1.0.0-SNAPSHOT + org.apache.commons From bf79ad633acdea559460e6bb7dc1fd35978187e0 Mon Sep 17 00:00:00 2001 From: Fatos Morina Date: Sun, 4 Mar 2018 10:36:55 +0100 Subject: [PATCH 08/11] Refactor NumberWordConverter --- ...IntoWords.java => MoneyWordConverter.java} | 7 +- .../NumberWordConverter.java | 78 +++++++++++++++++++ .../moneywords/MoneyIntoWordsTest.java | 42 ---------- .../moneywords/NumberWordConverterTest.java | 41 ++++++++++ 4 files changed, 123 insertions(+), 45 deletions(-) rename algorithms/src/main/java/com/baeldung/algorithms/moneywords/{MoneyIntoWords.java => MoneyWordConverter.java} (98%) create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java delete mode 100644 algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWordsTest.java create mode 100644 algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java diff --git a/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java b/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyWordConverter.java similarity index 98% rename from algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java rename to algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyWordConverter.java index 402a534f9daf..76f3acb4475b 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyIntoWords.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyWordConverter.java @@ -1,3 +1,4 @@ + package com.baeldung.algorithms.moneywords; import java.math.BigDecimal; @@ -5,7 +6,7 @@ import pl.allegro.finance.tradukisto.MoneyConverters; -public class MoneyIntoWords { +public class MoneyWordConverter { private final String[] tens = { "", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" }; @@ -79,7 +80,7 @@ private String convert(long number) { // nnnnnnXXXnnn int hundredThousands = Integer.parseInt(stringNumber.substring(6, 9)); - // nnnnnnnnnXXX + // nnnnnnnnnXXX int thousands = Integer.parseInt(stringNumber.substring(9, 12)); String formattedBillions = formatExpression(billions, "billion"); @@ -138,4 +139,4 @@ private String convertLessThanOneThousand(int number) { return ones[number] + " hundred" + result; } -} +} \ No newline at end of file diff --git a/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java b/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java new file mode 100644 index 000000000000..143fa054e6c7 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java @@ -0,0 +1,78 @@ +package com.baeldung.algorithms.numberwordconverter; + +import java.math.BigDecimal; + +import pl.allegro.finance.tradukisto.MoneyConverters; + +public class NumberWordConverter { + + public static final String INVALID_INPUT_GIVEN = "Invalid input given"; + + public static final String[] ones = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" }; + + public static final String[] tens = { "", // 0 + "", // 1 + "twenty", // 2 + "thirty", // 3 + "forty", // 4 + "fifty", // 5 + "sixty", // 6 + "seventy", // 7 + "eighty", // 8 + "ninety" // 9 + }; + + public static String getMoneyIntoWords(String input) { + MoneyConverters converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE; + return converter.asWords(new BigDecimal(input)); + } + + public static String getMoneyIntoWords(final double money) { + long dollar = (long) money; + long cents = Math.round((money - dollar) * 100); + String dollarPart = formatOutput(convert(dollar), dollar, "dollar"); + String centsPart = ""; + if (cents > 0) { + if (dollarPart.length() > 0) { + centsPart = " and "; + } + centsPart += formatOutput(convert(cents), cents, "cent"); + } + return dollarPart + centsPart; + } + + private static String convert(final long n) { + if (n < 0) { + return INVALID_INPUT_GIVEN; + } + if (n < 20) { + return ones[(int) n]; + } + if (n < 100) { + return tens[(int) n / 10] + ((n % 10 != 0) ? " " : "") + ones[(int) n % 10]; + } + if (n < 1000) { + return ones[(int) n / 100] + " hundred" + ((n % 100 != 0) ? " " : "") + convert(n % 100); + } + if (n < 1_000_000) { + return convert(n / 1000) + " thousand" + ((n % 1000 != 0) ? " " : "") + convert(n % 1000); + } + if (n < 1_000_000_000) { + return convert(n / 1_000_000) + " million" + ((n % 1_000_000 != 0) ? " " : "") + convert(n % 1_000_000); + } + return convert(n / 1_000_000_000) + " billion" + ((n % 1_000_000_000 != 0) ? " " : "") + convert(n % 1_000_000_000); + } + + private static String formatOutput(String input, long number, String type) { + if (input.equals(INVALID_INPUT_GIVEN)) { + return INVALID_INPUT_GIVEN; + } else if (input.length() > 0) { + if (number == 1) { + return input + " " + type; + } else { + return input + " " + type + "s"; + } + } + return ""; + } +} \ No newline at end of file diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWordsTest.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWordsTest.java deleted file mode 100644 index 4fcf92546b35..000000000000 --- a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/MoneyIntoWordsTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.baeldung.algorithms.moneywords; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class MoneyIntoWordsTest { - - private final MoneyIntoWords moneyIntoWords = new MoneyIntoWords(); - - @Test - public void whenMoneyNegative_thenReturnEmptyString() { - assertEquals((moneyIntoWords.getMoneyIntoWords(-13)), ""); - } - - @Test - public void whenZeroDollarsGiven_thenReturnZero() { - assertEquals((moneyIntoWords.getMoneyIntoWords(0)), "zero dollars"); - } - - @Test - public void whenOnlyDollarsGiven_thenReturnWords() { - assertEquals((moneyIntoWords.getMoneyIntoWords(1)), "one dollar"); - } - - @Test - public void whenOnlyCentsGiven_thenReturnWords() { - assertEquals((moneyIntoWords.getMoneyIntoWords(0.6)), "sixty cents"); - } - - @Test - public void whenGivenDollarsAndCents_thenReturnWords() { - String expectedResult = "nine hundred twenty four dollars and sixty cents"; - assertEquals((moneyIntoWords.getMoneyIntoWords(924.6)), expectedResult); - } - - @Test - public void whenGivenDollarsAndCents_thenReturnWordsVersionTwo() { - assertEquals((moneyIntoWords.getMoneyIntoWords("310")), "three hundred ten £ 00/100"); - } - -} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java new file mode 100644 index 000000000000..3ac63b492b14 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java @@ -0,0 +1,41 @@ +package com.baeldung.algorithms.moneywords; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.baeldung.algorithms.numberwordconverter.NumberWordConverter; + +public class NumberWordConverterTest { + + @Test + public void whenMoneyNegative_thenReturnInvalidInput() { + assertEquals((NumberWordConverter.getMoneyIntoWords(-13)), NumberWordConverter.INVALID_INPUT_GIVEN); + } + + @Test + public void whenZeroDollarsGiven_thenReturnEmptyString() { + assertEquals((NumberWordConverter.getMoneyIntoWords(0)), ""); + } + + @Test + public void whenOnlyDollarsGiven_thenReturnWords() { + assertEquals((NumberWordConverter.getMoneyIntoWords(1)), "one dollar"); + } + + @Test + public void whenOnlyCentsGiven_thenReturnWords() { + assertEquals((NumberWordConverter.getMoneyIntoWords(0.6)), "sixty cents"); + } + + @Test + public void whenGivenDollarsAndCents_thenReturnWords() { + String expectedResult = "nine hundred twenty four dollars and sixty cents"; + assertEquals((NumberWordConverter.getMoneyIntoWords(924.6)), expectedResult); + } + + @Test + public void whenGivenDollarsAndCents_thenReturnWordsVersionTwo() { + assertEquals((NumberWordConverter.getMoneyIntoWords("310")), "three hundred ten £ 00/100"); + } +} From b7b6d7efcfff106ac8f2b224dcd906793d3c4607 Mon Sep 17 00:00:00 2001 From: Predrag Maric Date: Mon, 5 Mar 2018 01:48:22 +0100 Subject: [PATCH 09/11] BAEL-1498 Small refactoring --- algorithms/pom.xml | 9 +- .../moneywords/MoneyWordConverter.java | 142 ------------------ .../NumberWordConverter.java | 47 +++--- .../moneywords/NumberWordConverterTest.java | 12 +- 4 files changed, 33 insertions(+), 177 deletions(-) delete mode 100644 algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyWordConverter.java diff --git a/algorithms/pom.xml b/algorithms/pom.xml index a18c9fdfd651..8751cf45c004 100644 --- a/algorithms/pom.xml +++ b/algorithms/pom.xml @@ -9,6 +9,7 @@ 1.5.0 1.16.12 3.6.1 + 1.0.1 @@ -40,10 +41,10 @@ 1.0.1 - pl.allegro.finance - tradukisto - 1.0.1 - + pl.allegro.finance + tradukisto + ${tradukisto.version} + org.assertj assertj-core diff --git a/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyWordConverter.java b/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyWordConverter.java deleted file mode 100644 index 76f3acb4475b..000000000000 --- a/algorithms/src/main/java/com/baeldung/algorithms/moneywords/MoneyWordConverter.java +++ /dev/null @@ -1,142 +0,0 @@ - -package com.baeldung.algorithms.moneywords; - -import java.math.BigDecimal; -import java.text.DecimalFormat; - -import pl.allegro.finance.tradukisto.MoneyConverters; - -public class MoneyWordConverter { - - private final String[] tens = { "", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" }; - - private final String[] ones = { "", " one", " two", " three", " four", " five", " six", " seven", " eight", " nine", " ten", " eleven", " twelve", " thirteen", " fourteen", " fifteen", " sixteen", " seventeen", " eighteen", " nineteen" }; - - public String getMoneyIntoWords(String input) { - MoneyConverters converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE; - return converter.asWords(new BigDecimal(input)); - } - - public String getMoneyIntoWords(double money) { - StringBuilder result = new StringBuilder(""); - if (money < 0) { - return result.toString(); - } - if (money == 0) { - return result.append("zero dollars") - .toString(); - } - long dollars = (long) money; - long cents = (long) (money * 100 - dollars * 100); - return addDollarsCentsWords(result, dollars, cents); - } - - private String addDollarsCentsWords(StringBuilder result, long dollars, long cents) { - long[] values = { dollars, cents }; - for (int i = 0; i < values.length; i++) { - if (values[i] != 0) { - if (result.length() != 0 && i == 1) { - result.append(" and "); - } - result.append(convert(values[i])); - if (i == 0) { - if (dollars == 1) { - result.append(" dollar"); - } else { - result.append(" dollars"); - } - } else { - if (cents == 1) { - result.append(" cent"); - } else { - result.append(" cents"); - } - } - } - } - return result.toString() - .trim(); - } - - private String convert(long number) { - // 0 to 999 999 999 999 - if (number == 0) { - return "zero"; - } - - String stringNumber = Long.toString(number); - - // Pad with "0" and avoid string exceptions if the number is smaller than a billion - String mask = "000000000000"; - DecimalFormat decimalFormat = new DecimalFormat(mask); - stringNumber = decimalFormat.format(number); - - // Get the number of billions from the format: XXXnnnnnnnnn - int billions = Integer.parseInt(stringNumber.substring(0, 3)); - - // nnnXXXnnnnnn - int millions = Integer.parseInt(stringNumber.substring(3, 6)); - - // nnnnnnXXXnnn - int hundredThousands = Integer.parseInt(stringNumber.substring(6, 9)); - - // nnnnnnnnnXXX - int thousands = Integer.parseInt(stringNumber.substring(9, 12)); - - String formattedBillions = formatExpression(billions, "billion"); - - String formattedMillions = formatExpression(millions, "million"); - - String formattedHundredThousand = formatExpression(hundredThousands, "thousand"); - - String tradThousand = convertLessThanOneThousand(thousands); - - String result = formattedBillions + formattedMillions + formattedHundredThousand + tradThousand; - - return result.trim(); - } - - private String formatExpression(int number, String type) { - String expression; - switch (number) { - case 0: - expression = ""; - break; - case 1: - if (type == "thousand") { - expression = "one thousand "; - } else { - expression = convertLessThanOneThousand(number) + " " + type + " "; - } - break; - default: - expression = convertLessThanOneThousand(number) + " " + type + " "; - } - return expression; - } - - private String convertLessThanOneThousand(int number) { - String result; - if (number % 100 >= 20) { - // get the number of ones as words - result = ones[number % 10]; - // remove the last digit - number /= 10; - // get the number of tens as words - result = tens[number % 10] + result; - // remove the last digit - number /= 10; - } else { - // get the number of ones as words - result = ones[number % 100]; - // remove the last two digits - number /= 100; - } - if (number == 0) { - return result; - } - // return the number of hundreds - return ones[number] + " hundred" + result; - } - -} \ No newline at end of file diff --git a/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java b/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java index 143fa054e6c7..0fe2960f968f 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java @@ -10,16 +10,17 @@ public class NumberWordConverter { public static final String[] ones = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" }; - public static final String[] tens = { "", // 0 - "", // 1 - "twenty", // 2 - "thirty", // 3 - "forty", // 4 - "fifty", // 5 - "sixty", // 6 - "seventy", // 7 - "eighty", // 8 - "ninety" // 9 + public static final String[] tens = { + "", // 0 + "", // 1 + "twenty", // 2 + "thirty", // 3 + "forty", // 4 + "fifty", // 5 + "sixty", // 6 + "seventy", // 7 + "eighty", // 8 + "ninety" // 9 }; public static String getMoneyIntoWords(String input) { @@ -30,13 +31,22 @@ public static String getMoneyIntoWords(String input) { public static String getMoneyIntoWords(final double money) { long dollar = (long) money; long cents = Math.round((money - dollar) * 100); - String dollarPart = formatOutput(convert(dollar), dollar, "dollar"); + if (money == 0D) { + return ""; + } + if (money < 0) { + return INVALID_INPUT_GIVEN; + } + String dollarPart = ""; + if (dollar > 0) { + dollarPart = convert(dollar) + " dollar" + (dollar == 1 ? "" : "s"); + } String centsPart = ""; if (cents > 0) { if (dollarPart.length() > 0) { centsPart = " and "; } - centsPart += formatOutput(convert(cents), cents, "cent"); + centsPart += convert(cents) + " cent" + (cents == 1 ? "" : "s"); } return dollarPart + centsPart; } @@ -62,17 +72,4 @@ private static String convert(final long n) { } return convert(n / 1_000_000_000) + " billion" + ((n % 1_000_000_000 != 0) ? " " : "") + convert(n % 1_000_000_000); } - - private static String formatOutput(String input, long number, String type) { - if (input.equals(INVALID_INPUT_GIVEN)) { - return INVALID_INPUT_GIVEN; - } else if (input.length() > 0) { - if (number == 1) { - return input + " " + type; - } else { - return input + " " + type + "s"; - } - } - return ""; - } } \ No newline at end of file diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java index 3ac63b492b14..51b88ae02632 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java @@ -10,32 +10,32 @@ public class NumberWordConverterTest { @Test public void whenMoneyNegative_thenReturnInvalidInput() { - assertEquals((NumberWordConverter.getMoneyIntoWords(-13)), NumberWordConverter.INVALID_INPUT_GIVEN); + assertEquals(NumberWordConverter.INVALID_INPUT_GIVEN, NumberWordConverter.getMoneyIntoWords(-13)); } @Test public void whenZeroDollarsGiven_thenReturnEmptyString() { - assertEquals((NumberWordConverter.getMoneyIntoWords(0)), ""); + assertEquals("", NumberWordConverter.getMoneyIntoWords(0)); } @Test public void whenOnlyDollarsGiven_thenReturnWords() { - assertEquals((NumberWordConverter.getMoneyIntoWords(1)), "one dollar"); + assertEquals("one dollar", NumberWordConverter.getMoneyIntoWords(1)); } @Test public void whenOnlyCentsGiven_thenReturnWords() { - assertEquals((NumberWordConverter.getMoneyIntoWords(0.6)), "sixty cents"); + assertEquals("sixty cents", NumberWordConverter.getMoneyIntoWords(0.6)); } @Test public void whenGivenDollarsAndCents_thenReturnWords() { String expectedResult = "nine hundred twenty four dollars and sixty cents"; - assertEquals((NumberWordConverter.getMoneyIntoWords(924.6)), expectedResult); + assertEquals(expectedResult, NumberWordConverter.getMoneyIntoWords(924.6)); } @Test public void whenGivenDollarsAndCents_thenReturnWordsVersionTwo() { - assertEquals((NumberWordConverter.getMoneyIntoWords("310")), "three hundred ten £ 00/100"); + assertEquals("three hundred ten £ 00/100", NumberWordConverter.getMoneyIntoWords("310")); } } From 67e7681fd53b32e71688fb23181754d6da037e03 Mon Sep 17 00:00:00 2001 From: Fatos Morina Date: Fri, 9 Mar 2018 08:46:20 +0100 Subject: [PATCH 10/11] Test edge cases --- .../moneywords/NumberWordConverterTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java index 51b88ae02632..1908a5109e8e 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java @@ -27,6 +27,24 @@ public void whenOnlyDollarsGiven_thenReturnWords() { public void whenOnlyCentsGiven_thenReturnWords() { assertEquals("sixty cents", NumberWordConverter.getMoneyIntoWords(0.6)); } + + @Test + public void whenAlmostAMillioDollarsGiven_thenReturnWords() { + String expectedResult = "nine hundred ninety nine thousand nine hundred ninety nine dollars"; + assertEquals(expectedResult, NumberWordConverter.getMoneyIntoWords(999_999)); + } + + @Test + public void whenThirtyMillionDollarsGiven_thenReturnWords() { + String expectedResult = "thirty three million three hundred forty eight thousand nine hundred seventy eight dollars"; + assertEquals(expectedResult, NumberWordConverter.getMoneyIntoWords(33_348_978)); + } + + @Test + public void whenTwoBillionDollarsGiven_thenReturnWords() { + String expectedResult = "two billion one hundred thirty three million two hundred forty seven thousand eight hundred ten dollars"; + assertEquals(expectedResult, NumberWordConverter.getMoneyIntoWords(2_133_247_810)); + } @Test public void whenGivenDollarsAndCents_thenReturnWords() { From c653a5e4c1d3584cc827b5768d168ed7cdf8ad66 Mon Sep 17 00:00:00 2001 From: Predrag Maric Date: Sat, 10 Mar 2018 10:31:28 +0100 Subject: [PATCH 11/11] BAEL-1498 Additional tests --- .../moneywords/NumberWordConverterTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java index 1908a5109e8e..a4a169f1584c 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java @@ -52,6 +52,31 @@ public void whenGivenDollarsAndCents_thenReturnWords() { assertEquals(expectedResult, NumberWordConverter.getMoneyIntoWords(924.6)); } + @Test + public void whenOneDollarAndNoCents_thenReturnDollarSingular() { + assertEquals("one dollar", NumberWordConverter.getMoneyIntoWords(1)); + } + + @Test + public void whenNoDollarsAndOneCent_thenReturnCentSingular() { + assertEquals("one cent", NumberWordConverter.getMoneyIntoWords(0.01)); + } + + @Test + public void whenNoDollarsAndTwoCents_thenReturnCentsPlural() { + assertEquals("two cents", NumberWordConverter.getMoneyIntoWords(0.02)); + } + + @Test + public void whenNoDollarsAndNinetyNineCents_thenReturnWords() { + assertEquals("ninety nine cents", NumberWordConverter.getMoneyIntoWords(0.99)); + } + + @Test + public void whenNoDollarsAndNineFiveNineCents_thenCorrectRounding() { + assertEquals("ninety six cents", NumberWordConverter.getMoneyIntoWords(0.959)); + } + @Test public void whenGivenDollarsAndCents_thenReturnWordsVersionTwo() { assertEquals("three hundred ten £ 00/100", NumberWordConverter.getMoneyIntoWords("310"));