Skip to content

Instantly share code, notes, and snippets.

@hectorsum
Forked from efrenfuentes/numero_letras.py
Created March 26, 2020 13:41
Show Gist options
  • Save hectorsum/76d93aa942411616ad212a5b607fa2aa to your computer and use it in GitHub Desktop.
Save hectorsum/76d93aa942411616ad212a5b607fa2aa to your computer and use it in GitHub Desktop.
Numero a letras (Python)
#!/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()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment