Source code for annotations.TextNorm.num2letter

# -*- coding: UTF-8 -*-
"""
:filename: sppas.src.annotations.TextNorm.num2letter.py
:author:   Brigitte Bigi
:contact:  develop@sppas.org
:summary:  Numerical to string.

.. _This file is part of SPPAS: http://www.sppas.org/
..
    -------------------------------------------------------------------------

     ___   __    __    __    ___
    /     |  \  |  \  |  \  /              the automatic
    \__   |__/  |__/  |___| \__             annotation and
       \  |     |     |   |    \             analysis
    ___/  |     |     |   | ___/              of speech

    Copyright (C) 2011-2021  Brigitte Bigi
    Laboratoire Parole et Langage, Aix-en-Provence, France

    Use of this software is governed by the GNU Public License, version 3.

    SPPAS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SPPAS 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with SPPAS. If not, see <http://www.gnu.org/licenses/>.

    This banner notice must not be removed.

    -------------------------------------------------------------------------

Module to convert numbers to their written form the multilingual text
normalization system.
Num2Letter conversion is language-specific.

"""

from sppas.src.config.makeunicode import u

# -------------------------------------------------------------------------


[docs]class sppasNum(object): """Numerical conversion using a multilingual algorithm. The language names used in this class are based on iso639-3. >>> num = sppasNum('fra') >>> num.convert("3") trois >>> num.convert("03") >>>zéro-trois >>> sppasNum('3.0') ValueError IMPORTANT: ========== Notice that this class should be fully re-implemented. It should use an external resource file to make the match between numbers and letters, for each language: 0 zéro 1 un ... 10 dix 100 cent 1000 mille 1000000 million 1000000000 milliard """ LANGUAGES = ["und", "yue", "cmn", "fra", "ita", "eng", "spa", "khm", "vie", "jpn", "pol", "por", "pcm"] ZERO = dict() ZERO["und"] = u("0") ZERO["yue"] = u("零") ZERO["cmn"] = u("零") ZERO["fra"] = u("zéro") ZERO["ita"] = u("zero") ZERO["eng"] = u("zero") ZERO["spa"] = u("cero") ZERO["khm"] = u("ស្សូន ") ZERO["vie"] = u("không") ZERO["jpn"] = u("ゼロ") ZERO['pol'] = u("zerowej") ZERO['por'] = u("zero")
[docs] def __init__(self, lang="und"): """Create a new sppasNum instance. :param lang: (str) the language code in ISO639-3 (fra, eng, spa, khm, ita, ...). If lang is set to "und" (undetermined), no conversion is performed. """ self._lang = "und" self.set_lang(lang)
# -------------------------------------------------------------------------
[docs] def set_lang(self, lang): """Set the language. :param lang: (str) the language code in ISO639-3. """ if lang == "pcm": lang = "eng" self._lang = lang
# -------------------------------------------------------------------------
[docs] def get_lang(self): """Return the current language code.""" return self._lang
# ------------------------------------------------------------------------- # Number 0 # -------------------------------------------------------------------------
[docs] def zero(self): """Convert the zero number. :param number: (int) the number to convert to letters. """ return sppasNum.ZERO[self._lang]
# ------------------------------------------------------------------------- # Numbers from 1 to 9 # ------------------------------------------------------------------------- def __unite_khm(self, number): _r = "" if number == 9: _r = u("ប្រាំបួន ") if number == 8: _r = u("ប្រាំបី ") if number == 7: _r = u("ប្រាំពីរ ") if number == 6: _r = u("ប្រាំមួយ ") if number == 5: _r = u("ប្រាំ ") if number == 4: _r = u("បួន ") if number == 3: _r = u("បី ") if number == 2: _r = u("ពីរ ") if number == 1: _r = u("មួយ ") if number == 0: _r = self.zero() return _r # ------------------------------------------------------------------------- def __unite_por(self, number): _r = "" if number == 9: _r = u("nove") if number == 8: _r = u("oito") if number == 7: _r = u("sete") if number == 6: _r = u("seis") if number == 5: _r = u("cinco") if number == 4: _r = u("quatro") if number == 3: _r = u("três") if number == 2: _r = u("dois") if number == 1: _r = u("um") if number == 0: _r = self.zero() return _r # ------------------------------------------------------------------------- def __unite_spa(self, number): _r = "" if number == 9: _r = u("nueve") if number == 8: _r = u("ocho") if number == 7: _r = u("siete") if number == 6: _r = u("seis") if number == 5: _r = u("cinco") if number == 4: _r = u("cuatro") if number == 3: _r = u("tres") if number == 2: _r = u("dos") if number == 1: _r = u("uno") if number == 0: _r = self.zero() return _r # ------------------------------------------------------------------------- def __unite_vie(self, number): _r = "" if number == 9: _r = u("chín") if number == 8: _r = u("tám") if number == 7: _r = u("bảy") if number == 6: _r = u("sáu") if number == 5: _r = u("năm") if number == 4: _r = u("bốn") if number == 3: _r = u("ba") if number == 2: _r = u("hai") if number == 1: _r = u("một") if number == 0: _r = self.zero() return _r # ------------------------------------------------------------------------- def __unite_cmn(self, number): _r = "" if number == 9: _r = u("九") if number == 8: _r = u("八") if number == 7: _r = u("七") if number == 6: _r = u("六") if number == 5: _r = u("五") if number == 4: _r = u("四") if number == 3: _r = u("三") if number == 2: _r = u("二") if number == 1: _r = u("一") if number == 0: _r = self.zero() return _r # ------------------------------------------------------------------------- def __unite_fra(self, number): _r = "" if number == 9: _r = u("neuf") if number == 8: _r = u("huit") if number == 7: _r = u("sept") if number == 6: _r = u("six") if number == 5: _r = u("cinq") if number == 4: _r = u("quatre") if number == 3: _r = u("trois") if number == 2: _r = u("deux") if number == 1: _r = u("un") if number == 0: _r = self.zero() return _r # ------------------------------------------------------------------------- def __unite_ita(self, number): _r = "" if number == 9: _r = u("nove") if number == 8: _r = u("otto") if number == 7: _r = u("sette") if number == 6: _r = u("sei") if number == 5: _r = u("cinque") if number == 4: _r = u("quattro") if number == 3: _r = u("tré") if number == 2: _r = u("due") if number == 1: _r = u("uno") if number == 0: _r = self.zero() return _r # ------------------------------------------------------------------------- def __unite_eng(self, number): _r = "" if number == 9: _r = u("nine") if number == 8: _r = u("eight") if number == 7: _r = u("seven") if number == 6: _r = u("six") if number == 5: _r = u("five") if number == 4: _r = u("four") if number == 3: _r = u("three") if number == 2: _r = u("two") if number == 1: _r = u("one") if number == 0: _r = self.zero() return _r # ------------------------------------------------------------------------- def __unite_pol(self, number): _r = "" if number == 9: _r = u("września") if number == 8: _r = u("osiem") if number == 7: _r = u("siedem") if number == 6: _r = u("sześć") if number == 5: _r = u("pięć") if number == 4: _r = u("cztery") if number == 3: _r = u("trzy") if number == 2: _r = u("dwa") if number == 1: _r = u("stycznia") if number == 0: _r = self.zero() return _r # -------------------------------------------------------------------------
[docs] def unite(self, number): """Convert a number from 0 to 9. :param number: (int) the number to convert to letters. """ if self._lang == "khm": return self.__unite_khm(number) if self._lang == "spa": return self.__unite_spa(number) if self._lang == "vie": return self.__unite_vie(number) if self._lang in ["cmn", "yue", "jpn"]: return self.__unite_cmn(number) if self._lang == "fra": return self.__unite_fra(number) if self._lang == "ita": return self.__unite_ita(number) if self._lang == "eng": return self.__unite_eng(number) if self._lang == "pol": return self.__unite_pol(number) if self._lang == "por": return self.__unite_por(number) if self._lang == "und": return str(number) raise ValueError("Unknown language {:s} to convert numbers" "".format(self._lang))
# ------------------------------------------------------------------------- # Numbers from 10 to 99 # ------------------------------------------------------------------------- def __dizaine_pol(self, number): if number < 10: return self.unite(number) if number < 22: if number == 10: _r = u("dziesięć") elif number == 11: _r = u("jedenaście") elif number == 12: _r = u("dwanaście") elif number == 13: _r = u("trzynaście") elif number == 14: _r = u("czternaście") elif number == 15: _r = u("piętnaście") elif number == 16: _r = u("szesnaście") elif number == 17: _r = u("siedemnaście") elif number == 18: _r = u("osiemnaście") elif number == 19: _r = u("dziewiętnaście") elif number == 20: _r = u("dwadzieścia") elif number == 21: _r = u("dwadzieścia jeden") return _r n = (number / 10) * 10 r = number % 10 if number < 50: dizaine = u("dzieścia") else: dizaine = u("dziesiąt") if r == 0: return u("%s%s") % (self.unite(n/10), dizaine) return u("%s%s-%s") % (self.unite(n/10), dizaine, self.unite(r)) # ------------------------------------------------------------------------- def __dizaine_por(self, number): if number < 10: return self.unite(number) if number < 20: if number == 10: return u("dez") elif number == 11: return u("onze") elif number == 12: return u("doze") elif number == 13: return u("treze") elif number == 14: return u("quatorze") elif number == 15: return u("quinze") elif number == 16: return u("dezesseis") elif number == 17: return u("dezessete") elif number == 18: return u("dezoito") elif number == 19: return u("dezenove") n = (number / 10) * 10 r = number % 10 if 19 < n < 30: dizaine = u("vinte") elif 29 < n < 40: dizaine = u("trinta") elif 39 < n < 50: dizaine = u("quarenta") elif 49 < n < 60: dizaine = u("cinquenta") elif 59 < n < 70: dizaine = u("sessenta") elif 69 < n < 80: dizaine = u("setenta") elif 79 < n < 90: dizaine = u("oitenta") elif 89 < n < 100: dizaine = u("noventa") if r == 0: return dizaine return u("%s-e-%s") % (dizaine, self.unite(r)) # ------------------------------------------------------------------------- def __dizaine_spa(self, number): if number < 10: return self.unite(number) if number == 10: return u("diez") if number == 11: return u("once") if number == 12: return u("doce") if number == 13: return u("trece") if number == 14: return u("catorce") if number == 15: return u("quince") if number == 16: return u("dieciséis") if number == 17: return u("diecisiete") if number == 18: return u("dieciocho") if number == 19: return u("diecinueve") if number == 20: return u("veinte") if number == 21: return u("veintiuno") if number == 22: return u("veintidós") if number == 23: return u("veintitrés") if number == 24: return u("veinticuatro") if number == 25: return u("veinticinco") if number == 26: return u("veintiséis") if number == 27: return u("veintisiete") if number == 28: return u("veintiocho") if number == 29: return u("veintinueve") n = (number / 10) * 10 r = number % 10 if 29 < n < 40: dizaine = u("treinta") elif 39 < n < 50: dizaine = u("cuarenta") elif 49 < n < 60: dizaine = u("cincuenta") elif 59 < n < 70: dizaine = u("sesenta") elif 69 < n < 80: dizaine = u("setenta") elif 79 < n < 90: dizaine = u("ochenta") elif 89 < n < 100: dizaine = u("noventa") if r == 0: return dizaine return u("%s-y-%s") % (dizaine, self.unite(r)) # ------------------------------------------------------------------------- def __dizaine_cmn(self, number): if number < 10: _str = self.unite(number) elif 10 <= number < 100: if (number % 10) == 0: _str = self.unite(int(number/10)) + u("十") else: _str = self.unite(int(number/10)) + u("十") + self.unite(number%10) return _str # ------------------------------------------------------------------------- def __dizaine_fra(self, number): if 90 <= number <= 99: _str = u("quatre-vingt-") + self.dizaine(number-80) elif 80 <= number <= 89: _str = u("quatre-vingt ") if number > 80: _str = u("quatre-vingt-") + self.unite(number-80) elif 70 <= number <= 79: _str = u("soixante-") + self.dizaine(number-60) elif 60 <= number <= 69: _str = u("soixante ") if number == 61: _str = u("soixante-et-un ") if number > 61: _str = u("soixante-") + self.unite(number-60) elif 50 <= number <= 59: _str = u("cinquante ") if number == 51: _str = u("cinquante-et-un ") if number > 51: _str = u("cinquante-") + self.unite(number-50) elif 40 <= number <= 49: _str = u("quarante ") if number == 41: _str = u("quarante-et-un ") if number > 41: _str = u("quarante-") + self.unite(number-40) elif 30 <= number <= 39: _str = u("trente ") if number == 31: _str = u("trente-et-un ") if number > 31: _str = u("trente-") + self.unite(number-30) elif 20 <= number <= 29: _str = u("vingt ") if number == 21: _str = u("vingt-et-un ") if number > 21: _str = u("vingt-") + self.unite(number-20) elif 10 <= number <= 19: if number == 10: _r = u("dix") if number == 11: _r = u("onze") if number == 12: _r = u("douze") if number == 13: _r = u("treize") if number == 14: _r = u("quatorze") if number == 15: _r = u("quinze") if number == 16: _r = u("seize") if number == 17: _r = u("dix-sept") if number == 18: _r = u("dix-huit") if number == 19: _r = u("dix-neuf") return _r else: _str = self.unite(number) return _str # ------------------------------------------------------------------------- def __dizaine_eng(self, number): if 90 < number <= 99: _str = u("ninety-") + self.dizaine(number-90) elif number == 90: _str = u("ninety") elif 80 < number <= 89: _str = u("eighty-") + self.dizaine(number-80) elif number == 80: _str = u("eighty") elif 70 < number <= 79: _str = u("seventy-") + self.dizaine(number-70) elif number == 70: _str = u("seventy") elif 60 < number <= 69: _str = u("sixty-") + self.unite(number-60) elif number == 60: _str = u("sixty ") elif 50 < number <= 59: _str = u("fifty-") + self.unite(number-50) elif number == 50: _str = u("fifty") elif 40 < number <= 49: _str = u("fourty-") + self.unite(number-40) elif number == 40: _str = u("fourty") elif 30 < number <= 39: _str = u("thirty-") + self.unite(number-30) elif number == 30: _str = u("thirty") elif 20 < number <= 29: _str = u("twenty-") + self.unite(number-20) elif number == 20: _str = u("twenty ") elif 10 <= number <= 19: if number == 10: _r = u("ten") if number == 11: _r = u("eleven") if number == 12: _r = u("twelve") if number == 13: _r = u("thirteen") if number == 14: _r = u("fourteen") if number == 15: _r = u("fifteen") if number == 16: _r = u("sixteen") if number == 17: _r = u("seventeen") if number == 18: _r = u("eigteen") if number == 19: _r = u("nineteen") return _r else: _str = self.unite(number) return _str # ------------------------------------------------------------------------- def __dizaine_ita(self,number): if number == 91 or number == 98: _str = u("novant") + self.dizaine(number-90).strip() + " " elif 90 < number <= 99: _str = u("novanti-") + self.dizaine(number-90).strip() + " " elif number == 90: _str = u("novanti") elif number == 81 or number == 88: _str = u("ottant") + self.dizaine(number-80).strip() + " " elif 81 < number <= 89: _str = u("ottanta-") + self.dizaine(number-80).strip() + " " elif number == 80: _str = u("ottanta") elif number == 71 or number == 78: _str = u("settant") + self.dizaine(number-70).strip() + " " elif number >= 71 and number <= 79: _str = u("settanta-") + self.dizaine(number-70).strip() + " " elif number == 70: _str = u("settanta") elif number == 61 or number == 68: _str = u("sessant") + self.unite(number-60).strip() + " " elif number > 61 and number <= 69: _str = u("sessanta-") + self.unite(number-60).strip() + " " elif number == 60: _str = u("sessanta") elif number == 51 or number == 58: _str = u("cinquant") + self.unite(number-50).strip() + " " elif number > 50 and number <= 59: _str = u("cinquanta-") + self.unite(number-50).strip() + " " elif number == 50: _str = u("cinquanta") elif number == 41 or number == 48: _str = u("quarant") + self.unite(number-40).strip() + " " elif number > 41 and number <= 49: _str = u("quaranta-") + self.unite(number-40).strip() + " " elif number == 40: _str = u("quaranta") elif number == 31 or number == 38: _str = u("trent") + self.unite(number-30).strip() + " " elif number > 31 and number <= 39: _str = u("trenta-") + self.unite(number-30).strip() + " " elif number == 30: _str = u("trenta") elif number == 21 or number == 28: _str = u("vent") + self.unite(number-20).strip() + " " elif number > 21 and number <= 29: _str = u("venti-") + self.unite(number-20).strip() + " " elif number == 20: _str = u("venti") elif number >= 10 and number <= 19: if number == 10: _r = u("dieci") if number == 11: _r = u("undici") if number == 12: _r = u("dodici") if number == 13: _r = u("tredici") if number == 14: _r = u("quattordici") if number == 15: _r = u("quindici") if number == 16: _r = u("sedici") if number == 17: _r = u("diciassette") if number == 18: _r = u("diciotto") if number == 19: _r = u("diciannove") return _r else: _str = self.unite(number) return _str # -------------------------------------------------------------------------
[docs] def dizaine(self, number): """Convert a number from 10 to 99. :param number: (int) """ if self._lang == "spa": return self.__dizaine_spa(number) if "cmn" in self._lang \ or "yue" in self._lang \ or "jpn" in self._lang: return self.__dizaine_cmn(number) if self._lang == "eng": return self.__dizaine_eng(number) if self._lang == "fra": return self.__dizaine_fra(number) if self._lang == "ita": return self.__dizaine_ita(number) if self._lang == "pol": return self.__dizaine_pol(number) if self._lang == "por": return self.__dizaine_por(number) if self._lang == "und": return str(number) raise Exception('Unrecognized language: '+self._lang)
# ------------------------------------------------------------------------- # Numbers from 100 to 999 # ------------------------------------------------------------------------- def __centaine_por(self, number): if number < 100: return self.dizaine(number) if number == 100: return u("centavo") n = number / 100 r = number % 100 s = "" if 100 < number < 200: return u("centavo-%s") % self.dizaine(r) if 199 < number < 300: s = u("duzentos") elif 299 < number < 400: s = u("trezentos") elif 399 < number < 500: s = u("quatrocentos") elif 499 < number < 600: s = u("quinhentos") elif 599 < number < 700: s = u("seiscentos") elif 699 < number < 800: s = u("setecentos") elif 799 < number < 900: s = u("oitocentos") elif 899 < number < 1000: s = u("novecentos") if r == 0: return s return u("%s-e-%s") % (s, self.dizaine(r)) # ------------------------------------------------------------------------- def __centaine_spa(self, number): if number < 100: return self.dizaine(number) if number == 100: return u("cien") n = number / 100 r = number % 100 s = "" if 100 < number < 200: return u("ciento-%s") % self.dizaine(r) if 499 < number < 600: s = u("quinientos") elif 699 < number < 800: s = u("setecientos") elif 899 < number < 1000: s = u("novecientos") else: s = u("{:s}cientos".format(self.unite(n))) if r == 0: return s return u("%s-%s") % (s, self.dizaine(r)) # ------------------------------------------------------------------------- def __centaine_cmn(self, number): if number < 100: return self.dizaine(number) if number >= 100 and number < 1000: if (number % 100) != 0: if (number % 100) > 0 and (number % 100) < 10: return self.dizaine(int(number/100)) + u("百零") + self.dizaine(number % 100) return self.dizaine(int(number/100)) + u("百") + self.dizaine(number % 100) else: return self.dizaine(int(number/100)) + u("百") return str(number) # ------------------------------------------------------------------------- def __centaine_fra(self, number): if number < 100: return self.dizaine(number) if number == 100: return u("cent") if number > 100 and number <= 199: return u("cent-") + self.dizaine(number % 100) if (number%100) == 0: return self.unite(number % 100) + u("-cents") return self.unite(int(number/100)) + u("-cent-") + self.dizaine(number % 100) # ------------------------------------------------------------------------- def __centaine_ita(self, number): if number < 100: return self.dizaine(number) if number == 100: return u("cento") if number > 100 and number <= 199: return u("cento-") + self.dizaine(number%100) if (number%100) == 0: return " " + self.unite(number % 100) + u("-cento") return " " + self.unite(int(number/100)) + u("-cento-") + self.dizaine(number % 100) # ------------------------------------------------------------------------- def __centaine_eng(self, number): if number < 100: return self.dizaine(number) n = number / 100 r = number % 100 s = u("%s hundred") % self.unite(n) if r == 0: return s else: return "%s %s" % (s, self.dizaine(r)) # ------------------------------------------------------------------------- def __centaine_pol(self, number): if number < 100: return self.dizaine(number) if number == 100: return u("sto") if number > 100 and number <= 199: return u("sto ") + self.dizaine(number % 100) if number == 200: return u("dwieście") if number > 200 and number <= 299: return u("dwieście ") + self.dizaine(number % 100) if number == 300: return u("trzysta") if number > 300 and number <= 399: return u("trzysta ") + self.dizaine(number % 100) if number == 400: return u("czterysta") if number > 400 and number <= 499: return u("czterysta ") + self.dizaine(number % 100) if number == 500: return u("pięćset") if number > 500 and number <= 599: return u("pięćset ") + self.dizaine(number % 100) if number == 600: return u("sześćset") if number > 600 and number <= 699: return u("sześćset ") + self.dizaine(number % 100) if number == 700: return u("siedemset") if number > 700 and number <= 799: return u("siedemset ") + self.dizaine(number % 100) if number == 800: return u("osiemset") if number > 800 and number <= 899: return u("osiemset ") + self.dizaine(number % 100) if number == 900: return u("osiemset") if number > 900 and number <= 999: return u("osiemset ") + self.dizaine(number % 100) # -------------------------------------------------------------------------
[docs] def centaine(self, number): """Convert a number from 100 to 999. :param number: (int) """ if self._lang == "spa": return self.__centaine_spa(number) if "cmn" in self._lang \ or "yue" in self._lang \ or "jpn" in self._lang: return self.__centaine_cmn(number) if self._lang == "fra": return self.__centaine_fra(number) if self._lang == "ita": return self.__centaine_ita(number) if self._lang == "eng": return self.__centaine_eng(number) if self._lang == "pol": return self.__centaine_pol(number) if self._lang == "por": return self.__centaine_por(number) if self._lang == "und": return str(number) raise Exception('Unrecognized language: ' + self._lang)
# ------------------------------------------------------------------------- # Numbers from more than 999 # ------------------------------------------------------------------------- def __milliers_por(self, number): if number < 1000: return self.centaine(number) n = number / 1000 r = number % 1000 if number < 2000: s = u("mil") else: s = u("%s-milhas") % self.centaine(n) if r == 0: return s return u("%s-%s") % (s, self.centaine(r)) # ----------------------------------------------------------------------- def __milliers_spa(self, number): if number < 1000: return self.centaine(number) n = number / 1000 r = number % 1000 if number < 2000: s = u("mil") else: s = u("%s-mil") % self.centaine(n) if r == 0: return s return u("%s-%s") % (s, self.centaine(r)) # ----------------------------------------------------------------------- def __millier_cmn(self, number): if number < 1000: return self.centaine(number) if number >= 1000 and number < 10000: if (number % 1000) != 0: if number % 1000 > 0 \ and number % 1000 < 100: return self.centaine(int(number/1000)) + u("千零") + self.centaine(number % 1000) else: return self.centaine(int(number/1000)) + u("千") + self.centaine(number % 1000) return self.centaine(int(number/1000)) + u("千") return str(number) # ----------------------------------------------------------------------- def __milliers_cmn(self, number): if number < 10000: return self.__millier_cmn(number) if (number % 10000) == 0: return self.unite(int(number/10000)) + u("万") if number >= 10000 and number < 100000000: if (number % 10000) != 0: if (number % 10000) > 0 and (number % 10000) < 1000: return self.unite(int(number/10000)) + u("万零") + self.__millier_cmn(number % 10000) return self.unite(int(number/10000)) + u("万") + self.__millier_cmn(number % 10000) else: return u("万") return str(number) # ----------------------------------------------------------------------- def __milliers_fra(self, number): if number < 1000: return self.centaine(number) # Milliers if number == 1000: return u("mille ") elif number > 1000 and number < 2000: return u("mille-") + self.centaine(number % 1000) elif number >= 2000 and number < 10000: if (number % 1000) == 0: return self.unite(int(number/1000)) + u("-mille-") return self.unite(int(number/1000)) + u("-mille-") + self.centaine(number % 1000) # Dizaines de milliers if number == 10000: return u("dix-mille") elif number > 10000 and number < 100000: if (number%1000) == 0: return self.dizaine(int(number/1000)) + u("-mille ") return self.dizaine(int(number/1000)) + u("-mille-") + self.centaine(number % 1000) # Centaines de milliers if number == 100000: return u("cent-mille") elif number >= 100000 and number < 1000000: if (number % 1000) == 0: return self.centaine(int(number/1000)) + u("-mille ") return self.centaine(int(number/1000)) + u("-mille-") + self.centaine(int(number % 1000)) return str(number) # ----------------------------------------------------------------------- def __milliers_ita(self,number): if number < 1000: return self.centaine(number) # Milliers if number == 1000: return u("mille") if number > 1000 and number < 2000: return u("mille-") + self.centaine(number % 1000) if number >= 2000 and number < 10000: if (number % 1000) != 0: return self.unite(int(number/1000)).strip() + u("-mila-") + self.centaine(number % 1000) return self.unite(int(number/1000)).strip() + u("-mila") # Dizaines de milliers if number == 10000: return u("diecimila") if number > 10000 and number < 100000: if (number % 1000) != 0: return self.dizaine(int(number/1000)).strip() + u("-mila-") + self.centaine(number % 1000) return self.dizaine(int(number/1000)) + u("-mila") # Centaines de milliers if number == 100000: return u("centomila") if number >= 100000 and number < 1000000: if (number % 1000) != 0: return self.centaine(int(number/1000)).strip() + u("-mila-") + self.centaine(int(number%1000)) return self.centaine(int(number/1000)).strip() + u("mila-") return str(number) # ----------------------------------------------------------------------- def __milliers_eng(self, number): if number < 1000: return self.centaine(number) n = number / 1000 r = number % 1000 s = u("%s thousand") % self.centaine(n) if r == 0: return s else: return u("%s %s") % (s, self.centaine(r)) # ----------------------------------------------------------------------- def __milliers_pol(self, number): if number < 1000: return self.centaine(number) n = number / 1000 r = number % 1000 if number < 2000: s = u("tysięcy") else: s = u("%s tysiące") % self.centaine(n) if r == 0: return s return u("%s %s") % (s, self.centaine(r)) # -----------------------------------------------------------------------
[docs] def milliers(self, number): """Convert a number from 1000 to 9999. :param number: (int) """ if self._lang == "spa": return self.__milliers_spa(number) if "cmn" in self._lang \ or "yue" in self._lang \ or "jpn" in self._lang: return self.__milliers_cmn(number) if self._lang == "fra": return self.__milliers_fra(number) if self._lang == "ita": return self.__milliers_ita(number) if self._lang == "eng": return self.__milliers_eng(number) if self._lang == "pol": return self.__milliers_pol(number) if self._lang == "por": return self.__milliers_por(number) raise Exception('Unrecognized language: '+self._lang)
# ------------------------------------------------------------------------- # ----------------------------------------------------------------------- def __millions_por(self, number): if number < 1000000: return self.milliers(number) n = number / 1000000 r = number % 1000000 if number < 2000000: s = u("un-millón") else: s = u("%s-millones") % self.milliers(n) if r == 0: return s return u("%s-%s") % (s, self.milliers(r)) # ----------------------------------------------------------------------- def __millions_spa(self, number): if number < 1000000: return self.milliers(number) n = number / 1000000 r = number % 1000000 if number < 2000000: s = u("un-millón") else: s = u("%s-millones") % self.milliers(n) if r == 0: return s return u("%s-%s") % (s, self.milliers(r)) # ----------------------------------------------------------------------- def __millions_cmn(self, number): if number < 100000000: return self.__milliers_cmn(number) if (number % 100000000) == 0: return self.__millier_cmn(int(number/100000000)) + u("亿") if (number % 100000000) != 0: if (number % 100000000) > 0 and (number % 100000000) < 10000000: return self.__millier_cmn(int(number/100000000)) + u("亿零") + self.__millier_cmn(number % 100000000) return self.__millier_cmn(int(number/100000000)) + u("亿") + self.__millier_cmn(number % 100000000) else: return u("亿") # ----------------------------------------------------------------------- def __millions_fra(self,number): if number < 1000000: return self.milliers(number) if number >= 1000000 and number < 2000000: return u("un-million-") + self.milliers(int(number%1000000)) if number >= 2000000 and number < 1000000000: return self.centaine(int(number/1000000)) + u("-millions-") + self.milliers(int(number % 1000000)) return str(number) # ----------------------------------------------------------------------- def __millions_ita(self,number): if number < 1000000: return self.milliers(number) if number >= 1000000 and number < 2000000: return u("un-milione-") + self.milliers(int(number % 1000000)) if number >= 2000000 and number < 1000000000: return self.centaine(int(number/1000000)).strip() + u("-milioni-") + self.milliers(int(number % 1000000)) return str(number) # ----------------------------------------------------------------------- def __millions_eng(self, number): if number < 1000000: return self.milliers(number) n = number / 1000000 r = number % 1000000 s = u("%s million") % self.centaine(n) if r == 0: return s else: return u("%s %s") % (s, self.milliers(r)) # ----------------------------------------------------------------------- def __millions_pol(self, number): if number < 1000000: return self.milliers(number) if number >= 1000000 and number < 2000000: return u("milion ") + self.milliers(int(number % 1000000)) if number >= 2000000 and number < 1000000000: return self.centaine(int(number/1000000)).strip() + u(" miliony ") + self.milliers(int(number % 1000000)) return str(number) # -----------------------------------------------------------------------
[docs] def millions(self,number): """ Convert a number from 1000 to 1000000. """ if self._lang == "spa": return self.__millions_spa(number) if "cmn" in self._lang \ or "yue" in self._lang \ or "jpn" in self._lang: return self.__millions_cmn(number) if self._lang == "fra": return self.__millions_fra(number) if self._lang == "ita": return self.__millions_ita(number) if self._lang == "eng": return self.__millions_eng(number) if self._lang == "pol": return self.__millions_pol(number) if self._lang == "por": return self.__millions_por(number) raise Exception('Unrecognized language: '+self._lang)
# ------------------------------------------------------------------------- # ----------------------------------------------------------------------- def __milliards_spa(self, number): if number < 1000000000: return self.millions(number) n = number / 1000000000 r = number % 1000000000 s = u("%s-mil-millones") % self.millions(n) if r == 0: return s else: return u("%s-%s") % (s, self.millions(r)) # ----------------------------------------------------------------------- def __milliards_fra(self, number): if number < 1000000000: return self.millions(number) if number >= 1000000000 and number < 2000000000: return u("un-milliard-") + self.millions(int(number % 1000000000)) if number >= 2000000000 and number < 1000000000000: return self.centaine(int(number/1000000000)) + u("-milliards-") + self.millions(int(number % 1000000000)) return str(number) # ----------------------------------------------------------------------- def __milliards_ita(self, number): if number < 1000000000: _str = self.millions(number) # Millions elif number >= 1000000000 and number < 2000000000: _str = u("un-miliardo-") + self.millions(int(number % 1000000000)) elif number >= 2000000000 and number < 1000000000000: _str = "-" + self.centaine(int(number/1000000000)).strip() + u("-miliardi-") + self.millions(int(number % 1000000000)) else: return str(number) return _str # ----------------------------------------------------------------------- def __milliards_eng(self, number): if number < 1000000000: return self.millions(number) n = number / 1000000000 r = number % 1000000000 s = u("%s billion") % self.centaine(n) if r == 0: return s else: return u("%s %s") % (s, self.millions(r)) # ----------------------------------------------------------------------- def __milliards_pol(self, number): if number < 1000000000: return self.millions(number) if number >= 1000000000 and number < 2000000000: return u("miliard") + self.millions(int(number % 1000000000)) if number >= 2000000000 and number < 1000000000000: return self.centaine(int(number/1000000000)) + u(" miliardy ") + self.millions(int(number % 1000000000)) return str(number) # ----------------------------------------------------------------------- def __milliards_por(self, number): if number < 1000000000: return self.millions(number) return self.milliers(int(number/1000000)) + u("-") + self.millions(int(number % 1000000)) # ----------------------------------------------------------------------- def __convert(self, number): if self._lang == "spa": return self.__milliards_spa(number) if "cmn" in self._lang \ or "yue" in self._lang \ or "jpn" in self._lang: return self.__millions_cmn(number) if self._lang == "fra": return self.__milliards_fra(number) if self._lang == "eng": return self.__milliards_eng(number) if self._lang == "ita": res = self.__milliards_ita(number) return res.replace('oo', 'o') # ex: centoottanta -> centottanta if self._lang == "pol": return self.__milliards_pol(number) if self._lang == "por": return self.__milliards_por(number) raise ValueError("Unknown language {:s} for numerical conversion".format(self._lang)) # -----------------------------------------------------------------------
[docs] def convert(self, number): """Convert a number to a string. Example: 23 => twenty-three :param number: (int) A numerical representation :returns: string corresponding to the given number :raises: ValueError """ if self._lang not in sppasNum.LANGUAGES: raise ValueError("Unknown language {:s} for numerical conversion".format(self._lang)) number = str(number) if number.isdigit() is False: raise ValueError("Numerical conversion is available only for positive unsigned integers. Got {:s}.".format(number)) _strnum = "" _w = str(number) _i = int(number) # Numbers starting by one or more '0' (like phone numbers...) while _w.startswith(u("0")): _strnum = _strnum + self.zero() _w = _w[1:] if len(_w) > 0: _strnum = _strnum + self.__convert(_i) return ' '.join(_strnum.split())
# ------------------------------------------------------------------ if __name__ == '__main__': import os import sys from argparse import ArgumentParser PROGRAM = os.path.abspath(__file__) parser = ArgumentParser(usage="%s -l lang" % os.path.basename(PROGRAM), prog=PROGRAM, description="Num2Letter command line interface.") parser.add_argument("-l", "--lang", required=True, help='Language code (iso639-3)') if len(sys.argv) <= 1: sys.argv.append('-h') args = parser.parse_args() nb = sppasNum(args.lang) for line in sys.stdin: print(nb.convert(line).encode('utf8'))