nepali 0.5.5__py3-none-any.whl → 1.2.0__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.
- nepali/__init__.py +1 -1
- nepali/char.py +102 -81
- nepali/constants.py +66 -0
- nepali/date_converter.py +334 -0
- nepali/datetime/__init__.py +13 -14
- nepali/datetime/_datetime.py +391 -402
- nepali/datetime/_formatter.py +325 -0
- nepali/datetime/_humanize.py +117 -132
- nepali/datetime/_nepalimonth.py +118 -0
- nepali/datetime/_nepaliweek.py +125 -0
- nepali/datetime/parser/__init__.py +4 -4
- nepali/datetime/parser/_parser.py +59 -50
- nepali/datetime/parser/validators.py +249 -159
- nepali/datetime/utils.py +38 -0
- nepali/exceptions.py +8 -3
- nepali/locations/__init__.py +3 -0
- nepali/locations/_data.py +4271 -0
- nepali/locations/_locations.py +38 -0
- nepali/locations/models.py +104 -0
- nepali/locations/utils.py +54 -0
- nepali/number/__init__.py +19 -0
- nepali/number/_nepalinumber.py +563 -0
- nepali/number/_number.py +53 -0
- nepali/number/utils.py +72 -0
- nepali/phone_number.py +183 -0
- nepali/templatetags/__init__.py +0 -0
- nepali/templatetags/nepalidatetime.py +194 -24
- nepali/templatetags/nepalinumber.py +97 -7
- nepali/tests/test_date_converter.py +148 -0
- nepali/tests/test_datetime.py +275 -29
- nepali/tests/test_humanize.py +78 -7
- nepali/tests/test_locations.py +154 -0
- nepali/tests/test_nepalimonth.py +152 -0
- nepali/tests/test_nepaliweek.py +154 -0
- nepali/tests/test_number.py +3152 -0
- nepali/tests/test_parser.py +82 -69
- nepali/tests/test_phone_number.py +254 -0
- nepali/tests/test_timezone.py +192 -0
- nepali/timezone.py +50 -7
- nepali/utils.py +9 -68
- nepali-1.2.0.dist-info/METADATA +476 -0
- nepali-1.2.0.dist-info/RECORD +46 -0
- {nepali-0.5.5.dist-info → nepali-1.2.0.dist-info}/WHEEL +1 -1
- {nepali-0.5.5.dist-info → nepali-1.2.0.dist-info/licenses}/LICENSE +1 -1
- {nepali-0.5.5.dist-info → nepali-1.2.0.dist-info}/top_level.txt +0 -0
- nepali/datetime/_converter.py +0 -394
- nepali/datetime/_formarter.py +0 -314
- nepali/datetime.py +0 -1169
- nepali/number.py +0 -51
- nepali-0.5.5.dist-info/METADATA +0 -220
- nepali-0.5.5.dist-info/RECORD +0 -27
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains the class for the nepalinumber feature
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from .utils import NP_NUMBERS, NP_NUMBERS_SET, english_to_nepali
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class nepalinumber:
|
|
13
|
+
"""
|
|
14
|
+
Represents the nepali(devanagari) numbers and
|
|
15
|
+
the features related to arithmetic operations
|
|
16
|
+
on them
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, value: Any) -> None:
|
|
20
|
+
"""
|
|
21
|
+
Constructor/Initializer
|
|
22
|
+
"""
|
|
23
|
+
self.__value = self.__parse(value)
|
|
24
|
+
|
|
25
|
+
def get_parse_exception(
|
|
26
|
+
self, obj: object, ex_class: type[Exception] = ValueError
|
|
27
|
+
) -> Exception:
|
|
28
|
+
"""
|
|
29
|
+
Returns the exception object to be raised when the parse is failed.
|
|
30
|
+
The methods also sets a proper message to the exception class.
|
|
31
|
+
|
|
32
|
+
:param obj: Object that is failed during the parse
|
|
33
|
+
:type obj: object
|
|
34
|
+
:param ex_class: Exception class type to be returned, defaults to ValueError
|
|
35
|
+
:type ex_class: type[Exception], optional
|
|
36
|
+
:return: Exception object to be raised
|
|
37
|
+
:rtype: Exception
|
|
38
|
+
"""
|
|
39
|
+
return ex_class(
|
|
40
|
+
f"could not convert {obj.__class__.__name__} to {self.__class__.__name__}: '{obj}'"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def __parse(self, value: Any) -> int | float:
|
|
44
|
+
"""
|
|
45
|
+
Parses nepali number input into a valid value.
|
|
46
|
+
|
|
47
|
+
Eg:
|
|
48
|
+
>>> self.__parse("१२")
|
|
49
|
+
12
|
|
50
|
+
>>> self.__parse("१२.३")
|
|
51
|
+
12.3
|
|
52
|
+
>>> self.__parse(1)
|
|
53
|
+
1
|
|
54
|
+
>>> self.__parse("invalid")
|
|
55
|
+
ValueError: could not convert str to nepalinumber: 'invalid'
|
|
56
|
+
|
|
57
|
+
:param value: Value to be parsed.
|
|
58
|
+
:return: returns value int or float
|
|
59
|
+
:raises ValueError: If the value is invalid
|
|
60
|
+
:raises TypeError: If the value object can't be parsed
|
|
61
|
+
"""
|
|
62
|
+
if isinstance(value, int):
|
|
63
|
+
return int(value)
|
|
64
|
+
|
|
65
|
+
elif isinstance(value, float):
|
|
66
|
+
return float(value)
|
|
67
|
+
|
|
68
|
+
elif isinstance(value, str):
|
|
69
|
+
return self.__parse_str(value)
|
|
70
|
+
|
|
71
|
+
return self.__parse_object(value)
|
|
72
|
+
|
|
73
|
+
def __parse_str(self, value: str) -> int | float:
|
|
74
|
+
"""
|
|
75
|
+
Parses str object into int and float.
|
|
76
|
+
This is a low level implementation.
|
|
77
|
+
|
|
78
|
+
:raises ValueError: If the value is invalid
|
|
79
|
+
"""
|
|
80
|
+
result: float = 0
|
|
81
|
+
sign = 1
|
|
82
|
+
decimal_found = False
|
|
83
|
+
decimal_place: float = 1
|
|
84
|
+
i = 0
|
|
85
|
+
|
|
86
|
+
# for negative sign
|
|
87
|
+
if value[0] == "-":
|
|
88
|
+
sign = -1
|
|
89
|
+
i = 1
|
|
90
|
+
|
|
91
|
+
while i < len(value):
|
|
92
|
+
# decimal number found
|
|
93
|
+
if value[i] == ".":
|
|
94
|
+
if decimal_found:
|
|
95
|
+
# decimal was already found
|
|
96
|
+
raise self.get_parse_exception(value) from None
|
|
97
|
+
decimal_found = True
|
|
98
|
+
i += 1
|
|
99
|
+
continue
|
|
100
|
+
|
|
101
|
+
digit = ord(value[i]) - ord("0")
|
|
102
|
+
if digit < 0 or digit > 9:
|
|
103
|
+
# checking nepali character
|
|
104
|
+
if value[i] not in NP_NUMBERS_SET:
|
|
105
|
+
raise self.get_parse_exception(value) from None
|
|
106
|
+
digit = NP_NUMBERS.index(value[i])
|
|
107
|
+
|
|
108
|
+
if decimal_found:
|
|
109
|
+
decimal_place /= 10
|
|
110
|
+
result += digit * decimal_place
|
|
111
|
+
else:
|
|
112
|
+
result = result * 10 + digit
|
|
113
|
+
|
|
114
|
+
i += 1
|
|
115
|
+
return sign * result
|
|
116
|
+
|
|
117
|
+
def __parse_object(self, obj: Any) -> int | float:
|
|
118
|
+
"""
|
|
119
|
+
Parses object using __int__, __float__, and __str__.
|
|
120
|
+
|
|
121
|
+
:raises TypeError: If the value object can't be parsed
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
if hasattr(obj, "__float__"):
|
|
125
|
+
return float(obj)
|
|
126
|
+
elif hasattr(obj, "__int__"):
|
|
127
|
+
return int(obj)
|
|
128
|
+
|
|
129
|
+
return self.__parse_str(str(obj))
|
|
130
|
+
except (ValueError, TypeError):
|
|
131
|
+
# object conversion must raise TypeError if fails
|
|
132
|
+
raise self.get_parse_exception(obj, ex_class=TypeError) from None
|
|
133
|
+
|
|
134
|
+
def __convert_or_return(self, obj) -> nepalinumber | object:
|
|
135
|
+
"""
|
|
136
|
+
Will try to parse the given object and convert to nepalinumber
|
|
137
|
+
else will return the same object
|
|
138
|
+
|
|
139
|
+
:param obj: The object to convert
|
|
140
|
+
|
|
141
|
+
:returns: Either a nepalinumber or the same object unchanged
|
|
142
|
+
"""
|
|
143
|
+
try:
|
|
144
|
+
return nepalinumber(obj)
|
|
145
|
+
except (TypeError, ValueError):
|
|
146
|
+
return obj
|
|
147
|
+
|
|
148
|
+
def __str__(self) -> str:
|
|
149
|
+
"""
|
|
150
|
+
Called when the object is called with functions
|
|
151
|
+
like print or logger.debug()
|
|
152
|
+
"""
|
|
153
|
+
return str(self.__value)
|
|
154
|
+
|
|
155
|
+
def __repr__(self) -> str:
|
|
156
|
+
return str(self.__value)
|
|
157
|
+
|
|
158
|
+
def __int__(self) -> int:
|
|
159
|
+
"""
|
|
160
|
+
Called when the object is typecasted into integer
|
|
161
|
+
"""
|
|
162
|
+
return int(self.__value)
|
|
163
|
+
|
|
164
|
+
def __float__(self) -> float:
|
|
165
|
+
"""
|
|
166
|
+
Called when the object is typecasted into float
|
|
167
|
+
"""
|
|
168
|
+
return float(self.__value)
|
|
169
|
+
|
|
170
|
+
def __add(self, other) -> int | float:
|
|
171
|
+
"""
|
|
172
|
+
Adds the value in the object with the passed object
|
|
173
|
+
|
|
174
|
+
:param other: The other number/object to be added to the object
|
|
175
|
+
:raises TypeError: Raised when unsupported data types
|
|
176
|
+
are added to the nepalinumber object
|
|
177
|
+
:return: A new nepalinumber object with the added values
|
|
178
|
+
"""
|
|
179
|
+
if isinstance(other, nepalinumber):
|
|
180
|
+
return self.__value + other.value
|
|
181
|
+
|
|
182
|
+
return self.__value + other
|
|
183
|
+
|
|
184
|
+
def __mul(self, other) -> int | float:
|
|
185
|
+
"""
|
|
186
|
+
Multiplies the value in the object with the passed object
|
|
187
|
+
|
|
188
|
+
:param other: The other number/object to be added to the object
|
|
189
|
+
:raises TypeError: Raised when unsupported data types
|
|
190
|
+
are multiplied to the nepalinumber object
|
|
191
|
+
:return: A new nepalinumber object with the multiplied values
|
|
192
|
+
"""
|
|
193
|
+
if isinstance(other, nepalinumber):
|
|
194
|
+
return self.__value * other.value
|
|
195
|
+
|
|
196
|
+
return self.__value * other
|
|
197
|
+
|
|
198
|
+
def __eq__(self, other) -> bool:
|
|
199
|
+
"""
|
|
200
|
+
Checks if nepalinumber is equal to another object
|
|
201
|
+
|
|
202
|
+
:param other: The other number/object which is to be checked for
|
|
203
|
+
equality against nepalinumber
|
|
204
|
+
:return: True if equal else False
|
|
205
|
+
"""
|
|
206
|
+
if isinstance(other, nepalinumber):
|
|
207
|
+
return self.__value == other.value
|
|
208
|
+
|
|
209
|
+
return self.__value == other
|
|
210
|
+
|
|
211
|
+
def __ne__(self, other) -> bool:
|
|
212
|
+
"""
|
|
213
|
+
Checks if nepalinumber is not equal to another object
|
|
214
|
+
|
|
215
|
+
:param other: The other number/object which is to be checked for
|
|
216
|
+
equality against nepalinumber
|
|
217
|
+
:return: True if not equal else False
|
|
218
|
+
"""
|
|
219
|
+
if isinstance(other, nepalinumber):
|
|
220
|
+
return self.__value != other.value
|
|
221
|
+
|
|
222
|
+
return self.__value != other
|
|
223
|
+
|
|
224
|
+
def __neg__(self) -> nepalinumber:
|
|
225
|
+
"""
|
|
226
|
+
Returns the negative value of the nepalinumber value
|
|
227
|
+
"""
|
|
228
|
+
return nepalinumber((-1) * self.__value)
|
|
229
|
+
|
|
230
|
+
def __add__(self, other) -> nepalinumber | object:
|
|
231
|
+
"""
|
|
232
|
+
Called when the addition operator + is used after
|
|
233
|
+
the nepalinumber object
|
|
234
|
+
|
|
235
|
+
:param other: The other number/object that is to be
|
|
236
|
+
added to the value onto the nepalinumber object
|
|
237
|
+
:raises TypeError: Raised when unsupported data types
|
|
238
|
+
are added to the nepalinumber object
|
|
239
|
+
:return: Returns the added value as a nepalinumber
|
|
240
|
+
object
|
|
241
|
+
"""
|
|
242
|
+
try:
|
|
243
|
+
return self.__convert_or_return(self.__add(other))
|
|
244
|
+
except TypeError:
|
|
245
|
+
return NotImplemented
|
|
246
|
+
|
|
247
|
+
def __radd__(self, other) -> nepalinumber | object:
|
|
248
|
+
"""
|
|
249
|
+
Called when the addition operator + is used before
|
|
250
|
+
the nepalinumber object
|
|
251
|
+
|
|
252
|
+
:param other: The other number/object that is to be
|
|
253
|
+
added to the value onto the nepalinumber object
|
|
254
|
+
:raises TypeError: Raised when nepalinumber object is
|
|
255
|
+
added to unsupported data types
|
|
256
|
+
:return: Returns the added value as a nepalinumber
|
|
257
|
+
object
|
|
258
|
+
"""
|
|
259
|
+
try:
|
|
260
|
+
return self.__convert_or_return(self.__add(other))
|
|
261
|
+
except TypeError:
|
|
262
|
+
return NotImplemented
|
|
263
|
+
|
|
264
|
+
def __sub__(self, other) -> nepalinumber | object:
|
|
265
|
+
"""
|
|
266
|
+
Called when the subtraction operator - is used after
|
|
267
|
+
the nepalinumber object
|
|
268
|
+
|
|
269
|
+
:param other: The other number/object that is to be
|
|
270
|
+
subtracted from the value in the nepalinumber object
|
|
271
|
+
:raises TypeError: Raised when unsupported data types are
|
|
272
|
+
subtracted from nepalinumber object
|
|
273
|
+
:return: Returns the subtracted number as a nepalinumber object
|
|
274
|
+
"""
|
|
275
|
+
try:
|
|
276
|
+
if isinstance(other, nepalinumber):
|
|
277
|
+
return self.__convert_or_return(self.__value - other.value)
|
|
278
|
+
|
|
279
|
+
return self.__convert_or_return(self.__value - other)
|
|
280
|
+
except TypeError:
|
|
281
|
+
return NotImplemented
|
|
282
|
+
|
|
283
|
+
def __rsub__(self, other) -> nepalinumber | object:
|
|
284
|
+
"""
|
|
285
|
+
Called when the subtraction operator - is used before
|
|
286
|
+
the nepalinumber object
|
|
287
|
+
|
|
288
|
+
:param other: The other number/object that is to get
|
|
289
|
+
subtracted by the value in the nepalinumber object
|
|
290
|
+
:raises TypeError: Raised when nepalinumber object is
|
|
291
|
+
subtracted from unsupported data types
|
|
292
|
+
:return: Returns the subtracted number as a nepalinumber
|
|
293
|
+
object
|
|
294
|
+
"""
|
|
295
|
+
try:
|
|
296
|
+
if isinstance(other, nepalinumber):
|
|
297
|
+
return self.__convert_or_return(other.value - self.__value)
|
|
298
|
+
|
|
299
|
+
return self.__convert_or_return(other - self.__value)
|
|
300
|
+
except TypeError:
|
|
301
|
+
return NotImplemented
|
|
302
|
+
|
|
303
|
+
def __mul__(self, other) -> nepalinumber | object:
|
|
304
|
+
"""
|
|
305
|
+
Called when the multiplication operator * is used after
|
|
306
|
+
the nepalinumber object
|
|
307
|
+
|
|
308
|
+
:param other: The other number/object that is to be
|
|
309
|
+
multiplied to the value onto the nepalinumber object
|
|
310
|
+
:raises TypeError: Raised when unsupported data types
|
|
311
|
+
are multiplied to the nepalinumber object
|
|
312
|
+
:return: Returns the multiplied value as a nepalinumber
|
|
313
|
+
object
|
|
314
|
+
"""
|
|
315
|
+
try:
|
|
316
|
+
if isinstance(other, str):
|
|
317
|
+
return self.__value * other # type: ignore
|
|
318
|
+
|
|
319
|
+
return self.__convert_or_return(self.__mul(other))
|
|
320
|
+
except TypeError:
|
|
321
|
+
return NotImplemented
|
|
322
|
+
|
|
323
|
+
def __rmul__(self, other) -> nepalinumber | object:
|
|
324
|
+
"""
|
|
325
|
+
Called when the multiplication operator * is used before
|
|
326
|
+
the nepalinumber object
|
|
327
|
+
|
|
328
|
+
:param other: The other number/object that is to be
|
|
329
|
+
multiplied to the value onto the nepalinumber object
|
|
330
|
+
:raises TypeError: Raised when nepalinumber object is
|
|
331
|
+
multiplied to unsupported data types
|
|
332
|
+
:return: Returns the multiplied value as a nepalinumber
|
|
333
|
+
object
|
|
334
|
+
"""
|
|
335
|
+
try:
|
|
336
|
+
if isinstance(other, str):
|
|
337
|
+
return other * self.__value # type: ignore
|
|
338
|
+
|
|
339
|
+
return self.__convert_or_return(self.__mul(other))
|
|
340
|
+
except TypeError:
|
|
341
|
+
return NotImplemented
|
|
342
|
+
|
|
343
|
+
def __truediv__(self, other) -> nepalinumber | object:
|
|
344
|
+
"""
|
|
345
|
+
Called when the division operator / is used after
|
|
346
|
+
the nepalinumber object
|
|
347
|
+
|
|
348
|
+
:param other: The other number/object that is to divide
|
|
349
|
+
the value in the nepalinumber object
|
|
350
|
+
:raises TypeError: Raised when unsupported data types are
|
|
351
|
+
used to divide nepalinumber object
|
|
352
|
+
:return: Returns the quotient number as a nepalinumber object
|
|
353
|
+
"""
|
|
354
|
+
try:
|
|
355
|
+
if isinstance(other, nepalinumber):
|
|
356
|
+
return self.__convert_or_return(self.__value / other.value)
|
|
357
|
+
|
|
358
|
+
return self.__convert_or_return(self.__value / other)
|
|
359
|
+
except TypeError:
|
|
360
|
+
return NotImplemented
|
|
361
|
+
|
|
362
|
+
def __rtruediv__(self, other) -> nepalinumber | object:
|
|
363
|
+
"""
|
|
364
|
+
Called when the division operator / is used before
|
|
365
|
+
the nepalinumber object
|
|
366
|
+
|
|
367
|
+
:param other: The other number/object that is to get
|
|
368
|
+
divided by the value in the nepalinumber object
|
|
369
|
+
:raises TypeError: Raised when nepalinumber object is
|
|
370
|
+
used to divide unsupported data types
|
|
371
|
+
:return: Returns the quotient number as a nepalinumber
|
|
372
|
+
object
|
|
373
|
+
"""
|
|
374
|
+
try:
|
|
375
|
+
if isinstance(other, nepalinumber):
|
|
376
|
+
return self.__convert_or_return(other.value / self.__value)
|
|
377
|
+
|
|
378
|
+
return self.__convert_or_return(other / self.__value)
|
|
379
|
+
except TypeError:
|
|
380
|
+
return NotImplemented
|
|
381
|
+
|
|
382
|
+
def __floordiv__(self, other) -> nepalinumber | object:
|
|
383
|
+
"""
|
|
384
|
+
Called when the floor/integer division operator // is used
|
|
385
|
+
after the nepalinumber object
|
|
386
|
+
|
|
387
|
+
:param other: The other number/object that is to divide
|
|
388
|
+
the value in the nepalinumber object
|
|
389
|
+
:raises TypeError: Raised when unsupported data types are
|
|
390
|
+
used to divide nepalinumber object
|
|
391
|
+
:return: Returns the quotient number as a nepalinumber object
|
|
392
|
+
"""
|
|
393
|
+
try:
|
|
394
|
+
if isinstance(other, nepalinumber):
|
|
395
|
+
return self.__convert_or_return(self.__value // other.value)
|
|
396
|
+
|
|
397
|
+
return self.__convert_or_return(self.__value // other)
|
|
398
|
+
except TypeError:
|
|
399
|
+
return NotImplemented
|
|
400
|
+
|
|
401
|
+
def __rfloordiv__(self, other) -> nepalinumber | object:
|
|
402
|
+
"""
|
|
403
|
+
Called when the floor/integer division operator // is used
|
|
404
|
+
before the nepalinumber object
|
|
405
|
+
|
|
406
|
+
:param other: The other number/object that is to get
|
|
407
|
+
divided by the value in the nepalinumber object
|
|
408
|
+
:raises TypeError: Raised when nepalinumber object is
|
|
409
|
+
used to divide unsupported data types
|
|
410
|
+
:return: Returns the quotient number as a nepalinumber
|
|
411
|
+
object
|
|
412
|
+
"""
|
|
413
|
+
try:
|
|
414
|
+
if isinstance(other, nepalinumber):
|
|
415
|
+
return self.__convert_or_return(other.value // self.__value)
|
|
416
|
+
|
|
417
|
+
return self.__convert_or_return(other // self.__value)
|
|
418
|
+
except TypeError:
|
|
419
|
+
return NotImplemented
|
|
420
|
+
|
|
421
|
+
def __mod__(self, other) -> nepalinumber | object:
|
|
422
|
+
"""
|
|
423
|
+
Called when the modulo operator % is used after
|
|
424
|
+
the nepalinumber object
|
|
425
|
+
|
|
426
|
+
:param other: The other number/object that is to be
|
|
427
|
+
perform modulo division from the value in the
|
|
428
|
+
nepalinumber object
|
|
429
|
+
:raises TypeError: Raised when unsupported data types are
|
|
430
|
+
modulo divided from nepalinumber object
|
|
431
|
+
:return: Returns the remainder number as a nepalinumber object
|
|
432
|
+
"""
|
|
433
|
+
try:
|
|
434
|
+
if isinstance(other, nepalinumber):
|
|
435
|
+
return self.__convert_or_return(self.__value % other.value)
|
|
436
|
+
|
|
437
|
+
return self.__convert_or_return(self.__value % other)
|
|
438
|
+
except TypeError:
|
|
439
|
+
return NotImplemented
|
|
440
|
+
|
|
441
|
+
def __rmod__(self, other) -> nepalinumber | object:
|
|
442
|
+
"""
|
|
443
|
+
Called when the modulo operator % is used before
|
|
444
|
+
the nepalinumber object
|
|
445
|
+
|
|
446
|
+
:param other: The other number/object that is to get
|
|
447
|
+
modulo divided by the value in the nepalinumber object
|
|
448
|
+
:raises TypeError: Raised when nepalinumber object is
|
|
449
|
+
used modulo divide unsupported data types
|
|
450
|
+
:return: Returns the remainder number as a nepalinumber
|
|
451
|
+
object
|
|
452
|
+
"""
|
|
453
|
+
try:
|
|
454
|
+
if isinstance(other, nepalinumber):
|
|
455
|
+
return self.__convert_or_return(other.value % self.__value)
|
|
456
|
+
|
|
457
|
+
return self.__convert_or_return(other % self.__value)
|
|
458
|
+
except TypeError:
|
|
459
|
+
return NotImplemented
|
|
460
|
+
|
|
461
|
+
def __divmod__(
|
|
462
|
+
self, other
|
|
463
|
+
) -> tuple[nepalinumber | object, nepalinumber | object]:
|
|
464
|
+
"""
|
|
465
|
+
Called when the built-in function divmod() is used
|
|
466
|
+
with nepalinumber as the dividend and other as divisor
|
|
467
|
+
|
|
468
|
+
:param other: The other number/object that is to be
|
|
469
|
+
divisor for the value in the nepalinumber object
|
|
470
|
+
:raises TypeError: Raised when unsupported data types are
|
|
471
|
+
used as divisor for nepalinumber object
|
|
472
|
+
:return: Returns a tuple of quotient and remainder
|
|
473
|
+
"""
|
|
474
|
+
try:
|
|
475
|
+
if isinstance(other, nepalinumber):
|
|
476
|
+
quotient, remainder = divmod(self.__value, other.value)
|
|
477
|
+
|
|
478
|
+
quotient, remainder = divmod(self.__value, other)
|
|
479
|
+
|
|
480
|
+
return self.__convert_or_return(quotient), self.__convert_or_return(
|
|
481
|
+
remainder
|
|
482
|
+
)
|
|
483
|
+
except TypeError:
|
|
484
|
+
return NotImplemented
|
|
485
|
+
|
|
486
|
+
def __rdivmod__(
|
|
487
|
+
self, other
|
|
488
|
+
) -> tuple[nepalinumber | object, nepalinumber | object]:
|
|
489
|
+
"""
|
|
490
|
+
Called when the built-in function divmod() is used
|
|
491
|
+
with nepalinumber as the divisor and other as dividend
|
|
492
|
+
|
|
493
|
+
:param other: The other number/object that is to be
|
|
494
|
+
dividend for the value in the nepalinumber object
|
|
495
|
+
:raises TypeError: Raised when unsupported data types are
|
|
496
|
+
used as dividend for nepalinumber object
|
|
497
|
+
:return: Returns a tuple of quotient and remainder
|
|
498
|
+
"""
|
|
499
|
+
try:
|
|
500
|
+
if isinstance(other, nepalinumber):
|
|
501
|
+
quotient, remainder = divmod(other.value, self.__value)
|
|
502
|
+
|
|
503
|
+
quotient, remainder = divmod(other, self.__value)
|
|
504
|
+
|
|
505
|
+
return self.__convert_or_return(quotient), self.__convert_or_return(
|
|
506
|
+
remainder
|
|
507
|
+
)
|
|
508
|
+
except TypeError:
|
|
509
|
+
return NotImplemented
|
|
510
|
+
|
|
511
|
+
def __pow__(self, other) -> nepalinumber | object:
|
|
512
|
+
"""
|
|
513
|
+
Called when the power operator ** is used after
|
|
514
|
+
the nepalinumber object
|
|
515
|
+
|
|
516
|
+
:param other: The other number/object that is to be
|
|
517
|
+
powered to the value onto the nepalinumber object
|
|
518
|
+
:raises TypeError: Raised when unsupported data types
|
|
519
|
+
are powered to the nepalinumber object
|
|
520
|
+
:return: Returns the powered by value as a nepalinumber
|
|
521
|
+
object
|
|
522
|
+
"""
|
|
523
|
+
try:
|
|
524
|
+
if isinstance(other, nepalinumber):
|
|
525
|
+
return self.__convert_or_return(self.__value**other.value)
|
|
526
|
+
|
|
527
|
+
return self.__convert_or_return(self.__value**other)
|
|
528
|
+
except TypeError:
|
|
529
|
+
return NotImplemented
|
|
530
|
+
|
|
531
|
+
def __rpow__(self, other) -> nepalinumber | object:
|
|
532
|
+
"""
|
|
533
|
+
Called when the power operator ** is used before
|
|
534
|
+
the nepalinumber object
|
|
535
|
+
|
|
536
|
+
:param other: The other number/object that is to be
|
|
537
|
+
powered by the value onto the nepalinumber object
|
|
538
|
+
:raises TypeError: Raised when unsupported data types
|
|
539
|
+
are powered by the nepalinumber object
|
|
540
|
+
:return: Returns the powered by value as a nepalinumber
|
|
541
|
+
object
|
|
542
|
+
"""
|
|
543
|
+
try:
|
|
544
|
+
if isinstance(other, nepalinumber):
|
|
545
|
+
return self.__convert_or_return(other.value**self.__value)
|
|
546
|
+
|
|
547
|
+
return self.__convert_or_return(other**self.__value)
|
|
548
|
+
except TypeError:
|
|
549
|
+
return NotImplemented
|
|
550
|
+
|
|
551
|
+
def str_ne(self) -> str:
|
|
552
|
+
"""
|
|
553
|
+
Returns nepali (devanagari) format for the number
|
|
554
|
+
|
|
555
|
+
:return: Stringified Nepali number
|
|
556
|
+
"""
|
|
557
|
+
if not hasattr(self, "__str_ne"):
|
|
558
|
+
self.__str_ne = english_to_nepali(self.__value)
|
|
559
|
+
return self.__str_ne
|
|
560
|
+
|
|
561
|
+
@property
|
|
562
|
+
def value(self):
|
|
563
|
+
return self.__value
|
nepali/number/_number.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
3
|
+
from .utils import add_comma, add_comma_english, english_to_nepali, nepali_to_english
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# Backward compatibility support for legacy NepaliNumber
|
|
7
|
+
class NepaliNumber:
|
|
8
|
+
@classmethod
|
|
9
|
+
def convert_and_add_comma(cls, number):
|
|
10
|
+
warnings.warn(
|
|
11
|
+
message="NepaliNumber.convert_and_add_comma has been moved to "
|
|
12
|
+
"`convert_and_add_comma. This function is depreciated and will "
|
|
13
|
+
"be removed in the future release.",
|
|
14
|
+
category=DeprecationWarning,
|
|
15
|
+
)
|
|
16
|
+
return add_comma(english_to_nepali(number))
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def convert(num):
|
|
20
|
+
warnings.warn(
|
|
21
|
+
message="NepaliNumber.convert has been moved to `english_to_nepali. "
|
|
22
|
+
"This function is depreciated and will be removed in the future release.",
|
|
23
|
+
category=DeprecationWarning,
|
|
24
|
+
)
|
|
25
|
+
return english_to_nepali(num)
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def revert(num):
|
|
29
|
+
warnings.warn(
|
|
30
|
+
message="NepaliNumber.revert has been moved to `nepali_to_english. "
|
|
31
|
+
"This function is depreciated and will be removed in the future release.",
|
|
32
|
+
category=DeprecationWarning,
|
|
33
|
+
)
|
|
34
|
+
return nepali_to_english(num)
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def add_comma(number):
|
|
38
|
+
warnings.warn(
|
|
39
|
+
message="NepaliNumber.add_comma has been moved to `add_comma. "
|
|
40
|
+
"This function is depreciated and will be removed in the future release.",
|
|
41
|
+
category=DeprecationWarning,
|
|
42
|
+
)
|
|
43
|
+
return add_comma(number)
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def add_comma_english(number):
|
|
47
|
+
warnings.warn(
|
|
48
|
+
message="NepaliNumber.add_comma_english has been moved to "
|
|
49
|
+
"`add_comma_english. This function is depreciated and will "
|
|
50
|
+
"be removed in the future release.",
|
|
51
|
+
category=DeprecationWarning,
|
|
52
|
+
)
|
|
53
|
+
return add_comma_english(number)
|
nepali/number/utils.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
NP_NUMBERS = ["०", "१", "२", "३", "४", "५", "६", "७", "८", "९"]
|
|
4
|
+
NP_NUMBERS_SET = set(NP_NUMBERS)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def english_to_nepali(number: Any) -> str:
|
|
8
|
+
"""
|
|
9
|
+
Converts english number to nepali.
|
|
10
|
+
"""
|
|
11
|
+
number = str(number)
|
|
12
|
+
converted_number = []
|
|
13
|
+
for n in number:
|
|
14
|
+
num = ord(n) - ord("0")
|
|
15
|
+
if num in range(0, 10):
|
|
16
|
+
converted_number.append(NP_NUMBERS[num])
|
|
17
|
+
else:
|
|
18
|
+
converted_number.append(n)
|
|
19
|
+
return "".join(converted_number)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def nepali_to_english(number: Any) -> str:
|
|
23
|
+
"""
|
|
24
|
+
Converts nepali number to english.
|
|
25
|
+
"""
|
|
26
|
+
number = str(number)
|
|
27
|
+
converted_number = []
|
|
28
|
+
for n in number:
|
|
29
|
+
if n in NP_NUMBERS_SET:
|
|
30
|
+
converted_number.append(str(NP_NUMBERS.index(n)))
|
|
31
|
+
else:
|
|
32
|
+
converted_number.append(n)
|
|
33
|
+
return "".join(converted_number)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def add_comma_english(number: Any) -> str:
|
|
37
|
+
"""
|
|
38
|
+
Adds comma in english style
|
|
39
|
+
Eg. 123456789 => 123,456,789
|
|
40
|
+
"""
|
|
41
|
+
return f"{int(number):,}"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def add_comma(number: Any, convert=False) -> str:
|
|
45
|
+
"""
|
|
46
|
+
Adds comma in nepali style
|
|
47
|
+
Eg. 123456789 => 12,34,56,789
|
|
48
|
+
|
|
49
|
+
:param number Any: Number to be converted
|
|
50
|
+
:param convert bool: If true converts english number to nepali
|
|
51
|
+
"""
|
|
52
|
+
if convert:
|
|
53
|
+
number = english_to_nepali(number)
|
|
54
|
+
else:
|
|
55
|
+
number = str(number)
|
|
56
|
+
|
|
57
|
+
number_with_comma = []
|
|
58
|
+
counter = 0
|
|
59
|
+
for nepali_number_char in list(str(number))[::-1]:
|
|
60
|
+
if counter == 3 or (counter != 1 and (counter - 1) % 2 == 0):
|
|
61
|
+
number_with_comma.append(",")
|
|
62
|
+
number_with_comma.append(nepali_number_char)
|
|
63
|
+
counter += 1
|
|
64
|
+
|
|
65
|
+
return "".join(number_with_comma[::-1])
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def convert_and_add_comma(number: Any) -> str:
|
|
69
|
+
"""
|
|
70
|
+
Converts the number into nepali text and adds comma to it.
|
|
71
|
+
"""
|
|
72
|
+
return add_comma(number, convert=True)
|