num2words2 0.1.0.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- num2words2/README.md +69 -0
- num2words2/__init__.py +196 -0
- num2words2/_version.py +3 -0
- num2words2/base.py +377 -0
- num2words2/compat.py +29 -0
- num2words2/currency.py +60 -0
- num2words2/lang_AF.py +202 -0
- num2words2/lang_AM.py +193 -0
- num2words2/lang_AR.py +435 -0
- num2words2/lang_AS.py +119 -0
- num2words2/lang_AZ.py +208 -0
- num2words2/lang_BA.py +119 -0
- num2words2/lang_BE.py +356 -0
- num2words2/lang_BG.py +393 -0
- num2words2/lang_BN.py +242 -0
- num2words2/lang_BO.py +122 -0
- num2words2/lang_BR.py +135 -0
- num2words2/lang_BS.py +189 -0
- num2words2/lang_CA.py +476 -0
- num2words2/lang_CE.py +546 -0
- num2words2/lang_CS.py +260 -0
- num2words2/lang_CY.py +574 -0
- num2words2/lang_DA.py +170 -0
- num2words2/lang_DE.py +180 -0
- num2words2/lang_EL.py +338 -0
- num2words2/lang_EN.py +118 -0
- num2words2/lang_EN_IN.py +26 -0
- num2words2/lang_EN_NG.py +45 -0
- num2words2/lang_EO.py +130 -0
- num2words2/lang_ES.py +399 -0
- num2words2/lang_ES_CO.py +37 -0
- num2words2/lang_ES_CR.py +38 -0
- num2words2/lang_ES_GT.py +37 -0
- num2words2/lang_ES_NI.py +35 -0
- num2words2/lang_ES_VE.py +43 -0
- num2words2/lang_ET.py +393 -0
- num2words2/lang_EU.py +158 -0
- num2words2/lang_EUR.py +104 -0
- num2words2/lang_FA.py +187 -0
- num2words2/lang_FI.py +759 -0
- num2words2/lang_FO.py +136 -0
- num2words2/lang_FR.py +133 -0
- num2words2/lang_FR_BE.py +49 -0
- num2words2/lang_FR_CH.py +48 -0
- num2words2/lang_FR_DZ.py +35 -0
- num2words2/lang_GL.py +135 -0
- num2words2/lang_GU.py +172 -0
- num2words2/lang_HA.py +293 -0
- num2words2/lang_HAW.py +144 -0
- num2words2/lang_HE.py +314 -0
- num2words2/lang_HI.py +243 -0
- num2words2/lang_HR.py +304 -0
- num2words2/lang_HT.py +136 -0
- num2words2/lang_HU.py +189 -0
- num2words2/lang_HY.py +364 -0
- num2words2/lang_ID.py +242 -0
- num2words2/lang_IS.py +208 -0
- num2words2/lang_IT.py +265 -0
- num2words2/lang_JA.py +615 -0
- num2words2/lang_JW.py +136 -0
- num2words2/lang_KA.py +169 -0
- num2words2/lang_KK.py +136 -0
- num2words2/lang_KM.py +173 -0
- num2words2/lang_KN.py +182 -0
- num2words2/lang_KO.py +175 -0
- num2words2/lang_KZ.py +161 -0
- num2words2/lang_LA.py +135 -0
- num2words2/lang_LB.py +135 -0
- num2words2/lang_LN.py +136 -0
- num2words2/lang_LO.py +149 -0
- num2words2/lang_LT.py +283 -0
- num2words2/lang_LV.py +266 -0
- num2words2/lang_MG.py +143 -0
- num2words2/lang_MI.py +151 -0
- num2words2/lang_MK.py +136 -0
- num2words2/lang_ML.py +159 -0
- num2words2/lang_MN.py +319 -0
- num2words2/lang_MR.py +187 -0
- num2words2/lang_MS.py +293 -0
- num2words2/lang_MT.py +159 -0
- num2words2/lang_MY.py +152 -0
- num2words2/lang_NE.py +157 -0
- num2words2/lang_NL.py +204 -0
- num2words2/lang_NN.py +136 -0
- num2words2/lang_NO.py +143 -0
- num2words2/lang_OC.py +135 -0
- num2words2/lang_PA.py +159 -0
- num2words2/lang_PL.py +336 -0
- num2words2/lang_PS.py +136 -0
- num2words2/lang_PT.py +280 -0
- num2words2/lang_PT_BR.py +224 -0
- num2words2/lang_RO.py +183 -0
- num2words2/lang_RU.py +570 -0
- num2words2/lang_SA.py +136 -0
- num2words2/lang_SD.py +136 -0
- num2words2/lang_SI.py +152 -0
- num2words2/lang_SK.py +250 -0
- num2words2/lang_SL.py +306 -0
- num2words2/lang_SN.py +447 -0
- num2words2/lang_SO.py +136 -0
- num2words2/lang_SQ.py +252 -0
- num2words2/lang_SR.py +254 -0
- num2words2/lang_SU.py +136 -0
- num2words2/lang_SV.py +169 -0
- num2words2/lang_SW.py +219 -0
- num2words2/lang_TA.py +303 -0
- num2words2/lang_TE.py +169 -0
- num2words2/lang_TET.py +285 -0
- num2words2/lang_TG.py +149 -0
- num2words2/lang_TH.py +214 -0
- num2words2/lang_TK.py +136 -0
- num2words2/lang_TL.py +145 -0
- num2words2/lang_TR.py +882 -0
- num2words2/lang_TT.py +136 -0
- num2words2/lang_UK.py +1101 -0
- num2words2/lang_UR.py +168 -0
- num2words2/lang_UZ.py +136 -0
- num2words2/lang_VI.py +143 -0
- num2words2/lang_WO.py +136 -0
- num2words2/lang_YI.py +135 -0
- num2words2/lang_YO.py +136 -0
- num2words2/lang_ZH.py +296 -0
- num2words2/lang_ZH_CN.py +85 -0
- num2words2/lang_ZH_HK.py +48 -0
- num2words2/lang_ZH_TW.py +198 -0
- num2words2/utils.py +35 -0
- num2words2-0.1.0.dev1.data/scripts/num2words2 +98 -0
- num2words2-0.1.0.dev1.dist-info/METADATA +244 -0
- num2words2-0.1.0.dev1.dist-info/RECORD +133 -0
- num2words2-0.1.0.dev1.dist-info/WHEEL +5 -0
- num2words2-0.1.0.dev1.dist-info/entry_points.txt +2 -0
- num2words2-0.1.0.dev1.dist-info/licenses/COPYING +145 -0
- num2words2-0.1.0.dev1.dist-info/top_level.txt +1 -0
num2words2/lang_SV.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
|
|
3
|
+
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License as published by the Free Software Foundation; either
|
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
+
# Lesser General Public License for more details.
|
|
13
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
14
|
+
# License along with this library; if not, write to the Free Software
|
|
15
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
16
|
+
# MA 02110-1301 USA
|
|
17
|
+
|
|
18
|
+
from __future__ import division, print_function, unicode_literals
|
|
19
|
+
|
|
20
|
+
from . import lang_EUR
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Num2Word_SV(lang_EUR.Num2Word_EUR):
|
|
24
|
+
GIGA_SUFFIX = "iljarder"
|
|
25
|
+
MEGA_SUFFIX = "iljoner"
|
|
26
|
+
|
|
27
|
+
def set_high_numwords(self, high):
|
|
28
|
+
cap = 3 + 6 * len(high)
|
|
29
|
+
|
|
30
|
+
for word, n in zip(high, range(cap, 3, -6)):
|
|
31
|
+
if self.GIGA_SUFFIX:
|
|
32
|
+
self.cards[10 ** n] = word + self.GIGA_SUFFIX
|
|
33
|
+
|
|
34
|
+
if self.MEGA_SUFFIX:
|
|
35
|
+
self.cards[10 ** (n - 3)] = word + self.MEGA_SUFFIX
|
|
36
|
+
|
|
37
|
+
def setup(self):
|
|
38
|
+
super(Num2Word_SV, self).setup()
|
|
39
|
+
|
|
40
|
+
self.negword = "minus "
|
|
41
|
+
self.pointword = "komma"
|
|
42
|
+
self.exclude_title = ["och", "komma", "minus"]
|
|
43
|
+
|
|
44
|
+
self.mid_numwords = [(1000, "tusen"), (100, "hundra"),
|
|
45
|
+
(90, "nittio"), (80, "åttio"), (70, "sjuttio"),
|
|
46
|
+
(60, "sextio"), (50, "femtio"), (40, "förtio"),
|
|
47
|
+
(30, "trettio")]
|
|
48
|
+
self.low_numwords = ["tjugo", "nitton", "arton", "sjutton",
|
|
49
|
+
"sexton", "femton", "fjorton", "tretton",
|
|
50
|
+
"tolv", "elva", "tio", "nio", "åtta",
|
|
51
|
+
"sju", "sex", "fem", "fyra", "tre", "två",
|
|
52
|
+
"ett", "noll"]
|
|
53
|
+
self.ords = {"noll": "nollte",
|
|
54
|
+
"ett": "första",
|
|
55
|
+
"två": "andra",
|
|
56
|
+
"tre": "tredje",
|
|
57
|
+
"fyra": "fjärde",
|
|
58
|
+
"fem": "femte",
|
|
59
|
+
"sex": "sjätte",
|
|
60
|
+
"sju": "sjunde",
|
|
61
|
+
"åtta": "åttonde",
|
|
62
|
+
"nio": "nionde",
|
|
63
|
+
"tio": "tionde",
|
|
64
|
+
"elva": "elfte",
|
|
65
|
+
"tolv": "tolfte",
|
|
66
|
+
"tjugo": "tjugonde"}
|
|
67
|
+
|
|
68
|
+
def merge(self, lpair, rpair):
|
|
69
|
+
ltext, lnum = lpair
|
|
70
|
+
rtext, rnum = rpair
|
|
71
|
+
if lnum == 1 and rnum < 100:
|
|
72
|
+
return (rtext, rnum)
|
|
73
|
+
elif 100 > lnum > rnum:
|
|
74
|
+
return ("%s%s" % (ltext, rtext), lnum + rnum)
|
|
75
|
+
elif lnum >= 100 > rnum:
|
|
76
|
+
return ("%s%s" % (ltext, rtext), lnum + rnum)
|
|
77
|
+
elif rnum >= 1000000 and lnum == 1:
|
|
78
|
+
return ("%s %s" % ('en', rtext[:-2]), lnum + rnum)
|
|
79
|
+
elif rnum >= 1000000 and lnum > 1:
|
|
80
|
+
return ("%s %s" % (ltext, rtext), lnum + rnum)
|
|
81
|
+
elif rnum > lnum:
|
|
82
|
+
# Special case: Swedish doesn't use "ett" before "hundra" in compounds
|
|
83
|
+
if lnum == 100 and rnum == 1000:
|
|
84
|
+
return ("hundratusen", 100000)
|
|
85
|
+
return ("%s%s" % (ltext, rtext), lnum * rnum)
|
|
86
|
+
return ("%s %s" % (ltext, rtext), lnum + rnum)
|
|
87
|
+
|
|
88
|
+
def to_currency(self, val, currency='EUR', cents=True, separator=',',
|
|
89
|
+
adjective=False):
|
|
90
|
+
# Handle integers specially - just add currency name without cents
|
|
91
|
+
if isinstance(val, int):
|
|
92
|
+
try:
|
|
93
|
+
cr1, cr2 = self.CURRENCY_FORMS[currency]
|
|
94
|
+
except (KeyError, AttributeError):
|
|
95
|
+
# Fallback to base implementation for unknown currency
|
|
96
|
+
return super(Num2Word_SV, self).to_currency(
|
|
97
|
+
val, currency=currency, cents=cents, separator=separator,
|
|
98
|
+
adjective=adjective)
|
|
99
|
+
|
|
100
|
+
minus_str = self.negword if val < 0 else ""
|
|
101
|
+
abs_val = abs(val)
|
|
102
|
+
money_str = self.to_cardinal(abs_val)
|
|
103
|
+
|
|
104
|
+
# Proper pluralization for currency
|
|
105
|
+
if abs_val == 1:
|
|
106
|
+
currency_str = cr1[0] if isinstance(cr1, tuple) else cr1
|
|
107
|
+
else:
|
|
108
|
+
currency_str = cr1[1] if isinstance(cr1, tuple) and len(cr1) > 1 else (cr1[0] if isinstance(cr1, tuple) else cr1)
|
|
109
|
+
|
|
110
|
+
return (u'%s %s %s' % (minus_str, money_str, currency_str)).strip()
|
|
111
|
+
|
|
112
|
+
# For floats, use the parent class implementation
|
|
113
|
+
return super(Num2Word_SV, self).to_currency(
|
|
114
|
+
val, currency=currency, cents=cents, separator=separator,
|
|
115
|
+
adjective=adjective)
|
|
116
|
+
|
|
117
|
+
def to_ordinal(self, value):
|
|
118
|
+
self.verify_ordinal(value)
|
|
119
|
+
outwords = self.to_cardinal(value).split(" ")
|
|
120
|
+
lastword = outwords[-1]
|
|
121
|
+
ending_length = 0
|
|
122
|
+
try:
|
|
123
|
+
lastword_ending = self.ords[lastword[-4:]]
|
|
124
|
+
ending_length = 4
|
|
125
|
+
except KeyError:
|
|
126
|
+
try:
|
|
127
|
+
lastword_ending = self.ords[lastword[-3:]]
|
|
128
|
+
ending_length = 3
|
|
129
|
+
except KeyError:
|
|
130
|
+
lastword_ending = "de"
|
|
131
|
+
if lastword_ending == 'de':
|
|
132
|
+
lastword_first_part = self.title(lastword)[:]
|
|
133
|
+
else:
|
|
134
|
+
lastword_first_part = self.title(lastword)[:-ending_length]
|
|
135
|
+
lastword_correct = lastword_first_part + lastword_ending
|
|
136
|
+
outwords[-1] = lastword_correct
|
|
137
|
+
return " ".join(outwords)
|
|
138
|
+
|
|
139
|
+
def to_ordinal_num(self, value):
|
|
140
|
+
"""Convert to abbreviated ordinal form in Swedish"""
|
|
141
|
+
# Swedish uses :e, :a, :de, :te etc. for ordinals
|
|
142
|
+
if value == 1 or value == 2:
|
|
143
|
+
return str(value) + ':a'
|
|
144
|
+
elif str(value).endswith(('1', '2')) and value not in (11, 12):
|
|
145
|
+
return str(value) + ':a'
|
|
146
|
+
elif str(value).endswith(('3', '4', '5', '6', '7', '8', '9', '0')):
|
|
147
|
+
return str(value) + ':e'
|
|
148
|
+
else:
|
|
149
|
+
return str(value) + ':e'
|
|
150
|
+
|
|
151
|
+
def to_year(self, val, longval=True):
|
|
152
|
+
"""Convert number to year representation in Swedish"""
|
|
153
|
+
if val < 0:
|
|
154
|
+
# BC years
|
|
155
|
+
return self.to_cardinal(-val) + " f.Kr."
|
|
156
|
+
elif val < 1000:
|
|
157
|
+
# Years before 1000
|
|
158
|
+
return self.to_cardinal(val)
|
|
159
|
+
elif val < 2000:
|
|
160
|
+
# Years 1000-1999: typically "nittonhundra" style
|
|
161
|
+
century = val // 100
|
|
162
|
+
remainder = val % 100
|
|
163
|
+
if remainder == 0:
|
|
164
|
+
return self.to_cardinal(century) + "hundra"
|
|
165
|
+
else:
|
|
166
|
+
return self.to_cardinal(century) + "hundra" + self.to_cardinal(remainder)
|
|
167
|
+
else:
|
|
168
|
+
# Years 2000+: typically "tvåtusen" style
|
|
169
|
+
return self.to_cardinal(val)
|
num2words2/lang_SW.py
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
|
|
3
|
+
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License as published by the Free Software Foundation; either
|
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
+
# Lesser General Public License for more details.
|
|
13
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
14
|
+
# License along with this library; if not, write to the Free Software
|
|
15
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
16
|
+
# MA 02110-1301 USA
|
|
17
|
+
|
|
18
|
+
from __future__ import unicode_literals
|
|
19
|
+
|
|
20
|
+
from .base import Num2Word_Base
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Num2Word_SW(Num2Word_Base):
|
|
24
|
+
CURRENCY_FORMS = {
|
|
25
|
+
'TZS': (('shilingi', 'shilingi'), ('senti', 'senti')), # Tanzanian Shilling
|
|
26
|
+
'KES': (('shilingi', 'shilingi'), ('senti', 'senti')), # Kenyan Shilling
|
|
27
|
+
'UGX': (('shilingi', 'shilingi'), ('senti', 'senti')), # Ugandan Shilling
|
|
28
|
+
|
|
29
|
+
'USD': (('dola', 'dola'), ('senti', 'senti')), # US Dollar
|
|
30
|
+
'EUR': (('yuro', 'yuro'), ('senti', 'senti')), # Euro
|
|
31
|
+
'GBP': (('pauni', 'pauni'), ('peni', 'peni')), # British Pound
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
def setup(self):
|
|
35
|
+
self.negword = "hasi "
|
|
36
|
+
self.pointword = "nukta"
|
|
37
|
+
|
|
38
|
+
# High-level numwords for large numbers
|
|
39
|
+
self.high_numwords = ["trilioni"]
|
|
40
|
+
|
|
41
|
+
self.mid_numwords = [
|
|
42
|
+
(1000000000, "bilioni"),
|
|
43
|
+
(1000000, "milioni"),
|
|
44
|
+
(100000, "laki"),
|
|
45
|
+
(1000, "elfu"),
|
|
46
|
+
(100, "mia"),
|
|
47
|
+
(90, "tisini"),
|
|
48
|
+
(80, "themanini"),
|
|
49
|
+
(70, "sabini"),
|
|
50
|
+
(60, "sitini"),
|
|
51
|
+
(50, "hamsini"),
|
|
52
|
+
(40, "arobaini"),
|
|
53
|
+
(30, "thelathini"),
|
|
54
|
+
(20, "ishirini")
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
self.low_numwords = [
|
|
58
|
+
"kumi na tisa", # 19
|
|
59
|
+
"kumi na nane", # 18
|
|
60
|
+
"kumi na saba", # 17
|
|
61
|
+
"kumi na sita", # 16
|
|
62
|
+
"kumi na tano", # 15
|
|
63
|
+
"kumi na nne", # 14
|
|
64
|
+
"kumi na tatu", # 13
|
|
65
|
+
"kumi na mbili", # 12
|
|
66
|
+
"kumi na moja", # 11
|
|
67
|
+
"kumi", # 10
|
|
68
|
+
"tisa", # 9
|
|
69
|
+
"nane", # 8
|
|
70
|
+
"saba", # 7
|
|
71
|
+
"sita", # 6
|
|
72
|
+
"tano", # 5
|
|
73
|
+
"nne", # 4
|
|
74
|
+
"tatu", # 3
|
|
75
|
+
"mbili", # 2
|
|
76
|
+
"moja", # 1
|
|
77
|
+
"sifuri" # 0
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
# Ordinal mappings
|
|
81
|
+
self.ordinal_words = {
|
|
82
|
+
"moja": "kwanza",
|
|
83
|
+
"mbili": "pili",
|
|
84
|
+
"tatu": "tatu",
|
|
85
|
+
"nne": "nne",
|
|
86
|
+
"tano": "tano",
|
|
87
|
+
"sita": "sita",
|
|
88
|
+
"saba": "saba",
|
|
89
|
+
"nane": "nane",
|
|
90
|
+
"tisa": "tisa",
|
|
91
|
+
"kumi": "kumi",
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
def set_high_numwords(self, high):
|
|
95
|
+
"""Set high numwords for large numbers."""
|
|
96
|
+
cap = 9 + 9 * len(high)
|
|
97
|
+
for word, n in zip(high, range(cap, 8, -9)):
|
|
98
|
+
self.cards[10 ** n] = word
|
|
99
|
+
|
|
100
|
+
def merge(self, lpair, rpair):
|
|
101
|
+
"""Merge two number parts using Swahili grammar rules."""
|
|
102
|
+
ltext, lnum = lpair
|
|
103
|
+
rtext, rnum = rpair
|
|
104
|
+
|
|
105
|
+
if lnum == 1 and rnum < 100:
|
|
106
|
+
return (rtext, rnum)
|
|
107
|
+
elif 100 > lnum > rnum:
|
|
108
|
+
return ("%s na %s" % (ltext, rtext), lnum + rnum)
|
|
109
|
+
elif lnum >= 100 > rnum:
|
|
110
|
+
return ("%s na %s" % (ltext, rtext), lnum + rnum)
|
|
111
|
+
elif rnum >= 1000000:
|
|
112
|
+
# For millions/billions: "milioni moja", "bilioni mbili", etc.
|
|
113
|
+
return ("%s %s" % (rtext, ltext), lnum * rnum)
|
|
114
|
+
elif rnum >= 1000:
|
|
115
|
+
# For thousands: "elfu moja", "elfu mbili", etc.
|
|
116
|
+
if lnum < 1000:
|
|
117
|
+
return ("%s %s" % (rtext, ltext), lnum * rnum)
|
|
118
|
+
else:
|
|
119
|
+
# When combining with other thousands, use "na"
|
|
120
|
+
return ("%s na %s" % (ltext, rtext), lnum + rnum)
|
|
121
|
+
elif rnum >= 100:
|
|
122
|
+
# For hundreds: "mia moja", "mia mbili", etc.
|
|
123
|
+
if lnum < 100:
|
|
124
|
+
return ("%s %s" % (rtext, ltext), lnum * rnum)
|
|
125
|
+
else:
|
|
126
|
+
# When combining with other hundreds or larger, use "na"
|
|
127
|
+
return ("%s na %s" % (ltext, rtext), lnum + rnum)
|
|
128
|
+
elif rnum > lnum:
|
|
129
|
+
return ("%s %s" % (ltext, rtext), lnum * rnum)
|
|
130
|
+
return ("%s na %s" % (ltext, rtext), lnum + rnum)
|
|
131
|
+
|
|
132
|
+
def to_ordinal(self, value):
|
|
133
|
+
"""Convert number to ordinal form."""
|
|
134
|
+
self.verify_ordinal(value)
|
|
135
|
+
cardinal_text = self.to_cardinal(value)
|
|
136
|
+
|
|
137
|
+
# Check if we have a special ordinal form
|
|
138
|
+
if cardinal_text in self.ordinal_words:
|
|
139
|
+
return f"wa {self.ordinal_words[cardinal_text]}"
|
|
140
|
+
|
|
141
|
+
# For ordinals, prefix with "wa" (of/the)
|
|
142
|
+
return f"wa {cardinal_text}"
|
|
143
|
+
|
|
144
|
+
def to_ordinal_num(self, value):
|
|
145
|
+
"""Convert number to ordinal number format."""
|
|
146
|
+
self.verify_ordinal(value)
|
|
147
|
+
return f"{value}."
|
|
148
|
+
|
|
149
|
+
def to_year(self, value, **kwargs):
|
|
150
|
+
"""Convert number to year format."""
|
|
151
|
+
return self.to_cardinal(value)
|
|
152
|
+
|
|
153
|
+
def pluralize(self, number, forms):
|
|
154
|
+
"""Handle pluralization - Swahili doesn't change form much."""
|
|
155
|
+
# Swahili typically doesn't change the noun form for plurals
|
|
156
|
+
# So we return the singular form for both cases
|
|
157
|
+
return forms[0] if len(forms) > 0 else forms
|
|
158
|
+
|
|
159
|
+
def _money_verbose(self, number, currency):
|
|
160
|
+
"""Convert money amount to verbose format."""
|
|
161
|
+
return self.to_cardinal(number)
|
|
162
|
+
|
|
163
|
+
def _cents_verbose(self, number, currency):
|
|
164
|
+
"""Convert cents amount to verbose format."""
|
|
165
|
+
return self.to_cardinal(number)
|
|
166
|
+
|
|
167
|
+
def to_currency(self, val, currency='TZS', cents=True, separator=' na',
|
|
168
|
+
adjective=False):
|
|
169
|
+
"""
|
|
170
|
+
Convert number to currency format in Swahili.
|
|
171
|
+
"""
|
|
172
|
+
# Import the parse function from the base currency module
|
|
173
|
+
# Check if value has fractional cents
|
|
174
|
+
from decimal import Decimal
|
|
175
|
+
|
|
176
|
+
from .currency import parse_currency_parts
|
|
177
|
+
decimal_val = Decimal(str(val))
|
|
178
|
+
has_fractional_cents = (decimal_val * 100) % 1 != 0
|
|
179
|
+
|
|
180
|
+
# For Swahili, treat integers as whole currency units, not cents
|
|
181
|
+
left, right, is_negative = parse_currency_parts(val, is_int_with_cents=False,
|
|
182
|
+
keep_precision=has_fractional_cents)
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
cr1, cr2 = self.CURRENCY_FORMS[currency]
|
|
186
|
+
except KeyError:
|
|
187
|
+
raise NotImplementedError(
|
|
188
|
+
'Currency code "%s" not implemented for "%s"' %
|
|
189
|
+
(currency, self.__class__.__name__))
|
|
190
|
+
|
|
191
|
+
minus_str = "%s " % self.negword.strip() if is_negative else ""
|
|
192
|
+
money_str = self.to_cardinal(left)
|
|
193
|
+
|
|
194
|
+
# Check if input is explicitly a decimal number or has non-zero cents
|
|
195
|
+
has_decimal = isinstance(val, float) or str(val).find('.') != -1
|
|
196
|
+
|
|
197
|
+
# Only include cents if there are actual cents or explicitly decimal
|
|
198
|
+
if has_decimal or right > 0:
|
|
199
|
+
# Handle fractional cents
|
|
200
|
+
from decimal import Decimal
|
|
201
|
+
if isinstance(right, Decimal):
|
|
202
|
+
# Convert fractional cents (e.g., 65.3 cents)
|
|
203
|
+
cents_str = self.to_cardinal_float(float(right)) if cents else str(float(right))
|
|
204
|
+
else:
|
|
205
|
+
cents_str = self.to_cardinal(right) if cents else "%02d" % right
|
|
206
|
+
return u'%s%s %s%s %s %s' % (
|
|
207
|
+
minus_str,
|
|
208
|
+
money_str,
|
|
209
|
+
self.pluralize(left, cr1),
|
|
210
|
+
separator,
|
|
211
|
+
cents_str,
|
|
212
|
+
self.pluralize(right, cr2)
|
|
213
|
+
)
|
|
214
|
+
else:
|
|
215
|
+
return u'%s%s %s' % (
|
|
216
|
+
minus_str,
|
|
217
|
+
money_str,
|
|
218
|
+
self.pluralize(left, cr1)
|
|
219
|
+
)
|
num2words2/lang_TA.py
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
|
|
3
|
+
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License as published by the Free Software Foundation; either
|
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
+
# Lesser General Public License for more details.
|
|
13
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
14
|
+
# License along with this library; if not, write to the Free Software
|
|
15
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
16
|
+
# MA 02110-1301 USA
|
|
17
|
+
|
|
18
|
+
from __future__ import unicode_literals
|
|
19
|
+
|
|
20
|
+
from .base import Num2Word_Base
|
|
21
|
+
from .currency import parse_currency_parts
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Num2Word_TA(Num2Word_Base):
|
|
25
|
+
CURRENCY_FORMS = {
|
|
26
|
+
'INR': (
|
|
27
|
+
('ரூபாய்', 'ரூபாய்'), ('பைசா', 'பைசா')
|
|
28
|
+
),
|
|
29
|
+
'LKR': (
|
|
30
|
+
('ரூபாய்', 'ரூபாய்'), ('சதம்', 'சதம்')
|
|
31
|
+
),
|
|
32
|
+
'USD': (
|
|
33
|
+
('டாலர்', 'டாலர்'), ('சென்ட்', 'சென்ட்')
|
|
34
|
+
),
|
|
35
|
+
'EUR': (
|
|
36
|
+
('யூரோ', 'யூரோ'), ('சென்ட்', 'சென்ட்')
|
|
37
|
+
),
|
|
38
|
+
'GBP': (
|
|
39
|
+
('பவுண்ட்', 'பவுண்ட்'), ('பென்னி', 'பென்னி')
|
|
40
|
+
),
|
|
41
|
+
'SGD': (
|
|
42
|
+
('டாலர்', 'டாலர்'), ('சென்ட்', 'சென்ட்')
|
|
43
|
+
),
|
|
44
|
+
'MYR': (
|
|
45
|
+
('ரிங்கிட்', 'ரிங்கிட்'), ('சென்', 'சென்')
|
|
46
|
+
),
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
def __init__(self):
|
|
50
|
+
super(Num2Word_TA, self).__init__()
|
|
51
|
+
|
|
52
|
+
self.ones = [
|
|
53
|
+
'',
|
|
54
|
+
'ஒன்று',
|
|
55
|
+
'இரண்டு',
|
|
56
|
+
'மூன்று',
|
|
57
|
+
'நான்கு',
|
|
58
|
+
'ஐந்து',
|
|
59
|
+
'ஆறு',
|
|
60
|
+
'ஏழு',
|
|
61
|
+
'எட்டு',
|
|
62
|
+
'ஒன்பது'
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
self.tens = [
|
|
66
|
+
'',
|
|
67
|
+
'பத்து',
|
|
68
|
+
'இருபது',
|
|
69
|
+
'முப்பது',
|
|
70
|
+
'நாற்பது',
|
|
71
|
+
'ஐம்பது',
|
|
72
|
+
'அறுபது',
|
|
73
|
+
'எழுபது',
|
|
74
|
+
'எண்பது',
|
|
75
|
+
'தொண்ணூறு'
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
self.teens = {
|
|
79
|
+
11: 'பதினொன்று',
|
|
80
|
+
12: 'பன்னிரண்டு',
|
|
81
|
+
13: 'பதின்மூன்று',
|
|
82
|
+
14: 'பதினான்கு',
|
|
83
|
+
15: 'பதினைந்து',
|
|
84
|
+
16: 'பதினாறு',
|
|
85
|
+
17: 'பதினேழு',
|
|
86
|
+
18: 'பதினெட்டு',
|
|
87
|
+
19: 'பத்தொன்பது'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
self.hundreds_special = {
|
|
91
|
+
100: 'நூறு',
|
|
92
|
+
200: 'இருநூறு',
|
|
93
|
+
300: 'முன்னூறு',
|
|
94
|
+
400: 'நானூறு',
|
|
95
|
+
500: 'ஐநூறு',
|
|
96
|
+
600: 'அறுநூறு',
|
|
97
|
+
700: 'எழுநூறு',
|
|
98
|
+
800: 'எண்ணூறு',
|
|
99
|
+
900: 'தொள்ளாயிரம்'
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
self.scale = {
|
|
103
|
+
1000: 'ஆயிரம்',
|
|
104
|
+
100000: 'இலட்சம்',
|
|
105
|
+
10000000: 'கோடி',
|
|
106
|
+
1000000000000: 'டிரில்லியன்'
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
self.ordinals = {
|
|
110
|
+
1: 'முதல்',
|
|
111
|
+
2: 'இரண்டாம்',
|
|
112
|
+
3: 'மூன்றாம்',
|
|
113
|
+
4: 'நான்காம்',
|
|
114
|
+
5: 'ஐந்தாம்',
|
|
115
|
+
6: 'ஆறாம்',
|
|
116
|
+
7: 'ஏழாம்',
|
|
117
|
+
8: 'எட்டாம்',
|
|
118
|
+
9: 'ஒன்பதாம்',
|
|
119
|
+
10: 'பத்தாம்'
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
self.negword = "கழித்தல் "
|
|
123
|
+
self.pointword = "புள்ளி"
|
|
124
|
+
|
|
125
|
+
def _setup(self):
|
|
126
|
+
super(Num2Word_TA, self)._setup()
|
|
127
|
+
|
|
128
|
+
def _int_to_word(self, n):
|
|
129
|
+
"""
|
|
130
|
+
Converts a number to words in Tamil.
|
|
131
|
+
Uses Indian numbering system (lakh/crore).
|
|
132
|
+
"""
|
|
133
|
+
if n == 0:
|
|
134
|
+
return 'பூஜ்ஜியம்'
|
|
135
|
+
|
|
136
|
+
parts = []
|
|
137
|
+
|
|
138
|
+
# Handle crores (1 crore = 10,000,000)
|
|
139
|
+
if n >= 10000000:
|
|
140
|
+
crores = n // 10000000
|
|
141
|
+
if crores == 1:
|
|
142
|
+
parts.append('ஒரு கோடி')
|
|
143
|
+
else:
|
|
144
|
+
parts.append(self._int_to_word(crores) + ' கோடி')
|
|
145
|
+
n %= 10000000
|
|
146
|
+
|
|
147
|
+
# Handle lakhs (1 lakh = 100,000)
|
|
148
|
+
if n >= 100000:
|
|
149
|
+
lakhs = n // 100000
|
|
150
|
+
if lakhs == 1:
|
|
151
|
+
parts.append('ஒரு இலட்சம்')
|
|
152
|
+
else:
|
|
153
|
+
parts.append(self._int_to_word(lakhs) + ' இலட்சம்')
|
|
154
|
+
n %= 100000
|
|
155
|
+
|
|
156
|
+
# Handle thousands
|
|
157
|
+
if n >= 1000:
|
|
158
|
+
thousands = n // 1000
|
|
159
|
+
if thousands == 1:
|
|
160
|
+
parts.append('ஆயிரம்')
|
|
161
|
+
else:
|
|
162
|
+
parts.append(self._int_to_word(thousands) + ' ஆயிரம்')
|
|
163
|
+
n %= 1000
|
|
164
|
+
|
|
165
|
+
# Handle hundreds with special forms
|
|
166
|
+
if n >= 100:
|
|
167
|
+
hundreds_val = (n // 100) * 100
|
|
168
|
+
if hundreds_val in self.hundreds_special:
|
|
169
|
+
parts.append(self.hundreds_special[hundreds_val])
|
|
170
|
+
else:
|
|
171
|
+
parts.append(self.ones[n // 100] + ' நூறு')
|
|
172
|
+
n %= 100
|
|
173
|
+
|
|
174
|
+
# Handle special case for teens (11-19)
|
|
175
|
+
if 10 < n < 20:
|
|
176
|
+
parts.append(self.teens[n])
|
|
177
|
+
else:
|
|
178
|
+
# Handle tens
|
|
179
|
+
if n >= 10:
|
|
180
|
+
tens_val = n // 10
|
|
181
|
+
parts.append(self.tens[tens_val])
|
|
182
|
+
n %= 10
|
|
183
|
+
|
|
184
|
+
# Handle ones
|
|
185
|
+
if n > 0:
|
|
186
|
+
parts.append(self.ones[n])
|
|
187
|
+
|
|
188
|
+
return ' '.join(parts)
|
|
189
|
+
|
|
190
|
+
def _int_to_cardinal(self, n):
|
|
191
|
+
if n == 0:
|
|
192
|
+
return 'பூஜ்ஜியம்'
|
|
193
|
+
|
|
194
|
+
if n < 0:
|
|
195
|
+
return self.negword + self._int_to_word(-n)
|
|
196
|
+
|
|
197
|
+
return self._int_to_word(n)
|
|
198
|
+
|
|
199
|
+
def _int_to_ordinal(self, n):
|
|
200
|
+
"""Convert to ordinal number."""
|
|
201
|
+
if n == 0:
|
|
202
|
+
return 'பூஜ்ஜியம்'
|
|
203
|
+
|
|
204
|
+
# Special cases for first ten ordinals
|
|
205
|
+
if n in self.ordinals:
|
|
206
|
+
return self.ordinals[n]
|
|
207
|
+
|
|
208
|
+
# For other numbers, add "-ஆவது" suffix
|
|
209
|
+
return self._int_to_cardinal(n) + 'ஆவது'
|
|
210
|
+
|
|
211
|
+
def to_cardinal(self, n):
|
|
212
|
+
try:
|
|
213
|
+
if isinstance(n, str):
|
|
214
|
+
n = int(n)
|
|
215
|
+
|
|
216
|
+
return self._int_to_cardinal(n)
|
|
217
|
+
except BaseException:
|
|
218
|
+
return self._int_to_cardinal(int(n))
|
|
219
|
+
|
|
220
|
+
def to_ordinal(self, n):
|
|
221
|
+
try:
|
|
222
|
+
if isinstance(n, str):
|
|
223
|
+
n = int(n)
|
|
224
|
+
|
|
225
|
+
return self._int_to_ordinal(n)
|
|
226
|
+
except BaseException:
|
|
227
|
+
return self._int_to_ordinal(int(n))
|
|
228
|
+
|
|
229
|
+
def to_ordinal_num(self, n):
|
|
230
|
+
try:
|
|
231
|
+
if isinstance(n, str):
|
|
232
|
+
n = int(n)
|
|
233
|
+
|
|
234
|
+
# In Tamil, ordinal numbers use "-ஆவது" suffix
|
|
235
|
+
# But for numeric form, use -வது
|
|
236
|
+
return str(n) + '-வது'
|
|
237
|
+
except BaseException:
|
|
238
|
+
return str(n) + '-வது'
|
|
239
|
+
|
|
240
|
+
def to_currency(self, n, currency='INR'):
|
|
241
|
+
try:
|
|
242
|
+
# Check if value has fractional cents
|
|
243
|
+
from decimal import Decimal
|
|
244
|
+
decimal_val = Decimal(str(n))
|
|
245
|
+
has_fractional_cents = (decimal_val * 100) % 1 != 0
|
|
246
|
+
|
|
247
|
+
left, right, is_negative = parse_currency_parts(n, is_int_with_cents=False,
|
|
248
|
+
keep_precision=has_fractional_cents)
|
|
249
|
+
|
|
250
|
+
if currency not in self.CURRENCY_FORMS:
|
|
251
|
+
raise NotImplementedError(
|
|
252
|
+
'Currency code "%s" not implemented for "%s"' %
|
|
253
|
+
(currency, self.__class__.__name__))
|
|
254
|
+
|
|
255
|
+
cr_major, cr_minor = self.CURRENCY_FORMS[currency]
|
|
256
|
+
|
|
257
|
+
result = []
|
|
258
|
+
|
|
259
|
+
if is_negative:
|
|
260
|
+
result.append(self.negword.strip())
|
|
261
|
+
|
|
262
|
+
left_words = self._int_to_cardinal(left)
|
|
263
|
+
result.append(left_words)
|
|
264
|
+
result.append(cr_major[0])
|
|
265
|
+
|
|
266
|
+
# Handle paise/cents if non-zero
|
|
267
|
+
if right > 0:
|
|
268
|
+
# Handle fractional paise
|
|
269
|
+
from decimal import Decimal
|
|
270
|
+
if isinstance(right, Decimal):
|
|
271
|
+
# Convert fractional paise (e.g., 65.3 paise)
|
|
272
|
+
right_words = self.to_cardinal(float(right))
|
|
273
|
+
else:
|
|
274
|
+
right_words = self._int_to_cardinal(right)
|
|
275
|
+
result.append(right_words)
|
|
276
|
+
result.append(cr_minor[0])
|
|
277
|
+
|
|
278
|
+
return ' '.join(result)
|
|
279
|
+
except NotImplementedError:
|
|
280
|
+
raise
|
|
281
|
+
except BaseException:
|
|
282
|
+
return str(n) + ' ' + currency
|
|
283
|
+
|
|
284
|
+
def to_year(self, n):
|
|
285
|
+
"""Convert to year representation."""
|
|
286
|
+
if n < 1000:
|
|
287
|
+
return self._int_to_cardinal(n)
|
|
288
|
+
elif n < 2000:
|
|
289
|
+
# Years like 1999 -> "ஆயிரத்து தொள்ளாயிரத்து தொண்ணூற்று ஒன்பது"
|
|
290
|
+
thousands = n // 1000
|
|
291
|
+
remainder = n % 1000
|
|
292
|
+
result = 'ஆயிரத்து'
|
|
293
|
+
if remainder > 0:
|
|
294
|
+
result += ' ' + self._int_to_cardinal(remainder)
|
|
295
|
+
return result
|
|
296
|
+
else:
|
|
297
|
+
# Years like 2023 -> "இரண்டாயிரத்து இருபத்து மூன்று"
|
|
298
|
+
thousands = n // 1000
|
|
299
|
+
remainder = n % 1000
|
|
300
|
+
result = self._int_to_cardinal(thousands) + ' ஆயிரத்து'
|
|
301
|
+
if remainder > 0:
|
|
302
|
+
result += ' ' + self._int_to_cardinal(remainder)
|
|
303
|
+
return result
|