Merge branch 'master' of github.com-ieski:ieski/num2words

This commit is contained in:
ismail eski
2022-08-17 18:09:30 +03:00
23 changed files with 1216 additions and 266 deletions

45
.github/workflows/ci.yml vendored Normal file
View 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 }}

View File

@@ -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

View File

@@ -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
----------------------------

View File

@@ -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::
@@ -76,6 +76,7 @@ Besides the numerical argument, there are two main optional arguments.
**lang:** The language in which to convert the number. Supported values are:
* ``en`` (English, default)
* ``am`` (Amharic)
* ``ar`` (Arabic)
* ``cz`` (Czech)
* ``de`` (German)
@@ -86,6 +87,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)
@@ -111,6 +113,7 @@ Besides the numerical argument, there are two main optional arguments.
* ``ro`` (Romanian)
* ``ru`` (Russian)
* ``te`` (Telugu)
* ``tg`` (Tajik)
* ``tr`` (Turkish)
* ``th`` (Thai)
* ``vi`` (Vietnamese)
@@ -148,4 +151,4 @@ added Lithuanian support, but didn't take over maintenance of the project.
I am thus basing myself on Marius Grigaitis' improvements and re-publishing
``pynum2word`` as ``num2words``.
Virgil Dupras, Savoir-faire Linux
Virgil Dupras, Savoir-faire Linux

View File

@@ -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"

View File

@@ -17,19 +17,21 @@
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)
from . import (lang_AM, 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_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_TG, lang_TH, lang_TR, lang_UK, lang_VI)
CONVERTER_CLASSES = {
'am': lang_AM.Num2Word_AM(),
'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(),
@@ -60,6 +62,7 @@ CONVERTER_CLASSES = {
'he': lang_HE.Num2Word_HE(),
'it': lang_IT.Num2Word_IT(),
'vi': lang_VI.Num2Word_VI(),
'tg': lang_TG.Num2Word_TG(),
'th': lang_TH.Num2Word_TH(),
'tr': lang_TR.Num2Word_TR(),
'nl': lang_NL.Num2Word_NL(),

129
num2words/lang_AM.py Normal file
View File

@@ -0,0 +1,129 @@
# -*- 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 division, print_function, unicode_literals
from . import lang_EU
class Num2Word_AM(lang_EU.Num2Word_EU):
CURRENCY_FORMS = {'ETB': (('ብር', 'ብር'), ('ሳንቲም', 'ሳንቲም'))}
GIGA_SUFFIX = 'ቢሊዮን'
MEGA_SUFFIX = 'ሚሊዮን'
def set_high_numwords(self, high):
cap = 3 * (len(high) + 1)
for word, n in zip(high, range(cap, 5, -3)):
if n == 9:
self.cards[10 ** n] = word + self.GIGA_SUFFIX
else:
self.cards[10 ** n] = word + self.MEGA_SUFFIX
def setup(self):
super(Num2Word_AM, self).setup()
self.negword = 'አሉታዊ '
self.pointword = 'ነጥብ'
self.exclude_title = ['እና', 'ነጥብ', 'አሉታዊ']
self.mid_numwords = [(1000, 'ሺህ'), (100, 'መቶ'), (90, 'ዘጠና'),
(80, 'ሰማኒያ'), (70, 'ሰባ'), (60, 'ስድሳ'),
(50, 'አምሳ'), (40, 'አርባ'), (30, 'ሠላሳ')]
self.low_numwords = ['ሃያ', 'አሥራ ዘጠኝ', 'አሥራ ስምንት', 'አሥራ ሰባት',
'አስራ ስድስት', 'አሥራ አምስት', 'አሥራ አራት', 'አሥራ ሦስት',
'አሥራ ሁለት', 'አሥራ አንድ', 'አሥር', 'ዘጠኝ', 'ስምንት',
'ሰባት', 'ስድስት', 'አምስት', 'አራት', 'ሦስት', 'ሁለት',
'አንድ', 'ዜሮ']
self.ords = {'አንድ': 'አንደኛ',
'ሁለት': 'ሁለተኛ',
'ሦስት': 'ሦስተኛ',
'አራት': 'አራተኛ',
'አምስት': 'አምስተኛ',
'ስድስት': 'ስድስተኛ',
'ሰባት': 'ሰባተኛ',
'ስምንት': 'ስምንተኛ',
'ዘጠኝ': 'ዘጠነኛ',
'አሥር': 'አሥረኛ',
'አሥራ አንድ': 'አሥራ አንደኛ',
'አሥራ ሁለት': 'አሥራ ሁለተኛ',
'አሥራ ሦስት': 'አሥራ ሦስተኛ',
'አሥራ አራት': 'አሥራ አራተኛ',
'አሥራ አምስት': 'አሥራ አምስተኛ',
'አሥራ ስድስት': 'አሥራ ስድስተኛ',
'አሥራ ሰባት': 'አሥራ ሰባተኛ',
'አሥራ ስምንት': 'አሥራ ስምንተኛ',
'አሥራ ዘጠኝ': 'አሥራ ዘጠነኛ'}
def to_cardinal(self, value):
try:
assert int(value) == value
except (ValueError, TypeError, AssertionError):
return self.to_cardinal_float(value)
out = ''
if value >= self.MAXVAL:
raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL))
if value == 100:
return self.title(out + 'መቶ')
else:
val = self.splitnum(value)
words, num = self.clean(val)
return self.title(out + words)
def merge(self, lpair, rpair):
ltext, lnum = lpair
rtext, rnum = rpair
if lnum == 1 and rnum < 100:
return rtext, rnum
elif 100 > lnum > rnum:
return '%s %s' % (ltext, rtext), lnum + rnum
elif lnum >= 100 > rnum:
return '%s %s' % (ltext, rtext), lnum + rnum
elif rnum > lnum:
return '%s %s' % (ltext, rtext), lnum * rnum
def to_ordinal(self, value):
self.verify_ordinal(value)
outwords = self.to_cardinal(value).split(' ')
lastwords = outwords[-1].split('-')
lastword = lastwords[-1].lower()
try:
lastword = self.ords[lastword]
except KeyError:
lastword += ''
lastwords[-1] = self.title(lastword)
outwords[-1] = ' '.join(lastwords)
return ' '.join(outwords)
def to_ordinal_num(self, value):
self.verify_ordinal(value)
return '%s%s' % (value, self.to_ordinal(value)[-1:])
def to_currency(self, val, currency='ብር', cents=True, separator='',
adjective=True):
result = super(Num2Word_AM, self).to_currency(
val, currency=currency, cents=cents, separator=separator,
adjective=adjective)
return result
def to_year(self, val, longval=True):
if not (val // 100) % 10:
return self.to_cardinal(val)
return self.to_splitnum(val, hightxt='መቶ', longval=longval)

View File

@@ -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
View 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)

View File

@@ -81,11 +81,7 @@ AND = u'ו'
def pluralize(n, forms):
# gettext implementation:
# (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)
form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2
form = 1 if n == 0 else 0 if n == 1 else 1
return forms[form]
@@ -140,17 +136,30 @@ def n2w(n):
return int2word(int(n))
def to_currency(n, currency='EUR', cents=True, separator=','):
raise NotImplementedError()
class Num2Word_HE(Num2Word_Base):
CURRENCY_FORMS = {
'NIS': (('שקל', 'שקלים'), ('אגורה', 'אגורות')),
'EUR': (('אירו', 'אירו'), ('סנט', 'סנט')),
'USD': (('דולר', 'דולרים'), ('סנט', 'סנט')),
}
def to_cardinal(self, number):
return n2w(number)
def to_ordinal(self, number):
raise NotImplementedError()
def pluralize(self, n, forms):
return pluralize(n, forms)
def to_currency(self, val, currency='NIS', cents=True, separator=' ו',
adjective=False):
result = super(Num2Word_HE, self).to_currency(
val, currency=currency, cents=cents, separator=separator,
adjective=adjective)
# In Hebrew the separator is along with the following word
return result.replace(" ו ", " ו")
if __name__ == '__main__':
yo = Num2Word_HE()

View File

@@ -335,6 +335,7 @@ ERA_START = [
(1912, ("大正", "たいしょう")),
(1926, ("昭和", "しょうわ")),
(1989, ("平成", "へいせい")),
(2019, ("令和", "れいわ")),
]

View File

@@ -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("")

149
num2words/lang_TG.py Normal file
View File

@@ -0,0 +1,149 @@
# -*- 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 division, print_function, unicode_literals
from . import lang_EU
GENERIC_DOLLARS = ("доллар", "доллар")
GENERIC_CENTS = ("сент", "сент")
class Num2Word_TG(lang_EU.Num2Word_EU):
CURRENCY_FORMS = {
# repalced by EUR
"EUR": (("евро", "евро"), GENERIC_CENTS),
# replaced by EUR
"USD": (GENERIC_DOLLARS, GENERIC_CENTS),
"RUB": (("рубл", "рубл"), ("копейк", "копейк")),
"TJS": (("сомонӣ", "сомонӣ"), ("дирам", "дирам")),
}
GIGA_SUFFIX = "иллиард"
MEGA_SUFFIX = "иллион"
def set_high_numwords(self, high):
cap = 3 * (len(high) + 1)
for word, n in zip(high, range(cap, 5, -3)):
if n == 9:
self.cards[10 ** n] = word + self.GIGA_SUFFIX
else:
self.cards[10 ** n] = word + self.MEGA_SUFFIX
def setup(self):
super(Num2Word_TG, self).setup()
lows = ["квинт", "квадр", "тр", "м", "м"]
self.high_numwords = self.gen_high_numwords([], [], lows)
self.negword = "минус "
self.pointword = "нуқта"
self.exclude_title = ["ва", "минус", "нуқта"]
self.mid_numwords = [
(1000, "ҳазор"),
(100, "сад"),
(90, "навад"),
(80, "ҳаштод"),
(70, "ҳафтод"),
(60, "шаст"),
(50, "панҷоҳ"),
(40, "чил"),
(30, "си"),
]
self.low_numwords = [
"бист",
"нуздаҳ",
"ҳаждаҳ",
"ҳабдаҳ",
"шонздаҳ",
"понздаҳ",
"чордаҳ",
"сенздаҳ",
"дувоздаҳ",
"ёздаҳ",
"даҳ",
"нӯҳ",
"ҳашт",
"ҳафт",
"шаш",
"панҷ",
"чор",
"се",
"ду",
"як",
"сифр",
]
def to_cardinal(self, value):
try:
assert int(value) == value
except (ValueError, TypeError, AssertionError):
return self.to_cardinal_float(value)
out = ""
if value < 0:
value = abs(value)
out = self.negword
if value >= self.MAXVAL:
raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL))
if value == 100:
return self.title(out + "сад")
else:
val = self.splitnum(value)
words, num = self.clean(val)
return self.title(out + words)
def merge(self, lpair, rpair):
ltext, lnum = lpair
rtext, rnum = rpair
if lnum == 1 and rnum < 100:
return (rtext, rnum)
elif 100 > lnum > rnum:
if ltext == "си":
return ("%sю %s" % (ltext, rtext), lnum + rnum)
elif ltext == "панҷоҳ":
return ("панҷову %s" % (rtext), lnum + rnum)
else:
return ("%sу %s" % (ltext, rtext), lnum + rnum)
elif lnum >= 100 > rnum:
return ("%sу %s" % (ltext, rtext), lnum + rnum)
elif rnum > lnum:
if ltext == "яксад" and rtext not in self.low_numwords:
return ("сад %s" % (rtext), lnum * rnum)
if rtext == "сад":
return ("%s%s" % (ltext, rtext), lnum * rnum)
else:
return ("%s %s" % (ltext, rtext), lnum * rnum)
return ("%sу %s" % (ltext, rtext), lnum + rnum)
def to_ordinal(self, value):
self.verify_ordinal(value)
cardinal = self.to_cardinal(value)
outwords = cardinal.split(" ")
lastword = outwords[-1]
if lastword in ["ду", "се", "си"]:
return "%sюм" % (cardinal)
else:
return "%sум" % (cardinal)
def to_ordinal_num(self, value):
self.verify_ordinal(value)
return "%s%s" % (value, self.to_ordinal(value)[-2:])

View File

@@ -1,3 +1,4 @@
tox
flake8
flake8-copyright
isort

View File

@@ -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',

94
tests/test_am.py Normal file
View File

@@ -0,0 +1,94 @@
# -*- 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 unittest import TestCase
from num2words import num2words
class Num2WordsAMTest(TestCase):
def test_cardinal(self):
self.assertEqual(num2words(100, lang='am'), 'መቶ')
self.assertEqual(num2words(100000, lang='am'), 'አንድ መቶ ሺህ')
self.assertEqual(num2words(101, lang='am'), 'አንድ መቶ አንድ')
def test_and_join_199(self):
self.assertEqual(num2words(199, lang='am'), 'አንድ መቶ ዘጠና ዘጠኝ')
def test_to_ordinal(self):
self.assertEqual(
num2words(1, lang='am', to='ordinal'),
'አንደኛ'
)
self.assertEqual(
num2words(13, lang='am', to='ordinal'),
'አሥራ ሦስተኛ'
)
self.assertEqual(
num2words(22, lang='am', to='ordinal'),
'ሃያ ሁለተኛ'
)
self.assertEqual(
num2words(10000, lang='am', to='ordinal'),
'አሥር ሺህኛ'
)
def test_to_ordinal_num(self):
self.assertEqual(num2words(10, lang='am', to='ordinal_num'), '10ኛ')
self.assertEqual(num2words(21, lang='am', to='ordinal_num'), '21ኛ')
self.assertEqual(num2words(102, lang='am', to='ordinal_num'), '102ኛ')
def test_cardinal_for_float_number(self):
self.assertEqual(num2words(12.5, lang='am'), 'አሥራ ሁለት ነጥብ አምስት')
self.assertEqual(num2words(12.51, lang='am'), 'አሥራ ሁለት ነጥብ አምስት አንድ')
self.assertEqual(num2words(12.53, lang='am'), 'አሥራ ሁለት ነጥብ አምስት ሦስት')
def test_to_overflow(self):
with self.assertRaises(OverflowError):
num2words('1000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000'
'00000000000000000000000000000000', lang='am')
def test_to_currency(self):
self.assertEqual(
num2words('38.4', lang='am', to='currency', cents=False,
currency='ETB'), 'ሠላሳ ስምንት ብር ከ 40 ሳንቲም'
)
self.assertEqual(
num2words('0', lang='am', to='currency', separator=' እና',
cents=True, currency='ETB'), 'ዜሮ ብር እና ዜሮ ሳንቲም'
)
self.assertEqual(
num2words('1.50', lang='am', to='currency', cents=True,
currency='ETB'), 'አንድ ብር ከ አምሳ ሳንቲም'
)
def test_to_year(self):
self.assertEqual(num2words(1990, lang='am', to='year'),
'አሥራ ዘጠኝ መቶ ዘጠና')
self.assertEqual(num2words(5555, lang='am', to='year'),
'አምሳ አምስት መቶ አምሳ አምስት')
self.assertEqual(num2words(2017, lang='am', to='year'),
'ሁለት ሺህ አሥራ ሰባት')
self.assertEqual(num2words(1066, lang='am', to='year'),
'አንድ ሺህ ስድሳ ስድስት')
self.assertEqual(num2words(1865, lang='am', to='year'),
'አሥራ ስምንት መቶ ስድሳ አምስት')

View File

@@ -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"
)

File diff suppressed because it is too large Load Diff

109
tests/test_fa.py Normal file
View 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")

View File

@@ -20,6 +20,7 @@ from __future__ import unicode_literals
from unittest import TestCase
from num2words import num2words
from num2words.lang_HE import Num2Word_HE
class Num2WordsHETest(TestCase):
@@ -71,3 +72,45 @@ class Num2WordsHETest(TestCase):
self.assertEqual(
num2words(6870, lang="he"), u'ששת אלפים שמונה מאות ושבעים'
)
def test_pluralize(self):
n = Num2Word_HE()
cr1, cr2 = n.CURRENCY_FORMS['NIS']
self.assertEqual(n.pluralize(1, cr1), 'שקל')
self.assertEqual(n.pluralize(2, cr1), 'שקלים')
self.assertEqual(n.pluralize(1, cr2), 'אגורה')
self.assertEqual(n.pluralize(2, cr2), 'אגורות')
cr1, cr2 = n.CURRENCY_FORMS['USD']
self.assertEqual(n.pluralize(1, cr1), 'דולר')
self.assertEqual(n.pluralize(2, cr1), 'דולרים')
self.assertEqual(n.pluralize(1, cr2), 'סנט')
self.assertEqual(n.pluralize(2, cr2), 'סנט')
def test_to_currency(self):
n = Num2Word_HE()
self.assertEqual(
n.to_currency(20.0, currency='NIS'), 'עשרים שקלים ואפס אגורות'
)
self.assertEqual(
n.to_currency(100.0, currency='NIS'), 'מאה שקלים ואפס אגורות'
)
self.assertEqual(
n.to_currency(100.50, currency='NIS'), 'מאה שקלים וחמישים אגורות'
)
def test_to_cardinal(self):
n = Num2Word_HE()
self.assertEqual(n.to_cardinal(1500), u'אלף וחמש מאות')
class Num2WordsHETestNotImplementedMethofs(TestCase):
n = Num2Word_HE()
def test_to_ordinal(self):
with self.assertRaises(NotImplementedError):
self.n.to_ordinal('1')
def test_large_number(self):
with self.assertRaises(NotImplementedError):
num2words(2000000, lang="he")

View File

@@ -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),
"きげんぜんきゅうじゅうくねん")

118
tests/test_tg.py Normal file
View File

@@ -0,0 +1,118 @@
# -*- 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 unittest import TestCase
from num2words import num2words
class Num2WordsTGTest(TestCase):
def test_cardinal(self):
with self.assertRaises(OverflowError):
num2words(1000000000000000000000000, lang="tg")
self.assertEqual(num2words(100, lang="tg"), "сад")
self.assertEqual(num2words(100000, lang="tg"), "сад ҳазор")
self.assertEqual(num2words(101, lang="tg"), "яксаду як")
self.assertEqual(num2words(110, lang="tg"), "яксаду даҳ")
self.assertEqual(num2words(115, lang="tg"), "яксаду понздаҳ")
self.assertEqual(num2words(123, lang="tg"), "яксаду бисту се")
self.assertEqual(num2words(1000, lang="tg"), "як ҳазор")
self.assertEqual(num2words(1001, lang="tg"), "як ҳазору як")
self.assertEqual(num2words(2012, lang="tg"), "ду ҳазору дувоздаҳ")
self.assertEqual(
num2words(12519.85, lang="tg"),
"дувоздаҳ ҳазору панҷсаду нуздаҳ нуқта ҳашт панҷ",
)
self.assertEqual(
num2words(1234567890, lang="tg"),
"як миллиарду дусаду сию чор миллиону панҷсаду шасту ҳафт ҳазору "
"ҳаштсаду навад",
)
self.assertEqual(num2words(1000000, lang="tg"), "як миллион")
self.assertEqual(num2words(1000000000, lang="tg"), "як миллиард")
self.assertEqual(num2words(1000000000000, lang="tg"), "як триллион")
self.assertEqual(num2words(5, lang="tg"), "панҷ")
self.assertEqual(num2words(-1, lang="tg"), "минус як")
self.assertEqual(num2words(-15, lang="tg"), "минус понздаҳ")
self.assertEqual(num2words(-100, lang="tg"), "минус сад")
def test_to_ordinal(self):
self.assertEqual(num2words(1, lang="tg", to="ordinal"), "якум")
self.assertEqual(num2words(2, lang="tg", to="ordinal"), "дуюм")
self.assertEqual(num2words(3, lang="tg", to="ordinal"), "сеюм")
self.assertEqual(num2words(30, lang="tg", to="ordinal"), "сиюм")
self.assertEqual(num2words(13, lang="tg", to="ordinal"), "сенздаҳум")
self.assertEqual(num2words(20, lang="tg", to="ordinal"), "бистум")
self.assertEqual(num2words(23, lang="tg", to="ordinal"), "бисту сеюм")
self.assertEqual(num2words(100, lang="tg", to="ordinal"), "садум")
self.assertEqual(
num2words(136, lang="tg", to="ordinal"), "яксаду сию шашум"
)
self.assertEqual(num2words(500, lang="tg", to="ordinal"), "панҷсадум")
self.assertEqual(
num2words(1000, lang="tg", to="ordinal"), "як ҳазорум"
)
self.assertEqual(
num2words(1001, lang="tg", to="ordinal"), "як ҳазору якум"
)
self.assertEqual(
num2words(2000, lang="tg", to="ordinal"), "ду ҳазорум"
)
self.assertEqual(
num2words(1000000, lang="tg", to="ordinal"), "як миллионум"
)
self.assertEqual(
num2words(1000000000, lang="tg", to="ordinal"), "як миллиардум"
)
def test_to_currency(self):
self.assertEqual(
num2words(1.0, lang="tg", to="currency", currency="EUR"),
"як евро, сифр сент",
)
self.assertEqual(
num2words(1.0, lang="tg", to="currency", currency="TJS"),
"як сомонӣ, сифр дирам",
)
self.assertEqual(
num2words(1234.56, lang="tg", to="currency", currency="TJS"),
"як ҳазору дусаду сию чор сомонӣ, панҷову шаш дирам",
)
self.assertEqual(
num2words(1234.56, lang="tg", to="currency", currency="RUB"),
"як ҳазору дусаду сию чор рубл, панҷову шаш копейк",
)
self.assertEqual(
num2words(
12519.85, lang="tg", to="currency", currency="TJS", cents=False
),
"дувоздаҳ ҳазору панҷсаду нуздаҳ сомонӣ, 85 дирам",
)
self.assertEqual(
num2words("1230.56", lang="tg", to="currency", currency="USD"),
"як ҳазору дусаду си доллар, панҷову шаш сент",
)
def test_to_ordinal_num(self):
self.assertEqual(
num2words("100", lang="tg", to="ordinal_num"),
"100ум",
)

19
tox.ini
View File

@@ -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