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.
Files changed (133) hide show
  1. num2words2/README.md +69 -0
  2. num2words2/__init__.py +196 -0
  3. num2words2/_version.py +3 -0
  4. num2words2/base.py +377 -0
  5. num2words2/compat.py +29 -0
  6. num2words2/currency.py +60 -0
  7. num2words2/lang_AF.py +202 -0
  8. num2words2/lang_AM.py +193 -0
  9. num2words2/lang_AR.py +435 -0
  10. num2words2/lang_AS.py +119 -0
  11. num2words2/lang_AZ.py +208 -0
  12. num2words2/lang_BA.py +119 -0
  13. num2words2/lang_BE.py +356 -0
  14. num2words2/lang_BG.py +393 -0
  15. num2words2/lang_BN.py +242 -0
  16. num2words2/lang_BO.py +122 -0
  17. num2words2/lang_BR.py +135 -0
  18. num2words2/lang_BS.py +189 -0
  19. num2words2/lang_CA.py +476 -0
  20. num2words2/lang_CE.py +546 -0
  21. num2words2/lang_CS.py +260 -0
  22. num2words2/lang_CY.py +574 -0
  23. num2words2/lang_DA.py +170 -0
  24. num2words2/lang_DE.py +180 -0
  25. num2words2/lang_EL.py +338 -0
  26. num2words2/lang_EN.py +118 -0
  27. num2words2/lang_EN_IN.py +26 -0
  28. num2words2/lang_EN_NG.py +45 -0
  29. num2words2/lang_EO.py +130 -0
  30. num2words2/lang_ES.py +399 -0
  31. num2words2/lang_ES_CO.py +37 -0
  32. num2words2/lang_ES_CR.py +38 -0
  33. num2words2/lang_ES_GT.py +37 -0
  34. num2words2/lang_ES_NI.py +35 -0
  35. num2words2/lang_ES_VE.py +43 -0
  36. num2words2/lang_ET.py +393 -0
  37. num2words2/lang_EU.py +158 -0
  38. num2words2/lang_EUR.py +104 -0
  39. num2words2/lang_FA.py +187 -0
  40. num2words2/lang_FI.py +759 -0
  41. num2words2/lang_FO.py +136 -0
  42. num2words2/lang_FR.py +133 -0
  43. num2words2/lang_FR_BE.py +49 -0
  44. num2words2/lang_FR_CH.py +48 -0
  45. num2words2/lang_FR_DZ.py +35 -0
  46. num2words2/lang_GL.py +135 -0
  47. num2words2/lang_GU.py +172 -0
  48. num2words2/lang_HA.py +293 -0
  49. num2words2/lang_HAW.py +144 -0
  50. num2words2/lang_HE.py +314 -0
  51. num2words2/lang_HI.py +243 -0
  52. num2words2/lang_HR.py +304 -0
  53. num2words2/lang_HT.py +136 -0
  54. num2words2/lang_HU.py +189 -0
  55. num2words2/lang_HY.py +364 -0
  56. num2words2/lang_ID.py +242 -0
  57. num2words2/lang_IS.py +208 -0
  58. num2words2/lang_IT.py +265 -0
  59. num2words2/lang_JA.py +615 -0
  60. num2words2/lang_JW.py +136 -0
  61. num2words2/lang_KA.py +169 -0
  62. num2words2/lang_KK.py +136 -0
  63. num2words2/lang_KM.py +173 -0
  64. num2words2/lang_KN.py +182 -0
  65. num2words2/lang_KO.py +175 -0
  66. num2words2/lang_KZ.py +161 -0
  67. num2words2/lang_LA.py +135 -0
  68. num2words2/lang_LB.py +135 -0
  69. num2words2/lang_LN.py +136 -0
  70. num2words2/lang_LO.py +149 -0
  71. num2words2/lang_LT.py +283 -0
  72. num2words2/lang_LV.py +266 -0
  73. num2words2/lang_MG.py +143 -0
  74. num2words2/lang_MI.py +151 -0
  75. num2words2/lang_MK.py +136 -0
  76. num2words2/lang_ML.py +159 -0
  77. num2words2/lang_MN.py +319 -0
  78. num2words2/lang_MR.py +187 -0
  79. num2words2/lang_MS.py +293 -0
  80. num2words2/lang_MT.py +159 -0
  81. num2words2/lang_MY.py +152 -0
  82. num2words2/lang_NE.py +157 -0
  83. num2words2/lang_NL.py +204 -0
  84. num2words2/lang_NN.py +136 -0
  85. num2words2/lang_NO.py +143 -0
  86. num2words2/lang_OC.py +135 -0
  87. num2words2/lang_PA.py +159 -0
  88. num2words2/lang_PL.py +336 -0
  89. num2words2/lang_PS.py +136 -0
  90. num2words2/lang_PT.py +280 -0
  91. num2words2/lang_PT_BR.py +224 -0
  92. num2words2/lang_RO.py +183 -0
  93. num2words2/lang_RU.py +570 -0
  94. num2words2/lang_SA.py +136 -0
  95. num2words2/lang_SD.py +136 -0
  96. num2words2/lang_SI.py +152 -0
  97. num2words2/lang_SK.py +250 -0
  98. num2words2/lang_SL.py +306 -0
  99. num2words2/lang_SN.py +447 -0
  100. num2words2/lang_SO.py +136 -0
  101. num2words2/lang_SQ.py +252 -0
  102. num2words2/lang_SR.py +254 -0
  103. num2words2/lang_SU.py +136 -0
  104. num2words2/lang_SV.py +169 -0
  105. num2words2/lang_SW.py +219 -0
  106. num2words2/lang_TA.py +303 -0
  107. num2words2/lang_TE.py +169 -0
  108. num2words2/lang_TET.py +285 -0
  109. num2words2/lang_TG.py +149 -0
  110. num2words2/lang_TH.py +214 -0
  111. num2words2/lang_TK.py +136 -0
  112. num2words2/lang_TL.py +145 -0
  113. num2words2/lang_TR.py +882 -0
  114. num2words2/lang_TT.py +136 -0
  115. num2words2/lang_UK.py +1101 -0
  116. num2words2/lang_UR.py +168 -0
  117. num2words2/lang_UZ.py +136 -0
  118. num2words2/lang_VI.py +143 -0
  119. num2words2/lang_WO.py +136 -0
  120. num2words2/lang_YI.py +135 -0
  121. num2words2/lang_YO.py +136 -0
  122. num2words2/lang_ZH.py +296 -0
  123. num2words2/lang_ZH_CN.py +85 -0
  124. num2words2/lang_ZH_HK.py +48 -0
  125. num2words2/lang_ZH_TW.py +198 -0
  126. num2words2/utils.py +35 -0
  127. num2words2-0.1.0.dev1.data/scripts/num2words2 +98 -0
  128. num2words2-0.1.0.dev1.dist-info/METADATA +244 -0
  129. num2words2-0.1.0.dev1.dist-info/RECORD +133 -0
  130. num2words2-0.1.0.dev1.dist-info/WHEEL +5 -0
  131. num2words2-0.1.0.dev1.dist-info/entry_points.txt +2 -0
  132. num2words2-0.1.0.dev1.dist-info/licenses/COPYING +145 -0
  133. num2words2-0.1.0.dev1.dist-info/top_level.txt +1 -0
num2words2/lang_EL.py ADDED
@@ -0,0 +1,338 @@
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 print_function, unicode_literals
19
+
20
+ from .lang_EUR import Num2Word_EUR
21
+
22
+
23
+ class Num2Word_EL(Num2Word_EUR):
24
+ CURRENCY_FORMS = {
25
+ 'EUR': (('ευρώ', 'ευρώ'), ('λεπτό', 'λεπτά')),
26
+ 'USD': (('δολάριο', 'δολάρια'), ('σεντ', 'σεντς')),
27
+ 'GBP': (('λίρα', 'λίρες'), ('πέννα', 'πένες')),
28
+ }
29
+
30
+ def setup(self):
31
+ Num2Word_EUR.setup(self)
32
+
33
+ self.negword = "μείον "
34
+ self.pointword = "κόμμα"
35
+ self.errmsg_nonnum = (
36
+ "Μόνο αριθμοί μπορούν να μετατραπούν σε λέξεις."
37
+ )
38
+ self.errmsg_toobig = (
39
+ "Αριθμός πολύ μεγάλος για να μετατραπεί σε λέξεις (abs(%s) > %s)."
40
+ )
41
+ self.exclude_title = ["και", "κόμμα", "μείον"]
42
+
43
+ # Override the EU settings with Greek
44
+ self.GIGA_SUFFIX = "" # Don't use the EU pattern
45
+ self.MEGA_SUFFIX = "" # Don't use the EU pattern
46
+
47
+ # Mid numbers: thousands and hundreds with tens
48
+ self.mid_numwords = [(1000000000000, "τρισεκατομμύριο"),
49
+ (1000000000, "δισεκατομμύριο"),
50
+ (1000000, "εκατομμύριο"),
51
+ (1000, "χίλια"), (100, "εκατό"),
52
+ (90, "ενενήντα"), (80, "ογδόντα"), (70, "εβδομήντα"),
53
+ (60, "εξήντα"), (50, "πενήντα"), (40, "σαράντα"),
54
+ (30, "τριάντα")]
55
+
56
+ # Low numbers 0-29
57
+ self.low_numwords = ["είκοσι", "δεκαεννέα", "δεκαοκτώ", "δεκαεπτά",
58
+ "δεκαέξι", "δεκαπέντε", "δεκατέσσερα", "δεκατρία",
59
+ "δώδεκα", "έντεκα", "δέκα", "εννέα", "οκτώ",
60
+ "επτά", "έξι", "πέντε", "τέσσερα", "τρία", "δύο",
61
+ "ένα", "μηδέν"]
62
+
63
+ # Ordinal numbers mapping
64
+ self.ordinals = {
65
+ "ένα": "πρώτος",
66
+ "δύο": "δεύτερος",
67
+ "τρία": "τρίτος",
68
+ "τέσσερα": "τέταρτος",
69
+ "πέντε": "πέμπτος",
70
+ "έξι": "έκτος",
71
+ "επτά": "έβδομος",
72
+ "οκτώ": "όγδοος",
73
+ "εννέα": "έννατος",
74
+ "δέκα": "δέκατος",
75
+ "έντεκα": "ενδέκατος",
76
+ "δώδεκα": "δωδέκατος",
77
+ "είκοσι": "εικοστός",
78
+ "εκατό": "εκατοστός",
79
+ "χίλια": "χιλιοστός",
80
+ "εκατομμύριο": "εκατομμυριοστός"
81
+ }
82
+
83
+ def merge(self, curr, next):
84
+ ctext, cnum, ntext, nnum = curr + next
85
+
86
+ # Special handling for 1
87
+ if cnum == 1:
88
+ if nnum == 100:
89
+ return ("εκατό", 100)
90
+ elif nnum == 1000:
91
+ return ("χίλια", 1000)
92
+ elif nnum >= 1000000:
93
+ return ("ένα " + ntext, cnum * nnum)
94
+ elif nnum < 1000000:
95
+ return next
96
+
97
+ # Handle multiplication (larger unit)
98
+ if nnum > cnum:
99
+ if nnum == 100:
100
+ # Hundreds
101
+ if cnum == 2:
102
+ return ("διακόσια", 200)
103
+ elif cnum == 3:
104
+ return ("τριακόσια", 300)
105
+ elif cnum == 4:
106
+ return ("τετρακόσια", 400)
107
+ elif cnum == 5:
108
+ return ("πεντακόσια", 500)
109
+ elif cnum == 6:
110
+ return ("εξακόσια", 600)
111
+ elif cnum == 7:
112
+ return ("επτακόσια", 700)
113
+ elif cnum == 8:
114
+ return ("οκτακόσια", 800)
115
+ elif cnum == 9:
116
+ return ("εννιακόσια", 900)
117
+ elif nnum == 1000:
118
+ # Thousands - need feminine forms for certain numbers
119
+ if cnum == 1:
120
+ # Special case: when merging compound numbers ending with 1
121
+ # For feminine thousands, "ένα" becomes "μία"
122
+ if "ένα" in ctext:
123
+ ctext_fem = ctext.replace("ένα", "μία")
124
+ return (ctext_fem + " χιλιάδες", cnum * nnum)
125
+ else:
126
+ return ("χίλια", 1000)
127
+ elif cnum == 2:
128
+ return ("δύο χιλιάδες", 2000)
129
+ elif cnum == 3:
130
+ return ("τρεις χιλιάδες", 3000)
131
+ elif cnum == 4:
132
+ return ("τέσσερις χιλιάδες", 4000)
133
+ elif cnum == 200:
134
+ return ("διακόσιες χιλιάδες", 200000)
135
+ elif cnum == 300:
136
+ return ("τριακόσιες χιλιάδες", 300000)
137
+ elif cnum == 400:
138
+ return ("τετρακόσιες χιλιάδες", 400000)
139
+ elif cnum == 500:
140
+ return ("πεντακόσιες χιλιάδες", 500000)
141
+ elif cnum == 600:
142
+ return ("εξακόσιες χιλιάδες", 600000)
143
+ elif cnum == 700:
144
+ return ("επτακόσιες χιλιάδες", 700000)
145
+ elif cnum == 800:
146
+ return ("οκτακόσιες χιλιάδες", 800000)
147
+ elif cnum == 900:
148
+ return ("εννιακόσιες χιλιάδες", 900000)
149
+ else:
150
+ # For other numbers, adjust the form for feminine thousands
151
+ ctext_new = ctext
152
+ # Convert "ένα" to "μία" for feminine thousands
153
+ ctext_new = ctext_new.replace("ένα", "μία")
154
+ # Convert all hundreds to feminine form for χιλιάδες
155
+ ctext_new = ctext_new.replace("διακόσια", "διακόσιες")
156
+ ctext_new = ctext_new.replace("τριακόσια", "τριακόσιες")
157
+ ctext_new = ctext_new.replace("τετρακόσια", "τετρακόσιες")
158
+ ctext_new = ctext_new.replace("πεντακόσια", "πεντακόσιες")
159
+ ctext_new = ctext_new.replace("εξακόσια", "εξακόσιες")
160
+ ctext_new = ctext_new.replace("επτακόσια", "επτακόσιες")
161
+ ctext_new = ctext_new.replace("οκτακόσια", "οκτακόσιες")
162
+ ctext_new = ctext_new.replace("εννιακόσια", "εννιακόσιες")
163
+ return (ctext_new + " χιλιάδες", cnum * nnum)
164
+ elif nnum == 1000000:
165
+ # Millions - need special grammar for compound numbers
166
+ if cnum == 1:
167
+ return ("ένα εκατομμύριο", 1000000)
168
+ elif cnum == 2:
169
+ return ("δύο εκατομμύρια", 2000000)
170
+ elif cnum == 3:
171
+ return ("τρία εκατομμύρια", 3000000)
172
+ elif cnum == 4:
173
+ return ("τέσσερα εκατομμύρια", 4000000)
174
+ else:
175
+ # For compound numbers with millions, εκατομμύρια is neuter
176
+ # so we keep the neuter forms (τέσσερα, not τέσσερις)
177
+ return (ctext + " εκατομμύρια", cnum * nnum)
178
+ elif nnum == 1000000000:
179
+ # Billions
180
+ if cnum == 1:
181
+ return ("ένα δισεκατομμύριο", 1000000000)
182
+ else:
183
+ return (ctext + " δισεκατομμύρια", cnum * nnum)
184
+ elif nnum == 1000000000000:
185
+ # Trillions
186
+ if cnum == 1:
187
+ return ("ένα τρισεκατομμύριο", 1000000000000)
188
+ else:
189
+ return (ctext + " τρισεκατομμύρια", cnum * nnum)
190
+ elif nnum >= 1000000:
191
+ # Other large numbers
192
+ if cnum == 1:
193
+ return ("ένα " + ntext, cnum * nnum)
194
+ else:
195
+ return (ctext + " " + ntext, cnum * nnum)
196
+ else:
197
+ # Regular multiplication
198
+ return (ctext + " " + ntext, cnum * nnum)
199
+
200
+ # Handle addition (smaller unit added)
201
+ else:
202
+ return (ctext + " " + ntext, cnum + nnum)
203
+
204
+ def to_ordinal(self, value):
205
+ self.verify_ordinal(value)
206
+ word = self.to_cardinal(value)
207
+
208
+ # Handle special cases first
209
+ for cardinal, ordinal in self.ordinals.items():
210
+ if word == cardinal:
211
+ return ordinal
212
+
213
+ # Handle special compound numbers
214
+ if word == "δεκατέσσερα":
215
+ return "δεκατέταρτος"
216
+ elif word == "δεκατρία":
217
+ return "δεκατρίτος"
218
+ elif word == "ένα εκατομμύριο":
219
+ return "εκατομμυριοστός"
220
+
221
+ # Handle compound ordinals
222
+ parts = word.split()
223
+ if len(parts) > 1:
224
+ # Handle "είκοσι ένα" -> "εικοστός πρώτος"
225
+ if parts[0] == "είκοσι" and parts[1] == "ένα":
226
+ return "εικοστός πρώτος"
227
+ elif parts[0] == "είκοσι" and parts[1] in self.ordinals:
228
+ return "εικοστός " + self.ordinals[parts[1]]
229
+ # Handle "εκατό ένα" -> "εκατοστός πρώτος"
230
+ elif parts[0] == "εκατό" and parts[1] == "ένα":
231
+ return "εκατοστός πρώτος"
232
+ elif parts[0] == "εκατό" and parts[1] in self.ordinals:
233
+ return "εκατοστός " + self.ordinals[parts[1]]
234
+
235
+ # For compound numbers, make only the last part ordinal
236
+ last_part = parts[-1]
237
+ if last_part in self.ordinals:
238
+ # Transform first part if needed
239
+ if parts[0] == "είκοσι":
240
+ parts[0] = "εικοστός"
241
+ elif parts[0] == "εκατό":
242
+ parts[0] = "εκατοστός"
243
+ parts[-1] = self.ordinals[last_part]
244
+ return " ".join(parts)
245
+ # Handle other compound forms
246
+ elif last_part == "τέσσερα":
247
+ parts[-1] = "τέταρτος"
248
+ return " ".join(parts)
249
+
250
+ # Default ordinal formation
251
+ if word.endswith("α"):
252
+ return word[:-1] + "ος"
253
+ elif word.endswith("ο"):
254
+ return word[:-1] + "ος"
255
+ elif word.endswith("ι"):
256
+ return word + "ος"
257
+ else:
258
+ return word + "ος"
259
+
260
+ def to_ordinal_num(self, value):
261
+ self.verify_ordinal(value)
262
+ return str(value) + "ος"
263
+
264
+ def _money_verbose(self, number, currency):
265
+ if currency == 'GBP' and number == 1:
266
+ return "μία" # Feminine form for λίρα
267
+ return self.to_cardinal(number)
268
+
269
+ def _cents_verbose(self, number, currency):
270
+ if currency == 'GBP' and number == 1:
271
+ return "μία" # Feminine form for πέννα
272
+ return self.to_cardinal(number)
273
+
274
+ def to_currency(self, val, currency='EUR', cents=True, separator=' και',
275
+ adjective=False):
276
+ from decimal import Decimal
277
+
278
+ from .currency import parse_currency_parts, prefix_currency
279
+
280
+ # Check if value has fractional cents
281
+ decimal_val = Decimal(str(val))
282
+ has_fractional_cents = (decimal_val * 100) % 1 != 0
283
+
284
+ # Fix the currency parsing issue - integers should be treated as whole units
285
+ if isinstance(val, int):
286
+ left, right, is_negative = parse_currency_parts(val, is_int_with_cents=False)
287
+ else:
288
+ left, right, is_negative = parse_currency_parts(val, is_int_with_cents=False,
289
+ keep_precision=has_fractional_cents)
290
+
291
+ try:
292
+ cr1, cr2 = self.CURRENCY_FORMS[currency]
293
+ except KeyError:
294
+ raise NotImplementedError(
295
+ 'Currency code "%s" not implemented for "%s"' %
296
+ (currency, self.__class__.__name__))
297
+
298
+ if adjective and currency in self.CURRENCY_ADJECTIVES:
299
+ cr1 = prefix_currency(self.CURRENCY_ADJECTIVES[currency], cr1)
300
+
301
+ minus_str = "%s " % self.negword.strip() if is_negative else ""
302
+ money_str = self._money_verbose(left, currency)
303
+
304
+ # Explicitly check if input has decimal point or non-zero cents
305
+ has_decimal = isinstance(val, float) or str(val).find('.') != -1
306
+
307
+ # Only include cents if:
308
+ # 1. Input has decimal point OR
309
+ # 2. Cents are non-zero
310
+ if has_decimal or right > 0:
311
+ # Handle fractional cents
312
+ if isinstance(right, Decimal) and has_fractional_cents:
313
+ # Convert fractional cents (e.g., 65.3 cents)
314
+ cents_str = self.to_cardinal_float(float(right)) if cents else str(float(right))
315
+ else:
316
+ cents_str = self._cents_verbose(int(right) if isinstance(right, Decimal) else right, currency) \
317
+ if cents else self._cents_terse(int(right) if isinstance(right, Decimal) else right, currency)
318
+
319
+ return u'%s%s %s%s %s %s' % (
320
+ minus_str,
321
+ money_str,
322
+ self.pluralize(left, cr1),
323
+ separator,
324
+ cents_str,
325
+ self.pluralize(right, cr2)
326
+ )
327
+ else:
328
+ return u'%s%s %s' % (
329
+ minus_str,
330
+ money_str,
331
+ self.pluralize(left, cr1)
332
+ )
333
+
334
+ def pluralize(self, n, forms):
335
+ if n == 1:
336
+ return forms[0]
337
+ else:
338
+ return forms[1]
num2words2/lang_EN.py ADDED
@@ -0,0 +1,118 @@
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_EN(lang_EUR.Num2Word_EUR):
24
+ def __init__(self):
25
+ super(Num2Word_EN, self).__init__()
26
+ # Override specific currency forms for proper English pluralization
27
+ self.CURRENCY_FORMS['EUR'] = (('euro', 'euros'), ('cent', 'cents'))
28
+ self.CURRENCY_FORMS['USD'] = (('dollar', 'dollars'), ('cent', 'cents'))
29
+ self.CURRENCY_FORMS['GBP'] = (('pound', 'pounds'), ('penny', 'pence'))
30
+ self.CURRENCY_FORMS['NGN'] = (('naira', 'naira'), ('kobo', 'kobo'))
31
+
32
+ def set_high_numwords(self, high):
33
+ max = 3 + 3 * len(high)
34
+ for word, n in zip(high, range(max, 3, -3)):
35
+ self.cards[10 ** n] = word + "illion"
36
+
37
+ def setup(self):
38
+ super(Num2Word_EN, self).setup()
39
+
40
+ self.negword = "minus "
41
+ self.pointword = "point"
42
+ self.exclude_title = ["and", "point", "minus"]
43
+
44
+ self.mid_numwords = [(1000, "thousand"), (100, "hundred"),
45
+ (90, "ninety"), (80, "eighty"), (70, "seventy"),
46
+ (60, "sixty"), (50, "fifty"), (40, "forty"),
47
+ (30, "thirty")]
48
+ self.low_numwords = ["twenty", "nineteen", "eighteen", "seventeen",
49
+ "sixteen", "fifteen", "fourteen", "thirteen",
50
+ "twelve", "eleven", "ten", "nine", "eight",
51
+ "seven", "six", "five", "four", "three", "two",
52
+ "one", "zero"]
53
+ self.ords = {"one": "first",
54
+ "two": "second",
55
+ "three": "third",
56
+ "four": "fourth",
57
+ "five": "fifth",
58
+ "six": "sixth",
59
+ "seven": "seventh",
60
+ "eight": "eighth",
61
+ "nine": "ninth",
62
+ "ten": "tenth",
63
+ "eleven": "eleventh",
64
+ "twelve": "twelfth"}
65
+
66
+ def merge(self, lpair, rpair):
67
+ ltext, lnum = lpair
68
+ rtext, rnum = rpair
69
+ if lnum == 1 and rnum < 100:
70
+ return (rtext, rnum)
71
+ elif 100 > lnum > rnum:
72
+ return ("%s-%s" % (ltext, rtext), lnum + rnum)
73
+ elif lnum >= 100 > rnum:
74
+ return ("%s and %s" % (ltext, rtext), lnum + rnum)
75
+ elif rnum > lnum:
76
+ return ("%s %s" % (ltext, rtext), lnum * rnum)
77
+ return ("%s, %s" % (ltext, rtext), lnum + rnum)
78
+
79
+ def to_ordinal(self, value):
80
+ self.verify_ordinal(value)
81
+ outwords = self.to_cardinal(value).split(" ")
82
+ lastwords = outwords[-1].split("-")
83
+ lastword = lastwords[-1].lower()
84
+ try:
85
+ lastword = self.ords[lastword]
86
+ except KeyError:
87
+ if lastword[-1] == "y":
88
+ lastword = lastword[:-1] + "ie"
89
+ lastword += "th"
90
+ lastwords[-1] = self.title(lastword)
91
+ outwords[-1] = "-".join(lastwords)
92
+ return " ".join(outwords)
93
+
94
+ def to_ordinal_num(self, value):
95
+ self.verify_ordinal(value)
96
+ return "%s%s" % (value, self.to_ordinal(value)[-2:])
97
+
98
+ def to_year(self, val, suffix=None, longval=True):
99
+ if val < 0:
100
+ val = abs(val)
101
+ suffix = 'BC' if not suffix else suffix
102
+ high, low = (val // 100, val % 100)
103
+ # If year is 00XX, X00X, or beyond 9999, go cardinal.
104
+ if (high == 0
105
+ or (high % 10 == 0 and low < 10)
106
+ or high >= 100):
107
+ valtext = self.to_cardinal(val)
108
+ else:
109
+ hightext = self.to_cardinal(high)
110
+ if low == 0:
111
+ lowtext = "hundred"
112
+ elif low < 10:
113
+ lowtext = "oh-%s" % self.to_cardinal(low)
114
+ else:
115
+ lowtext = self.to_cardinal(low)
116
+ valtext = "%s %s" % (hightext, lowtext)
117
+ return (valtext if not suffix
118
+ else "%s %s" % (valtext, suffix))
@@ -0,0 +1,26 @@
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 .lang_EN import Num2Word_EN
21
+
22
+
23
+ class Num2Word_EN_IN(Num2Word_EN):
24
+ def set_high_numwords(self, high):
25
+ self.cards[10 ** 7] = "crore"
26
+ self.cards[10 ** 5] = "lakh"
@@ -0,0 +1,45 @@
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 . import lang_EN
21
+
22
+
23
+ class Num2Word_EN_NG(lang_EN.Num2Word_EN):
24
+
25
+ CURRENCY_FORMS = {
26
+ 'NGN': (('naira', 'naira'), ('kobo', 'kobo')),
27
+ 'EUR': (('euro', 'euros'), ('cent', 'cents')),
28
+ 'USD': (('dollar', 'dollars'), ('cent', 'cents')),
29
+ }
30
+
31
+ CURRENCY_ADJECTIVES = {
32
+ 'NGN': 'Nigerian',
33
+ 'EUR': 'European',
34
+ 'USD': 'US',
35
+ }
36
+
37
+ def to_currency(
38
+ self, val, currency='NGN',
39
+ kobo=True, separator=',',
40
+ adjective=False
41
+ ):
42
+ result = super(Num2Word_EN_NG, self).to_currency(
43
+ val, currency=currency, cents=kobo, separator=separator,
44
+ adjective=adjective)
45
+ return result
num2words2/lang_EO.py ADDED
@@ -0,0 +1,130 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) 2021, Savoir-faire Linux inc. All Rights Reserved.
3
+
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License as published by the Free Software Foundation; either
7
+ # version 2.1 of the License, or (at your option) any later version.
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15
+ # MA 02110-1301 USA
16
+
17
+ from __future__ import print_function, unicode_literals
18
+
19
+ from .base import Num2Word_Base
20
+
21
+
22
+ class Num2Word_EO(Num2Word_Base):
23
+ CURRENCY_FORMS = {
24
+ "EUR": (("eŭro", "eŭroj"), ("centimo", "centimoj")),
25
+ "USD": (("dolaro", "dolaroj"), ("cendo", "cendoj")),
26
+ "FRF": (("franko", "frankoj"), ("centimo", "centimoj")),
27
+ "GBP": (("pundo", "pundoj"), ("penco", "pencoj")),
28
+ "CNY": (("juano", "juanoj"), ("feno", "fenoj")),
29
+ }
30
+
31
+ GIGA_SUFFIX = "iliardo"
32
+ MEGA_SUFFIX = "iliono"
33
+
34
+ def set_high_numwords(self, high):
35
+ cap = 3 + 6 * len(high)
36
+
37
+ for word, n in zip(high, range(cap, 3, -6)):
38
+ if self.GIGA_SUFFIX:
39
+ self.cards[10 ** n] = word + self.GIGA_SUFFIX
40
+
41
+ if self.MEGA_SUFFIX:
42
+ self.cards[10 ** (n - 3)] = word + self.MEGA_SUFFIX
43
+
44
+ def gen_high_numwords(self, units, tens, lows):
45
+ out = [u + t for t in tens for u in units]
46
+ out.reverse()
47
+ return out + lows
48
+
49
+ def setup(self):
50
+ lows = ["naŭ", "ok", "sep", "ses", "kvin", "kvar", "tr", "b", "m"]
51
+ units = ["", "un", "duo", "tre", "kvatuor",
52
+ "kvin", "seks", "septen", "okto", "novem"]
53
+ tens = ["dek", "vigint", "trigint", "kvadragint", "kvinkvagint",
54
+ "seksagint", "septuagint", "oktogint", "nonagint"]
55
+
56
+ self.high_numwords = ["cent"] + self.gen_high_numwords(units, tens,
57
+ lows)
58
+
59
+ self.negword = "minus "
60
+ self.pointword = "komo"
61
+ self.errmsg_nonnum = u"Sole nombroj povas esti konvertita en vortojn."
62
+ self.errmsg_toobig = (
63
+ u"Tro granda nombro por esti konvertita en vortojn (abs(%s) > %s)."
64
+ )
65
+ self.exclude_title = ["kaj", "komo", "minus"]
66
+ self.mid_numwords = [(1000, "mil"), (100, "cent"), (90, "naŭdek"),
67
+ (80, "okdek"), (70, "sepdek"), (60, "sesdek"),
68
+ (50, "kvindek"), (40, "kvardek"), (30, "tridek")]
69
+ self.low_numwords = ["dudek", "dek naŭ", "dek ok", "dek sep",
70
+ "dek ses", "dek kvin", "dek kvar", "dek tri",
71
+ "dek du", "dek unu", "dek", "naŭ", "ok", "sep",
72
+ "ses", "kvin", "kvar", "tri", "du", "unu", "nul"]
73
+ self.ords = {
74
+ "unu": "unua",
75
+ "du": "dua",
76
+ "tri": "tria",
77
+ "kvar": "kvara",
78
+ "kvin": "kvina",
79
+ "ses": "sesa",
80
+ "sep": "sepa",
81
+ "ok": "oka",
82
+ "naŭ": "naŭa",
83
+ "dek": "deka"
84
+ }
85
+
86
+ def merge(self, curr, next):
87
+ ctext, cnum, ntext, nnum = curr + next
88
+ if cnum == 1 and nnum < 1000000:
89
+ return next
90
+
91
+ if nnum >= 10**6 and cnum > 1:
92
+ return ("%s %sj" % (ctext, ntext), cnum + nnum)
93
+
94
+ if nnum == 100:
95
+ return ("%s%s" % (ctext, ntext), cnum + nnum)
96
+
97
+ return ("%s %s" % (ctext, ntext), cnum + nnum)
98
+
99
+ def to_ordinal(self, value):
100
+ self.verify_ordinal(value)
101
+ word = self.to_cardinal(value)
102
+ for src, repl in self.ords.items():
103
+ if word.endswith(src):
104
+ word = word[:-len(src)] + repl
105
+ return word
106
+
107
+ if word.endswith("o"):
108
+ word = word[:-1] + "a"
109
+ elif word.endswith("oj"):
110
+ word = word[:-2] + "a"
111
+ else:
112
+ word = word + "a"
113
+ return word
114
+
115
+ def to_ordinal_num(self, value):
116
+ self.verify_ordinal(value)
117
+ out = str(value)
118
+ out += "a"
119
+ return out
120
+
121
+ def to_currency(self, val, currency="EUR", cents=True, separator=" kaj",
122
+ adjective=False):
123
+ result = super(Num2Word_EO, self).to_currency(
124
+ val, currency=currency, cents=cents, separator=separator,
125
+ adjective=adjective)
126
+ return result
127
+
128
+ def pluralize(self, n, forms):
129
+ form = 0 if n <= 1 else 1
130
+ return forms[form]