Merge branch 'master' into master

This commit is contained in:
Marlon Rodriguez Garcia
2022-08-04 16:14:55 -04:00
committed by GitHub
39 changed files with 7705 additions and 226 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::
@@ -108,6 +108,7 @@ Besides the numerical argument, there are two main optional arguments.
* ``pt_BR`` (Portuguese - Brazilian)
* ``sl`` (Slovene)
* ``sr`` (Serbian)
* ``sv`` (Swedish)
* ``ro`` (Romanian)
* ``ru`` (Russian)
* ``te`` (Telugu)

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

@@ -22,8 +22,8 @@ from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN,
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_TE, lang_TH, lang_TR,
lang_UK, lang_VI)
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(),
@@ -53,6 +53,7 @@ CONVERTER_CLASSES = {
'ru': lang_RU.Num2Word_RU(),
'sl': lang_SL.Num2Word_SL(),
'sr': lang_SR.Num2Word_SR(),
'sv': lang_SV.Num2Word_SV(),
'no': lang_NO.Num2Word_NO(),
'dk': lang_DK.Num2Word_DK(),
'pt': lang_PT.Num2Word_PT(),
@@ -68,7 +69,6 @@ CONVERTER_CLASSES = {
'hu': lang_HU.Num2Word_HU()
}
CONVERTES_TYPES = ['cardinal', 'ordinal', 'ordinal_num', 'year', 'currency']

View File

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

View File

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

View File

@@ -21,13 +21,191 @@ import math
from .lang_EU import Num2Word_EU
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', 'TRY', 'ITL')
CENTS_UNA = ('EGP', 'JOD', 'LBP', 'SDG', 'SSP', 'SYP')
class Num2Word_ES(Num2Word_EU):
CURRENCY_FORMS = {
'EUR': (('euro', 'euros'), ('céntimo', 'céntimos')),
'ESP': (('peseta', 'pesetas'), ('céntimo', 'céntimos')),
'USD': (('dolar', 'dólares'), ('centavo', 'centavos')),
'USD': (GENERIC_DOLLARS, GENERIC_CENTS),
'PEN': (('sol', 'soles'), ('céntimo', 'céntimos')),
'CRC': (('colón', 'colones'), GENERIC_CENTS),
'AUD': (GENERIC_DOLLARS, GENERIC_CENTS),
'CAD': (GENERIC_DOLLARS, GENERIC_CENTS),
'GBP': (('libra', 'libras'), ('penique', 'peniques')),
'RUB': (('rublo', 'rublos'), ('kopeyka', 'kopeykas')),
'SEK': (('corona', 'coronas'), ('öre', 'öre')),
'NOK': (('corona', 'coronas'), ('øre', 'øre')),
'PLN': (('zloty', 'zlotys'), ('grosz', 'groszy')),
'MXN': (('peso', 'pesos'), GENERIC_CENTS),
'RON': (('leu', 'leus'), ('ban', 'bani')),
'INR': (('rupia', 'rupias'), ('paisa', 'paisas')),
'HUF': (('florín', 'florines'), ('fillér', 'fillér')),
'FRF': (('franco', 'francos'), ('céntimo', 'céntimos')),
'CNY': (('yuan', 'yuanes'), ('fen', 'jiaos')),
'CZK': (('corona', 'coronas'), ('haléř', 'haléř')),
'NIO': (('córdoba', 'córdobas'), GENERIC_CENTS),
'VES': (('bolívar', 'bolívares'), ('céntimo', 'céntimos')),
'BRL': (('real', 'reales'), GENERIC_CENTS),
'CHF': (('franco', 'francos'), ('céntimo', 'céntimos')),
'JPY': (('yen', 'yenes'), ('sen', 'sen')),
'KRW': (('won', 'wones'), ('jeon', 'jeon')),
'KPW': (('won', 'wones'), ('chon', 'chon')),
'TRY': (('lira', 'liras'), ('kuruş', 'kuruş')),
'ZAR': (('rand', 'rands'), ('céntimo', 'céntimos')),
'KZT': (('tenge', 'tenges'), ('ın', 'ın')),
'UAH': (('hryvnia', 'hryvnias'), ('kopiyka', 'kopiykas')),
'THB': (('baht', 'bahts'), ('satang', 'satang')),
'AED': (('dirham', 'dirhams'), ('fils', 'fils')),
'AFN': (('afghani', 'afghanis'), ('pul', 'puls')),
'ALL': (('lek ', 'leke'), ('qindarkë', 'qindarka')),
'AMD': (('dram', 'drams'), ('luma', 'lumas')),
'ANG': (('florín', 'florines'), GENERIC_CENTS),
'AOA': (('kwanza', 'kwanzas'), ('céntimo', 'céntimos')),
'ARS': (('peso', 'pesos'), GENERIC_CENTS),
'AWG': (('florín', 'florines'), GENERIC_CENTS),
'AZN': (('manat', 'manat'), ('qəpik', 'qəpik')),
'BBD': (GENERIC_DOLLARS, GENERIC_CENTS),
'BDT': (('taka', 'takas'), ('paisa', 'paisas')),
'BGN': (('lev', 'leva'), ('stotinka', 'stotinki')),
'BHD': (('dinar', 'dinares'), ('fils', 'fils')),
'BIF': (('franco', 'francos'), ('céntimo', 'céntimos')),
'BMD': (GENERIC_DOLLARS, GENERIC_CENTS),
'BND': (GENERIC_DOLLARS, GENERIC_CENTS),
'BOB': (('boliviano', 'bolivianos'), GENERIC_CENTS),
'BSD': (GENERIC_DOLLARS, GENERIC_CENTS),
'BTN': (('ngultrum', 'ngultrum'), ('chetrum', 'chetrum')),
'BWP': (('pula', 'pulas'), ('thebe', 'thebes')),
'BYN': (('rublo', 'rublos'), ('kópek', 'kópeks')),
'BYR': (('rublo', 'rublos'), ('kópek', 'kópeks')),
'BZD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'CDF': (('franco', 'francos'), ('céntimo', 'céntimos')),
'CLP': (('peso', 'pesos'), GENERIC_CENTS),
'COP': (('peso', 'pesos'), GENERIC_CENTS),
'CUP': (('peso', 'pesos'), GENERIC_CENTS),
'CVE': (('escudo', 'escudos'), GENERIC_CENTS),
'CYP': (('libra', 'libras'), ('céntimo', 'céntimos')),
'DJF': (('franco', 'francos'), ('céntimo', 'céntimos')),
'DKK': (('corona', 'coronas'), ('øre', 'øre')),
'DOP': (('peso', 'pesos'), GENERIC_CENTS),
'DZD': (('dinar', 'dinares'), ('céntimo', 'céntimos')),
'ECS': (('sucre', 'sucres'), GENERIC_CENTS),
'EGP': (('libra', 'libras'), ('piastra', 'piastras')),
'ERN': (('nakfa', 'nakfas'), ('céntimo', 'céntimos')),
'ETB': (('birr', 'birrs'), ('céntimo', 'céntimos')),
'FJD': (GENERIC_DOLLARS, GENERIC_CENTS),
'FKP': (('libra', 'libras'), ('penique', 'peniques')),
'GEL': (('lari', 'laris'), ('tetri', 'tetris')),
'GHS': (('cedi', 'cedis'), ('pesewa', 'pesewas')),
'GIP': (('libra', 'libras'), ('penique', 'peniques')),
'GMD': (('dalasi', 'dalasis'), ('butut', 'bututs')),
'GNF': (('franco', 'francos'), ('céntimo', 'céntimos')),
'GTQ': (('quetzal', 'quetzales'), GENERIC_CENTS),
'GYD': (GENERIC_DOLLARS, GENERIC_CENTS),
'HKD': (GENERIC_DOLLARS, GENERIC_CENTS),
'HNL': (('lempira', 'lempiras'), GENERIC_CENTS),
'HRK': (('kuna', 'kunas'), ('lipa', 'lipas')),
'HTG': (('gourde', 'gourdes'), ('céntimo', 'céntimos')),
'IDR': (('rupia', 'rupias'), ('céntimo', 'céntimos')),
'ILS': (('séquel', 'séqueles'), ('agora', 'agoras')),
'IQD': (('dinar', 'dinares'), ('fils', 'fils')),
'IRR': (('rial', 'riales'), ('dinar', 'dinares')),
'ISK': (('corona', 'coronas'), ('eyrir', 'aurar')),
'ITL': (('lira', 'liras'), ('céntimo', 'céntimos')),
'JMD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'JOD': (('dinar', 'dinares'), ('piastra', 'piastras')),
'KES': (('chelín', 'chelines'), ('céntimo', 'céntimos')),
'KGS': (('som', 'som'), ('tyiyn', 'tyiyn')),
'KHR': (('riel', 'rieles'), ('céntimo', 'céntimos')),
'KMF': (('franco', 'francos'), ('céntimo', 'céntimos')),
'KWD': (('dinar', 'dinares'), ('fils', 'fils')),
'KYD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'LAK': (('kip', 'kips'), ('att', 'att')),
'LBP': (('libra', 'libras'), ('piastra', 'piastras')),
'LKR': (('rupia', 'rupias'), ('céntimo', 'céntimos')),
'LRD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'LSL': (('loti', 'lotis'), ('céntimo', 'céntimos')),
'LTL': (('lita', 'litas'), ('céntimo', 'céntimos')),
'LVL': (('lat', 'lats'), ('céntimo', 'céntimos')),
'LYD': (('dinar', 'dinares'), ('dírham', 'dírhams')),
'MAD': (('dírham', 'dirhams'), ('céntimo', 'céntimos')),
'MDL': (('leu', 'lei'), ('ban', 'bani')),
'MGA': (('ariary', 'ariaris'), ('iraimbilanja', 'iraimbilanja')),
'MKD': (('denar', 'denares'), ('deni', 'denis')),
'MMK': (('kiat', 'kiats'), ('pya', 'pyas')),
'MNT': (('tugrik', 'tugriks'), ('möngö', 'möngö')),
'MOP': (('pataca', 'patacas'), ('avo', 'avos')),
'MRO': (('ouguiya', 'ouguiyas'), ('khoums', 'khoums')),
'MRU': (('ouguiya', 'ouguiyas'), ('khoums', 'khoums')),
'MUR': (('rupia', 'rupias'), ('céntimo', 'céntimos')),
'MVR': (('rufiyaa', 'rufiyaas'), ('laari', 'laari')),
'MWK': (('kuacha', 'kuachas'), ('tambala', 'tambalas')),
'MYR': (('ringgit', 'ringgit'), ('céntimo', 'céntimos')),
'MZN': (('metical', 'metical'), GENERIC_CENTS),
'NAD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'NGN': (('naira', 'nairas'), ('kobo', 'kobo')),
'NPR': (('rupia', 'rupias'), ('paisa', 'paisas')),
'NZD': (GENERIC_DOLLARS, GENERIC_CENTS),
'OMR': (('rial', 'riales'), ('baisa', 'baisa')),
'PAB': (('balboa', 'balboas'), ('centésimo', 'centésimos')),
'PGK': (('kina', 'kinas'), ('toea', 'toea')),
'PHP': (('peso', 'pesos'), GENERIC_CENTS),
'PKR': (('rupia', 'rupias'), ('paisa', 'paisas')),
'PLZ': (('zloty', 'zlotys'), ('grosz', 'groszy')),
'PYG': (('guaraní', 'guaranís'), ('céntimo', 'céntimos')),
'QAR': (('rial', 'riales'), ('dírham', 'dírhams')),
'QTQ': (('quetzal', 'quetzales'), GENERIC_CENTS),
'RSD': (('dinar', 'dinares'), ('para', 'para')),
'RUR': (('rublo', 'rublos'), ('kopek', 'kopeks')),
'RWF': (('franco', 'francos'), ('céntimo', 'céntimos')),
'SAR': (('riyal', 'riales'), ('halala', 'halalas')),
'SBD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'SCR': (('rupia', 'rupias'), ('céntimo', 'céntimos')),
'SDG': (('libra', 'libras'), ('piastra', 'piastras')),
'SGD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'SHP': (('libra', 'libras'), ('penique', 'peniques')),
'SKK': (('corona', 'coronas'), ('halier', 'haliers')),
'SLL': (('leona', 'leonas'), ('céntimo', 'céntimos')),
'SRD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'SSP': (('libra', 'libras'), ('piastra', 'piastras')),
'STD': (('dobra', 'dobras'), ('céntimo', 'céntimos')),
'SVC': (('colón', 'colones'), GENERIC_CENTS),
'SYP': (('libra', 'libras'), ('piastra', 'piastras')),
'SZL': (('lilangeni', 'emalangeni'), ('céntimo', 'céntimos')),
'TJS': (('somoni', 'somonis'), ('dirame', 'dirames')),
'TMT': (('manat', 'manat'), ('tenge', 'tenge')),
'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 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')),
'UYU': (('peso', 'pesos'), ('centésimo', 'centésimos')),
'UZS': (('sum', 'sum'), ('tiyin', 'tiyin')),
'VEF': (('bolívar fuerte', 'bolívares fuertes'),
('céntimo', 'céntimos')),
'VND': (('dong', 'dongs'), ('xu', 'xu')),
'VUV': (('vatu', 'vatu'), ('nenhum', 'nenhum')),
'WST': (('tala', 'tala'), GENERIC_CENTS),
'XAF': (('franco CFA', 'francos CFA'), ('céntimo', 'céntimos')),
'XCD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'XOF': (('franco CFA', 'francos CFA'), ('céntimo', 'céntimos')),
'XPF': (('franco CFP', 'francos CFP'), ('céntimo', 'céntimos')),
'YER': (('rial', 'riales'), ('fils', 'fils')),
'YUM': (('dinar', 'dinares'), ('para', 'para')),
'ZMW': (('kwacha', 'kwachas'), ('ngwee', 'ngwee')),
'ZRZ': (('zaire', 'zaires'), ('likuta', 'makuta')),
'ZWL': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
'ZWL': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
}
# //CHECK: Is this sufficient??
@@ -39,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"]
@@ -53,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",
@@ -175,5 +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"
return result.replace("uno", "un")
# 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:
# "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

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

View File

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

View File

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

View File

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

View File

@@ -135,7 +135,7 @@ class Num2Word_NL(Num2Word_EU):
def to_ordinal_num(self, value):
self.verify_ordinal(value)
return str(value) + "."
return str(value) + "e"
def pluralize(self, n, forms):
"""

View File

@@ -36,6 +36,28 @@ ONES = {
9: ('dziewięć',),
}
ONES_ORDINALS = {
1: ('pierwszy', "pierwszo"),
2: ('drugi', "dwu"),
3: ('trzeci', "trzy"),
4: ('czwarty', "cztero"),
5: ('piąty', "pięcio"),
6: ('szósty', "sześcio"),
7: ('siódmy', "siedmio"),
8: ('ósmy', "ośmio"),
9: ('dziewiąty', "dziewięcio"),
10: ('dziesiąty', "dziesięcio"),
11: ('jedenasty', "jedenasto"),
12: ('dwunasty', "dwunasto"),
13: ('trzynasty', "trzynasto"),
14: ('czternasty', "czternasto"),
15: ('piętnasty', "piętnasto"),
16: ('szesnasty', "szesnasto"),
17: ('siedemnasty', "siedemnasto"),
18: ('osiemnasty', "osiemnasto"),
19: ('dziewiętnasty', "dziewiętnasto"),
}
TENS = {
0: ('dziesięć',),
1: ('jedenaście',),
@@ -49,6 +71,7 @@ TENS = {
9: ('dziewiętnaście',),
}
TWENTIES = {
2: ('dwadzieścia',),
3: ('trzydzieści',),
@@ -60,6 +83,17 @@ TWENTIES = {
9: ('dziewięćdzisiąt',),
}
TWENTIES_ORDINALS = {
2: ('dwudziesty', "dwudziesto"),
3: ('trzydziesty', "trzydiesto"),
4: ('czterdziesty', "czterdziesto"),
5: ('pięćdziesiąty', "pięćdziesięcio"),
6: ('sześćdziesiąty', "sześćdziesięcio"),
7: ('siedemdziesiąty', "siedemdziesięcio"),
8: ('osiemdziesiąty', "osiemdziesięcio"),
9: ('dziewięćdzisiąty', "dziewięćdziesięcio"),
}
HUNDREDS = {
1: ('sto',),
2: ('dwieście',),
@@ -72,10 +106,28 @@ HUNDREDS = {
9: ('dziewięćset',),
}
HUNDREDS_ORDINALS = {
1: ('setny', "stu"),
2: ('dwusetny', "dwustu"),
3: ('trzysetny', "trzystu"),
4: ('czterysetny', "czterystu"),
5: ('pięćsetny', "pięcset"),
6: ('sześćsetny', "sześćset"),
7: ('siedemsetny', "siedemset"),
8: ('osiemsetny', "ośiemset"),
9: ('dziewięćsetny', "dziewięćset"),
}
THOUSANDS = {
1: ('tysiąc', 'tysiące', 'tysięcy'), # 10^3
}
prefixes_ordinal = {
1: "tysięczny",
2: "milionowy",
3: "milairdowy"
}
prefixes = ( # 10^(6*x)
"mi", # 10^6
"bi", # 10^12
@@ -113,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))
@@ -130,8 +185,48 @@ class Num2Word_PL(Num2Word_Base):
form = 2
return forms[form]
def last_fragment_to_ordinal(self, 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 n3 > 0:
words.append(HUNDREDS[n3][level])
words.append(ONES_ORDINALS[last_two][level])
elif last_two % 10 == 0:
if n3 > 0:
words.append(HUNDREDS[n3][level])
words.append(TWENTIES_ORDINALS[n2][level])
else:
if n3 > 0:
words.append(HUNDREDS[n3][0])
words.append(TWENTIES_ORDINALS[n2][0])
words.append(ONES_ORDINALS[n1][0])
def to_ordinal(self, number):
if number % 1 != 0:
raise NotImplementedError()
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)
self.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
def _int2word(self, n):
if n == 0:

View File

@@ -227,12 +227,7 @@ class Num2Word_PT(Num2Word_EU):
self.negword = backup_negword
# transforms "milhões euros" em "milhões de euros"
try:
cr1, _ = self.CURRENCY_FORMS[currency]
except KeyError:
raise NotImplementedError(
'Currency code "%s" not implemented for "%s"' %
(currency, self.__class__.__name__))
for ext in (
'milhão', 'milhões', 'bilião',

View File

@@ -53,8 +53,6 @@ class Num2Word_PT_BR(lang_PT.Num2Word_PT):
ctext = "cento"
if nnum < cnum:
if cnum < 100:
return ("%s e %s" % (ctext, ntext), cnum + nnum)
return ("%s e %s" % (ctext, ntext), cnum + nnum)
elif (not nnum % 1000000) and cnum > 1:

View File

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

View File

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

117
num2words/lang_SV.py Normal file
View File

@@ -0,0 +1,117 @@
# -*- 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_SV(lang_EU.Num2Word_EU):
GIGA_SUFFIX = "iljarder"
MEGA_SUFFIX = "iljoner"
def set_high_numwords(self, high):
cap = 3 + 6 * len(high)
for word, n in zip(high, range(cap, 3, -6)):
if self.GIGA_SUFFIX:
self.cards[10 ** n] = word + self.GIGA_SUFFIX
if self.MEGA_SUFFIX:
self.cards[10 ** (n - 3)] = word + self.MEGA_SUFFIX
def setup(self):
super(Num2Word_SV, self).setup()
self.negword = "minus "
self.pointword = "komma"
self.exclude_title = ["och", "komma", "minus"]
self.mid_numwords = [(1000, "tusen"), (100, "hundra"),
(90, "nittio"), (80, "åttio"), (70, "sjuttio"),
(60, "sextio"), (50, "femtio"), (40, "förtio"),
(30, "trettio")]
self.low_numwords = ["tjugo", "nitton", "arton", "sjutton",
"sexton", "femton", "fjorton", "tretton",
"tolv", "elva", "tio", "nio", "åtta",
"sju", "sex", "fem", "fyra", "tre", "två",
"ett", "noll"]
self.ords = {"noll": "nollte",
"ett": "första",
"två": "andra",
"tre": "tredje",
"fyra": "fjärde",
"fem": "femte",
"sex": "sjätte",
"sju": "sjunde",
"åtta": "åttonde",
"nio": "nionde",
"tio": "tionde",
"elva": "elfte",
"tolv": "tolfte",
"tjugo": "tjugonde"}
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 >= 1000000 and lnum == 1:
return ("%s %s" % ('en', rtext[:-2]), lnum + rnum)
elif rnum >= 1000000 and lnum > 1:
return ("%s %s" % (ltext, rtext), lnum + rnum)
elif rnum > lnum:
return ("%s%s" % (ltext, rtext), lnum * rnum)
return ("%s %s" % (ltext, rtext), lnum + rnum)
def to_ordinal(self, value):
self.verify_ordinal(value)
outwords = self.to_cardinal(value).split(" ")
lastword = outwords[-1]
ending_length = 0
try:
lastword_ending = self.ords[lastword[-4:]]
ending_length = 4
except KeyError:
try:
lastword_ending = self.ords[lastword[-3:]]
ending_length = 3
except KeyError:
lastword_ending = "de"
if lastword_ending == 'de':
lastword_first_part = self.title(lastword)[:]
else:
lastword_first_part = self.title(lastword)[:-ending_length]
lastword_correct = lastword_first_part + lastword_ending
outwords[-1] = lastword_correct
return " ".join(outwords)
def to_ordinal_num(self, value):
raise NotImplementedError(
"'ordinal_num' is not implemented for swedish language")
def to_year(self, val, longval=True):
raise NotImplementedError(
"'year' is not implemented for swedish language")
def to_currency(self, val, longval=True):
raise NotImplementedError(
"'currency' is not implemented for swedish language")

View File

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

View File

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

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

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

View File

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

File diff suppressed because it is too large Load Diff

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

View File

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

View File

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

View File

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

View File

@@ -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 "
@@ -83,9 +91,32 @@ class Num2WordsPLTest(TestCase):
)
def test_to_ordinal(self):
# @TODO: implement to_ordinal
with self.assertRaises(NotImplementedError):
num2words(1, lang='pl', to='ordinal')
self.assertEqual(num2words(100, lang='pl', to='ordinal'), "setny")
self.assertEqual(
num2words(101, lang='pl', to='ordinal'), "sto pierwszy")
self.assertEqual(num2words(121, lang='pl', to='ordinal'),
"sto dwudziesty pierwszy")
self.assertEqual(
num2words(115, lang='pl', to='ordinal'), "sto piętnasty")
self.assertEqual(
num2words(25, lang='pl', to='ordinal'), "dwudziesty piąty")
self.assertEqual(num2words(1021, lang='pl', to='ordinal'),
"tysiąc dwudziesty pierwszy")
self.assertEqual(
num2words(120, lang='pl', to='ordinal'), "sto dwudziesty")
self.assertEqual(num2words(1000021, lang='pl',
to='ordinal'), "milion dwudziesty pierwszy")
self.assertEqual(num2words(1000, lang='pl', to='ordinal'), "tysięczny")
self.assertEqual(num2words(10000, lang='pl',
to='ordinal'), "dziesięciotysięczny")
self.assertEqual(num2words(100000000, lang='pl',
to='ordinal'), "stumilionowy")
self.assertEqual(num2words(1002000, lang='pl',
to='ordinal'), "milion dwutysięczny")
self.assertEqual(num2words(1001000, lang='pl',
to='ordinal'), "milion tysięczny")
self.assertEqual(num2words(1000000, lang='pl',
to='ordinal'), "milionowy")
def test_currency(self):
self.assertEqual(

View File

@@ -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'),
'одна тысяча двести тридцать долларов, пятьдесят шесть центов'

View File

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

70
tests/test_sv.py Normal file
View File

@@ -0,0 +1,70 @@
# 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 Num2WordsSVTest(TestCase):
def test_ordinal(self):
self.assertEqual(num2words(14, to="ordinal", lang="sv"), "fjortonde")
self.assertEqual(num2words(1435, to="ordinal", lang="sv"),
"etttusen fyrahundratrettiofemte")
self.assertEqual(num2words(32, to="ordinal", lang="sv"),
"trettioandra")
self.assertEqual(num2words(1, to="ordinal", lang="sv"), "första")
self.assertEqual(num2words(5, to="ordinal", lang="sv"), "femte")
self.assertEqual(num2words(10, to="ordinal", lang="sv"), "tionde")
def test_cardinal(self):
self.assertEqual(num2words(0, to="cardinal", lang="sv"), "noll")
self.assertEqual(num2words(1, to="cardinal", lang="sv"), "ett")
self.assertEqual(num2words(3, to="cardinal", lang="sv"), "tre")
self.assertEqual(num2words(5, to="cardinal", lang="sv"), "fem")
self.assertEqual(num2words(18, to="cardinal", lang="sv"), "arton")
self.assertEqual(num2words(45, to="cardinal", lang="sv"), "förtiofem")
self.assertEqual(num2words(1345, to="cardinal", lang="sv"),
"etttusen trehundraförtiofem")
self.assertEqual(num2words(4435, to="cardinal", lang="sv"),
"fyratusen fyrahundratrettiofem")
self.assertEqual(num2words(1004135, to="cardinal", lang="sv"),
"en miljon fyratusen etthundratrettiofem")
self.assertEqual(num2words(4335000, to="cardinal", lang="sv"),
"fyra miljoner trehundratrettiofemtusen")
self.assertEqual(num2words(14004535, to="cardinal", lang="sv"),
"fjorton miljoner fyratusen femhundratrettiofem")
self.assertEqual(num2words(1.5, to="cardinal", lang="sv"),
"ett komma fem")
def test_not_implemented_options(self):
with self.assertRaises(NotImplementedError) as context:
num2words(1235, to="year", lang="sv")
self.assertTrue("'year' is not implemented for swedish language"
in str(context.exception))
with self.assertRaises(NotImplementedError) as context:
num2words(1235, to="currency", lang="sv")
self.assertTrue("'currency' is not implemented for swedish language"
in str(context.exception))
with self.assertRaises(NotImplementedError) as context:
num2words(1235, to="ordinal_num", lang="sv")
self.assertTrue("'ordinal_num' is not implemented for swedish language"
in str(context.exception))

View File

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

File diff suppressed because it is too large Load Diff

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