From 5479aa59c64952035e6c4d5de28aa40c50f6cd20 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Tue, 28 May 2013 11:34:53 -0400 Subject: [PATCH] Added README and re-designed the API --- README.rst | 48 ++++++++++++++++++++++++++++++++++ pynum2word/num2word.py | 54 +++++++++++++++++++-------------------- pynum2word/num2word_LT.py | 7 ++++- 3 files changed, 80 insertions(+), 29 deletions(-) create mode 100644 README.rst diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..1cdd1b1 --- /dev/null +++ b/README.rst @@ -0,0 +1,48 @@ +num2words - Convert numbers to words in multiple languages +========================================================== + +``num2words`` is a library that converts numbers like ``42`` to words like ``forty-two``. It +supports multiple languages (English, French, Spanish, German and Lithuanian) and can even generate +ordinal numbers like ``forty-second`` (altough this last feature is a bit buggy at the moment). + +The project is hosted on https://github.com/savoirfairelinux/num2words + +Usage +----- + +There's only one function to use:: + + >>> from num2words import num2words + >>> num2words(42) + forty-two + >>> num2words(42, ordinal=True) + forty-second + >>> num2words(42, lang='fr') + quarante-deux + +Besides the numerical argument, there's two optional arguments. + +**ordinal:** A boolean flag indicating to return an ordinal number instead of a cardinal one. + +**lang:** The language in which to convert the number. Supported languages are ``en``, ``fr``, +``de``, ``es``, ``lt`` and ``en_GB``. You can supply values like ``fr_FR``, the code will be +correctly interpreted. If you supply an unsupported language, ``NotImplementedError`` is raised. +Therefore, if you want to call ``num2words`` with a fallback, you can do:: + + try: + return num2words(42, lang=mylang) + except NotImplementedError: + return num2words(42, lang='en') + +History +------- + +``num2words`` is based on an old library , ``pynum2word`` created by Taro Ogawa in 2003. +Unfortunately, the library stopped being maintained and the author can't be reached. There was +another developer, Marius Grigaitis, who in 2011 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 diff --git a/pynum2word/num2word.py b/pynum2word/num2word.py index b3da49a..2a34f71 100644 --- a/pynum2word/num2word.py +++ b/pynum2word/num2word.py @@ -29,34 +29,32 @@ History: 0.2: n2w, to_card, to_ord, to_ordnum now imported correctly ''' from __future__ import unicode_literals -import locale as _locale -# Correct omissions in locale: -# Bugrep these... -_locdict = { "English_Australia" : "en_AU", } +import num2word_EN +import num2word_EN_GB +import num2word_FR +import num2word_DE +import num2word_ES +import num2word_LT +CONVERTER_CLASSES = { + 'en': num2word_EN.Num2Word_EN(), + 'en_GB': num2word_EN_GB.Num2Word_EN_GB(), + 'fr': num2word_FR.Num2Word_FR(), + 'de': num2word_DE.Num2Word_DE(), + 'es': num2word_ES.Num2Word_ES(), + 'lt': num2word_LT.Num2Word_LT(), +} -_modules = [] -for _loc in [_locale.getlocale(), _locale.getdefaultlocale()]: - _lang = _loc[0] - if _lang: - _lang = _locdict.get(_lang, _lang) - _lang = _lang.upper() - - _modules.append("num2word_" + _lang) - _modules.append("num2word_" + _lang.split("_")[0]) - -for _module in _modules: - try: - n2wmod = __import__(_module) - break - except ImportError: - pass - -try: - n2w, to_card, to_ord, to_ordnum, to_year = (n2wmod.n2w, n2wmod.to_card, - n2wmod.to_ord, n2wmod.to_ordnum, - n2wmod.to_year) -except NameError: - raise ImportError("Could not import any of these modules: %s" - % (", ".join(_modules))) +def num2words(number, ordinal=False, lang='en'): + # We try the full language first + if lang not in CONVERTER_CLASSES: + # ... and then try only the first 2 letters + lang = lang[:2] + if lang not in CONVERTER_CLASSES: + raise NotImplementedError() + converter = CONVERTER_CLASSES[lang] + if ordinal: + return converter.to_ordinal(number) + else: + return converter.to_cardinal(number) diff --git a/pynum2word/num2word_LT.py b/pynum2word/num2word_LT.py index 8c5811f..76d7e2b 100644 --- a/pynum2word/num2word_LT.py +++ b/pynum2word/num2word_LT.py @@ -227,7 +227,12 @@ def to_currency(n, currency='LTL', cents = True): return u'%s%s %s, %s %s' % (minus_str, int2word(left), pluralize(left, cr1), cents_str, pluralize(right, cr2)) -to_card = n2w +class Num2Word_LT(object): + def to_cardinal(self, number): + return n2w(number) + + def to_ordinal(self, number): + raise NotImplementedError() if __name__ == '__main__': import doctest