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_AR.py
ADDED
|
@@ -0,0 +1,435 @@
|
|
|
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
|
+
# Copyright (c) 2018, Abdullah Alhazmy, Alhazmy13. All Rights Reserved.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# This library is free software; you can redistribute it and/or
|
|
8
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
9
|
+
# License as published by the Free Software Foundation; either
|
|
10
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
11
|
+
# This library is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14
|
+
# Lesser General Public License for more details.
|
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
16
|
+
# License along with this library; if not, write to the Free Software
|
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
18
|
+
# MA 02110-1301 USA
|
|
19
|
+
|
|
20
|
+
import decimal
|
|
21
|
+
import math
|
|
22
|
+
import re
|
|
23
|
+
from decimal import Decimal
|
|
24
|
+
from math import floor
|
|
25
|
+
|
|
26
|
+
from .base import Num2Word_Base
|
|
27
|
+
|
|
28
|
+
CURRENCY_SR = [("ريال", "ريالان", "ريالات", "ريالاً"),
|
|
29
|
+
("هللة", "هللتان", "هللات", "هللة")]
|
|
30
|
+
CURRENCY_EGP = [("جنيه", "جنيهان", "جنيهات", "جنيهاً"),
|
|
31
|
+
("قرش", "قرشان", "قروش", "قرش")]
|
|
32
|
+
CURRENCY_KWD = [("دينار", "ديناران", "دينارات", "ديناراً"),
|
|
33
|
+
("فلس", "فلسان", "فلس", "فلس")]
|
|
34
|
+
CURRENCY_TND = [("دينار", "ديناران", "دينارات", "ديناراً"),
|
|
35
|
+
("مليماً", "ميلمان", "مليمات", "مليم")]
|
|
36
|
+
|
|
37
|
+
ARABIC_ONES = [
|
|
38
|
+
"", "واحد", "اثنان", "ثلاثة", "أربعة", "خمسة", "ستة", "سبعة", "ثمانية",
|
|
39
|
+
"تسعة",
|
|
40
|
+
"عشرة", "أحد عشر", "اثنا عشر", "ثلاثة عشر", "أربعة عشر", "خمسة عشر",
|
|
41
|
+
"ستة عشر", "سبعة عشر", "ثمانية عشر",
|
|
42
|
+
"تسعة عشر"
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Num2Word_AR(Num2Word_Base):
|
|
47
|
+
errmsg_toobig = "abs(%s) must be less than %s."
|
|
48
|
+
MAXVAL = 10**51
|
|
49
|
+
|
|
50
|
+
def __init__(self):
|
|
51
|
+
super().__init__()
|
|
52
|
+
|
|
53
|
+
self.number = 0
|
|
54
|
+
self.arabicPrefixText = ""
|
|
55
|
+
self.arabicSuffixText = ""
|
|
56
|
+
self.integer_value = 0
|
|
57
|
+
self._decimalValue = ""
|
|
58
|
+
self.partPrecision = 2
|
|
59
|
+
self.currency_unit = CURRENCY_SR[0]
|
|
60
|
+
self.currency_subunit = CURRENCY_SR[1]
|
|
61
|
+
self.isCurrencyPartNameFeminine = True
|
|
62
|
+
self.isCurrencyNameFeminine = False
|
|
63
|
+
self.separator = 'و'
|
|
64
|
+
|
|
65
|
+
self.arabicOnes = ARABIC_ONES
|
|
66
|
+
self.arabicFeminineOnes = [
|
|
67
|
+
"", "إحدى", "اثنتان", "ثلاث", "أربع", "خمس", "ست", "سبع", "ثمان",
|
|
68
|
+
"تسع",
|
|
69
|
+
"عشر", "إحدى عشرة", "اثنتا عشرة", "ثلاث عشرة", "أربع عشرة",
|
|
70
|
+
"خمس عشرة", "ست عشرة", "سبع عشرة", "ثماني عشرة",
|
|
71
|
+
"تسع عشرة"
|
|
72
|
+
]
|
|
73
|
+
self.arabicOrdinal = [
|
|
74
|
+
"", "اول", "ثاني", "ثالث", "رابع", "خامس", "سادس", "سابع", "ثامن",
|
|
75
|
+
"تاسع", "عاشر", "حادي عشر", "ثاني عشر", "ثالث عشر", "رابع عشر",
|
|
76
|
+
"خامس عشر", "سادس عشر", "سابع عشر", "ثامن عشر", "تاسع عشر"
|
|
77
|
+
]
|
|
78
|
+
self.arabicTens = [
|
|
79
|
+
"عشرون", "ثلاثون", "أربعون", "خمسون", "ستون", "سبعون", "ثمانون",
|
|
80
|
+
"تسعون"
|
|
81
|
+
]
|
|
82
|
+
self.arabicHundreds = [
|
|
83
|
+
"", "مائة", "مئتان", "ثلاثمائة", "أربعمائة", "خمسمائة", "ستمائة",
|
|
84
|
+
"سبعمائة", "ثمانمائة", "تسعمائة"
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
self.arabicAppendedTwos = [
|
|
88
|
+
"مئتا", "ألفا", "مليونا", "مليارا", "تريليونا", "كوادريليونا",
|
|
89
|
+
"كوينتليونا", "سكستيليونا", "سبتيليونا", "أوكتيليونا ",
|
|
90
|
+
"نونيليونا", "ديسيليونا", "أندسيليونا", "دوديسيليونا",
|
|
91
|
+
"تريديسيليونا", "كوادريسيليونا", "كوينتينيليونا"
|
|
92
|
+
]
|
|
93
|
+
self.arabicTwos = [
|
|
94
|
+
"مئتان", "ألفان", "مليونان", "ملياران", "تريليونان",
|
|
95
|
+
"كوادريليونان", "كوينتليونان", "سكستيليونان", "سبتيليونان",
|
|
96
|
+
"أوكتيليونان ", "نونيليونان ", "ديسيليونان", "أندسيليونان",
|
|
97
|
+
"دوديسيليونان", "تريديسيليونان", "كوادريسيليونان", "كوينتينيليونان"
|
|
98
|
+
]
|
|
99
|
+
self.arabicGroup = [
|
|
100
|
+
"مائة", "ألف", "مليون", "مليار", "تريليون", "كوادريليون",
|
|
101
|
+
"كوينتليون", "سكستيليون", "سبتيليون", "أوكتيليون", "نونيليون",
|
|
102
|
+
"ديسيليون", "أندسيليون", "دوديسيليون", "تريديسيليون",
|
|
103
|
+
"كوادريسيليون", "كوينتينيليون"
|
|
104
|
+
]
|
|
105
|
+
self.arabicAppendedGroup = [
|
|
106
|
+
"", "ألفاً", "مليوناً", "ملياراً", "تريليوناً", "كوادريليوناً",
|
|
107
|
+
"كوينتليوناً", "سكستيليوناً", "سبتيليوناً", "أوكتيليوناً",
|
|
108
|
+
"نونيليوناً", "ديسيليوناً", "أندسيليوناً", "دوديسيليوناً",
|
|
109
|
+
"تريديسيليوناً", "كوادريسيليوناً", "كوينتينيليوناً"
|
|
110
|
+
]
|
|
111
|
+
self.arabicPluralGroups = [
|
|
112
|
+
"", "آلاف", "ملايين", "مليارات", "تريليونات", "كوادريليونات",
|
|
113
|
+
"كوينتليونات", "سكستيليونات", "سبتيليونات", "أوكتيليونات",
|
|
114
|
+
"نونيليونات", "ديسيليونات", "أندسيليونات", "دوديسيليونات",
|
|
115
|
+
"تريديسيليونات", "كوادريسيليونات", "كوينتينيليونات"
|
|
116
|
+
]
|
|
117
|
+
assert len(self.arabicAppendedGroup) == len(self.arabicGroup)
|
|
118
|
+
assert len(self.arabicPluralGroups) == len(self.arabicGroup)
|
|
119
|
+
assert len(self.arabicAppendedTwos) == len(self.arabicTwos)
|
|
120
|
+
|
|
121
|
+
def number_to_arabic(self, arabic_prefix_text, arabic_suffix_text):
|
|
122
|
+
self.arabicPrefixText = arabic_prefix_text
|
|
123
|
+
self.arabicSuffixText = arabic_suffix_text
|
|
124
|
+
self.extract_integer_and_decimal_parts()
|
|
125
|
+
|
|
126
|
+
def extract_integer_and_decimal_parts(self):
|
|
127
|
+
splits = re.split('\\.', str(self.number))
|
|
128
|
+
|
|
129
|
+
self.integer_value = int(splits[0])
|
|
130
|
+
if len(splits) > 1:
|
|
131
|
+
self._decimalValue = int(self.decimal_value(splits[1]))
|
|
132
|
+
else:
|
|
133
|
+
self._decimalValue = 0
|
|
134
|
+
|
|
135
|
+
def decimal_value(self, decimal_part):
|
|
136
|
+
|
|
137
|
+
if self.partPrecision is not len(decimal_part):
|
|
138
|
+
decimal_part_length = len(decimal_part)
|
|
139
|
+
|
|
140
|
+
decimal_part_builder = decimal_part
|
|
141
|
+
for i in range(0, self.partPrecision - decimal_part_length):
|
|
142
|
+
decimal_part_builder += '0'
|
|
143
|
+
decimal_part = decimal_part_builder
|
|
144
|
+
|
|
145
|
+
if len(decimal_part) <= self.partPrecision:
|
|
146
|
+
dec = len(decimal_part)
|
|
147
|
+
else:
|
|
148
|
+
dec = self.partPrecision
|
|
149
|
+
result = decimal_part[0: dec]
|
|
150
|
+
else:
|
|
151
|
+
result = decimal_part
|
|
152
|
+
|
|
153
|
+
# The following is useless (never happens)
|
|
154
|
+
# for i in range(len(result), self.partPrecision):
|
|
155
|
+
# result += '0'
|
|
156
|
+
return result
|
|
157
|
+
|
|
158
|
+
def digit_feminine_status(self, digit, group_level):
|
|
159
|
+
if group_level == -1:
|
|
160
|
+
if self.isCurrencyPartNameFeminine:
|
|
161
|
+
return self.arabicFeminineOnes[int(digit)]
|
|
162
|
+
else:
|
|
163
|
+
# Note: this never happens
|
|
164
|
+
return self.arabicOnes[int(digit)]
|
|
165
|
+
elif group_level == 0:
|
|
166
|
+
if self.isCurrencyNameFeminine:
|
|
167
|
+
return self.arabicFeminineOnes[int(digit)]
|
|
168
|
+
else:
|
|
169
|
+
return self.arabicOnes[int(digit)]
|
|
170
|
+
else:
|
|
171
|
+
return self.arabicOnes[int(digit)]
|
|
172
|
+
|
|
173
|
+
def process_arabic_group(self, group_number, group_level,
|
|
174
|
+
remaining_number):
|
|
175
|
+
tens = Decimal(group_number) % Decimal(100)
|
|
176
|
+
hundreds = Decimal(group_number) / Decimal(100)
|
|
177
|
+
ret_val = ""
|
|
178
|
+
|
|
179
|
+
if int(hundreds) > 0:
|
|
180
|
+
if tens == 0 and int(hundreds) == 2:
|
|
181
|
+
ret_val = "{}".format(self.arabicAppendedTwos[0])
|
|
182
|
+
else:
|
|
183
|
+
ret_val = "{}".format(self.arabicHundreds[int(hundreds)])
|
|
184
|
+
if ret_val != "" and tens != 0:
|
|
185
|
+
ret_val += " و"
|
|
186
|
+
|
|
187
|
+
if tens > 0:
|
|
188
|
+
if tens < 20:
|
|
189
|
+
# if int(group_level) >= len(self.arabicTwos):
|
|
190
|
+
# raise OverflowError(self.errmsg_toobig %
|
|
191
|
+
# (self.number, self.MAXVAL))
|
|
192
|
+
assert int(group_level) < len(self.arabicTwos)
|
|
193
|
+
if tens == 2 and int(hundreds) == 0 and group_level > 0:
|
|
194
|
+
pow = int(math.log10(self.integer_value))
|
|
195
|
+
if self.integer_value > 10 and pow % 3 == 0 and \
|
|
196
|
+
self.integer_value == 2 * (10 ** pow):
|
|
197
|
+
ret_val = "{}".format(
|
|
198
|
+
self.arabicAppendedTwos[int(group_level)])
|
|
199
|
+
else:
|
|
200
|
+
ret_val = "{}".format(
|
|
201
|
+
self.arabicTwos[int(group_level)])
|
|
202
|
+
else:
|
|
203
|
+
|
|
204
|
+
if tens == 1 and group_level > 0 and hundreds == 0:
|
|
205
|
+
# Note: this never happens
|
|
206
|
+
# (hundreds == 0 only if group_number is 0)
|
|
207
|
+
ret_val += ""
|
|
208
|
+
elif (tens == 1 or tens == 2) and (
|
|
209
|
+
group_level == 0 or group_level == -1) and \
|
|
210
|
+
hundreds == 0 and remaining_number == 0:
|
|
211
|
+
# Note: this never happens (idem)
|
|
212
|
+
ret_val += ""
|
|
213
|
+
elif tens == 1 and group_level > 0:
|
|
214
|
+
ret_val += self.arabicGroup[int(group_level)]
|
|
215
|
+
else:
|
|
216
|
+
ret_val += self.digit_feminine_status(int(tens),
|
|
217
|
+
group_level)
|
|
218
|
+
else:
|
|
219
|
+
ones = tens % 10
|
|
220
|
+
tens = (tens / 10) - 2
|
|
221
|
+
if ones > 0:
|
|
222
|
+
ret_val += self.digit_feminine_status(ones, group_level)
|
|
223
|
+
if ret_val != "" and ones != 0:
|
|
224
|
+
ret_val += " و"
|
|
225
|
+
|
|
226
|
+
ret_val += self.arabicTens[int(tens)]
|
|
227
|
+
|
|
228
|
+
return ret_val
|
|
229
|
+
|
|
230
|
+
# We use this instead of built-in `abs` function,
|
|
231
|
+
# because `abs` suffers from loss of precision for big numbers
|
|
232
|
+
def abs(self, number):
|
|
233
|
+
return number if number >= 0 else -number
|
|
234
|
+
|
|
235
|
+
# We use this instead of `"{:09d}".format(number)`,
|
|
236
|
+
# because the string conversion suffers from loss of
|
|
237
|
+
# precision for big numbers
|
|
238
|
+
def to_str(self, number):
|
|
239
|
+
integer = int(number)
|
|
240
|
+
if integer == number:
|
|
241
|
+
return str(integer)
|
|
242
|
+
decimal = round((number - integer) * 10**9)
|
|
243
|
+
return str(integer) + "." + "{:09d}".format(decimal).rstrip("0")
|
|
244
|
+
|
|
245
|
+
def convert(self, value):
|
|
246
|
+
self.number = self.to_str(value)
|
|
247
|
+
self.number_to_arabic(self.arabicPrefixText, self.arabicSuffixText)
|
|
248
|
+
return self.convert_to_arabic()
|
|
249
|
+
|
|
250
|
+
def convert_to_arabic(self):
|
|
251
|
+
temp_number = Decimal(self.number)
|
|
252
|
+
|
|
253
|
+
if temp_number == Decimal(0):
|
|
254
|
+
return "صفر"
|
|
255
|
+
|
|
256
|
+
decimal_string = self.process_arabic_group(self._decimalValue,
|
|
257
|
+
-1,
|
|
258
|
+
Decimal(0))
|
|
259
|
+
ret_val = ""
|
|
260
|
+
group = 0
|
|
261
|
+
|
|
262
|
+
while temp_number > Decimal(0):
|
|
263
|
+
|
|
264
|
+
temp_number_dec = Decimal(str(temp_number))
|
|
265
|
+
try:
|
|
266
|
+
number_to_process = int(temp_number_dec % Decimal(str(1000)))
|
|
267
|
+
except decimal.InvalidOperation:
|
|
268
|
+
decimal.getcontext().prec = len(
|
|
269
|
+
temp_number_dec.as_tuple().digits
|
|
270
|
+
)
|
|
271
|
+
number_to_process = int(temp_number_dec % Decimal(str(1000)))
|
|
272
|
+
|
|
273
|
+
temp_number = int(temp_number_dec / Decimal(1000))
|
|
274
|
+
|
|
275
|
+
group_description = \
|
|
276
|
+
self.process_arabic_group(number_to_process,
|
|
277
|
+
group,
|
|
278
|
+
Decimal(floor(temp_number)))
|
|
279
|
+
if group_description != '':
|
|
280
|
+
if group > 0:
|
|
281
|
+
if ret_val != "":
|
|
282
|
+
ret_val = "و{}".format(ret_val)
|
|
283
|
+
if number_to_process != 2 and number_to_process != 1:
|
|
284
|
+
# if group >= len(self.arabicGroup):
|
|
285
|
+
# raise OverflowError(self.errmsg_toobig %
|
|
286
|
+
# (self.number, self.MAXVAL)
|
|
287
|
+
# )
|
|
288
|
+
assert group < len(self.arabicGroup)
|
|
289
|
+
if number_to_process % 100 != 1:
|
|
290
|
+
if 3 <= number_to_process <= 10:
|
|
291
|
+
ret_val = "{} {}".format(
|
|
292
|
+
self.arabicPluralGroups[group], ret_val)
|
|
293
|
+
else:
|
|
294
|
+
if ret_val != "":
|
|
295
|
+
ret_val = "{} {}".format(
|
|
296
|
+
self.arabicAppendedGroup[group],
|
|
297
|
+
ret_val)
|
|
298
|
+
else:
|
|
299
|
+
ret_val = "{} {}".format(
|
|
300
|
+
self.arabicGroup[group], ret_val)
|
|
301
|
+
|
|
302
|
+
else:
|
|
303
|
+
ret_val = "{} {}".format(self.arabicGroup[group],
|
|
304
|
+
ret_val)
|
|
305
|
+
ret_val = "{} {}".format(group_description, ret_val)
|
|
306
|
+
group += 1
|
|
307
|
+
formatted_number = ""
|
|
308
|
+
if self.arabicPrefixText != "":
|
|
309
|
+
formatted_number += "{} ".format(self.arabicPrefixText)
|
|
310
|
+
formatted_number += ret_val
|
|
311
|
+
if self.integer_value != 0:
|
|
312
|
+
remaining100 = int(self.integer_value % 100)
|
|
313
|
+
|
|
314
|
+
if remaining100 == 0:
|
|
315
|
+
formatted_number += self.currency_unit[0]
|
|
316
|
+
elif remaining100 == 1:
|
|
317
|
+
formatted_number += self.currency_unit[0]
|
|
318
|
+
elif remaining100 == 2:
|
|
319
|
+
if self.integer_value == 2:
|
|
320
|
+
formatted_number += self.currency_unit[1]
|
|
321
|
+
else:
|
|
322
|
+
formatted_number += self.currency_unit[0]
|
|
323
|
+
elif 3 <= remaining100 <= 10:
|
|
324
|
+
formatted_number += self.currency_unit[2]
|
|
325
|
+
elif 11 <= remaining100 <= 99:
|
|
326
|
+
formatted_number += self.currency_unit[3]
|
|
327
|
+
if self._decimalValue != 0:
|
|
328
|
+
if self.separator == 'و':
|
|
329
|
+
formatted_number += " و"
|
|
330
|
+
else:
|
|
331
|
+
formatted_number += " {} ".format(self.separator)
|
|
332
|
+
formatted_number += decimal_string
|
|
333
|
+
|
|
334
|
+
if self._decimalValue != 0:
|
|
335
|
+
formatted_number += " "
|
|
336
|
+
remaining100 = int(self._decimalValue % 100)
|
|
337
|
+
|
|
338
|
+
if remaining100 == 0:
|
|
339
|
+
formatted_number += self.currency_subunit[0]
|
|
340
|
+
elif remaining100 == 1:
|
|
341
|
+
formatted_number += self.currency_subunit[0]
|
|
342
|
+
elif remaining100 == 2:
|
|
343
|
+
formatted_number += self.currency_subunit[1]
|
|
344
|
+
elif 3 <= remaining100 <= 10:
|
|
345
|
+
formatted_number += self.currency_subunit[2]
|
|
346
|
+
elif 11 <= remaining100 <= 99:
|
|
347
|
+
formatted_number += self.currency_subunit[3]
|
|
348
|
+
|
|
349
|
+
if self.arabicSuffixText != "":
|
|
350
|
+
formatted_number += " {}".format(self.arabicSuffixText)
|
|
351
|
+
|
|
352
|
+
return formatted_number
|
|
353
|
+
|
|
354
|
+
def validate_number(self, number):
|
|
355
|
+
if number >= self.MAXVAL:
|
|
356
|
+
raise OverflowError(self.errmsg_toobig % (number, self.MAXVAL))
|
|
357
|
+
return number
|
|
358
|
+
|
|
359
|
+
def set_currency_prefer(self, currency):
|
|
360
|
+
if currency == 'TND':
|
|
361
|
+
self.currency_unit = CURRENCY_TND[0]
|
|
362
|
+
self.currency_subunit = CURRENCY_TND[1]
|
|
363
|
+
self.partPrecision = 3
|
|
364
|
+
elif currency == 'EGP':
|
|
365
|
+
self.currency_unit = CURRENCY_EGP[0]
|
|
366
|
+
self.currency_subunit = CURRENCY_EGP[1]
|
|
367
|
+
self.partPrecision = 2
|
|
368
|
+
elif currency == 'KWD':
|
|
369
|
+
self.currency_unit = CURRENCY_KWD[0]
|
|
370
|
+
self.currency_subunit = CURRENCY_KWD[1]
|
|
371
|
+
self.partPrecision = 2
|
|
372
|
+
else:
|
|
373
|
+
self.currency_unit = CURRENCY_SR[0]
|
|
374
|
+
self.currency_subunit = CURRENCY_SR[1]
|
|
375
|
+
self.partPrecision = 2
|
|
376
|
+
|
|
377
|
+
def to_ordinal(self, number, prefix=''):
|
|
378
|
+
if number <= 19:
|
|
379
|
+
return "{}".format(self.arabicOrdinal[number])
|
|
380
|
+
if number < 100:
|
|
381
|
+
self.isCurrencyNameFeminine = True
|
|
382
|
+
else:
|
|
383
|
+
self.isCurrencyNameFeminine = False
|
|
384
|
+
self.currency_subunit = ('', '', '', '')
|
|
385
|
+
self.currency_unit = ('', '', '', '')
|
|
386
|
+
self.arabicPrefixText = prefix
|
|
387
|
+
self.arabicSuffixText = ""
|
|
388
|
+
return "{}".format(self.convert(self.abs(number)).strip())
|
|
389
|
+
|
|
390
|
+
def to_year(self, value):
|
|
391
|
+
value = self.validate_number(value)
|
|
392
|
+
return self.to_cardinal(value)
|
|
393
|
+
|
|
394
|
+
def to_ordinal_num(self, value):
|
|
395
|
+
return self.to_ordinal(value).strip()
|
|
396
|
+
|
|
397
|
+
def to_cardinal(self, number):
|
|
398
|
+
self.isCurrencyNameFeminine = False
|
|
399
|
+
number = self.validate_number(number)
|
|
400
|
+
minus = ''
|
|
401
|
+
if number < 0:
|
|
402
|
+
minus = 'سالب '
|
|
403
|
+
self.separator = ','
|
|
404
|
+
self.currency_subunit = ('', '', '', '')
|
|
405
|
+
self.currency_unit = ('', '', '', '')
|
|
406
|
+
self.arabicPrefixText = ""
|
|
407
|
+
self.arabicSuffixText = ""
|
|
408
|
+
self.arabicOnes = ARABIC_ONES
|
|
409
|
+
return minus + self.convert(value=self.abs(number)).strip()
|
|
410
|
+
|
|
411
|
+
def to_currency(self, n, currency='SR', cents=True, separator=',',
|
|
412
|
+
adjective=False):
|
|
413
|
+
# Arabic has a special currency implementation
|
|
414
|
+
# Set the currency preference based on the currency code
|
|
415
|
+
self.set_currency_prefer(currency)
|
|
416
|
+
|
|
417
|
+
# Reset settings for currency mode
|
|
418
|
+
self.isCurrencyNameFeminine = False
|
|
419
|
+
self.arabicPrefixText = ''
|
|
420
|
+
self.arabicSuffixText = ''
|
|
421
|
+
self.separator = 'و'
|
|
422
|
+
|
|
423
|
+
# Validate and handle negative numbers
|
|
424
|
+
n = self.validate_number(n)
|
|
425
|
+
minus = ''
|
|
426
|
+
if n < 0:
|
|
427
|
+
minus = 'سالب '
|
|
428
|
+
n = -n
|
|
429
|
+
|
|
430
|
+
# Convert and return
|
|
431
|
+
result = self.convert(value=n)
|
|
432
|
+
if minus:
|
|
433
|
+
# Need to prepend minus to the result
|
|
434
|
+
return minus + result
|
|
435
|
+
return result
|
num2words2/lang_AS.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
# Assamese language support
|
|
24
|
+
class Num2Word_AS(Num2Word_Base):
|
|
25
|
+
CURRENCY_FORMS = {
|
|
26
|
+
'INR': (('ৰুপী', 'ৰুপী'), ('পইচা', 'পইচা')),
|
|
27
|
+
'USD': (('ডলাৰ', 'ডলাৰ'), ('চেণ্ট', 'চেণ্ট')),
|
|
28
|
+
'EUR': (('ইউৰো', 'ইউৰো'), ('চেণ্ট', 'চেণ্ট')),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
def setup(self):
|
|
32
|
+
self.negword = "ঋণাত্মক "
|
|
33
|
+
self.pointword = "দশমিক"
|
|
34
|
+
|
|
35
|
+
def to_cardinal(self, number):
|
|
36
|
+
"""Convert a number to its word representation in Assamese."""
|
|
37
|
+
n = str(number).strip()
|
|
38
|
+
|
|
39
|
+
if n.startswith('-'):
|
|
40
|
+
n = n[1:]
|
|
41
|
+
ret = self.negword
|
|
42
|
+
else:
|
|
43
|
+
ret = ""
|
|
44
|
+
|
|
45
|
+
if '.' in n:
|
|
46
|
+
left, right = n.split('.', 1)
|
|
47
|
+
ret += self._int_to_word(int(left)) + " " + self.pointword + " "
|
|
48
|
+
ret += " ".join(self._int_to_word(int(d)) for d in right)
|
|
49
|
+
return ret
|
|
50
|
+
else:
|
|
51
|
+
return ret + self._int_to_word(int(n))
|
|
52
|
+
|
|
53
|
+
def _int_to_word(self, number):
|
|
54
|
+
"""Convert an integer to its word representation in Assamese."""
|
|
55
|
+
if number == 0:
|
|
56
|
+
return "শূন্য"
|
|
57
|
+
|
|
58
|
+
ones = ["", "এক", "দুই", "তিনি", "চাৰি", "পাঁচ", "ছয়", "সাত", "আঠ", "নয়"]
|
|
59
|
+
tens = ["", "", "বিশ", "ত্ৰিশ", "চল্লিশ", "পঞ্চাশ", "ষাঠি", "সত্তৰ", "আশী", "নব্বই"]
|
|
60
|
+
teens = ["দহ", "এঘাৰ", "বাৰ", "তেৰ", "চৈধ্য", "পোন্ধৰ", "ষোল্ল", "সোতৰ", "ওঠৰ", "উনিশ"]
|
|
61
|
+
|
|
62
|
+
if number < 10:
|
|
63
|
+
return ones[number]
|
|
64
|
+
elif number < 20:
|
|
65
|
+
return teens[number - 10]
|
|
66
|
+
elif number < 100:
|
|
67
|
+
return tens[number // 10] + (" " + ones[number % 10] if number % 10 else "")
|
|
68
|
+
elif number < 1000:
|
|
69
|
+
return ones[number // 100] + " শ" + (self._int_to_word(number % 100) if number % 100 else "")
|
|
70
|
+
elif number < 100000:
|
|
71
|
+
return self._int_to_word(number // 1000) + " হাজাৰ" + (" " + self._int_to_word(number % 1000) if number % 1000 else "")
|
|
72
|
+
elif number < 10000000:
|
|
73
|
+
return self._int_to_word(number // 100000) + " লাখ" + (" " + self._int_to_word(number % 100000) if number % 100000 else "")
|
|
74
|
+
else:
|
|
75
|
+
return self._int_to_word(number // 10000000) + " কোটি" + (" " + self._int_to_word(number % 10000000) if number % 10000000 else "")
|
|
76
|
+
|
|
77
|
+
def to_ordinal(self, number):
|
|
78
|
+
"""Convert to ordinal."""
|
|
79
|
+
cardinal = self.to_cardinal(number)
|
|
80
|
+
return cardinal + " -তম"
|
|
81
|
+
|
|
82
|
+
def to_ordinal_num(self, number):
|
|
83
|
+
"""Convert to abbreviated ordinal."""
|
|
84
|
+
return str(number) + "-তম"
|
|
85
|
+
|
|
86
|
+
def to_year(self, val, longval=True):
|
|
87
|
+
"""Convert to year."""
|
|
88
|
+
return "চন " + self.to_cardinal(val)
|
|
89
|
+
|
|
90
|
+
def to_currency(self, val, currency='INR', cents=True, separator=' আৰু', adjective=False):
|
|
91
|
+
"""Convert to currency."""
|
|
92
|
+
try:
|
|
93
|
+
left, right, is_negative = self.parse_currency(val)
|
|
94
|
+
except AttributeError:
|
|
95
|
+
is_negative = False
|
|
96
|
+
if val < 0:
|
|
97
|
+
is_negative = True
|
|
98
|
+
val = abs(val)
|
|
99
|
+
|
|
100
|
+
left, right = self._split_currency(val)
|
|
101
|
+
|
|
102
|
+
cr1, cr2 = self.CURRENCY_FORMS.get(currency, self.CURRENCY_FORMS['INR'])
|
|
103
|
+
|
|
104
|
+
left_str = self._int_to_word(int(left))
|
|
105
|
+
cents_str = self._int_to_word(int(right)) if cents and right else ""
|
|
106
|
+
|
|
107
|
+
result = left_str + " " + (cr1[1] if left != 1 else cr1[0])
|
|
108
|
+
|
|
109
|
+
if cents_str:
|
|
110
|
+
result += separator + cents_str + " " + (cr2[1] if right != 1 else cr2[0])
|
|
111
|
+
|
|
112
|
+
return self.negword + result if is_negative else result
|
|
113
|
+
|
|
114
|
+
def _split_currency(self, n):
|
|
115
|
+
"""Split currency into whole and fraction parts."""
|
|
116
|
+
parts = str(n).split('.')
|
|
117
|
+
left = int(parts[0]) if parts[0] else 0
|
|
118
|
+
right = int(parts[1][:2].ljust(2, '0')) if len(parts) > 1 and parts[1] else 0
|
|
119
|
+
return left, right
|