mirror of
https://github.com/bblaz/num2words.git
synced 2025-12-06 06:42:25 +00:00
Merge branch 'master' into master
This commit is contained in:
45
.github/workflows/ci.yml
vendored
Normal file
45
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8, 3.9, '3.10']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install tox tox-gh-actions coveralls
|
||||
pip install -r requirements-test.txt
|
||||
- name: Test with tox
|
||||
run: |
|
||||
tox
|
||||
- name: Upload coverage data to coveralls.io
|
||||
run: coveralls --service=github
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COVERALLS_FLAG_NAME: ${{ matrix.python-version }}
|
||||
COVERALLS_PARALLEL: true
|
||||
|
||||
coveralls:
|
||||
name: Indicate completion to coveralls.io
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
container: python:3-slim
|
||||
steps:
|
||||
- name: Finished
|
||||
run: |
|
||||
pip3 install --upgrade coveralls
|
||||
coveralls --service=github --finish
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
20
.travis.yml
20
.travis.yml
@@ -1,20 +0,0 @@
|
||||
sudo: false
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
matrix:
|
||||
include:
|
||||
- { python: 3.6, env: TOXENV=flake8 }
|
||||
- { python: 3.6, env: TOXENV=isort }
|
||||
# Py37 requires xenial distrubution and sudo
|
||||
# See travis-ci/travis-ci#9069
|
||||
- { python: 3.7, dist: xenial, sudo: true }
|
||||
|
||||
install:
|
||||
- pip install tox-travis
|
||||
- pip install coveralls
|
||||
script: tox
|
||||
after_success: if [ -e .coverage ]; then coveralls; fi
|
||||
28
CHANGES.rst
28
CHANGES.rst
@@ -1,6 +1,34 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 0.5.11 -- 2022/08/03
|
||||
----------------------------
|
||||
|
||||
* Add KZT and UAH currencies to lang RU (#264)
|
||||
* Add es_NI currency (#276)
|
||||
* Update .gitignore to add .eggs/ directory (#280)
|
||||
* Fix Hebrew support (#289)
|
||||
* Update test_tr.py to increase coverage (#298)
|
||||
* Add ordinal 12,345 to ES test suite to increase coverage (#287)
|
||||
* Add simple tests for lang_DK.py (#286)
|
||||
* Add testcase for lang_EN.py (#288)
|
||||
* Add more tests to base.py (#283)
|
||||
* Fixed misspelling of 21 (cardinal and ordinal number) in IT language (#270)
|
||||
* Romanian issues 259 (#260)
|
||||
* Adding Language Support for Telugu / Bug Fix in Kannada (#263)
|
||||
* Add support of Kazakh language (KZ) (#306)
|
||||
* Update README.rst (#307)
|
||||
* Added support for Hungarian language (#310)
|
||||
* [UPD] Readme file (#363)
|
||||
* [ADD] num2words: add traslation to spanish of several currencies (#356)
|
||||
* added swedish language including test cases (#352)
|
||||
* Remove dupplicated line in lang_PT_BR (#355)
|
||||
* Fix ordinal_num output for Dutch (NL) (#369)
|
||||
* Polishordinals (#367)
|
||||
* [tr] return Turkish 0 ordinal and cardinal (#347)
|
||||
* Improve Ukrainian support and minor fixes in CZ, KZ, LT, LV, PL, RU, SR languages (#400)
|
||||
* feat: ci: replace travis by github workflows (#448)
|
||||
* [ES] Added missing accents ("dieciséis", "dólar", "dólares", "veintiún"), improved currency gender handling, fixed pound cent names (#443)
|
||||
|
||||
Version 0.5.10 -- 2019/05/12
|
||||
----------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
num2words library - Convert numbers to words in multiple languages
|
||||
==========================================================
|
||||
==================================================================
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/num2words.svg
|
||||
:target: https://pypi.python.org/pypi/num2words
|
||||
@@ -51,7 +51,7 @@ Command line::
|
||||
$ num2words 24,120.10 -l es
|
||||
veinticuatro mil ciento veinte punto uno
|
||||
$num2words 2.14 -l es --to currency
|
||||
dos euros con catorce centimos
|
||||
dos euros con catorce céntimos
|
||||
|
||||
In code there's only one function to use::
|
||||
|
||||
@@ -86,6 +86,7 @@ Besides the numerical argument, there are two main optional arguments.
|
||||
* ``es_CO`` (Spanish - Colombia)
|
||||
* ``es_VE`` (Spanish - Venezuela)
|
||||
* ``eu`` (EURO)
|
||||
* ``fa`` (Farsi)
|
||||
* ``fi`` (Finnish)
|
||||
* ``fr`` (French)
|
||||
* ``fr_CH`` (French - Switzerland)
|
||||
|
||||
@@ -46,7 +46,7 @@ Examples:
|
||||
veinticuatro mil ciento veinte punto uno
|
||||
|
||||
$num2words 2.14 -l es --to currency
|
||||
dos euros con catorce centimos
|
||||
dos euros con catorce céntimos
|
||||
"""
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
@@ -55,7 +55,7 @@ import sys
|
||||
from docopt import docopt
|
||||
import num2words
|
||||
|
||||
__version__ = "0.5.10"
|
||||
__version__ = "0.5.11"
|
||||
__license__ = "LGPL"
|
||||
|
||||
|
||||
|
||||
@@ -18,18 +18,19 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN,
|
||||
lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR,
|
||||
lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID,
|
||||
lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV,
|
||||
lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO,
|
||||
lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR,
|
||||
lang_UK, lang_VI)
|
||||
lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI,
|
||||
lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU,
|
||||
lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT,
|
||||
lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR,
|
||||
lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH,
|
||||
lang_TR, lang_UK, lang_VI)
|
||||
|
||||
CONVERTER_CLASSES = {
|
||||
'ar': lang_AR.Num2Word_AR(),
|
||||
'cz': lang_CZ.Num2Word_CZ(),
|
||||
'en': lang_EN.Num2Word_EN(),
|
||||
'en_IN': lang_EN_IN.Num2Word_EN_IN(),
|
||||
'fa': lang_FA.Num2Word_FA(),
|
||||
'fr': lang_FR.Num2Word_FR(),
|
||||
'fr_CH': lang_FR_CH.Num2Word_FR_CH(),
|
||||
'fr_BE': lang_FR_BE.Num2Word_FR_BE(),
|
||||
|
||||
@@ -257,6 +257,9 @@ class Num2Word_Base(object):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def _money_verbose(self, number, currency):
|
||||
return self.to_cardinal(number)
|
||||
|
||||
def _cents_verbose(self, number, currency):
|
||||
return self.to_cardinal(number)
|
||||
|
||||
@@ -290,12 +293,13 @@ class Num2Word_Base(object):
|
||||
cr1 = prefix_currency(self.CURRENCY_ADJECTIVES[currency], cr1)
|
||||
|
||||
minus_str = "%s " % self.negword if is_negative else ""
|
||||
money_str = self._money_verbose(left, currency)
|
||||
cents_str = self._cents_verbose(right, currency) \
|
||||
if cents else self._cents_terse(right, currency)
|
||||
|
||||
return u'%s%s %s%s %s %s' % (
|
||||
minus_str,
|
||||
self.to_cardinal(left),
|
||||
money_str,
|
||||
self.pluralize(left, cr1),
|
||||
separator,
|
||||
cents_str,
|
||||
|
||||
@@ -102,10 +102,13 @@ class Num2Word_CZ(Num2Word_Base):
|
||||
n = str(number).replace(',', '.')
|
||||
if '.' in n:
|
||||
left, right = n.split('.')
|
||||
leading_zero_count = len(right) - len(right.lstrip('0'))
|
||||
decimal_part = ((ZERO[0] + ' ') * leading_zero_count +
|
||||
self._int2word(int(right)))
|
||||
return u'%s %s %s' % (
|
||||
self._int2word(int(left)),
|
||||
self.pointword,
|
||||
self._int2word(int(right))
|
||||
decimal_part
|
||||
)
|
||||
else:
|
||||
return self._int2word(int(n))
|
||||
|
||||
@@ -21,13 +21,14 @@ import math
|
||||
|
||||
from .lang_EU import Num2Word_EU
|
||||
|
||||
GENERIC_DOLLARS = ('dolar', 'dólares')
|
||||
GENERIC_DOLLARS = ('dólar', 'dólares')
|
||||
GENERIC_CENTS = ('centavo', 'centavos')
|
||||
CURRENCIES_UNA = ('SLL', 'SEK', 'NOK', 'CZK', 'DKK', 'ISK',
|
||||
'SKK', 'GBP', 'CYP', 'EGP', 'FKP', 'GIP',
|
||||
'LBP', 'SDG', 'SHP', 'SSP', 'SYP', 'INR',
|
||||
'IDR', 'LKR', 'MUR', 'NPR', 'PKR', 'SCR',
|
||||
'ESP')
|
||||
'ESP', 'TRY', 'ITL')
|
||||
CENTS_UNA = ('EGP', 'JOD', 'LBP', 'SDG', 'SSP', 'SYP')
|
||||
|
||||
|
||||
class Num2Word_ES(Num2Word_EU):
|
||||
@@ -39,7 +40,7 @@ class Num2Word_ES(Num2Word_EU):
|
||||
'CRC': (('colón', 'colones'), GENERIC_CENTS),
|
||||
'AUD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'CAD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'GBP': (('libra', 'libras'), ('penny', 'pence')),
|
||||
'GBP': (('libra', 'libras'), ('penique', 'peniques')),
|
||||
'RUB': (('rublo', 'rublos'), ('kopeyka', 'kopeykas')),
|
||||
'SEK': (('corona', 'coronas'), ('öre', 'öre')),
|
||||
'NOK': (('corona', 'coronas'), ('øre', 'øre')),
|
||||
@@ -101,7 +102,7 @@ class Num2Word_ES(Num2Word_EU):
|
||||
'ERN': (('nakfa', 'nakfas'), ('céntimo', 'céntimos')),
|
||||
'ETB': (('birr', 'birrs'), ('céntimo', 'céntimos')),
|
||||
'FJD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'FKP': (('libra', 'libras'), ('penny', 'peniques')),
|
||||
'FKP': (('libra', 'libras'), ('penique', 'peniques')),
|
||||
'GEL': (('lari', 'laris'), ('tetri', 'tetris')),
|
||||
'GHS': (('cedi', 'cedis'), ('pesewa', 'pesewas')),
|
||||
'GIP': (('libra', 'libras'), ('penique', 'peniques')),
|
||||
@@ -170,7 +171,7 @@ class Num2Word_ES(Num2Word_EU):
|
||||
'SCR': (('rupia', 'rupias'), ('céntimo', 'céntimos')),
|
||||
'SDG': (('libra', 'libras'), ('piastra', 'piastras')),
|
||||
'SGD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
|
||||
'SHP': (('libra', 'libras'), ('penny', 'peniques')),
|
||||
'SHP': (('libra', 'libras'), ('penique', 'peniques')),
|
||||
'SKK': (('corona', 'coronas'), ('halier', 'haliers')),
|
||||
'SLL': (('leona', 'leonas'), ('céntimo', 'céntimos')),
|
||||
'SRD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
|
||||
@@ -184,7 +185,7 @@ class Num2Word_ES(Num2Word_EU):
|
||||
'TND': (('dinar', 'dinares'), ('milésimo', 'milésimos')),
|
||||
'TOP': (('paanga', 'paangas'), ('céntimo', 'céntimos')),
|
||||
'TTD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
|
||||
'TWD': (('nuevo dólar', 'nuevos dolares'), ('céntimo', 'céntimos')),
|
||||
'TWD': (('nuevo dólar', 'nuevos dólares'), ('céntimo', 'céntimos')),
|
||||
'TZS': (('chelín', 'chelines'), ('céntimo', 'céntimos')),
|
||||
'UAG': (('hryvnia', 'hryvnias'), ('kopiyka', 'kopiykas')),
|
||||
'UGX': (('chelín', 'chelines'), ('céntimo', 'céntimos')),
|
||||
@@ -216,9 +217,13 @@ class Num2Word_ES(Num2Word_EU):
|
||||
self.high_numwords = self.gen_high_numwords([], [], lows)
|
||||
self.negword = "menos "
|
||||
self.pointword = "punto"
|
||||
self.errmsg_nonnum = "Solo números pueden ser convertidos a palabras."
|
||||
self.errmsg_nonnum = "type(%s) no es [long, int, float]"
|
||||
self.errmsg_floatord = "El float %s no puede ser tratado como un" \
|
||||
" ordinal."
|
||||
self.errmsg_negord = "El número negativo %s no puede ser tratado" \
|
||||
" como un ordinal."
|
||||
self.errmsg_toobig = (
|
||||
"Numero muy grande para ser convertido a palabras."
|
||||
"abs(%s) deber ser inferior a %s."
|
||||
)
|
||||
self.gender_stem = "o"
|
||||
self.exclude_title = ["y", "menos", "punto"]
|
||||
@@ -230,7 +235,7 @@ class Num2Word_ES(Num2Word_EU):
|
||||
"veintiséis", "veinticinco", "veinticuatro",
|
||||
"veintitrés", "veintidós", "veintiuno",
|
||||
"veinte", "diecinueve", "dieciocho", "diecisiete",
|
||||
"dieciseis", "quince", "catorce", "trece", "doce",
|
||||
"dieciséis", "quince", "catorce", "trece", "doce",
|
||||
"once", "diez", "nueve", "ocho", "siete", "seis",
|
||||
"cinco", "cuatro", "tres", "dos", "uno", "cero"]
|
||||
self.ords = {1: "primer",
|
||||
@@ -352,15 +357,52 @@ class Num2Word_ES(Num2Word_EU):
|
||||
result = super(Num2Word_ES, self).to_currency(
|
||||
val, currency=currency, cents=cents, separator=separator,
|
||||
adjective=adjective)
|
||||
# Handle exception, in spanish is "un euro" and not "uno euro"
|
||||
# except in this currencies: leona, corona,
|
||||
# libra, rupia, lempira, peseta, is 'una'
|
||||
# but only when it's first word, otherwise
|
||||
# it's replaced in others words like 'veintiun'
|
||||
# Handle exception: In Spanish it's "un euro" and not "uno euro",
|
||||
# except in these currencies, where it's "una": leona, corona,
|
||||
# libra, lira, rupia, lempira, peseta.
|
||||
# The same goes for "veintiuna", "treinta y una"...
|
||||
# Also, this needs to be handled separately for "dollars" and
|
||||
# "cents".
|
||||
# All "cents" are masculine except for: piastra.
|
||||
# Source: https://www.rae.es/dpd/una (section 2.2)
|
||||
|
||||
# split "dollars" part from "cents" part
|
||||
list_result = result.split(separator + " ")
|
||||
|
||||
# "DOLLARS" PART (list_result[0])
|
||||
|
||||
# Feminine currencies ("una libra", "trescientas libras"...)
|
||||
if currency in CURRENCIES_UNA:
|
||||
list_result = result.split(" ")
|
||||
if list_result[0] == "uno":
|
||||
list_result[0] = list_result[0].replace("uno", "una")
|
||||
result = " ".join(list_result)
|
||||
result = result.replace("uno", "un")
|
||||
|
||||
# "una libra", "veintiuna libras", "treinta y una libras"...
|
||||
list_result[0] = list_result[0].replace("uno", "una")
|
||||
|
||||
# "doscientas libras", "trescientas libras"...
|
||||
list_result[0] = list_result[0].replace("cientos", "cientas")
|
||||
|
||||
# Masc.: Correct orthography for the specific case of "veintiún":
|
||||
list_result[0] = list_result[0].replace("veintiuno", "veintiún")
|
||||
|
||||
# Masculine currencies: general case ("un euro", "treinta y un
|
||||
# euros"...):
|
||||
list_result[0] = list_result[0].replace("uno", "un")
|
||||
|
||||
# "CENTS" PART (list_result[1])
|
||||
|
||||
# Feminine "cents" ("una piastra", "veintiuna piastras"...)
|
||||
if currency in CENTS_UNA:
|
||||
|
||||
# "una piastra", "veintiuna piastras", "treinta y una piastras"...
|
||||
list_result[1] = list_result[1].replace("uno", "una")
|
||||
|
||||
# Masc.: Correct orthography for the specific case of "veintiún":
|
||||
list_result[1] = list_result[1].replace("veintiuno", "veintiún")
|
||||
|
||||
# Masculine "cents": general case ("un centavo", "treinta y un
|
||||
# centavos"...):
|
||||
list_result[1] = list_result[1].replace("uno", "un")
|
||||
|
||||
# join back "dollars" part with "cents" part
|
||||
result = (separator + " ").join(list_result)
|
||||
|
||||
return result
|
||||
|
||||
165
num2words/lang_FA.py
Normal file
165
num2words/lang_FA.py
Normal file
@@ -0,0 +1,165 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
|
||||
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
|
||||
# Copyright (c) 2018, Abdullah Alhazmy, Alhazmy13. All Rights Reserved.
|
||||
# Copyright (c) 2020, Hamidreza Kalbasi. 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 decimal import Decimal
|
||||
from math import floor
|
||||
|
||||
farsiOnes = [
|
||||
"", "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت",
|
||||
"نه",
|
||||
"ده",
|
||||
"یازده",
|
||||
"دوازده",
|
||||
"سیزده",
|
||||
"چهارده",
|
||||
"پونزده",
|
||||
"شونزده",
|
||||
"هیفده",
|
||||
"هیجده",
|
||||
"نوزده",
|
||||
]
|
||||
|
||||
farsiTens = [
|
||||
"",
|
||||
"ده",
|
||||
"بیست",
|
||||
"سی",
|
||||
"چهل",
|
||||
"پنجاه",
|
||||
"شصت",
|
||||
"هفتاد",
|
||||
"هشتاد",
|
||||
"نود",
|
||||
]
|
||||
|
||||
farsiHundreds = [
|
||||
"",
|
||||
"صد",
|
||||
"دویست",
|
||||
"سیصد",
|
||||
"چهارصد",
|
||||
"پانصد",
|
||||
"ششصد",
|
||||
"هفتصد",
|
||||
"هشتصد",
|
||||
"نهصد",
|
||||
]
|
||||
|
||||
farsiBig = [
|
||||
'',
|
||||
' هزار',
|
||||
' میلیون',
|
||||
" میلیارد",
|
||||
' تریلیون',
|
||||
" تریلیارد",
|
||||
]
|
||||
|
||||
farsiFrac = ["", "دهم", "صدم"]
|
||||
farsiFracBig = ["", "هزارم", "میلیونیم", "میلیاردیم"]
|
||||
|
||||
farsiSeperator = ' و '
|
||||
|
||||
|
||||
class Num2Word_FA(object):
|
||||
errmsg_too_big = "Too large"
|
||||
max_num = 10 ** 36
|
||||
|
||||
def __init__(self):
|
||||
self.number = 0
|
||||
|
||||
def float2tuple(self, value):
|
||||
pre = int(value)
|
||||
|
||||
# Simple way of finding decimal places to update the precision
|
||||
self.precision = abs(Decimal(str(value)).as_tuple().exponent)
|
||||
|
||||
post = abs(value - pre) * 10**self.precision
|
||||
if abs(round(post) - post) < 0.01:
|
||||
# We generally floor all values beyond our precision (rather than
|
||||
# rounding), but in cases where we have something like 1.239999999,
|
||||
# which is probably due to python's handling of floats, we actually
|
||||
# want to consider it as 1.24 instead of 1.23
|
||||
post = int(round(post))
|
||||
else:
|
||||
post = int(floor(post))
|
||||
return pre, post, self.precision
|
||||
|
||||
def cardinal3(self, number):
|
||||
if (number < 19):
|
||||
return farsiOnes[number]
|
||||
if (number < 100):
|
||||
x, y = divmod(number, 10)
|
||||
if y == 0:
|
||||
return farsiTens[x]
|
||||
return farsiTens[x] + farsiSeperator + farsiOnes[y]
|
||||
x, y = divmod(number, 100)
|
||||
if y == 0:
|
||||
return farsiHundreds[x]
|
||||
return farsiHundreds[x] + farsiSeperator + self.cardinal3(y)
|
||||
|
||||
def cardinalPos(self, number):
|
||||
x = number
|
||||
res = ''
|
||||
for b in farsiBig:
|
||||
x, y = divmod(x, 1000)
|
||||
if (y == 0):
|
||||
continue
|
||||
yx = self.cardinal3(y) + b
|
||||
if b == ' هزار' and y == 1:
|
||||
yx = 'هزار'
|
||||
if (res == ''):
|
||||
res = yx
|
||||
else:
|
||||
res = yx + farsiSeperator + res
|
||||
return res
|
||||
|
||||
def fractional(self, number, level):
|
||||
if (number == 5):
|
||||
return "نیم"
|
||||
x = self.cardinalPos(number)
|
||||
ld3, lm3 = divmod(level, 3)
|
||||
ltext = (farsiFrac[lm3] + " " + farsiFracBig[ld3]).strip()
|
||||
return x + " " + ltext
|
||||
|
||||
def to_currency(self, value):
|
||||
return self.to_cardinal(value) + " تومان"
|
||||
|
||||
def to_ordinal(self, number):
|
||||
r = self.to_cardinal(number)
|
||||
if (r[-1] == 'ه' and r[-2] == 'س'):
|
||||
return r[:-1] + 'وم'
|
||||
return r + 'م'
|
||||
|
||||
def to_year(self, value):
|
||||
return self.to_cardinal(value)
|
||||
|
||||
def to_ordinal_num(self, value):
|
||||
return str(value)+"م"
|
||||
|
||||
def to_cardinal(self, number):
|
||||
if number < 0:
|
||||
return "منفی " + self.to_cardinal(-number)
|
||||
if (number == 0):
|
||||
return "صفر"
|
||||
x, y, level = self.float2tuple(number)
|
||||
if y == 0:
|
||||
return self.cardinalPos(x)
|
||||
if x == 0:
|
||||
return self.fractional(y, level)
|
||||
return self.cardinalPos(x) + farsiSeperator + self.fractional(y, level)
|
||||
@@ -335,6 +335,7 @@ ERA_START = [
|
||||
(1912, ("大正", "たいしょう")),
|
||||
(1926, ("昭和", "しょうわ")),
|
||||
(1989, ("平成", "へいせい")),
|
||||
(2019, ("令和", "れいわ")),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ class Num2Word_KO(Num2Word_Base):
|
||||
|
||||
def to_ordinal(self, value):
|
||||
self.verify_ordinal(value)
|
||||
if(value == 1):
|
||||
if value == 1:
|
||||
return "첫 번째"
|
||||
outwords = self.to_cardinal(value).split(" ")
|
||||
lastwords = outwords[-1].split("백")
|
||||
|
||||
@@ -77,10 +77,11 @@ class Num2Word_KZ(Num2Word_Base):
|
||||
n = str(number).replace(',', '.')
|
||||
if '.' in n:
|
||||
left, right = n.split('.')
|
||||
leading_zero_count = len(right) - len(right.lstrip('0'))
|
||||
return u'%s %s %s' % (
|
||||
self._int2word(int(left)),
|
||||
self.pointword,
|
||||
self._int2word(int(right))
|
||||
(ZERO + ' ') * leading_zero_count + self._int2word(int(right))
|
||||
)
|
||||
else:
|
||||
return self._int2word(int(n))
|
||||
|
||||
@@ -124,11 +124,14 @@ class Num2Word_LT(Num2Word_Base):
|
||||
base_str, n = self.parse_minus(n)
|
||||
if '.' in n:
|
||||
left, right = n.split('.')
|
||||
leading_zero_count = len(right) - len(right.lstrip('0'))
|
||||
decimal_part = ((ZERO[0] + ' ') * leading_zero_count +
|
||||
self._int2word(int(right)))
|
||||
return '%s%s %s %s' % (
|
||||
base_str,
|
||||
self._int2word(int(left)),
|
||||
self.pointword,
|
||||
self._int2word(int(right))
|
||||
decimal_part
|
||||
)
|
||||
else:
|
||||
return "%s%s" % (base_str, self._int2word(int(n)))
|
||||
|
||||
@@ -132,11 +132,14 @@ class Num2Word_LV(Num2Word_Base):
|
||||
base_str, n = self.parse_minus(n)
|
||||
if '.' in n:
|
||||
left, right = n.split('.')
|
||||
leading_zero_count = len(right) - len(right.lstrip('0'))
|
||||
decimal_part = ((ZERO[0] + ' ') * leading_zero_count +
|
||||
self._int2word(int(right)))
|
||||
return '%s%s %s %s' % (
|
||||
base_str,
|
||||
self._int2word(int(left)),
|
||||
self.pointword,
|
||||
self._int2word(int(right))
|
||||
decimal_part
|
||||
)
|
||||
else:
|
||||
return "%s%s" % (base_str, self._int2word(int(n)))
|
||||
|
||||
@@ -165,10 +165,13 @@ class Num2Word_PL(Num2Word_Base):
|
||||
n = str(number).replace(',', '.')
|
||||
if '.' in n:
|
||||
left, right = n.split('.')
|
||||
leading_zero_count = len(right) - len(right.lstrip('0'))
|
||||
decimal_part = ((ZERO[0] + ' ') * leading_zero_count +
|
||||
self._int2word(int(right)))
|
||||
return u'%s %s %s' % (
|
||||
self._int2word(int(left)),
|
||||
self.pointword,
|
||||
self._int2word(int(right))
|
||||
decimal_part
|
||||
)
|
||||
else:
|
||||
return self._int2word(int(n))
|
||||
|
||||
@@ -144,10 +144,13 @@ class Num2Word_RU(Num2Word_Base):
|
||||
n = str(number).replace(',', '.')
|
||||
if '.' in n:
|
||||
left, right = n.split('.')
|
||||
leading_zero_count = len(right) - len(right.lstrip('0'))
|
||||
decimal_part = ((ZERO[0] + ' ') * leading_zero_count +
|
||||
self._int2word(int(right)))
|
||||
return u'%s %s %s' % (
|
||||
self._int2word(int(left)),
|
||||
self.pointword,
|
||||
self._int2word(int(right))
|
||||
decimal_part
|
||||
)
|
||||
else:
|
||||
return self._int2word(int(n))
|
||||
@@ -201,8 +204,11 @@ class Num2Word_RU(Num2Word_Base):
|
||||
outwords[-1] = self.title(lastword)
|
||||
return " ".join(outwords).strip()
|
||||
|
||||
def _money_verbose(self, number, currency):
|
||||
return self._int2word(number, currency == 'UAH')
|
||||
|
||||
def _cents_verbose(self, number, currency):
|
||||
return self._int2word(number, currency == 'RUB')
|
||||
return self._int2word(number, currency in ('UAH', 'RUB'))
|
||||
|
||||
def _int2word(self, n, feminine=False):
|
||||
if n < 0:
|
||||
|
||||
@@ -110,10 +110,13 @@ class Num2Word_SR(Num2Word_Base):
|
||||
n = str(number).replace(',', '.')
|
||||
if '.' in n:
|
||||
left, right = n.split('.')
|
||||
leading_zero_count = len(right) - len(right.lstrip('0'))
|
||||
decimal_part = ((ZERO[0] + ' ') * leading_zero_count +
|
||||
self._int2word(int(right), feminine))
|
||||
return u'%s %s %s' % (
|
||||
self._int2word(int(left), feminine),
|
||||
self.pointword,
|
||||
self._int2word(int(right), feminine)
|
||||
decimal_part
|
||||
)
|
||||
else:
|
||||
return self._int2word(int(n), feminine)
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .base import Num2Word_Base
|
||||
|
||||
class Num2Word_TR(object):
|
||||
|
||||
class Num2Word_TR(Num2Word_Base):
|
||||
def __init__(self):
|
||||
self.precision = 2
|
||||
self.negword = u"eksi"
|
||||
@@ -152,6 +154,8 @@ class Num2Word_TR(object):
|
||||
wrd += self.CARDINAL_ONES.get(
|
||||
self.integers_to_read[0][0], ""
|
||||
)
|
||||
if self.integers_to_read[0][0] == "0":
|
||||
return self.ZERO
|
||||
return wrd
|
||||
|
||||
if self.total_digits_outside_triplets == 0:
|
||||
@@ -507,6 +511,8 @@ class Num2Word_TR(object):
|
||||
wrd += self.ORDINAL_ONES.get(
|
||||
self.integers_to_read[0][0], ""
|
||||
)
|
||||
if self.integers_to_read[0][0] == "0":
|
||||
return u"sıfırıncı"
|
||||
return wrd
|
||||
|
||||
if self.total_digits_outside_triplets == 0:
|
||||
|
||||
@@ -24,13 +24,13 @@ ZERO = ('нуль',)
|
||||
|
||||
ONES_FEMININE = {
|
||||
1: ('одна',),
|
||||
2: ('двi',),
|
||||
2: ('дві',),
|
||||
3: ('три',),
|
||||
4: ('чотири',),
|
||||
5: ('п\'ять',),
|
||||
6: ('шiсть',),
|
||||
7: ('сiм',),
|
||||
8: ('вiсiм',),
|
||||
6: ('шість',),
|
||||
7: ('сім',),
|
||||
8: ('вісім',),
|
||||
9: ('дев\'ять',),
|
||||
}
|
||||
|
||||
@@ -40,12 +40,34 @@ ONES = {
|
||||
3: ('три',),
|
||||
4: ('чотири',),
|
||||
5: ('п\'ять',),
|
||||
6: ('шiсть',),
|
||||
7: ('сiм',),
|
||||
8: ('вiсiм',),
|
||||
6: ('шість',),
|
||||
7: ('сім',),
|
||||
8: ('вісім',),
|
||||
9: ('дев\'ять',),
|
||||
}
|
||||
|
||||
ONES_ORDINALS = {
|
||||
1: ("перший", "одно"),
|
||||
2: ("другий", "двох"),
|
||||
3: ("третій", "трьох"),
|
||||
4: ("четвертий", "чотирьох"),
|
||||
5: ("п'ятий", "п'яти"),
|
||||
6: ("шостий", "шести"),
|
||||
7: ("сьомий", "семи"),
|
||||
8: ("восьмий", "восьми"),
|
||||
9: ("дев'ятий", "дев'яти"),
|
||||
10: ("десятий", "десяти"),
|
||||
11: ("одинадцятий", "одинадцяти"),
|
||||
12: ("дванадцятий", "дванадцяти"),
|
||||
13: ("тринадцятий", "тринадцяти"),
|
||||
14: ("чотирнадцятий", "чотирнадцяти"),
|
||||
15: ("п'ятнадцятий", "п'ятнадцяти"),
|
||||
16: ("шістнадцятий", "шістнадцяти"),
|
||||
17: ("сімнадцятий", "сімнадцяти"),
|
||||
18: ("вісімнадцятий", "вісімнадцяти"),
|
||||
19: ("дев'ятнадцятий", "дев'ятнадцяти"),
|
||||
}
|
||||
|
||||
TENS = {
|
||||
0: ('десять',),
|
||||
1: ('одинадцять',),
|
||||
@@ -53,9 +75,9 @@ TENS = {
|
||||
3: ('тринадцять',),
|
||||
4: ('чотирнадцять',),
|
||||
5: ('п\'ятнадцять',),
|
||||
6: ('шiстнадцять',),
|
||||
7: ('сiмнадцять',),
|
||||
8: ('вiсiмнадцять',),
|
||||
6: ('шістнадцять',),
|
||||
7: ('сімнадцять',),
|
||||
8: ('вісімнадцять',),
|
||||
9: ('дев\'ятнадцять',),
|
||||
}
|
||||
|
||||
@@ -64,61 +86,642 @@ TWENTIES = {
|
||||
3: ('тридцять',),
|
||||
4: ('сорок',),
|
||||
5: ('п\'ятдесят',),
|
||||
6: ('шiстдесят',),
|
||||
7: ('сiмдесят',),
|
||||
8: ('вiсiмдесят',),
|
||||
6: ('шістдесят',),
|
||||
7: ('сімдесят',),
|
||||
8: ('вісімдесят',),
|
||||
9: ('дев\'яносто',),
|
||||
}
|
||||
|
||||
TWENTIES_ORDINALS = {
|
||||
2: ("двадцятий", "двадцяти"),
|
||||
3: ("тридцятий", "тридцяти"),
|
||||
4: ("сороковий", "сорока"),
|
||||
5: ("п'ятдесятий", "п'ятдесяти"),
|
||||
6: ("шістдесятий", "шістдесяти"),
|
||||
7: ("сімдесятий", "сімдесяти"),
|
||||
8: ("вісімдесятий", "вісімдесяти"),
|
||||
9: ("дев'яностий", "дев'яности"),
|
||||
}
|
||||
|
||||
HUNDREDS = {
|
||||
1: ('сто',),
|
||||
2: ('двiстi',),
|
||||
2: ('двісті',),
|
||||
3: ('триста',),
|
||||
4: ('чотириста',),
|
||||
5: ('п\'ятсот',),
|
||||
6: ('шiстсот',),
|
||||
7: ('сiмсот',),
|
||||
8: ('вiсiмсот',),
|
||||
6: ('шістсот',),
|
||||
7: ('сімсот',),
|
||||
8: ('вісімсот',),
|
||||
9: ('дев\'ятсот',),
|
||||
}
|
||||
|
||||
THOUSANDS = {
|
||||
1: ('тисяча', 'тисячi', 'тисяч'), # 10^3
|
||||
2: ('мiльйон', 'мiльйони', 'мiльйонiв'), # 10^6
|
||||
3: ('мiльярд', 'мiльярди', 'мiльярдiв'), # 10^9
|
||||
4: ('трильйон', 'трильйони', 'трильйонiв'), # 10^12
|
||||
5: ('квадрильйон', 'квадрильйони', 'квадрильйонiв'), # 10^15
|
||||
6: ('квiнтильйон', 'квiнтильйони', 'квiнтильйонiв'), # 10^18
|
||||
7: ('секстильйон', 'секстильйони', 'секстильйонiв'), # 10^21
|
||||
8: ('септильйон', 'септильйони', 'септильйонiв'), # 10^24
|
||||
9: ('октильйон', 'октильйони', 'октильйонiв'), # 10^27
|
||||
10: ('нонiльйон', 'нонiльйони', 'нонiльйонiв'), # 10^30
|
||||
HUNDREDS_ORDINALS = {
|
||||
1: ("сотий", "сто"),
|
||||
2: ("двохсотий", "двохсот"),
|
||||
3: ("трьохсотий", "трьохсот"),
|
||||
4: ("чотирьохсотий", "чотирьохсот"),
|
||||
5: ("п'ятисотий", "п'ятсот"),
|
||||
6: ("шестисотий", "шістсот"),
|
||||
7: ("семисотий", "сімсот"),
|
||||
8: ("восьмисотий", "вісімсот"),
|
||||
9: ("дев'ятисотий", "дев'ятсот"),
|
||||
}
|
||||
|
||||
THOUSANDS = {
|
||||
1: ('тисяча', 'тисячі', 'тисяч'), # 10^3
|
||||
2: ('мільйон', 'мільйони', 'мільйонів'), # 10^6
|
||||
3: ('мільярд', 'мільярди', 'мільярдів'), # 10^9
|
||||
4: ('трильйон', 'трильйони', 'трильйонів'), # 10^12
|
||||
5: ('квадрильйон', 'квадрильйони', 'квадрильйонів'), # 10^15
|
||||
6: ('квінтильйон', 'квінтильйони', 'квінтильйонів'), # 10^18
|
||||
7: ('секстильйон', 'секстильйони', 'секстильйонів'), # 10^21
|
||||
8: ('септильйон', 'септильйони', 'септильйонів'), # 10^24
|
||||
9: ('октильйон', 'октильйони', 'октильйонів'), # 10^27
|
||||
10: ('нонільйон', 'нонільйони', 'нонільйонів'), # 10^30
|
||||
}
|
||||
|
||||
prefixes_ordinal = {
|
||||
1: "тисячний",
|
||||
2: "мільйонний",
|
||||
3: "мільярдний",
|
||||
4: "трильйонний",
|
||||
5: "квадрильйонний",
|
||||
6: "квінтильйонний",
|
||||
7: "секстильйонний",
|
||||
8: "септильйонний",
|
||||
9: "октильйонний",
|
||||
10: "нонільйонний",
|
||||
}
|
||||
|
||||
FEMININE_MONEY = ('AOA', 'BAM', 'BDT', 'BWP', 'CZK', 'DKK',
|
||||
'ERN', 'HNL', 'HRK', 'IDR', 'INR', 'ISK',
|
||||
'JPY', 'KPW', 'KRW', 'LKR', 'MOP', 'MRU',
|
||||
'MUR', 'MVR', 'MWK', 'NGN', 'NIO', 'NOK',
|
||||
'NPR', 'PKR', 'SCR', 'SEK', 'STN', 'TRY',
|
||||
'WST', 'UAH', 'ZMW')
|
||||
FEMININE_CENTS = ('ALL', 'BDT', 'BGN', 'BYN', 'GHS', 'HRK',
|
||||
'ILS', 'INR', 'NPR', 'OMR', 'OMR', 'PKR',
|
||||
'RSD', 'RUB', 'UAH')
|
||||
|
||||
GENERIC_DOLLARS = ('долар', 'долари', 'доларів')
|
||||
GENERIC_CENTS = ('цент', 'центи', 'центів')
|
||||
|
||||
|
||||
class Num2Word_UK(Num2Word_Base):
|
||||
CURRENCY_FORMS = {
|
||||
'UAH': (
|
||||
('гривня', 'гривнi', 'гривень'),
|
||||
('копiйка', 'копiйки', 'копiйок')
|
||||
'AED': (
|
||||
('дирхам', 'дирхами', 'дирхамів'),
|
||||
('філс', 'філси', 'філсів')
|
||||
),
|
||||
'AFN': (
|
||||
('афгані', 'афгані', 'афгані'),
|
||||
('пул', 'пули', 'пулів')
|
||||
),
|
||||
'ALL': (
|
||||
('лек', 'леки', 'леків'),
|
||||
('кіндарка', 'кіндарки', 'кіндарок')
|
||||
),
|
||||
'AMD': (
|
||||
('драм', 'драми', 'драмів'),
|
||||
('лум', 'лум', 'лум')
|
||||
),
|
||||
'ANG': (
|
||||
('гульден', 'гульдени', 'гульденів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'AOA': (
|
||||
('кванза', 'кванзи', 'кванз'),
|
||||
('сентимо', 'сентимо', 'сентимо')
|
||||
),
|
||||
'ARS': (
|
||||
('песо', 'песо', 'песо'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'AUD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'AWG': (
|
||||
('флорин', 'флорини', 'флоринів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'AZN': (
|
||||
('манат', 'манати', 'манатів'),
|
||||
('гяпік', 'гяпіки', 'гяпіків')
|
||||
),
|
||||
'BAM': (
|
||||
('марка', 'марки', 'марок'),
|
||||
('фенінг', 'фенінги', 'фенінгів')
|
||||
),
|
||||
'BBD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'BDT': (
|
||||
('така', 'таки', 'так'),
|
||||
('пойша', 'пойші', 'пойш')
|
||||
),
|
||||
'BGN': (
|
||||
('лев', 'леви', 'левів'),
|
||||
('стотинка', 'стотинки', 'стотинок')
|
||||
),
|
||||
'BHD': (
|
||||
('динар', 'динари', 'динарів'),
|
||||
('філс', 'філси', 'філсів')
|
||||
),
|
||||
'BIF': (
|
||||
('франк', 'франки', 'франків'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'BMD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'BND': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'BOB': (
|
||||
('болівіано', 'болівіано', 'болівіано'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'BRL': (
|
||||
('реал', 'реали', 'реалів'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'BSD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'BTN': (
|
||||
('нгултрум', 'нгултруми', 'нгултрумів'),
|
||||
('четрум', 'четруми', 'четрумів')
|
||||
),
|
||||
'BWP': (
|
||||
('пула', 'пули', 'пул'),
|
||||
('тхебе', 'тхебе', 'тхебе')
|
||||
),
|
||||
'BYN': (
|
||||
('рубель', 'рублі', 'рублів'),
|
||||
('копійка', 'копійки', 'копійок')
|
||||
),
|
||||
'BZD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'CAD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'CDF': (
|
||||
('франк', 'франки', 'франків'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'CHF': (
|
||||
('франк', 'франки', 'франків'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'CLP': (
|
||||
('песо', 'песо', 'песо'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'CNY': (
|
||||
('юань', 'юані', 'юанів'),
|
||||
('финь', 'фині', 'финів')
|
||||
),
|
||||
'COP': (
|
||||
('песо', 'песо', 'песо'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'CRC': (
|
||||
('колон', 'колони', 'колонів'),
|
||||
('сентімо', 'сентімо', 'сентімо')
|
||||
),
|
||||
'CUC': (
|
||||
('песо', 'песо', 'песо'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'CUP': (
|
||||
('песо', 'песо', 'песо'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'CVE': (
|
||||
('ескудо', 'ескудо', 'ескудо'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'CZK': (
|
||||
('крона', 'крони', 'крон'),
|
||||
('гелер', 'гелери', 'гелерів')
|
||||
),
|
||||
'DJF': (
|
||||
('франк', 'франки', 'франків'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'DKK': (
|
||||
('крона', 'крони', 'крон'),
|
||||
('ере', 'ере', 'ере')
|
||||
),
|
||||
'DOP': (
|
||||
('песо', 'песо', 'песо'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'DZD': (
|
||||
('динар', 'динари', 'динарів'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'EGP': (
|
||||
('фунт', 'фунти', 'фунтів'),
|
||||
('піастр', 'піастри', 'піастрів')
|
||||
),
|
||||
'ERN': (
|
||||
('накфа', 'накфи', 'накф'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'ETB': (
|
||||
('бир', 'бири', 'бирів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'EUR': (
|
||||
('євро', 'євро', 'євро'), ('цент', 'центи', 'центiв')
|
||||
('євро', 'євро', 'євро'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'FJD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'FKP': (
|
||||
('фунт', 'фунти', 'фунтів'),
|
||||
('пенс', 'пенси', 'пенсів')
|
||||
),
|
||||
'GBP': (
|
||||
('фунт', 'фунти', 'фунтів'),
|
||||
('пенс', 'пенси', 'пенсів')
|
||||
),
|
||||
'GEL': (
|
||||
('ларі', 'ларі', 'ларі'),
|
||||
('тетрі', 'тетрі', 'тетрі')
|
||||
),
|
||||
'GHS': (
|
||||
('седі', 'седі', 'седі'),
|
||||
('песева', 'песеви', 'песев')
|
||||
),
|
||||
'GIP': (
|
||||
('фунт', 'фунти', 'фунтів'),
|
||||
('пенс', 'пенси', 'пенсів')
|
||||
),
|
||||
'GMD': (
|
||||
('даласі', 'даласі', 'даласі'),
|
||||
('бутут', 'бутути', 'бутутів')
|
||||
),
|
||||
'GNF': (
|
||||
('франк', 'франки', 'франків'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'GTQ': (
|
||||
('кетсаль', 'кетсалі', 'кетсалів'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'GYD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'HKD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'HNL': (
|
||||
('лемпіра', 'лемпіри', 'лемпір'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'HRK': (
|
||||
('куна', 'куни', 'кун'),
|
||||
('ліпа', 'ліпи', 'ліп')
|
||||
),
|
||||
'HTG': (
|
||||
('гурд', 'гурди', 'гурдів'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'HUF': (
|
||||
('форинт', 'форинти', 'форинтів'),
|
||||
('філлер', 'філлери', 'філлерів')
|
||||
),
|
||||
'IDR': (
|
||||
('рупія', 'рупії', 'рупій'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'ILS': (
|
||||
('шекель', 'шекелі', 'шекелів'),
|
||||
('агора', 'агори', 'агор')
|
||||
),
|
||||
'INR': (
|
||||
('рупія', 'рупії', 'рупій'),
|
||||
('пайса', 'пайси', 'пайс')
|
||||
),
|
||||
'IQD': (
|
||||
('динар', 'динари', 'динарів'),
|
||||
('філс', 'філси', 'філсів')
|
||||
),
|
||||
'IRR': (
|
||||
('ріал', 'ріали', 'ріалів'),
|
||||
('динар', 'динари', 'динарів')
|
||||
),
|
||||
'ISK': (
|
||||
('крона', 'крони', 'крон'),
|
||||
('ейре', 'ейре', 'ейре')
|
||||
),
|
||||
'JMD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'JOD': (
|
||||
('динар', 'динари', 'динарів'),
|
||||
('філс', 'філси', 'філсів')
|
||||
),
|
||||
'JPY': (
|
||||
('єна', 'єни', 'єн'),
|
||||
('сен', 'сен', 'сен')
|
||||
),
|
||||
'KES': (
|
||||
('шилінг', 'шилінги', 'шилінгів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'KGS': (
|
||||
('сом', 'соми', 'сомів'),
|
||||
('тиїн', 'тиїни', 'тиїнів')
|
||||
),
|
||||
'KHR': (
|
||||
('рієль', 'рієлі', 'рієлів'),
|
||||
('су', 'су', 'су')
|
||||
),
|
||||
'KMF': (
|
||||
('франк', 'франки', 'франків'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'KPW': (
|
||||
('вона', 'вони', 'вон'),
|
||||
('чон', 'чони', 'чонів')
|
||||
),
|
||||
'KRW': (
|
||||
('вона', 'вони', 'вон'),
|
||||
('джеон', 'джеони', 'джеонів')
|
||||
),
|
||||
'KWD': (
|
||||
('динар', 'динари', 'динарів'),
|
||||
('філс', 'філси', 'філсів')
|
||||
),
|
||||
'KYD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'KZT': (
|
||||
('теньге', 'теньге', 'теньге'),
|
||||
('тиїн', 'тиїни', 'тиїнів')),
|
||||
'LAK': (
|
||||
('кіп', 'кіпи', 'кіпів'),
|
||||
('ат', 'ати', 'атів')
|
||||
),
|
||||
'LBP': (
|
||||
('фунт', 'фунти', 'фунтів'),
|
||||
('піастр', 'піастри', 'піастрів')
|
||||
),
|
||||
'LKR': (
|
||||
('рупія', 'рупії', 'рупій'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'LRD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'LSL': (
|
||||
('лоті', 'малоті', 'малоті'),
|
||||
('сенте', 'лісенте', 'лісенте')
|
||||
),
|
||||
'LYD': (
|
||||
('динар', 'динари', 'динарів'),
|
||||
('дирхам', 'дирхами', 'дирхамів')
|
||||
),
|
||||
'MAD': (
|
||||
('дирхам', 'дирхами', 'дирхамів'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'MDL': (
|
||||
('лей', 'леї', 'леї'),
|
||||
('бан', 'бані', 'бані')
|
||||
),
|
||||
'MGA': (
|
||||
('аріарі', 'аріарі', 'аріарі'),
|
||||
('іраймбіланья', 'іраймбіланья', 'іраймбіланья')
|
||||
),
|
||||
'MKD': (
|
||||
('денар', 'денари', 'денарів'),
|
||||
('дені', 'дені', 'дені')
|
||||
),
|
||||
'MMK': (
|
||||
('к\'ят', 'к\'ят', 'к\'ят'),
|
||||
('п\'я', 'п\'я', 'п\'я')
|
||||
),
|
||||
'MNT': (
|
||||
('тугрик', 'тугрики', 'тугриків'),
|
||||
('мунгу', 'мунгу', 'мунгу')
|
||||
),
|
||||
'MOP': (
|
||||
('патака', 'патакі', 'патак'),
|
||||
('аво', 'аво', 'аво')
|
||||
),
|
||||
'MRU': (
|
||||
('угія', 'угії', 'угій'),
|
||||
('хумс', 'хумс', 'хумс')
|
||||
),
|
||||
'MUR': (
|
||||
('рупія', 'рупії', 'рупій'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'MVR': (
|
||||
('руфія', 'руфії', 'руфій'),
|
||||
('ларі', 'ларі', 'ларі')
|
||||
),
|
||||
'MWK': (
|
||||
('квача', 'квачі', 'квач'),
|
||||
('тамбала', 'тамбала', 'тамбала')
|
||||
),
|
||||
'MXN': (
|
||||
('песо', 'песо', 'песо'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'MYR': (
|
||||
('рингіт', 'рингіти', 'рингітів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'MZN': (
|
||||
('метікал', 'метікали', 'метікалів'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'NAD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'NGN': (
|
||||
('найра', 'найри', 'найр'),
|
||||
('кобо', 'кобо', 'кобо')
|
||||
),
|
||||
'NIO': (
|
||||
('кордоба', 'кордоби', 'кордоб'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'NOK': (
|
||||
('крона', 'крони', 'крон'),
|
||||
('ере', 'ере', 'ере')
|
||||
),
|
||||
'NPR': (
|
||||
('рупія', 'рупії', 'рупій'),
|
||||
('пайса', 'пайси', 'пайс')
|
||||
),
|
||||
'NZD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'OMR': (
|
||||
('ріал', 'ріали', 'ріалів'),
|
||||
('байза', 'байзи', 'байз')
|
||||
),
|
||||
'PAB': (
|
||||
('бальбоа', 'бальбоа', 'бальбоа'),
|
||||
('сентесімо', 'сентесімо', 'сентесімо')
|
||||
),
|
||||
'PEN': (
|
||||
('соль', 'соль', 'соль'),
|
||||
('сентімо', 'сентімо', 'сентімо')
|
||||
),
|
||||
'PGK': (
|
||||
('кіна', 'кіна', 'кіна'),
|
||||
('тойя', 'тойя', 'тойя')
|
||||
),
|
||||
'PHP': (
|
||||
('песо', 'песо', 'песо'),
|
||||
('сентаво', 'сентаво', 'сентаво')
|
||||
),
|
||||
'PKR': (
|
||||
('рупія', 'рупії', 'рупій'),
|
||||
('пайса', 'пайси', 'пайс')
|
||||
),
|
||||
'PLN': (
|
||||
('злотий', 'злоті', 'злотих'),
|
||||
('грош', 'гроші', 'грошів')
|
||||
),
|
||||
'PYG': (
|
||||
('гуарані', 'гуарані', 'гуарані'),
|
||||
('сентімо', 'сентімо', 'сентімо')
|
||||
),
|
||||
'QAR': (
|
||||
('ріал', 'ріали', 'ріалів'),
|
||||
('дирхам', 'дирхами', 'дирхамів')
|
||||
),
|
||||
'RON': (
|
||||
('лей', 'леї', 'леї'),
|
||||
('бан', 'бані', 'бані')
|
||||
),
|
||||
'RSD': (
|
||||
('динар', 'динари', 'динарів'),
|
||||
('пара', 'пари', 'пар')
|
||||
),
|
||||
'RUB': (
|
||||
('рубль', 'рублі', 'рублів'),
|
||||
('копійка', 'копійки', 'копійок')
|
||||
),
|
||||
'RWF': (
|
||||
('франк', 'франки', 'франків'),
|
||||
('сантим', 'сантими', 'сантимів')
|
||||
),
|
||||
'SAR': (
|
||||
('ріал', 'ріали', 'ріалів'),
|
||||
('халал', 'халали', 'халалів')
|
||||
),
|
||||
'SBD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'SCR': (
|
||||
('рупія', 'рупії', 'рупій'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'SDG': (
|
||||
('фунт', 'фунти', 'фунтів'),
|
||||
('піастр', 'піастри', 'піастрів')
|
||||
),
|
||||
'SEK': (
|
||||
('крона', 'крони', 'крон'),
|
||||
('ере', 'ере', 'ере')
|
||||
),
|
||||
'SGD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'SHP': (
|
||||
('фунт', 'фунти', 'фунтів'),
|
||||
('пенс', 'пенси', 'пенсів')
|
||||
),
|
||||
'SLL': (
|
||||
('леоне', 'леоне', 'леоне'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'SOS': (
|
||||
('шилінг', 'шилінги', 'шилінгів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'SRD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'SSP': (
|
||||
('фунт', 'фунти', 'фунтів'),
|
||||
('піастр', 'піастри', 'піастрів')
|
||||
),
|
||||
'STN': (
|
||||
('добра', 'добри', 'добр'),
|
||||
('сентімо', 'сентімо', 'сентімо')
|
||||
),
|
||||
'SYP': (
|
||||
('фунт', 'фунти', 'фунтів'),
|
||||
('піастр', 'піастри', 'піастрів')
|
||||
),
|
||||
'SZL': (
|
||||
('ліланґені', 'ліланґені', 'ліланґені'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'THB': (
|
||||
('бат', 'бати', 'батів'),
|
||||
('сатанг', 'сатанги', 'сатангів')
|
||||
),
|
||||
'TJS': (
|
||||
('сомоні', 'сомоні', 'сомоні'),
|
||||
('дірам', 'дірами', 'дірамів')
|
||||
),
|
||||
'TMT': (
|
||||
('манат', 'манати', 'манатів'),
|
||||
('тенге', 'тенге', 'тенге')
|
||||
),
|
||||
'TND': (
|
||||
('динар', 'динари', 'динарів'),
|
||||
('міллім', 'мілліми', 'міллімів')
|
||||
),
|
||||
'TOP': (
|
||||
('паанга', 'паанга', 'паанга'),
|
||||
('сеніті', 'сеніті', 'сеніті')
|
||||
),
|
||||
'TRY': (
|
||||
('ліра', 'ліри', 'лір'),
|
||||
('куруш', 'куруші', 'курушів')
|
||||
),
|
||||
'TTD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'TWD': (
|
||||
('новий долар', 'нові долари', 'нових доларів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'TZS': (
|
||||
('шилінг', 'шилінги', 'шилінгів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'UAH': (
|
||||
('гривня', 'гривні', 'гривень'),
|
||||
('копійка', 'копійки', 'копійок')
|
||||
),
|
||||
'UGX': (
|
||||
('шилінг', 'шилінги', 'шилінгів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'USD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'UYU': (
|
||||
('песо', 'песо', 'песо'),
|
||||
('сентесімо', 'сентесімо', 'сентесімо')
|
||||
),
|
||||
'UZS': (
|
||||
('сум', 'суми', 'сумів'),
|
||||
('тиїн', 'тиїни', 'тиїнів')
|
||||
),
|
||||
'VND': (
|
||||
('донг', 'донги', 'донгів'),
|
||||
('су', 'су', 'су')
|
||||
),
|
||||
'WST': (
|
||||
('тала', 'тали', 'тал'),
|
||||
('сене', 'сене', 'сене')
|
||||
),
|
||||
'XCD': (GENERIC_DOLLARS, GENERIC_CENTS),
|
||||
'YER': (
|
||||
('ріал', 'ріали', 'ріалів'),
|
||||
('філс', 'філси', 'філсів')
|
||||
),
|
||||
'ZAR': (
|
||||
('ранд', 'ранди', 'рандів'),
|
||||
GENERIC_CENTS
|
||||
),
|
||||
'ZMW': (
|
||||
('квача', 'квачі', 'квач'),
|
||||
('нгве', 'нгве', 'нгве')
|
||||
),
|
||||
}
|
||||
|
||||
def setup(self):
|
||||
self.negword = "мiнус"
|
||||
self.negword = "мінус"
|
||||
self.pointword = "кома"
|
||||
|
||||
def to_cardinal(self, number):
|
||||
n = str(number).replace(',', '.')
|
||||
if '.' in n:
|
||||
left, right = n.split('.')
|
||||
return '%s %s %s' % (
|
||||
leading_zero_count = len(right) - len(right.lstrip('0'))
|
||||
decimal_part = ((ZERO[0] + ' ') * leading_zero_count +
|
||||
self._int2word(int(right)))
|
||||
return u'%s %s %s' % (
|
||||
self._int2word(int(left)),
|
||||
self.pointword,
|
||||
self._int2word(int(right))
|
||||
decimal_part
|
||||
)
|
||||
else:
|
||||
return self._int2word(int(n))
|
||||
@@ -136,7 +739,7 @@ class Num2Word_UK(Num2Word_Base):
|
||||
|
||||
return forms[form]
|
||||
|
||||
def _int2word(self, n, feminine=True):
|
||||
def _int2word(self, n, feminine=False):
|
||||
if n < 0:
|
||||
return ' '.join([self.negword, self._int2word(abs(n))])
|
||||
|
||||
@@ -172,8 +775,78 @@ class Num2Word_UK(Num2Word_Base):
|
||||
|
||||
return ' '.join(words)
|
||||
|
||||
def _money_verbose(self, number, currency):
|
||||
return self._int2word(number, currency in FEMININE_MONEY)
|
||||
|
||||
def _cents_verbose(self, number, currency):
|
||||
return self._int2word(number, currency == 'UAH')
|
||||
return self._int2word(number, currency in FEMININE_CENTS)
|
||||
|
||||
@staticmethod
|
||||
def last_fragment_to_ordinal(last, words, level):
|
||||
n1, n2, n3 = get_digits(last)
|
||||
last_two = n2*10+n1
|
||||
if last_two == 0:
|
||||
words.append(HUNDREDS_ORDINALS[n3][level])
|
||||
elif level == 1 and last == 1:
|
||||
return
|
||||
elif last_two < 20:
|
||||
if level == 0:
|
||||
if n3 > 0:
|
||||
words.append(HUNDREDS[n3][0])
|
||||
words.append(ONES_ORDINALS[last_two][0])
|
||||
else:
|
||||
last_fragment_string = ''
|
||||
if n3 > 0:
|
||||
last_fragment_string += HUNDREDS_ORDINALS[n3][1]
|
||||
last_fragment_string += ONES_ORDINALS[last_two][1]
|
||||
words.append(last_fragment_string)
|
||||
elif last_two % 10 == 0:
|
||||
if level == 0:
|
||||
if n3 > 0:
|
||||
words.append(HUNDREDS[n3][0])
|
||||
words.append(TWENTIES_ORDINALS[n2][0])
|
||||
else:
|
||||
last_fragment_string = ''
|
||||
if n3 > 0:
|
||||
last_fragment_string += HUNDREDS_ORDINALS[n3][1]
|
||||
last_fragment_string += TWENTIES_ORDINALS[n2][1]
|
||||
words.append(last_fragment_string)
|
||||
else:
|
||||
if level == 0:
|
||||
if n3 > 0:
|
||||
words.append(HUNDREDS[n3][0])
|
||||
words.append(TWENTIES[n2][0])
|
||||
words.append(ONES_ORDINALS[n1][0])
|
||||
else:
|
||||
last_fragment_string = ''
|
||||
if n3 > 0:
|
||||
last_fragment_string += HUNDREDS_ORDINALS[n3][1]
|
||||
last_fragment_string += TWENTIES_ORDINALS[n2][1]
|
||||
last_fragment_string += ONES_ORDINALS[n1][1]
|
||||
words.append(last_fragment_string)
|
||||
|
||||
def to_ordinal(self, number):
|
||||
raise NotImplementedError()
|
||||
self.verify_ordinal(number)
|
||||
|
||||
words = []
|
||||
fragments = list(splitbyx(str(number), 3))
|
||||
level = 0
|
||||
last = fragments[-1]
|
||||
while last == 0:
|
||||
level = level + 1
|
||||
fragments.pop()
|
||||
last = fragments[-1]
|
||||
if len(fragments) > 1:
|
||||
pre_part = self._int2word(number - (last * 1000 ** level))
|
||||
words.append(pre_part)
|
||||
Num2Word_UK.last_fragment_to_ordinal(
|
||||
last,
|
||||
words,
|
||||
0 if level == 0 else 1
|
||||
)
|
||||
output = " ".join(words)
|
||||
if last == 1 and level > 0 and output != "":
|
||||
output = output + " "
|
||||
if level > 0:
|
||||
output = output + prefixes_ordinal[level]
|
||||
return output
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
tox
|
||||
flake8
|
||||
flake8-copyright
|
||||
isort
|
||||
|
||||
10
setup.py
10
setup.py
@@ -27,8 +27,11 @@ CLASSIFIERS = [
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: GNU Library or Lesser General Public License '
|
||||
'(LGPL)',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: 3.10',
|
||||
'Topic :: Software Development :: Internationalization',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Topic :: Software Development :: Localization',
|
||||
@@ -61,11 +64,12 @@ setup(
|
||||
version=find_version("bin/num2words"),
|
||||
description='Modules to convert numbers to words. Easily extensible.',
|
||||
long_description=LONG_DESC,
|
||||
long_description_content_type="text/markdown",
|
||||
license='LGPL',
|
||||
author='Taro Ogawa <tso at users sourceforge net>',
|
||||
author_email='tos@users.sourceforge.net',
|
||||
maintainer='Savoir-faire Linux inc.',
|
||||
maintainer_email='istvan.szalai@savoirfairelinux.com',
|
||||
maintainer_email='support@savoirfairelinux.com',
|
||||
keywords=' number word numbers words convert conversion i18n '
|
||||
'localisation localization internationalisation '
|
||||
'internationalization',
|
||||
|
||||
@@ -58,3 +58,8 @@ class Num2WordBaseTest(TestCase):
|
||||
self.base.title("one"),
|
||||
"One"
|
||||
)
|
||||
self.base.exclude_title.append('one')
|
||||
self.assertEqual(
|
||||
self.base.title("one"),
|
||||
"one"
|
||||
)
|
||||
|
||||
@@ -32,6 +32,14 @@ class Num2WordsCZTest(TestCase):
|
||||
self.assertEqual(num2words(1000, lang='cz'), "tisíc")
|
||||
self.assertEqual(num2words(1001, lang='cz'), "tisíc jedna")
|
||||
self.assertEqual(num2words(2012, lang='cz'), "dva tisíce dvanáct")
|
||||
self.assertEqual(
|
||||
num2words(10.02, lang='cz'),
|
||||
"deset celá nula dva"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(15.007, lang='cz'),
|
||||
"patnáct celá nula nula sedm"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(12519.85, lang='cz'),
|
||||
"dvanáct tisíc pětset devatenáct celá osmdesát pět"
|
||||
|
||||
390
tests/test_es.py
390
tests/test_es.py
File diff suppressed because it is too large
Load Diff
109
tests/test_fa.py
Normal file
109
tests/test_fa.py
Normal file
@@ -0,0 +1,109 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
|
||||
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
|
||||
# Copyright (c) 2020, Hamidreza Kalbasi. 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 unittest import TestCase
|
||||
|
||||
from num2words import num2words
|
||||
|
||||
|
||||
class Num2WordsFATest(TestCase):
|
||||
def test_and_join_199(self):
|
||||
self.assertEqual(num2words(199, lang='fa'), "صد و نود و نه")
|
||||
|
||||
def test_ordinal(self):
|
||||
self.assertEqual(
|
||||
num2words(0, lang='fa', to='ordinal'),
|
||||
'صفرم'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(1, lang='fa', to='ordinal'),
|
||||
'یکم'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(13, lang='fa', to='ordinal'),
|
||||
'سیزدهم'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(23, lang='fa', to='ordinal'),
|
||||
'بیست و سوم'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(12, lang='fa', to='ordinal'),
|
||||
'دوازدهم'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(113, lang='fa', to='ordinal'),
|
||||
'صد و سیزدهم'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(103, lang='fa', to='ordinal'),
|
||||
'صد و سوم'
|
||||
)
|
||||
|
||||
def test_cardinal(self):
|
||||
self.assertEqual(num2words(130000, lang='fa'), "صد و سی هزار")
|
||||
self.assertEqual(num2words(242, lang='fa'), "دویست و چهل و دو")
|
||||
self.assertEqual(num2words(800, lang='fa'), "هشتصد")
|
||||
self.assertEqual(num2words(-203, lang='fa'), "منفی دویست و سه")
|
||||
self.assertEqual(
|
||||
num2words(1234567890, lang='fa'),
|
||||
"یک میلیارد و دویست و سی و چهار میلیون و"
|
||||
" پانصد و شصت و هفت هزار و هشتصد و نود"
|
||||
)
|
||||
|
||||
def test_year(self):
|
||||
self.assertEqual(num2words(1398, lang='fa', to='year'),
|
||||
"هزار و سیصد و نود و هشت")
|
||||
self.assertEqual(num2words(1399, lang='fa', to='year'),
|
||||
"هزار و سیصد و نود و نه")
|
||||
self.assertEqual(
|
||||
num2words(1400, lang='fa', to='year'), "هزار و چهارصد")
|
||||
|
||||
def test_currency(self):
|
||||
self.assertEqual(
|
||||
num2words(1000, lang='fa', to='currency'), 'هزار تومان')
|
||||
self.assertEqual(
|
||||
num2words(1500000, lang='fa', to='currency'),
|
||||
'یک میلیون و پانصد هزار تومان'
|
||||
)
|
||||
|
||||
def test_ordinal_num(self):
|
||||
self.assertEqual(num2words(10, lang='fa', to='ordinal_num'), '10م')
|
||||
self.assertEqual(num2words(21, lang='fa', to='ordinal_num'), '21م')
|
||||
self.assertEqual(num2words(102, lang='fa', to='ordinal_num'), '102م')
|
||||
self.assertEqual(num2words(73, lang='fa', to='ordinal_num'), '73م')
|
||||
|
||||
def test_cardinal_for_float_number(self):
|
||||
self.assertEqual(num2words(12.5, lang='fa'), "دوازده و نیم")
|
||||
self.assertEqual(num2words(0.75, lang='fa'), "هفتاد و پنج صدم")
|
||||
self.assertEqual(num2words(12.51, lang='fa'),
|
||||
"دوازده و پنجاه و یک صدم")
|
||||
self.assertEqual(num2words(12.53, lang='fa'),
|
||||
"دوازده و پنجاه و سه صدم")
|
||||
self.assertEqual(num2words(12.59, lang='fa'),
|
||||
"دوازده و پنجاه و نه صدم")
|
||||
self.assertEqual(num2words(0.000001, lang='fa'), "یک میلیونیم")
|
||||
|
||||
def test_overflow(self):
|
||||
with self.assertRaises(OverflowError):
|
||||
num2words("1000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000"
|
||||
"00000000000000000000000000000000")
|
||||
@@ -163,6 +163,21 @@ class Num2WordsJATest(TestCase):
|
||||
"はちじゅうきゅうえん")
|
||||
|
||||
def test_year(self):
|
||||
self.assertEqual(n2j(2021, to="year"), "令和三年")
|
||||
self.assertEqual(n2j(2021, to="year", reading=True),
|
||||
"れいわさんねん")
|
||||
self.assertEqual(n2j(2021, to="year", reading="arabic"),
|
||||
"令和3年")
|
||||
self.assertEqual(n2j(2019, to="year"), "令和元年")
|
||||
self.assertEqual(n2j(2019, to="year", reading=True),
|
||||
"れいわがんねん")
|
||||
self.assertEqual(n2j(2019, to="year", reading="arabic"),
|
||||
"令和1年")
|
||||
self.assertEqual(n2j(2018, to="year"), "平成三十年")
|
||||
self.assertEqual(n2j(2018, to="year", reading=True),
|
||||
"へいせいさんじゅうねん")
|
||||
self.assertEqual(n2j(2018, to="year", reading="arabic"),
|
||||
"平成30年")
|
||||
self.assertEqual(n2j(2017, to="year"), "平成二十九年")
|
||||
self.assertEqual(n2j(2017, to="year", reading=True),
|
||||
"へいせいにじゅうくねん")
|
||||
@@ -176,8 +191,6 @@ class Num2WordsJATest(TestCase):
|
||||
"にせんねん")
|
||||
self.assertEqual(n2j(645, to="year"), "大化元年")
|
||||
self.assertEqual(n2j(645, to="year", reading=True), "たいかがんねん")
|
||||
self.assertEqual(n2j(645, to="year"), "大化元年")
|
||||
self.assertEqual(n2j(645, to="year", reading=True), "たいかがんねん")
|
||||
self.assertEqual(n2j(-99, to="year", era=False), "紀元前九十九年")
|
||||
self.assertEqual(n2j(-99, to="year", era=False, reading=True),
|
||||
"きげんぜんきゅうじゅうくねん")
|
||||
|
||||
@@ -44,6 +44,14 @@ class Num2WordsKZTest(TestCase):
|
||||
self.assertEqual(num2words(100.67, lang="kz"), "жүз бүтін алпыс жеті")
|
||||
self.assertEqual(num2words(0.7, lang="kz"), "нөл бүтін жеті")
|
||||
self.assertEqual(num2words(1.73, lang="kz"), "бір бүтін жетпіс үш")
|
||||
self.assertEqual(
|
||||
num2words(10.02, lang='kz'),
|
||||
"он бүтін нөл екі"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(15.007, lang='kz'),
|
||||
"он бес бүтін нөл нөл жеті"
|
||||
)
|
||||
|
||||
def test_to_ordinal(self):
|
||||
with self.assertRaises(NotImplementedError):
|
||||
|
||||
@@ -68,6 +68,14 @@ class Num2WordsLTTest(TestCase):
|
||||
num2words(-5000.22, lang='lt'),
|
||||
'minus penki tūkstančiai kablelis dvidešimt du',
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10.02, lang='lt'),
|
||||
"dešimt kablelis nulis du"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(15.007, lang='lt'),
|
||||
"penkiolika kablelis nulis nulis septyni"
|
||||
)
|
||||
|
||||
def test_to_ordinal(self):
|
||||
# @TODO: implement to_ordinal
|
||||
|
||||
@@ -63,6 +63,14 @@ class Num2WordsLVTest(TestCase):
|
||||
num2words(-5000.22, lang='lv'),
|
||||
'mīnus pieci tūkstoši komats divdesmit divi',
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10.02, lang='lv'),
|
||||
"desmit komats nulle divi"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(15.007, lang='lv'),
|
||||
"piecpadsmit komats nulle nulle septiņi"
|
||||
)
|
||||
|
||||
self.assertEqual(num2words(0, lang='lv'), 'nulle')
|
||||
self.assertEqual(num2words(5, lang='lv'), "pieci")
|
||||
|
||||
@@ -32,6 +32,14 @@ class Num2WordsPLTest(TestCase):
|
||||
self.assertEqual(num2words(1000, lang='pl'), "tysiąc")
|
||||
self.assertEqual(num2words(1001, lang='pl'), "tysiąc jeden")
|
||||
self.assertEqual(num2words(2012, lang='pl'), "dwa tysiące dwanaście")
|
||||
self.assertEqual(
|
||||
num2words(10.02, lang='pl'),
|
||||
"dziesięć przecinek zero dwa"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(15.007, lang='pl'),
|
||||
"piętnaście przecinek zero zero siedem"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(12519.85, lang='pl'),
|
||||
"dwanaście tysięcy pięćset dziewiętnaście przecinek "
|
||||
|
||||
@@ -75,6 +75,14 @@ class Num2WordsRUTest(TestCase):
|
||||
|
||||
def test_floating_point(self):
|
||||
self.assertEqual(num2words(5.2, lang='ru'), "пять запятая два")
|
||||
self.assertEqual(
|
||||
num2words(10.02, lang='ru'),
|
||||
"десять запятая ноль два"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(15.007, lang='ru'),
|
||||
"пятнадцать запятая ноль ноль семь"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(561.42, lang='ru'),
|
||||
"пятьсот шестьдесят один запятая сорок два"
|
||||
@@ -160,6 +168,10 @@ class Num2WordsRUTest(TestCase):
|
||||
num2words(1.0, lang='ru', to='currency', currency='RUB'),
|
||||
'один рубль, ноль копеек'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(1.0, lang='ru', to='currency', currency='UAH'),
|
||||
'одна гривна, ноль копеек'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(1234.56, lang='ru', to='currency', currency='EUR'),
|
||||
'одна тысяча двести тридцать четыре евро, пятьдесят шесть центов'
|
||||
@@ -168,36 +180,85 @@ class Num2WordsRUTest(TestCase):
|
||||
num2words(1234.56, lang='ru', to='currency', currency='RUB'),
|
||||
'одна тысяча двести тридцать четыре рубля, пятьдесят шесть копеек'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(1234.56, lang='ru', to='currency', currency='UAH'),
|
||||
'одна тысяча двести тридцать четыре гривны, пятьдесят шесть копеек'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10111, lang='ru', to='currency', currency='EUR',
|
||||
separator=' и'),
|
||||
'сто один евро и одиннадцать центов'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10121, lang='ru', to='currency', currency='RUB',
|
||||
num2words(10111, lang='ru', to='currency', currency='RUB',
|
||||
separator=' и'),
|
||||
'сто один рубль и двадцать одна копейка'
|
||||
'сто один рубль и одиннадцать копеек'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10122, lang='ru', to='currency', currency='RUB',
|
||||
num2words(10111, lang='ru', to='currency', currency='UAH',
|
||||
separator=' и'),
|
||||
'сто один рубль и двадцать две копейки'
|
||||
'сто одна гривна и одиннадцать копеек'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10121, lang='ru', to='currency', currency='EUR',
|
||||
separator=' и'),
|
||||
'сто один евро и двадцать один цент'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10121, lang='ru', to='currency', currency='RUB',
|
||||
separator=' и'),
|
||||
'сто один рубль и двадцать одна копейка'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10121, lang='ru', to='currency', currency='UAH',
|
||||
separator=' и'),
|
||||
'сто одна гривна и двадцать одна копейка'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10122, lang='ru', to='currency', currency='EUR',
|
||||
separator=' и'),
|
||||
'сто один евро и двадцать два цента'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10122, lang='ru', to='currency', currency='RUB',
|
||||
separator=' и'),
|
||||
'сто один рубль и двадцать две копейки'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(10122, lang='ru', to='currency', currency='UAH',
|
||||
separator=' и'),
|
||||
'сто одна гривна и двадцать две копейки'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(-1251985, lang='ru', to='currency', currency='EUR',
|
||||
cents=False),
|
||||
'минус двенадцать тысяч пятьсот девятнадцать евро, 85 центов'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(-1251985, lang='ru', to='currency', currency='RUB',
|
||||
cents=False),
|
||||
'минус двенадцать тысяч пятьсот девятнадцать рублей, 85 копеек'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(-1251985, lang='ru', to='currency', currency='UAH',
|
||||
cents=False),
|
||||
'минус двенадцать тысяч пятьсот девятнадцать гривен, 85 копеек'
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words('38.4', lang='ru', to='currency', separator=' и',
|
||||
cents=False, currency='EUR'),
|
||||
"тридцать восемь евро и 40 центов"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words('38.4', lang='ru', to='currency', separator=' и',
|
||||
cents=False, currency='RUB'),
|
||||
"тридцать восемь рублей и 40 копеек"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words('38.4', lang='ru', to='currency', separator=' и',
|
||||
cents=False, currency='UAH'),
|
||||
"тридцать восемь гривен и 40 копеек"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words('1230.56', lang='ru', to='currency', currency='USD'),
|
||||
'одна тысяча двести тридцать долларов, пятьдесят шесть центов'
|
||||
|
||||
@@ -86,6 +86,14 @@ class Num2WordsSRTest(TestCase):
|
||||
|
||||
def test_floating_point(self):
|
||||
self.assertEqual("pet zapeta dva", num2words(5.2, lang='sr'))
|
||||
self.assertEqual(
|
||||
num2words(10.02, lang='sr'),
|
||||
"deset zapeta nula dva"
|
||||
)
|
||||
self.assertEqual(
|
||||
num2words(15.007, lang='sr'),
|
||||
"petnaest zapeta nula nula sedam"
|
||||
)
|
||||
self.assertEqual(
|
||||
"petsto šezdeset jedan zapeta četrdeset dva",
|
||||
num2words(561.42, lang='sr')
|
||||
|
||||
@@ -36,6 +36,7 @@ class Num2WordsTRTest(TestCase):
|
||||
"expected": u"birmilyonikibinbirlira"},
|
||||
{"test": 1100000, "to": "currency",
|
||||
"expected": u"birmilyonyüzbinlira"},
|
||||
{"test": 0, "to": "ordinal", "expected": u"sıfırıncı"},
|
||||
{"test": 1, "to": "ordinal", "expected": u"birinci"},
|
||||
{"test": 2, "to": "ordinal", "expected": u"ikinci"},
|
||||
{"test": 9, "to": "ordinal", "expected": u"dokuzuncu"},
|
||||
@@ -108,6 +109,7 @@ class Num2WordsTRTest(TestCase):
|
||||
"expected": u"birmilyonüçbininci"},
|
||||
{"test": 1200000, "to": "ordinal",
|
||||
"expected": u"birmilyonikiyüzbininci"},
|
||||
{"test": 0, "to": "cardinal", "expected": u"sıfır"},
|
||||
{"test": 1, "to": "cardinal", "expected": u"bir"},
|
||||
{"test": 2, "to": "cardinal", "expected": u"iki"},
|
||||
{"test": 9, "to": "cardinal", "expected": u"dokuz"},
|
||||
|
||||
3438
tests/test_uk.py
3438
tests/test_uk.py
File diff suppressed because it is too large
Load Diff
19
tox.ini
19
tox.ini
@@ -1,8 +1,17 @@
|
||||
[tox]
|
||||
envlist = flake8,isort,py27,py34,py35,py36,py37
|
||||
envlist = py36,py37,py38,py39,py310,flake8,isort
|
||||
|
||||
[gh-actions]
|
||||
python =
|
||||
3.6: py36
|
||||
3.7: py37
|
||||
3.8: py38
|
||||
3.9: py39
|
||||
3.10: isort, flake8, py310
|
||||
|
||||
|
||||
[testenv]
|
||||
passenv = TRAVIS TRAVIS_*
|
||||
passenv = GITHUB_*
|
||||
deps =
|
||||
coverage
|
||||
delegator.py
|
||||
@@ -25,8 +34,4 @@ deps =
|
||||
isort
|
||||
delegator.py
|
||||
commands =
|
||||
isort --check-only --recursive --diff num2words tests
|
||||
|
||||
[testenv:py27]
|
||||
setenv =
|
||||
PYTHONIOENCODING = UTF-8
|
||||
isort --check-only --float-to-top --diff num2words tests
|
||||
|
||||
Reference in New Issue
Block a user