Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
toofun666 authored Sep 16, 2023
2 parents b3e717c + 305242f commit 0135528
Show file tree
Hide file tree
Showing 60 changed files with 5,234 additions and 532 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9, '3.10']
python-version: [3.7, 3.8, 3.9, '3.10', '3.11']

steps:
- uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ dist
*.egg-info
/.tox
.eggs/
/venv/
19 changes: 17 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
Changelog
=========

Version 0.5.12 -- 2022/08/19
----------------------------

* Support Japanese Reiwa (令和/れいわ) era. (#412)
* Add basic farsi support (#354)
* Added Tajik language support (#406)
* Fix Amharic language support (#465)
* Fix Hebrew pluralize and implement to_currency (#330)
* Add support to translate some currencies in italian language (#434)
* Fix Polish twenties (#345)
* Add uzs for ru and en (#422)
* Added support for Esperanto numbers. (#387)
* [ADD] to ordinal number for Turkish (#468)
* Fix zeroth in Dutch to nulde fixing (#326)

Version 0.5.11 -- 2022/08/03
----------------------------

Expand Down Expand Up @@ -77,9 +92,9 @@ Version 0.5.7 -- 2018/06/27
* Add Finnish localization. (#170)
* Add Japanese localization. (#171)
* Add belgian-french localization. (#151)
* Add Czech localization. (#154)
* Add Czech localization. (#154)
* Add Thai localization. (#139)
* Improve English localization. (#144)
* Improve English localization. (#144)
* Improve Spanish localization. (#167)
* Improve Italian localization. (#143)
* Improve documentation. (#155, #145, #174)
Expand Down
11 changes: 9 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ In code there's only one function to use::
>>> num2words(42, lang='fr')
quarante-deux

Besides the numerical argument, there are two main optional arguments.
Besides the numerical argument, there are two main optional arguments, ``to:`` and ``lang:``

**to:** The converter to use. Supported values are:

Expand All @@ -76,16 +76,21 @@ 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)
* ``az`` (Azerbaijani)
* ``cz`` (Czech)
* ``de`` (German)
* ``dk`` (Danish)
* ``en_GB`` (English - Great Britain)
* ``en_IN`` (English - India)
* ``en_NG`` (English - Nigeria)
* ``es`` (Spanish)
* ``es_CO`` (Spanish - Colombia)
* ``es_VE`` (Spanish - Venezuela)
* ``es_GT`` (Spanish - Guatemala)
* ``eu`` (EURO)
* ``fa`` (Farsi)
* ``fi`` (Finnish)
* ``fr`` (French)
* ``fr_CH`` (French - Switzerland)
Expand All @@ -94,6 +99,7 @@ Besides the numerical argument, there are two main optional arguments.
* ``he`` (Hebrew)
* ``hu`` (Hungarian)
* ``id`` (Indonesian)
* ``is`` (Icelandic)
* ``it`` (Italian)
* ``ja`` (Japanese)
* ``kn`` (Kannada)
Expand All @@ -111,6 +117,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)
Expand Down Expand Up @@ -148,4 +155,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
10 changes: 5 additions & 5 deletions bin/num2words
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Options:
-t --to=<to> Output converter [default: cardinal].
-h --help Show this message.
-v --version Show version.
Examples:
$ num2words 10001
ten thousand and one
Expand All @@ -55,7 +55,7 @@ import sys
from docopt import docopt
import num2words

__version__ = "0.5.11"
__version__ = "0.5.12"
__license__ = "LGPL"


Expand All @@ -76,13 +76,13 @@ def main():
sys.stdout.write(os.linesep)
sys.exit(0)
if args["--list-converters"]:
for lang in get_converters():
sys.stdout.write(lang)
for cvt in get_converters():
sys.stdout.write(cvt)
sys.stdout.write(os.linesep)
sys.exit(0)
try:
words = num2words.num2words(args['<number>'], lang=args['--lang'], to=args['--to'])
sys.stdout.write(words+os.linesep)
sys.stdout.write(words + os.linesep)
sys.exit(0)
except Exception as err:
sys.stderr.write(str(args['<number>']))
Expand Down
26 changes: 18 additions & 8 deletions num2words/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,34 @@

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,
from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN,
lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO,
lang_ES_GT, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR,
lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID,
lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV,
lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO,
lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR,
lang_UK, lang_VI)
lang_IS, 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_SK, 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(),
'az': lang_AZ.Num2Word_AZ(),
'cz': lang_CZ.Num2Word_CZ(),
'en': lang_EN.Num2Word_EN(),
'en_IN': lang_EN_IN.Num2Word_EN_IN(),
'en_NG': lang_EN_NG.Num2Word_EN_NG(),
'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(),
'fr_DZ': lang_FR_DZ.Num2Word_FR_DZ(),
'de': lang_DE.Num2Word_DE(),
'fi': lang_FI.Num2Word_FI(),
'eo': lang_EO.Num2Word_EO(),
'es': lang_ES.Num2Word_ES(),
'es_CO': lang_ES_CO.Num2Word_ES_CO(),
'es_GT': lang_ES_GT.Num2Word_ES_GT(),
'es_NI': lang_ES_NI.Num2Word_ES_NI(),
'es_VE': lang_ES_VE.Num2Word_ES_VE(),
'id': lang_ID.Num2Word_ID(),
Expand All @@ -50,6 +57,7 @@
'pl': lang_PL.Num2Word_PL(),
'ro': lang_RO.Num2Word_RO(),
'ru': lang_RU.Num2Word_RU(),
'sk': lang_SK.Num2Word_SK(),
'sl': lang_SL.Num2Word_SL(),
'sr': lang_SR.Num2Word_SR(),
'sv': lang_SV.Num2Word_SV(),
Expand All @@ -60,12 +68,14 @@
'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(),
'uk': lang_UK.Num2Word_UK(),
'te': lang_TE.Num2Word_TE(),
'hu': lang_HU.Num2Word_HU()
'hu': lang_HU.Num2Word_HU(),
'is': lang_IS.Num2Word_IS()
}

CONVERTES_TYPES = ['cardinal', 'ordinal', 'ordinal_num', 'year', 'currency']
Expand All @@ -85,7 +95,7 @@ def num2words(number, ordinal=False, lang='en', to='cardinal', **kwargs):

# backwards compatible
if ordinal:
return converter.to_ordinal(number)
to = 'ordinal'

if to not in CONVERTES_TYPES:
raise NotImplementedError()
Expand Down
6 changes: 3 additions & 3 deletions num2words/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def parse_minus(self, num_str):
"""Detach minus and return it as symbol with new num_str."""
if num_str.startswith('-'):
# Extra spacing to compensate if there is no minus.
return '%s ' % self.negword, num_str[1:]
return '%s ' % self.negword.strip(), num_str[1:]
return '', num_str

def str_to_number(self, value):
Expand All @@ -109,7 +109,7 @@ def to_cardinal(self, value):
out = ""
if value < 0:
value = abs(value)
out = self.negword
out = "%s " % self.negword.strip()

if value >= self.MAXVAL:
raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL))
Expand Down Expand Up @@ -292,7 +292,7 @@ def to_currency(self, val, currency='EUR', cents=True, separator=',',
if adjective and currency in self.CURRENCY_ADJECTIVES:
cr1 = prefix_currency(self.CURRENCY_ADJECTIVES[currency], cr1)

minus_str = "%s " % self.negword if is_negative else ""
minus_str = "%s " % self.negword.strip() 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)
Expand Down
129 changes: 129 additions & 0 deletions num2words/lang_AM.py
Original file line number Diff line number Diff line change
@@ -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)
Loading

0 comments on commit 0135528

Please sign in to comment.