add indonesian ('id')

This commit is contained in:
isnani
2015-12-18 03:17:17 +01:00
committed by Virgil Dupras
parent b9b6a8de42
commit d3d0af3040
4 changed files with 246 additions and 1 deletions

View File

@@ -27,6 +27,7 @@ from . import lang_LT
from . import lang_LV from . import lang_LV
from . import lang_PL from . import lang_PL
from . import lang_RU from . import lang_RU
from . import lang_ID
CONVERTER_CLASSES = { CONVERTER_CLASSES = {
'en': lang_EN.Num2Word_EN(), 'en': lang_EN.Num2Word_EN(),
@@ -36,6 +37,7 @@ CONVERTER_CLASSES = {
'fr_CH': lang_FR_CH.Num2Word_FR_CH(), 'fr_CH': lang_FR_CH.Num2Word_FR_CH(),
'de': lang_DE.Num2Word_DE(), 'de': lang_DE.Num2Word_DE(),
'es': lang_ES.Num2Word_ES(), 'es': lang_ES.Num2Word_ES(),
'id': lang_ID.Num2Word_ID(),
'lt': lang_LT.Num2Word_LT(), 'lt': lang_LT.Num2Word_LT(),
'lv': lang_LV.Num2Word_LV(), 'lv': lang_LV.Num2Word_LV(),
'pl': lang_PL.Num2Word_PL(), 'pl': lang_PL.Num2Word_PL(),

View File

@@ -182,7 +182,7 @@ class Num2Word_Base(object):
pass pass
def to_ordinal(value): def to_ordinal(self, value):
return self.to_cardinal(value) return self.to_cardinal(value)

194
num2words/lang_ID.py Normal file
View File

@@ -0,0 +1,194 @@
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
class Num2Word_ID():
BASE = {0: [],
1: ["satu"],
2: ["dua"],
3: ["tiga"],
4: ["empat"],
5: ["lima"],
6: ["enam"],
7: ["tujuh"],
8: ["delapan"],
9: ["sembilan"]}
TENS_TO = {3: "ribu",
6: "juta",
9: "miliar",
12: "triliun",
15: "kuadriliun",
18: "kuantiliun",
21: "sekstiliun",
24: "septiliun",
27: "oktiliun",
30: "noniliun",
33: "desiliun"}
errmsg_floatord = "Cannot treat float number as ordinal"
errmsg_negord = "Cannot treat negative number as ordinal"
errmsg_toobig = "Too large"
max_num = 10**36
def split_by_koma(self, number):
return str(number).split('.')
def split_by_3(self, number):
"""
starting here, it groups the number by three from the tail
'1234567' -> (('1',),('234',),('567',))
:param number:str
:rtype:tuple
"""
blocks = ()
length = len(number)
if length < 3:
blocks += ((number,),)
else:
len_of_first_block = length % 3
if len_of_first_block > 0:
first_block = number[0:len_of_first_block],
blocks += first_block,
for i in range(len_of_first_block, length, 3):
next_block = (number[i:i+3],),
blocks += next_block
return blocks
def spell(self, blocks):
"""
it adds the list of spelling to the blocks
(('1',),('034',)) -> (('1',['satu']),('234',['tiga', 'puluh', 'empat']))
:param blocks: tuple
:rtype: tuple
"""
word_blocks = ()
first_block = blocks[0]
if len(first_block[0]) == 1:
if first_block[0] == '0':
spelling = ['nol']
else:
spelling = self.BASE[int(first_block[0])]
elif len(first_block[0]) == 2:
spelling = self.puluh(first_block[0])
else:
spelling = self.ratus(first_block[0][0]) + self.puluh(first_block[0][1:3])
word_blocks += (first_block[0], spelling),
for block in blocks[1:]:
spelling = self.ratus(block[0][0]) + self.puluh(block[0][1:3])
block += spelling,
word_blocks += block,
return word_blocks
def ratus(self, number):
# it is used to spell
if number == '1':
return ['seratus']
elif number == '0':
return []
else:
return self.BASE[int(number)]+['ratus']
def puluh(self, number):
# it is used to spell
if number[0] == '1':
if number[1]== '0':
return ['sepuluh']
elif number[1] == '1':
return ['sebelas']
else:
return self.BASE[int(number[1])]+['belas']
elif number[0] == '0':
return self.BASE[int(number[1])]
else:
return self.BASE[int(number[0])]+['puluh']+ self.BASE[int(number[1])]
def spell_float(self, float_part):
# spell the float number
word_list = []
for n in float_part:
if n == '0':
word_list += ['nol']
continue
word_list += self.BASE[int(n)]
return ' '.join(['','koma']+word_list)
def join(self, word_blocks, float_part):
"""
join the words by first join lists in the tuple
:param word_blocks: tuple
:rtype: str
"""
word_list = []
length = len(word_blocks)-1
first_block = word_blocks[0],
start = 0
if length == 1 and first_block[0][0] == '1':
word_list += ['seribu']
start = 1
for i in range(start, length+1, 1):
word_list += word_blocks[i][1]
if not word_blocks[i][1]:
continue
if i == length:
break
word_list += [self.TENS_TO[(length-i)*3]]
return ' '.join(word_list)+float_part
def to_cardinal(self, number):
if number >= self.max_num:
raise OverflowError(self.errmsg_toobig % (number, self.maxnum))
minus = ''
if number < 0:
minus = 'min '
float_word = ''
n = self.split_by_koma(abs(number))
if len(n)==2:
float_word = self.spell_float(n[1])
return minus + self.join(self.spell(self.split_by_3(n[0])), float_word)
def to_ordinal(self, number):
self.verify_ordinal(number)
out_word = self.to_cardinal(number)
if out_word == "satu":
return "pertama"
return "ke" + out_word
def to_ordinal_num(self, number):
self.verify_ordinal(number)
return "ke-" + str(number)
def to_currency(self, value):
return self.to_cardinal(value)+" rupiah"
def to_year(self, value):
return self.to_cardinal(value)
def verify_ordinal(self, value):
if not value == long(value):
raise TypeError, self.errmsg_floatord %(value)
if not abs(value) == value:
raise TypeError, self.errmsg_negord %(value)

49
tests/test_id.py Normal file
View File

@@ -0,0 +1,49 @@
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
from unittest import TestCase
from num2words import num2words
class Num2WordsIDTest(TestCase):
def test_cardinal_for_natural_number(self):
self.assertEqual(num2words(10, lang='id'), "sepuluh")
self.assertEqual(num2words(11, lang='id'), "sebelas")
self.assertEqual(num2words(108, lang='id'), "seratus delapan")
self.assertEqual(num2words(1075, lang='id'), "seribu tujuh puluh lima")
self.assertEqual(num2words(1087231, lang='id'), "satu juta delapan puluh tujuh ribu dua ratus tiga puluh satu")
self.assertEqual(num2words(1000000408, lang='id'), "satu miliar empat ratus delapan")
def test_cardinal_for_decimal_number(self):
self.assertEqual(num2words(12.234, lang='id'), "dua belas koma dua tiga empat")
self.assertEqual(num2words(9.076, lang='id'), "sembilan koma nol tujuh enam")
def test_cardinal_for_negative_number(self):
self.assertEqual(num2words(-923, lang='id'), "min sembilan ratus dua puluh tiga")
self.assertEqual(num2words(-0.234, lang='id'), "min nol koma dua tiga empat")
def test_ordinal_for_natural_number(self):
self.assertEqual(num2words(1, ordinal=True, lang='id'), "pertama")
self.assertEqual(num2words(10, ordinal=True, lang='id'), "kesepuluh")
#def test_ordinal_numeric_for_natural_number(self):
# self.assertEqual(num2words(1, ordinal=True, lang='id'), "ke-1")
# self.assertEqual(num2words(10, ordinal=True, lang='id'), "ke-10")
def test_ordinal_for_negative_number(self):
self.assertRaises(TypeError, num2words, -12, ordinal=True, lang='id')
def test_ordinal_for_floating_number(self):
self.assertRaises(TypeError, num2words, 3.243, ordinal=True, lang='id')