-
-
Save hectorsum/76d93aa942411616ad212a5b607fa2aa to your computer and use it in GitHub Desktop.
Numero a letras (Python)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
__author__ = 'efrenfuentes' | |
MONEDA_SINGULAR = 'bolivar' | |
MONEDA_PLURAL = 'bolivares' | |
CENTIMOS_SINGULAR = 'centimo' | |
CENTIMOS_PLURAL = 'centimos' | |
MAX_NUMERO = 999999999999 | |
UNIDADES = ( | |
'cero', | |
'uno', | |
'dos', | |
'tres', | |
'cuatro', | |
'cinco', | |
'seis', | |
'siete', | |
'ocho', | |
'nueve' | |
) | |
DECENAS = ( | |
'diez', | |
'once', | |
'doce', | |
'trece', | |
'catorce', | |
'quince', | |
'dieciseis', | |
'diecisiete', | |
'dieciocho', | |
'diecinueve' | |
) | |
DIEZ_DIEZ = ( | |
'cero', | |
'diez', | |
'veinte', | |
'treinta', | |
'cuarenta', | |
'cincuenta', | |
'sesenta', | |
'setenta', | |
'ochenta', | |
'noventa' | |
) | |
CIENTOS = ( | |
'_', | |
'ciento', | |
'doscientos', | |
'trescientos', | |
'cuatroscientos', | |
'quinientos', | |
'seiscientos', | |
'setecientos', | |
'ochocientos', | |
'novecientos' | |
) | |
def numero_a_letras(numero): | |
numero_entero = int(numero) | |
if numero_entero > MAX_NUMERO: | |
raise OverflowError('Número demasiado alto') | |
if numero_entero < 0: | |
return 'menos %s' % numero_a_letras(abs(numero)) | |
letras_decimal = '' | |
parte_decimal = int(round((abs(numero) - abs(numero_entero)) * 100)) | |
if parte_decimal > 9: | |
letras_decimal = 'punto %s' % numero_a_letras(parte_decimal) | |
elif parte_decimal > 0: | |
letras_decimal = 'punto cero %s' % numero_a_letras(parte_decimal) | |
if (numero_entero <= 99): | |
resultado = leer_decenas(numero_entero) | |
elif (numero_entero <= 999): | |
resultado = leer_centenas(numero_entero) | |
elif (numero_entero <= 999999): | |
resultado = leer_miles(numero_entero) | |
elif (numero_entero <= 999999999): | |
resultado = leer_millones(numero_entero) | |
else: | |
resultado = leer_millardos(numero_entero) | |
resultado = resultado.replace('uno mil', 'un mil') | |
resultado = resultado.strip() | |
resultado = resultado.replace(' _ ', ' ') | |
resultado = resultado.replace(' ', ' ') | |
if parte_decimal > 0: | |
resultado = '%s %s' % (resultado, letras_decimal) | |
return resultado | |
def numero_a_moneda(numero): | |
numero_entero = int(numero) | |
parte_decimal = int(round((abs(numero) - abs(numero_entero)) * 100)) | |
centimos = '' | |
if parte_decimal == 1: | |
centimos = CENTIMOS_SINGULAR | |
else: | |
centimos = CENTIMOS_PLURAL | |
moneda = '' | |
if numero_entero == 1: | |
moneda = MONEDA_SINGULAR | |
else: | |
moneda = MONEDA_PLURAL | |
letras = numero_a_letras(numero_entero) | |
letras = letras.replace('uno', 'un') | |
letras_decimal = 'con %s %s' % (numero_a_letras(parte_decimal).replace('uno', 'un'), centimos) | |
letras = '%s %s %s' % (letras, moneda, letras_decimal) | |
return letras | |
def leer_decenas(numero): | |
if numero < 10: | |
return UNIDADES[numero] | |
decena, unidad = divmod(numero, 10) | |
if numero <= 19: | |
resultado = DECENAS[unidad] | |
elif numero <= 29: | |
resultado = 'veinti%s' % UNIDADES[unidad] | |
else: | |
resultado = DIEZ_DIEZ[decena] | |
if unidad > 0: | |
resultado = '%s y %s' % (resultado, UNIDADES[unidad]) | |
return resultado | |
def leer_centenas(numero): | |
centena, decena = divmod(numero, 100) | |
if numero == 0: | |
resultado = 'cien' | |
else: | |
resultado = CIENTOS[centena] | |
if decena > 0: | |
resultado = '%s %s' % (resultado, leer_decenas(decena)) | |
return resultado | |
def leer_miles(numero): | |
millar, centena = divmod(numero, 1000) | |
resultado = '' | |
if (millar == 1): | |
resultado = '' | |
if (millar >= 2) and (millar <= 9): | |
resultado = UNIDADES[millar] | |
elif (millar >= 10) and (millar <= 99): | |
resultado = leer_decenas(millar) | |
elif (millar >= 100) and (millar <= 999): | |
resultado = leer_centenas(millar) | |
resultado = '%s mil' % resultado | |
if centena > 0: | |
resultado = '%s %s' % (resultado, leer_centenas(centena)) | |
return resultado | |
def leer_millones(numero): | |
millon, millar = divmod(numero, 1000000) | |
resultado = '' | |
if (millon == 1): | |
resultado = ' un millon ' | |
if (millon >= 2) and (millon <= 9): | |
resultado = UNIDADES[millon] | |
elif (millon >= 10) and (millon <= 99): | |
resultado = leer_decenas(millon) | |
elif (millon >= 100) and (millon <= 999): | |
resultado = leer_centenas(millon) | |
if millon > 1: | |
resultado = '%s millones' % resultado | |
if (millar > 0) and (millar <= 999): | |
resultado = '%s %s' % (resultado, leer_centenas(millar)) | |
elif (millar >= 1000) and (millar <= 999999): | |
resultado = '%s %s' % (resultado, leer_miles(millar)) | |
return resultado | |
def leer_millardos(numero): | |
millardo, millon = divmod(numero, 1000000) | |
return '%s millones %s' % (leer_miles(millardo), leer_millones(millon)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
__author__ = 'efrenfuentes' | |
import unittest | |
from numero_letras import numero_a_letras, numero_a_moneda | |
class TestNumeroLetras(unittest.TestCase): | |
def test_numero_demasiado_alto(self): | |
numero = 1000000000000 | |
self.assertRaises(OverflowError, numero_a_letras, numero) | |
def test_unidades(self): | |
numero = 8 | |
self.assertEqual(numero_a_letras(numero), 'ocho') | |
numero = 2 | |
self.assertEqual(numero_a_letras(numero), 'dos') | |
numero = 0 | |
self.assertEqual(numero_a_letras(numero), 'cero') | |
def test_decena_diez(self): | |
numero = 15 | |
self.assertEqual(numero_a_letras(numero), 'quince') | |
numero = 17 | |
self.assertEqual(numero_a_letras(numero), 'diecisiete') | |
numero = 19 | |
self.assertEqual(numero_a_letras(numero), 'diecinueve') | |
def test_decena_veinte(self): | |
numero = 23 | |
self.assertEqual(numero_a_letras(numero), 'veintitres') | |
numero = 26 | |
self.assertEqual(numero_a_letras(numero), 'veintiseis') | |
numero = 21 | |
self.assertEqual(numero_a_letras(numero), 'veintiuno') | |
def test_menores_cien(self): | |
numero = 32 | |
self.assertEqual(numero_a_letras(numero), 'treinta y dos') | |
numero = 73 | |
self.assertEqual(numero_a_letras(numero), 'setenta y tres') | |
numero = 89 | |
self.assertEqual(numero_a_letras(numero), 'ochenta y nueve') | |
def test_centenas(self): | |
numero = 167 | |
self.assertEqual(numero_a_letras(numero), 'ciento sesenta y siete') | |
numero = 735 | |
self.assertEqual(numero_a_letras(numero), 'setecientos treinta y cinco') | |
numero = 899 | |
self.assertEqual(numero_a_letras(numero), 'ochocientos noventa y nueve') | |
def test_miles(self): | |
numero = 1973 | |
self.assertEqual(numero_a_letras(numero), 'mil novecientos setenta y tres') | |
numero = 5230 | |
self.assertEqual(numero_a_letras(numero), 'cinco mil doscientos treinta') | |
numero = 41378 | |
self.assertEqual(numero_a_letras(numero), 'cuarenta y un mil trescientos setenta y ocho') | |
numero = 197356 | |
self.assertEqual(numero_a_letras(numero), 'ciento noventa y siete mil trescientos cincuenta y seis') | |
numero = 2004 | |
self.assertEqual(numero_a_letras(numero), 'dos mil cuatro') | |
def test_millones(self): | |
numero = 11852739 | |
self.assertEqual(numero_a_letras(numero), 'once millones ochocientos cincuenta y dos mil setecientos treinta y nueve') | |
numero = 2000000 | |
self.assertEqual(numero_a_letras(numero), 'dos millones') | |
def test_millardos(self): | |
numero = 1212673201 | |
self.assertEqual(numero_a_letras(numero), 'mil doscientos doce millones seiscientos setenta y tres mil doscientos uno') | |
numero = 56547567945 | |
self.assertEqual(numero_a_letras(numero), 'cincuenta y seis mil quinientos cuarenta y siete millones quinientos sesenta y siete mil novecientos cuarenta y cinco') | |
def test_decimales(self): | |
numero = 1.87 | |
self.assertEqual(numero_a_letras(numero), 'uno punto ochenta y siete') | |
numero = 1.50 | |
self.assertEqual(numero_a_letras(numero), 'uno punto cincuenta') | |
numero = 1.04 | |
self.assertEqual(numero_a_letras(numero), 'uno punto cero cuatro') | |
numero = 1.00 | |
self.assertEqual(numero_a_letras(numero), 'uno') | |
def test_negativos(self): | |
numero = -4.5 | |
self.assertEqual(numero_a_letras(numero), 'menos cuatro punto cincuenta') | |
def test_moneda(self): | |
numero = 1212673201 | |
self.assertEqual(numero_a_moneda(numero), 'mil doscientos doce millones seiscientos setenta y tres mil doscientos un bolivares con cero centimos') | |
numero = 56547567945.5 | |
self.assertEqual(numero_a_moneda(numero), 'cincuenta y seis mil quinientos cuarenta y siete millones quinientos sesenta y siete mil novecientos cuarenta y cinco bolivares con cincuenta centimos') | |
numero = 1.01 | |
self.assertEqual(numero_a_moneda(numero), 'un bolivar con un centimo') | |
if __name__ == '__main__': | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment