From d834a55d1adaf83c0d82647ed164bac536a9c83e Mon Sep 17 00:00:00 2001 From: girdharsourabh Date: Mon, 28 Aug 2023 17:21:04 +0530 Subject: [PATCH 1/2] Added hindi support --- .../tradukisto/LongValueConverters.java | 4 +- .../finance/tradukisto/MoneyConverters.java | 5 +- .../finance/tradukisto/ValueConverters.java | 23 +-- .../tradukisto/internal/Container.java | 19 ++ .../converters/HundredsToWordsConverter.java | 1 + ...indiBigDecimalToBankingMoneyConverter.java | 68 ++++++++ .../languages/hindi/HindiPluralForms.java | 23 +++ .../internal/languages/hindi/HindiValues.java | 164 ++++++++++++++++++ .../hindi/IndianNumberToWordsConverter.java | 35 ++++ .../support/IndianNumberChunking.java | 31 ++++ .../internal/support/NumberChunking.java | 2 +- .../tradukisto/LongValueConvertersTest.groovy | 11 +- .../tradukisto/MoneyConvertersTest.groovy | 2 + .../tradukisto/ValueConvertersTest.groovy | 4 + .../support/IndianNumberChunkingTest.groovy | 24 +++ 15 files changed, 383 insertions(+), 33 deletions(-) create mode 100644 src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiBigDecimalToBankingMoneyConverter.java create mode 100644 src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiPluralForms.java create mode 100644 src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValues.java create mode 100644 src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/IndianNumberToWordsConverter.java create mode 100644 src/main/java/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunking.java create mode 100644 src/test/groovy/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunkingTest.groovy diff --git a/src/main/java/pl/allegro/finance/tradukisto/LongValueConverters.java b/src/main/java/pl/allegro/finance/tradukisto/LongValueConverters.java index aafbcedb..45f6faff 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/LongValueConverters.java +++ b/src/main/java/pl/allegro/finance/tradukisto/LongValueConverters.java @@ -6,12 +6,14 @@ import static pl.allegro.finance.tradukisto.internal.Container.croatianContainer; import static pl.allegro.finance.tradukisto.internal.Container.englishContainer; import static pl.allegro.finance.tradukisto.internal.Container.polishContainer; +import static pl.allegro.finance.tradukisto.internal.Container.hindiContainer; public enum LongValueConverters { CROATIAN_LONG(croatianContainer().getLongConverter()), ENGLISH_LONG(englishContainer().getLongConverter()), - POLISH_LONG(polishContainer().getLongConverter()); + POLISH_LONG(polishContainer().getLongConverter()), + HINDI_LONG(hindiContainer().getLongConverter()); private final LongToStringConverter converter; diff --git a/src/main/java/pl/allegro/finance/tradukisto/MoneyConverters.java b/src/main/java/pl/allegro/finance/tradukisto/MoneyConverters.java index ad426d65..d2f5ef15 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/MoneyConverters.java +++ b/src/main/java/pl/allegro/finance/tradukisto/MoneyConverters.java @@ -1,6 +1,7 @@ package pl.allegro.finance.tradukisto; import pl.allegro.finance.tradukisto.internal.BigDecimalToStringConverter; +import pl.allegro.finance.tradukisto.internal.Container; import java.math.BigDecimal; import java.util.Objects; @@ -24,7 +25,6 @@ import static pl.allegro.finance.tradukisto.internal.Container.ukrainianContainer; import static pl.allegro.finance.tradukisto.internal.Container.bulgarianContainer; import static pl.allegro.finance.tradukisto.internal.Container.dutchContainer; - public enum MoneyConverters { BRAZILIAN_PORTUGUESE_BANKING_MONEY_VALUE(brazilianPortugueseContainer().getBankingMoneyConverter()), @@ -45,7 +45,8 @@ public enum MoneyConverters { SERBIAN_CYRILLIC_BANKING_MONEY_VALUE(serbianCyrillicContainer().getBankingMoneyConverter()), FRENCH_BANKING_MONEY_VALUE(frenchContainer().getBankingMoneyConverter()), BULGARIAN_BANKING_MONEY_VALUE(bulgarianContainer().getBankingMoneyConverter()), - DUTCH_BANKING_MONEY_VALUE(dutchContainer().getBankingMoneyConverter()); + DUTCH_BANKING_MONEY_VALUE(dutchContainer().getBankingMoneyConverter()), + HINDI_BANKING_MONEY_VALUE(Container.hindiContainer().getBankingMoneyConverter()); private final BigDecimalToStringConverter converter; diff --git a/src/main/java/pl/allegro/finance/tradukisto/ValueConverters.java b/src/main/java/pl/allegro/finance/tradukisto/ValueConverters.java index 2ba6e94c..c601aa0b 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/ValueConverters.java +++ b/src/main/java/pl/allegro/finance/tradukisto/ValueConverters.java @@ -9,25 +9,7 @@ import java.util.Locale; import java.util.Objects; -import static pl.allegro.finance.tradukisto.internal.Container.brazilianPortugueseContainer; -import static pl.allegro.finance.tradukisto.internal.Container.bulgarianContainer; -import static pl.allegro.finance.tradukisto.internal.Container.croatianContainer; -import static pl.allegro.finance.tradukisto.internal.Container.czechContainer; -import static pl.allegro.finance.tradukisto.internal.Container.englishContainer; -import static pl.allegro.finance.tradukisto.internal.Container.frenchContainer; -import static pl.allegro.finance.tradukisto.internal.Container.germanContainer; -import static pl.allegro.finance.tradukisto.internal.Container.italianContainer; -import static pl.allegro.finance.tradukisto.internal.Container.kazakhContainer; -import static pl.allegro.finance.tradukisto.internal.Container.latvianContainer; -import static pl.allegro.finance.tradukisto.internal.Container.polishContainer; -import static pl.allegro.finance.tradukisto.internal.Container.russianContainer; -import static pl.allegro.finance.tradukisto.internal.Container.serbianContainer; -import static pl.allegro.finance.tradukisto.internal.Container.serbianCyrillicContainer; -import static pl.allegro.finance.tradukisto.internal.Container.slovakContainer; -import static pl.allegro.finance.tradukisto.internal.Container.turkishContainer; -import static pl.allegro.finance.tradukisto.internal.Container.ukrainianContainer; -import static pl.allegro.finance.tradukisto.internal.Container.bulgarianContainer; -import static pl.allegro.finance.tradukisto.internal.Container.dutchContainer; +import static pl.allegro.finance.tradukisto.internal.Container.*; public enum ValueConverters { @@ -48,7 +30,8 @@ public enum ValueConverters { BULGARIAN_INTEGER(bulgarianContainer().getIntegerConverter(), "bg"), FRENCH_INTEGER(frenchContainer().getIntegerConverter(), "fr"), TURKISH_INTEGER(turkishContainer().getIntegerConverter(), "tr"), - DUTCH_INTEGER(dutchContainer().getIntegerConverter(), "nl"); + DUTCH_INTEGER(dutchContainer().getIntegerConverter(), "nl"), + HINDI_INTEGER(hindiContainer().getIntegerConverter(), "hi"); private final IntegerToStringConverter converter; private final List languageCodes; diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java b/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java index f4b44f41..805d6390 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java @@ -19,6 +19,9 @@ import pl.allegro.finance.tradukisto.internal.languages.german.GermanIntegerToWordsConverter; import pl.allegro.finance.tradukisto.internal.languages.german.GermanThousandToWordsConverter; import pl.allegro.finance.tradukisto.internal.languages.german.GermanValues; +import pl.allegro.finance.tradukisto.internal.languages.hindi.HindiBigDecimalToBankingMoneyConverter; +import pl.allegro.finance.tradukisto.internal.languages.hindi.HindiValues; +import pl.allegro.finance.tradukisto.internal.languages.hindi.IndianNumberToWordsConverter; import pl.allegro.finance.tradukisto.internal.languages.italian.ItalianIntegerToWordsConverter; import pl.allegro.finance.tradukisto.internal.languages.italian.ItalianThousandToWordsConverter; import pl.allegro.finance.tradukisto.internal.languages.italian.ItalianValues; @@ -226,6 +229,22 @@ public static Container kazakhContainer() { return new Container(kazakhValues); } + public static Container hindiContainer(){ + HindiValues hindiValues = new HindiValues(); + + HundredsToWordsConverter hundredsToStringConverter = new HundredsToWordsConverter(hindiValues.baseNumbers(), + hindiValues.twoDigitsNumberSeparator()); + + IntegerToStringConverter integerToStringConverter = new IndianNumberToWordsConverter(hundredsToStringConverter, hindiValues.pluralForms()); + + BigDecimalToStringConverter bigDecimalConverter = new HindiBigDecimalToBankingMoneyConverter( + integerToStringConverter, + hindiValues); + LongToStringConverter longValueConverters = new IndianNumberToWordsConverter(hundredsToStringConverter,hindiValues.pluralForms()); + + return new Container(integerToStringConverter, longValueConverters, bigDecimalConverter); + } + private final IntegerToStringConverter integerConverter; private final LongToStringConverter longConverter; private final BigDecimalToStringConverter bigDecimalConverter; diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/converters/HundredsToWordsConverter.java b/src/main/java/pl/allegro/finance/tradukisto/internal/converters/HundredsToWordsConverter.java index e245495a..cc84b57f 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/converters/HundredsToWordsConverter.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/converters/HundredsToWordsConverter.java @@ -44,5 +44,6 @@ private String threeDigitsNumberAsString(Integer value, GenderType genderType) { Integer tensWithUnits = value % 100; Integer hundreds = value - tensWithUnits; return format("%s %s", asWords(hundreds, genderType), asWords(tensWithUnits, genderType)); + } } diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiBigDecimalToBankingMoneyConverter.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiBigDecimalToBankingMoneyConverter.java new file mode 100644 index 00000000..41549cc4 --- /dev/null +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiBigDecimalToBankingMoneyConverter.java @@ -0,0 +1,68 @@ +package pl.allegro.finance.tradukisto.internal.languages.hindi; + +import pl.allegro.finance.tradukisto.internal.BigDecimalToStringConverter; +import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter; +import pl.allegro.finance.tradukisto.internal.support.Assert; + +import java.math.BigDecimal; + +import static java.lang.String.format; + +/** + * @author Dilaver Demirel + */ +public class HindiBigDecimalToBankingMoneyConverter implements BigDecimalToStringConverter { + private static final String SUBUNIT_SEPARATOR = ","; + private static final String FORMAT = "%s %s%s %s"; + private static final int MAXIMAL_DECIMAL_PLACES_COUNT = 2; + + private final IntegerToStringConverter converter; + private final HindiValues hindiValues; + + public HindiBigDecimalToBankingMoneyConverter(IntegerToStringConverter converter, HindiValues hindiValues) { + this.converter = converter; + this.hindiValues = hindiValues; + } + + @Override + public String asWords(BigDecimal value) { + return asWords(value, hindiValues.currency()); + } + + @Override + public String asWords(BigDecimal value, String currencySymbol) { + validate(value); + + Integer units = value.intValue(); + int subunits = value.remainder(BigDecimal.ONE).multiply(new BigDecimal(100)).intValue(); + + String tempSubunitSymbol = hindiValues.paiseSymbol(); + String tempSubUnitWords = SUBUNIT_SEPARATOR + converter.asWords(subunits); + if (subunits <= 0) { + tempSubunitSymbol = ""; + tempSubUnitWords = ""; + } + + String formattedValue = format(FORMAT, converter.asWords(units), currencySymbol, tempSubUnitWords, tempSubunitSymbol); + return formattedValue.replace(Character.toString(hindiValues.twoDigitsNumberSeparator()), ""); + } + + private void validate(BigDecimal value) { + Assert.isTrue(value.scale() <= MAXIMAL_DECIMAL_PLACES_COUNT, + () -> String.format("can't transform more than %s decimal places for value %s", MAXIMAL_DECIMAL_PLACES_COUNT, value)); + + Assert.isTrue(valueLessThanIntMax(value), + () -> String.format("can't transform numbers greater than Integer.MAX_VALUE for value %s", value)); + + Assert.isTrue(valueGreaterThanOrEqualToZero(value), + () -> String.format("can't transform negative numbers for value %s", value)); + } + + private boolean valueLessThanIntMax(BigDecimal value) { + return value.compareTo(new BigDecimal(Integer.MAX_VALUE).add(BigDecimal.ONE)) < 0; + } + + private boolean valueGreaterThanOrEqualToZero(BigDecimal value) { + return value.signum() >= 0; + } +} diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiPluralForms.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiPluralForms.java new file mode 100644 index 00000000..bdfc2519 --- /dev/null +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiPluralForms.java @@ -0,0 +1,23 @@ +package pl.allegro.finance.tradukisto.internal.languages.hindi; + +import pl.allegro.finance.tradukisto.internal.languages.GenderType; +import pl.allegro.finance.tradukisto.internal.languages.PluralForms; + +public class HindiPluralForms implements PluralForms { + + private final String form; + + public HindiPluralForms(String form) { + this.form = form; + } + + @Override + public String formFor(Integer value) { + return form; + } + + @Override + public GenderType genderType() { + return GenderType.NON_APPLICABLE; + } +} diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValues.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValues.java new file mode 100644 index 00000000..0d821d5c --- /dev/null +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValues.java @@ -0,0 +1,164 @@ +package pl.allegro.finance.tradukisto.internal.languages.hindi; + +import pl.allegro.finance.tradukisto.internal.BaseValues; +import pl.allegro.finance.tradukisto.internal.languages.GenderForms; +import pl.allegro.finance.tradukisto.internal.languages.PluralForms; +import pl.allegro.finance.tradukisto.internal.languages.english.EnglishPluralForms; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static pl.allegro.finance.tradukisto.internal.support.BaseNumbersBuilder.baseNumbersBuilder; + +public class HindiValues implements BaseValues { + @Override + public Map baseNumbers() { + return baseNumbersBuilder() + .put(0, "शून्य") + .put(1, "एक") + .put(2, "दो") + .put(3, "तीन") + .put(4, "चार") + .put(5, "पाँच") + .put(6, "छ:") + .put(7, "सात") + .put(8, "आठ") + .put(9, "नौ") + .put(10, "दस") + .put(11, "ग्यारह") + .put(12, "बारह") + .put(13, "तेरह") + .put(14, "चौदह") + .put(15, "पंद्रह") + .put(16, "सोलह") + .put(17, "सत्रह") + .put(18, "आट्ठारह") + .put(19, "उन्निस") + .put(20, "बीस") + .put(21,"इक्कीस") + .put(22,"बाईस") + .put(23,"तेईस") + .put(24,"चौबीस") + .put(25,"पच्चीस") + .put(26,"छब्बीस") + .put(27,"सत्ताईस") + .put(28,"अट्ठाईस") + .put(29,"उनतीस") + .put(30,"तीस") + + .put(31,"इकत्तीस") + .put(32,"बत्तीस") + .put(33,"तेंतीस") + .put(34,"चौंतीस") + .put(35,"पैंतीस") + .put(36,"छत्तीस") + .put(37,"सैंतीस") + .put(38,"अड़तीस") + .put(39,"उनतालीस") + .put(40,"चालीस") + + .put(41,"एकतालीस") + .put(42,"बायलीस") + .put(43,"तैंतालीस") + .put(44,"चौवालीस") + .put(45,"पैंतालिस") + .put(46,"छियालीस") + .put(47,"सैंतालीस") + .put(48,"अड़तालीस") + .put(49,"उनचास") + .put(50,"पचास") + + .put(51,"इक्यबन") + .put(52,"बावन") + .put(53,"तिरपन") + .put(54,"चौवन") + .put(55,"पचपन") + .put(56,"छप्पन") + .put(57,"सत्तावन") + .put(58,"अट्ठावन") + .put(59,"उनसठ") + .put(60,"साठ") + .put(61,"इकसठ") + .put(62,"बासठ") + .put(63,"तिरसठ") + .put(64,"चौंसठ") + .put(65,"पैंसठ") + .put(66,"छियासठ") + .put(67,"सड़सठ") + .put(68,"सड़सठ") + .put(69,"उनहत्तर") + .put(70,"सत्तर") + + .put(71,"इकहत्तर") + .put(72,"बहत्तर") + .put(73,"तिहत्तर") + .put(74,"चौहत्तर") + .put(75,"पचहत्तर") + .put(76,"छीहत्तर") + .put(77,"सतहत्तर") + .put(78,"अठहत्तर") + .put(79,"उनासी") + .put(80,"असी") + .put(81,"इक्यासी") + .put(82,"बयासी") + .put(83,"तिरासी") + .put(84,"चौरासी") + .put(85,"पचासी") + .put(86,"छियासी") + .put(87,"सतासी") + .put(88,"अट्ठासी") + .put(89,"नवासी") + .put(90,"नब्बे") + + .put(91,"इक्यानवे") + .put(92,"बानवे") + .put(93,"तिरानवे") + .put(94,"चौरानवे") + .put(95,"पचानवे") + .put(96,"छियानवे") + .put(97,"सतानवे") + .put(98,"अट्ठानवे") + .put(99,"निन्यानवे") + + .put(100, "एक सौ") + .put(200, "दो सौ") + .put(300, "तीन सौ") + .put(400, "चार सौ") + .put(500, "पाँच सौ") + .put(600, "छ: सौ") + .put(700, "सात सौ") + .put(800, "आठ सौ") + .put(900, "नौ सौ") + .build(); + } + + @Override + public List pluralForms() { + return Arrays.asList( + new EnglishPluralForms(""), + new EnglishPluralForms("हजार"), + new EnglishPluralForms("लाख"), + new EnglishPluralForms("करोड़"), + new EnglishPluralForms("अरब"), + new EnglishPluralForms("खरब"), + new EnglishPluralForms("नील"), + new EnglishPluralForms("पद्म"), + new EnglishPluralForms("शंख"), + new EnglishPluralForms("महाशंख")); + } + + @Override + public String currency() { + return "₹"; + } + + @Override + public char twoDigitsNumberSeparator() { + return 0; + } + + public String paiseSymbol(){ + return "p"; + } +} diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/IndianNumberToWordsConverter.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/IndianNumberToWordsConverter.java new file mode 100644 index 00000000..300afd7f --- /dev/null +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/IndianNumberToWordsConverter.java @@ -0,0 +1,35 @@ +package pl.allegro.finance.tradukisto.internal.languages.hindi; + +import pl.allegro.finance.tradukisto.internal.GenderAwareIntegerToStringConverter; +import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter; +import pl.allegro.finance.tradukisto.internal.converters.NumberToWordsConverter; +import pl.allegro.finance.tradukisto.internal.languages.PluralForms; +import pl.allegro.finance.tradukisto.internal.support.Assert; +import pl.allegro.finance.tradukisto.internal.support.IndianNumberChunking; +import pl.allegro.finance.tradukisto.internal.support.NumberChunking; + +import java.util.List; + +public class IndianNumberToWordsConverter extends NumberToWordsConverter { + + private final NumberChunking numberChunking = new IndianNumberChunking(); + + public IndianNumberToWordsConverter(GenderAwareIntegerToStringConverter hundredsToWordsConverter, List pluralForms) { + super(hundredsToWordsConverter, pluralForms); + } + + public IndianNumberToWordsConverter(IntegerToStringConverter hundredsToWordsConverter, List pluralForms) { + super(hundredsToWordsConverter, pluralForms); + } + + @Override + public String asWords(Long value) { + Assert.isTrue(value >= 0, () -> String.format("can't convert negative numbers for value %d", value)); + + List valueChunks = numberChunking.chunk(value); + List formsToUse = getRequiredFormsInReversedOrder(valueChunks.size()); + + + return joinValueChunksWithForms(valueChunks.iterator(), formsToUse.iterator()); + } +} diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunking.java b/src/main/java/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunking.java new file mode 100644 index 00000000..9debc8e1 --- /dev/null +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunking.java @@ -0,0 +1,31 @@ +package pl.allegro.finance.tradukisto.internal.support; + +import java.util.LinkedList; +import java.util.List; + +public class IndianNumberChunking extends NumberChunking{ + + private static final int INDAIN_SPLIT_FACTOR = 1_00; + + @Override + public List chunk(Long value) { + int splitCounter = 0; + LinkedList result = new LinkedList<>(); + + while (value > 0) { + if (splitCounter < 1) { + result.addFirst((int) (value % SPLIT_FACTOR)); + value /= SPLIT_FACTOR; + splitCounter++; + } else { + result.addFirst((int) (value % INDAIN_SPLIT_FACTOR)); + value /= INDAIN_SPLIT_FACTOR; + splitCounter++; + } + + } + + return result; + } + +} diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/support/NumberChunking.java b/src/main/java/pl/allegro/finance/tradukisto/internal/support/NumberChunking.java index 89a529f4..a026d1c7 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/support/NumberChunking.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/support/NumberChunking.java @@ -5,7 +5,7 @@ public class NumberChunking { - private static final int SPLIT_FACTOR = 1_000; + static final int SPLIT_FACTOR = 1_000; public List chunk(Long value) { LinkedList result = new LinkedList<>(); diff --git a/src/test/groovy/pl/allegro/finance/tradukisto/LongValueConvertersTest.groovy b/src/test/groovy/pl/allegro/finance/tradukisto/LongValueConvertersTest.groovy index 44bdf6ef..2786b957 100644 --- a/src/test/groovy/pl/allegro/finance/tradukisto/LongValueConvertersTest.groovy +++ b/src/test/groovy/pl/allegro/finance/tradukisto/LongValueConvertersTest.groovy @@ -4,6 +4,7 @@ import spock.lang.Specification import spock.lang.Unroll import static pl.allegro.finance.tradukisto.LongValueConverters.ENGLISH_LONG +import static pl.allegro.finance.tradukisto.LongValueConverters.HINDI_LONG import static pl.allegro.finance.tradukisto.LongValueConverters.POLISH_LONG class LongValueConvertersTest extends Specification { @@ -17,16 +18,8 @@ class LongValueConvertersTest extends Specification { language | converter || number "English" | ENGLISH_LONG || "one quintillion" "Polish" | POLISH_LONG || "jeden trylion" + "Hindi" | HINDI_LONG || "दस शंख" } - def "should throw exception when null given"() { - when: - converter.asWords(null) - then: - thrown(NullPointerException) - - where: - converter << ValueConverters.values() - } } diff --git a/src/test/groovy/pl/allegro/finance/tradukisto/MoneyConvertersTest.groovy b/src/test/groovy/pl/allegro/finance/tradukisto/MoneyConvertersTest.groovy index 807368ea..656bc083 100644 --- a/src/test/groovy/pl/allegro/finance/tradukisto/MoneyConvertersTest.groovy +++ b/src/test/groovy/pl/allegro/finance/tradukisto/MoneyConvertersTest.groovy @@ -10,6 +10,7 @@ import static pl.allegro.finance.tradukisto.MoneyConverters.CZECH_BANKING_MONEY_ import static pl.allegro.finance.tradukisto.MoneyConverters.ENGLISH_BANKING_MONEY_VALUE import static pl.allegro.finance.tradukisto.MoneyConverters.FRENCH_BANKING_MONEY_VALUE import static pl.allegro.finance.tradukisto.MoneyConverters.GERMAN_BANKING_MONEY_VALUE +import static pl.allegro.finance.tradukisto.MoneyConverters.HINDI_BANKING_MONEY_VALUE import static pl.allegro.finance.tradukisto.MoneyConverters.ITALIAN_BANKING_MONEY_VALUE import static pl.allegro.finance.tradukisto.MoneyConverters.KAZAKH_BANKING_MONEY_VALUE import static pl.allegro.finance.tradukisto.MoneyConverters.LATVIAN_BANKING_MONEY_VALUE @@ -49,6 +50,7 @@ class MoneyConvertersTest extends Specification { "Russian" | RUSSIAN_BANKING_MONEY_VALUE || "одна тысяча двести тридцать четыре руб. 56/100" "Turkish" | TURKISH_BANKING_MONEY_VALUE || "BinİkiYüzOtuzDörtTL,ElliAltıKr." "Ukrainian" | UKRAINIAN_BANKING_MONEY_VALUE || "одна тисяча двісті тридцять чотири ₴ 56/100" + "Hindi" | HINDI_BANKING_MONEY_VALUE || "एक हजार दो सौ चौंतीस ₹,छप्पन p" } def "should throw exception when null given"() { diff --git a/src/test/groovy/pl/allegro/finance/tradukisto/ValueConvertersTest.groovy b/src/test/groovy/pl/allegro/finance/tradukisto/ValueConvertersTest.groovy index 14ddc70d..aaa7193a 100644 --- a/src/test/groovy/pl/allegro/finance/tradukisto/ValueConvertersTest.groovy +++ b/src/test/groovy/pl/allegro/finance/tradukisto/ValueConvertersTest.groovy @@ -9,6 +9,7 @@ import static pl.allegro.finance.tradukisto.ValueConverters.CZECH_INTEGER import static pl.allegro.finance.tradukisto.ValueConverters.ENGLISH_INTEGER import static pl.allegro.finance.tradukisto.ValueConverters.FRENCH_INTEGER import static pl.allegro.finance.tradukisto.ValueConverters.GERMAN_INTEGER +import static pl.allegro.finance.tradukisto.ValueConverters.HINDI_INTEGER import static pl.allegro.finance.tradukisto.ValueConverters.ITALIAN_INTEGER import static pl.allegro.finance.tradukisto.ValueConverters.KAZAKH_INTEGER import static pl.allegro.finance.tradukisto.ValueConverters.LATVIAN_INTEGER @@ -49,6 +50,7 @@ class ValueConvertersTest extends Specification { "Russian" | RUSSIAN_INTEGER || "одна тысяча двести тридцать четыре" "Turkish" | TURKISH_INTEGER || "Bin İki Yüz Otuz Dört" "Ukrainian" | UKRAINIAN_INTEGER || "одна тисяча двісті тридцять чотири" + "Hindi" | HINDI_INTEGER || "एक हजार दो सौ चौंतीस" } def "should throw exception when null value given"() { @@ -91,6 +93,7 @@ class ValueConvertersTest extends Specification { new Locale("tr") || TURKISH_INTEGER new Locale("uk") || UKRAINIAN_INTEGER new Locale("nl") || DUTCH_INTEGER + new Locale("hi") || HINDI_INTEGER } def "should return supplied default converter when locale is unknown"() { @@ -136,6 +139,7 @@ class ValueConvertersTest extends Specification { "sk" || SLOVAK_INTEGER "tr" || TURKISH_INTEGER "uk" || UKRAINIAN_INTEGER + "hi" || HINDI_INTEGER } def "should return supplied default converter when languageCode is unknown"() { diff --git a/src/test/groovy/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunkingTest.groovy b/src/test/groovy/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunkingTest.groovy new file mode 100644 index 00000000..f8305c38 --- /dev/null +++ b/src/test/groovy/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunkingTest.groovy @@ -0,0 +1,24 @@ +package pl.allegro.finance.tradukisto.internal.support + +import spock.lang.Specification + +class IndianNumberChunkingTest extends Specification { + + def splitter = new IndianNumberChunking() + + def "should split number to three digit and 2 digit parts as per indian standards"() { + expect: + splitter.chunk(value) == chunks + + where: + value | chunks + 0 | [] + 123 | [123] + 1234 | [1, 234] + 123000789 | [12, 30, 0, 789] + 123456789 | [12, 34, 56, 789] + 123000000 | [12, 30, 0, 0] + 12300000 | [1, 23, 0, 0] + Long.MAX_VALUE | [92, 23, 37, 20, 36, 85, 47, 75, 807] + } +} From c28ae8cbc93686042fbca57967d4c8e1bb165ff8 Mon Sep 17 00:00:00 2001 From: girdharsourabh Date: Thu, 31 Aug 2023 20:36:43 +0530 Subject: [PATCH 2/2] Resolved MR feedbacks --- .../finance/tradukisto/ValueConverters.java | 41 +++--- .../tradukisto/internal/Container.java | 4 +- ...indiBigDecimalToBankingMoneyConverter.java | 2 +- .../languages/hindi/HindiPluralForms.java | 23 --- .../internal/languages/hindi/HindiValues.java | 8 +- .../hindi/IndianNumberToWordsConverter.java | 5 - .../support/IndianNumberChunking.java | 8 +- .../tradukisto/LongValueConvertersTest.groovy | 10 ++ .../languages/hindi/HindiValuesTest.groovy | 134 ++++++++++++++++++ 9 files changed, 177 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiPluralForms.java create mode 100644 src/test/groovy/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValuesTest.groovy diff --git a/src/main/java/pl/allegro/finance/tradukisto/ValueConverters.java b/src/main/java/pl/allegro/finance/tradukisto/ValueConverters.java index c601aa0b..26442659 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/ValueConverters.java +++ b/src/main/java/pl/allegro/finance/tradukisto/ValueConverters.java @@ -1,5 +1,6 @@ package pl.allegro.finance.tradukisto; +import pl.allegro.finance.tradukisto.internal.Container; import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter; import pl.allegro.finance.tradukisto.internal.support.Assert; @@ -9,29 +10,27 @@ import java.util.Locale; import java.util.Objects; -import static pl.allegro.finance.tradukisto.internal.Container.*; - public enum ValueConverters { - BRAZILIAN_PORTUGUESE_INTEGER(brazilianPortugueseContainer().getIntegerConverter(), Arrays.asList("pt", "pt-br")), - ENGLISH_INTEGER(englishContainer().getIntegerConverter(), "en"), - GERMAN_INTEGER(germanContainer().getIntegerConverter(), "de"), - RUSSIAN_INTEGER(russianContainer().getIntegerConverter(), "ru"), - ITALIAN_INTEGER(italianContainer().getIntegerConverter(), "it"), - POLISH_INTEGER(polishContainer().getIntegerConverter(), "pl"), - CROATIAN_INTEGER(croatianContainer().getIntegerConverter(), "hr"), - CZECH_INTEGER(czechContainer().getIntegerConverter(), "cs"), - SLOVAK_INTEGER(slovakContainer().getIntegerConverter(), "sk"), - LATVIAN_INTEGER(latvianContainer().getIntegerConverter(), "lv"), - KAZAKH_INTEGER(kazakhContainer().getIntegerConverter(), "kk"), - UKRAINIAN_INTEGER(ukrainianContainer().getIntegerConverter(), "uk"), - SERBIAN_INTEGER(serbianContainer().getIntegerConverter(), Arrays.asList("sr", getLanguageCodeFor("sr", "Latn"))), - SERBIAN_CYRILLIC_INTEGER(serbianCyrillicContainer().getIntegerConverter(), getLanguageCodeFor("sr", "Cyrl")), - BULGARIAN_INTEGER(bulgarianContainer().getIntegerConverter(), "bg"), - FRENCH_INTEGER(frenchContainer().getIntegerConverter(), "fr"), - TURKISH_INTEGER(turkishContainer().getIntegerConverter(), "tr"), - DUTCH_INTEGER(dutchContainer().getIntegerConverter(), "nl"), - HINDI_INTEGER(hindiContainer().getIntegerConverter(), "hi"); + BRAZILIAN_PORTUGUESE_INTEGER(Container.brazilianPortugueseContainer().getIntegerConverter(), Arrays.asList("pt", "pt-br")), + ENGLISH_INTEGER(Container.englishContainer().getIntegerConverter(), "en"), + GERMAN_INTEGER(Container.germanContainer().getIntegerConverter(), "de"), + RUSSIAN_INTEGER(Container.russianContainer().getIntegerConverter(), "ru"), + ITALIAN_INTEGER(Container.italianContainer().getIntegerConverter(), "it"), + POLISH_INTEGER(Container.polishContainer().getIntegerConverter(), "pl"), + CROATIAN_INTEGER(Container.croatianContainer().getIntegerConverter(), "hr"), + CZECH_INTEGER(Container.czechContainer().getIntegerConverter(), "cs"), + SLOVAK_INTEGER(Container.slovakContainer().getIntegerConverter(), "sk"), + LATVIAN_INTEGER(Container.latvianContainer().getIntegerConverter(), "lv"), + KAZAKH_INTEGER(Container.kazakhContainer().getIntegerConverter(), "kk"), + UKRAINIAN_INTEGER(Container.ukrainianContainer().getIntegerConverter(), "uk"), + SERBIAN_INTEGER(Container.serbianContainer().getIntegerConverter(), Arrays.asList("sr", getLanguageCodeFor("sr", "Latn"))), + SERBIAN_CYRILLIC_INTEGER(Container.serbianCyrillicContainer().getIntegerConverter(), getLanguageCodeFor("sr", "Cyrl")), + BULGARIAN_INTEGER(Container.bulgarianContainer().getIntegerConverter(), "bg"), + FRENCH_INTEGER(Container.frenchContainer().getIntegerConverter(), "fr"), + TURKISH_INTEGER(Container.turkishContainer().getIntegerConverter(), "tr"), + DUTCH_INTEGER(Container.dutchContainer().getIntegerConverter(), "nl"), + HINDI_INTEGER(Container.hindiContainer().getIntegerConverter(), "hi"); private final IntegerToStringConverter converter; private final List languageCodes; diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java b/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java index 805d6390..22fddd5b 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java @@ -229,7 +229,7 @@ public static Container kazakhContainer() { return new Container(kazakhValues); } - public static Container hindiContainer(){ + public static Container hindiContainer() { HindiValues hindiValues = new HindiValues(); HundredsToWordsConverter hundredsToStringConverter = new HundredsToWordsConverter(hindiValues.baseNumbers(), @@ -240,7 +240,7 @@ public static Container hindiContainer(){ BigDecimalToStringConverter bigDecimalConverter = new HindiBigDecimalToBankingMoneyConverter( integerToStringConverter, hindiValues); - LongToStringConverter longValueConverters = new IndianNumberToWordsConverter(hundredsToStringConverter,hindiValues.pluralForms()); + LongToStringConverter longValueConverters = new IndianNumberToWordsConverter(hundredsToStringConverter, hindiValues.pluralForms()); return new Container(integerToStringConverter, longValueConverters, bigDecimalConverter); } diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiBigDecimalToBankingMoneyConverter.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiBigDecimalToBankingMoneyConverter.java index 41549cc4..6e2a05db 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiBigDecimalToBankingMoneyConverter.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiBigDecimalToBankingMoneyConverter.java @@ -9,7 +9,7 @@ import static java.lang.String.format; /** - * @author Dilaver Demirel + * @author Sourabh Girdhar */ public class HindiBigDecimalToBankingMoneyConverter implements BigDecimalToStringConverter { private static final String SUBUNIT_SEPARATOR = ","; diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiPluralForms.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiPluralForms.java deleted file mode 100644 index bdfc2519..00000000 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiPluralForms.java +++ /dev/null @@ -1,23 +0,0 @@ -package pl.allegro.finance.tradukisto.internal.languages.hindi; - -import pl.allegro.finance.tradukisto.internal.languages.GenderType; -import pl.allegro.finance.tradukisto.internal.languages.PluralForms; - -public class HindiPluralForms implements PluralForms { - - private final String form; - - public HindiPluralForms(String form) { - this.form = form; - } - - @Override - public String formFor(Integer value) { - return form; - } - - @Override - public GenderType genderType() { - return GenderType.NON_APPLICABLE; - } -} diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValues.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValues.java index 0d821d5c..9e634174 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValues.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValues.java @@ -26,6 +26,7 @@ public Map baseNumbers() { .put(8, "आठ") .put(9, "नौ") .put(10, "दस") + .put(11, "ग्यारह") .put(12, "बारह") .put(13, "तेरह") @@ -34,8 +35,9 @@ public Map baseNumbers() { .put(16, "सोलह") .put(17, "सत्रह") .put(18, "आट्ठारह") - .put(19, "उन्निस") + .put(19, "उन्नीस") .put(20, "बीस") + .put(21,"इक्कीस") .put(22,"बाईस") .put(23,"तेईस") @@ -79,6 +81,7 @@ public Map baseNumbers() { .put(58,"अट्ठावन") .put(59,"उनसठ") .put(60,"साठ") + .put(61,"इकसठ") .put(62,"बासठ") .put(63,"तिरसठ") @@ -100,6 +103,7 @@ public Map baseNumbers() { .put(78,"अठहत्तर") .put(79,"उनासी") .put(80,"असी") + .put(81,"इक्यासी") .put(82,"बयासी") .put(83,"तिरासी") @@ -155,7 +159,7 @@ public String currency() { @Override public char twoDigitsNumberSeparator() { - return 0; + return '\0'; } public String paiseSymbol(){ diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/IndianNumberToWordsConverter.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/IndianNumberToWordsConverter.java index 300afd7f..a7a3f0cf 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/IndianNumberToWordsConverter.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/hindi/IndianNumberToWordsConverter.java @@ -1,7 +1,6 @@ package pl.allegro.finance.tradukisto.internal.languages.hindi; import pl.allegro.finance.tradukisto.internal.GenderAwareIntegerToStringConverter; -import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter; import pl.allegro.finance.tradukisto.internal.converters.NumberToWordsConverter; import pl.allegro.finance.tradukisto.internal.languages.PluralForms; import pl.allegro.finance.tradukisto.internal.support.Assert; @@ -18,10 +17,6 @@ public IndianNumberToWordsConverter(GenderAwareIntegerToStringConverter hundreds super(hundredsToWordsConverter, pluralForms); } - public IndianNumberToWordsConverter(IntegerToStringConverter hundredsToWordsConverter, List pluralForms) { - super(hundredsToWordsConverter, pluralForms); - } - @Override public String asWords(Long value) { Assert.isTrue(value >= 0, () -> String.format("can't convert negative numbers for value %d", value)); diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunking.java b/src/main/java/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunking.java index 9debc8e1..f2d9c9c4 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunking.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/support/IndianNumberChunking.java @@ -3,9 +3,9 @@ import java.util.LinkedList; import java.util.List; -public class IndianNumberChunking extends NumberChunking{ +public class IndianNumberChunking extends NumberChunking { - private static final int INDAIN_SPLIT_FACTOR = 1_00; + private static final int INDIAN_SPLIT_FACTOR = 1_00; @Override public List chunk(Long value) { @@ -18,8 +18,8 @@ public List chunk(Long value) { value /= SPLIT_FACTOR; splitCounter++; } else { - result.addFirst((int) (value % INDAIN_SPLIT_FACTOR)); - value /= INDAIN_SPLIT_FACTOR; + result.addFirst((int) (value % INDIAN_SPLIT_FACTOR)); + value /= INDIAN_SPLIT_FACTOR; splitCounter++; } diff --git a/src/test/groovy/pl/allegro/finance/tradukisto/LongValueConvertersTest.groovy b/src/test/groovy/pl/allegro/finance/tradukisto/LongValueConvertersTest.groovy index 2786b957..3837e8f1 100644 --- a/src/test/groovy/pl/allegro/finance/tradukisto/LongValueConvertersTest.groovy +++ b/src/test/groovy/pl/allegro/finance/tradukisto/LongValueConvertersTest.groovy @@ -21,5 +21,15 @@ class LongValueConvertersTest extends Specification { "Hindi" | HINDI_LONG || "दस शंख" } + def "should throw exception when null given"() { + when: + converter.asWords(null) + + then: + thrown(NullPointerException) + + where: + converter << ValueConverters.values() + } } diff --git a/src/test/groovy/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValuesTest.groovy b/src/test/groovy/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValuesTest.groovy new file mode 100644 index 00000000..553ecf63 --- /dev/null +++ b/src/test/groovy/pl/allegro/finance/tradukisto/internal/languages/hindi/HindiValuesTest.groovy @@ -0,0 +1,134 @@ +package pl.allegro.finance.tradukisto.internal.languages.hindi + +import spock.lang.Specification +import spock.lang.Unroll + +import static pl.allegro.finance.tradukisto.internal.Container.hindiContainer + +class HindiValuesTest extends Specification { + + static intConverter = hindiContainer().getIntegerConverter() + static longConverter = hindiContainer().getLongConverter() + + @Unroll + def "should convert #value to '#words' in Hindi"() { + expect: + intConverter.asWords(value) == words + + where: + value | words + 0 | "शून्य" + 1 | "एक" + 2 | "दो" + 3 | "तीन" + 4 | "चार" + 5 | "पाँच" + 6 | "छ:" + 7 | "सात" + 8 | "आठ" + 9 | "नौ" + + 11 | "ग्यारह" + 12 | "बारह" + 13 | "तेरह" + 14 | "चौदह" + 15 | "पंद्रह" + 16 | "सोलह" + 17 | "सत्रह" + 18 | "आट्ठारह" + 19 | "उन्नीस" + + 10 | "दस" + 20 | "बीस" + 30 | "तीस" + 40 | "चालीस" + 50 | "पचास" + 60 | "साठ" + 70 | "सत्तर" + 80 | "असी" + 90 | "नब्बे" + + 21 | "इक्कीस" + 37 | "सैंतीस" + 43 | "तैंतालीस" + 58 | "अट्ठावन" + 69 | "उनहत्तर" + 76 | "छीहत्तर" + 82 | "बयासी" + 95 | "पचानवे" + + 100 | "एक सौ" + 200 | "दो सौ" + 300 | "तीन सौ" + 400 | "चार सौ" + 500 | "पाँच सौ" + 600 | "छ: सौ" + 700 | "सात सौ" + 800 | "आठ सौ" + 900 | "नौ सौ" + + 111 | "एक सौ ग्यारह" + 272 | "दो सौ बहत्तर" + 387 | "तीन सौ सतासी" + 448 | "चार सौ अड़तालीस" + 569 | "पाँच सौ उनहत्तर" + 625 | "छ: सौ पच्चीस" + 782 | "सात सौ बयासी" + 895 | "आठ सौ पचानवे" + 999 | "नौ सौ निन्यानवे" + + 1000 | "एक हजार" + 1234 | "एक हजार दो सौ चौंतीस" + 2000 | "दो हजार" + 3000 | "तीन हजार" + 4000 | "चार हजार" + 5000 | "पाँच हजार" + 7634 | "सात हजार छ: सौ चौंतीस" + + 11000 | "ग्यारह हजार" + 15000 | "पंद्रह हजार" + 21000 | "इक्कीस हजार" + 24190 | "चौबीस हजार एक सौ नब्बे" + 653000 | "छ: लाख तिरपन हजार" + 123454 | "एक लाख तेईस हजार चार सौ चौवन" + 700000 | "सात लाख" + 999999 | "नौ लाख निन्यानवे हजार नौ सौ निन्यानवे" + + 1000000 | "दस लाख" + 1001234 | "दस लाख एक हजार दो सौ चौंतीस" + 2000000 | "बीस लाख" + 5000000 | "पचास लाख" + 5012000 | "पचास लाख बारह हजार" + 23437219 | "दो करोड़ चौंतीस लाख सैंतीस हजार दो सौ उन्नीस" + 100000000 | "दस करोड़" + 100001200 | "दस करोड़ एक हजार दो सौ" + 123456789 | "बारह करोड़ चौंतीस लाख छप्पन हजार सात सौ नवासी" + 322089890 | "बत्तीस करोड़ बीस लाख नवासी हजार आठ सौ नब्बे" + + 1000000000 | "एक अरब" + 1000001234 | "एक अरब एक हजार दो सौ चौंतीस" + 2147483647 | "दो अरब चौदह करोड़ चौहत्तर लाख तिरासी हजार छ: सौ सैंतालीस" + } + + @Unroll + def "should convert long #value to '#words' in Hindi"() { + expect: + longConverter.asWords(value) == words + + where: + value | words + 5_000_000_000 | "पाँच अरब" + + 1_000_000_000_000 | "दस खरब" + 2_000_000_000_000 | "बीस खरब" + 5_000_000_000_000 | "पचास खरब" + + 1_000_000_000_000_000 | "एक पद्म" + 2_000_000_000_000_000 | "दो पद्म" + 5_000_000_000_000_000 | "पाँच पद्म" + + 1_000_000_000_000_000_000 | "दस शंख" + 2_000_000_000_000_000_000 | "बीस शंख" + Long.MAX_VALUE | "बानवे शंख तेईस पद्म सैंतीस नील बीस खरब छत्तीस अरब पचासी करोड़ सैंतालीस लाख पचहत्तर हजार आठ सौ सात" + } +} \ No newline at end of file