205 lines
6.2 KiB
Python
205 lines
6.2 KiB
Python
# -*- coding: utf-8 -*-
|
||
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
|
||
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
|
||
|
||
# This library is free software; you can redistribute it and/or
|
||
# modify it under the terms of the GNU Lesser General Public
|
||
# License as published by the Free Software Foundation; either
|
||
# version 2.1 of the License, or (at your option) any later version.
|
||
# This library is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
# Lesser General Public License for more details.
|
||
# You should have received a copy of the GNU Lesser General Public
|
||
# License along with this library; if not, write to the Free Software
|
||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||
# MA 02110-1301 USA
|
||
|
||
from __future__ import unicode_literals
|
||
|
||
from .base import Num2Word_Base
|
||
|
||
|
||
class Num2Word_AZ(Num2Word_Base):
|
||
DIGITS = {
|
||
0: u"sıfır",
|
||
1: u"bir",
|
||
2: u"iki",
|
||
3: u"üç",
|
||
4: u"dörd",
|
||
5: u"beş",
|
||
6: u"altı",
|
||
7: u"yeddi",
|
||
8: u"səkkiz",
|
||
9: u"doqquz",
|
||
}
|
||
|
||
DECIMALS = {
|
||
1: u"on",
|
||
2: u"iyirmi",
|
||
3: u"otuz",
|
||
4: u"qırx",
|
||
5: u"əlli",
|
||
6: u"altmış",
|
||
7: u"yetmiş",
|
||
8: u"səksən",
|
||
9: u"doxsan",
|
||
}
|
||
|
||
POWERS_OF_TEN = {
|
||
2: u"yüz",
|
||
3: u"min",
|
||
6: u"milyon",
|
||
9: u"milyard",
|
||
12: u"trilyon",
|
||
15: u"katrilyon",
|
||
18: u"kentilyon",
|
||
21: u"sekstilyon",
|
||
24: u"septilyon",
|
||
27: u"oktilyon",
|
||
30: u"nonilyon",
|
||
33: u"desilyon",
|
||
36: u"undesilyon",
|
||
39: u"dodesilyon",
|
||
42: u"tredesilyon",
|
||
45: u"katordesilyon",
|
||
48: u"kendesilyon",
|
||
51: u"seksdesilyon",
|
||
54: u"septendesilyon",
|
||
57: u"oktodesilyon",
|
||
60: u"novemdesilyon",
|
||
63: u"vigintilyon",
|
||
}
|
||
|
||
VOWELS = u"aıoueəiöü"
|
||
VOWEL_TO_CARDINAL_SUFFIX_MAP = {
|
||
**dict.fromkeys(["a", "ı"], "ıncı"),
|
||
**dict.fromkeys(["e", "ə", "i"], "inci"),
|
||
**dict.fromkeys(["o", "u"], "uncu"),
|
||
**dict.fromkeys(["ö", "ü"], "üncü"),
|
||
}
|
||
|
||
VOWEL_TO_CARDINAL_NUM_SUFFIX_MAP = {
|
||
**dict.fromkeys(["a", "ı"], "cı"),
|
||
**dict.fromkeys(["e", "ə", "i"], "ci"),
|
||
**dict.fromkeys(["o", "u"], "cu"),
|
||
**dict.fromkeys(["ö", "ü"], "cü"),
|
||
}
|
||
|
||
CURRENCY_INTEGRAL = ('manat', 'manat')
|
||
CURRENCY_FRACTION = ('qəpik', 'qəpik')
|
||
CURRENCY_FORMS = {'AZN': (CURRENCY_INTEGRAL, CURRENCY_FRACTION)}
|
||
|
||
def setup(self):
|
||
super().setup()
|
||
|
||
self.negword = u"mənfi"
|
||
self.pointword = u"nöqtə"
|
||
|
||
def to_cardinal(self, value):
|
||
value_str = str(value)
|
||
parts = value_str.split(".")
|
||
integral_part = parts[0]
|
||
fraction_part = parts[1] if len(parts) > 1 else ""
|
||
|
||
if integral_part.startswith("-"):
|
||
integral_part = integral_part[1:] # ignore minus sign here
|
||
|
||
integral_part_in_words = self.int_to_word(integral_part)
|
||
fraction_part_in_words = "" if not fraction_part else self.int_to_word(
|
||
fraction_part, leading_zeros=True)
|
||
|
||
value_in_words = integral_part_in_words
|
||
if fraction_part:
|
||
value_in_words = " ".join(
|
||
[
|
||
integral_part_in_words,
|
||
self.pointword,
|
||
fraction_part_in_words
|
||
]
|
||
)
|
||
|
||
if value < 0:
|
||
value_in_words = " ".join([self.negword, value_in_words])
|
||
|
||
return value_in_words
|
||
|
||
def to_ordinal(self, value):
|
||
assert int(value) == value
|
||
|
||
cardinal = self.to_cardinal(value)
|
||
last_vowel = self._last_vowel(cardinal)
|
||
assert last_vowel is not None
|
||
suffix = self.VOWEL_TO_CARDINAL_SUFFIX_MAP[last_vowel]
|
||
|
||
if cardinal.endswith(tuple(self.VOWELS)):
|
||
cardinal = cardinal[:-1]
|
||
|
||
ordinal = "".join([cardinal, suffix])
|
||
|
||
return ordinal
|
||
|
||
def to_ordinal_num(self, value):
|
||
assert int(value) == value
|
||
|
||
cardinal = self.to_cardinal(value)
|
||
last_vowel = self._last_vowel(cardinal)
|
||
assert last_vowel is not None
|
||
suffix = self.VOWEL_TO_CARDINAL_NUM_SUFFIX_MAP[last_vowel]
|
||
ordinal_num = "-".join([str(value), suffix])
|
||
|
||
return ordinal_num
|
||
|
||
def to_year(self, value):
|
||
assert int(value) == value
|
||
|
||
year = self.to_cardinal(abs(value))
|
||
if value < 0:
|
||
year = " ".join(["e.ə.", year])
|
||
|
||
return year
|
||
|
||
def pluralize(self, n, forms):
|
||
form = 0 if n == 1 else 1
|
||
return forms[form]
|
||
|
||
def int_to_word(self, num_str, leading_zeros=False):
|
||
words = []
|
||
reversed_str = list(reversed(num_str))
|
||
|
||
for index, digit in enumerate(reversed_str):
|
||
digit_int = int(digit)
|
||
# calculate remainder after dividing index by 3
|
||
# because number is parsed by three digit chunks
|
||
remainder_to_3 = index % 3
|
||
if remainder_to_3 == 0:
|
||
if index > 0:
|
||
if set(reversed_str[index:index+3]) != {'0'}:
|
||
words.insert(0, self.POWERS_OF_TEN[index])
|
||
if digit_int > 0:
|
||
# we say "min" not "bir min"
|
||
if not (digit_int == 1 and index == 3):
|
||
words.insert(0, self.DIGITS[digit_int])
|
||
elif remainder_to_3 == 1:
|
||
if digit_int != 0:
|
||
words.insert(0, self.DECIMALS[digit_int])
|
||
else: # remainder is 2
|
||
if digit_int > 0:
|
||
words.insert(0, self.POWERS_OF_TEN[2]) # "yüz"
|
||
if digit_int > 1:
|
||
words.insert(0, self.DIGITS[digit_int])
|
||
|
||
if num_str == '0':
|
||
words.append(self.DIGITS[0])
|
||
|
||
if leading_zeros:
|
||
zeros_count = len(num_str) - len(str(int(num_str)))
|
||
words[:0] = zeros_count * [self.DIGITS[0]]
|
||
|
||
return " ".join(words)
|
||
|
||
def _last_vowel(self, value):
|
||
for char in value[::-1]:
|
||
if char in self.VOWELS:
|
||
return char
|