-
-
Save efrenfuentes/3785655 to your computer and use it in GitHub Desktop.
#!/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)) |
#!/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() |
Al resultado falta agregarle algunos reeplazos para texto con moneda
resultado = resultado.replace('cientos uno', 'cientos un')
resultado = resultado.replace('ciento uno', 'ciento un')
resultado = resultado.replace('quinientos uno', 'quinientos un')
No podemos decir "quinietos uno pesos" en mi caso México o "quinietos uno bolivares" porque lo real es "quinietos un pesos" o "quinietos un bolivares" igual pasa con todos los cientos, doscientos, trecientos, etc.
Saludos y muchisimas gracias por la aportación
Gracia por el codigo veo que sean corregido las observaciones de los demas usuaros, yo solo cree un metodo para colocar los centimos en formato de fraccion ya que asi los utilizo mas
def numero_a_monedas(numero):
numero_entero = int(numero)
parte_decimal = int(round((abs(numero) - abs(numero_entero)) * 100))
letras = numero_a_letras(numero_entero)
letras_decimal = f'{parte_decimal:02n}/100 { MONEDA_PLURAL}'
letras = '%s %s' % (letras, letras_decimal)
return letras
por ejemplo
print(numero_a_monedas(300000.23).upper())
tenemos:
TRESCIENTOS MIL 23/100 DOLARES
Yo hice un update a este codigo basado en python3 y espero les ayude.
en la 132 me sale con, ya lo he probado.
'if centena ==0:'
#Ya que siempre la decenas para los números que terminan en 00 se quedarán ahi.
Genial el aporte efrenfuentes.