Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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()
@sdelquin

This comment has been minimized.

Copy link

@sdelquin sdelquin commented Dec 9, 2016

Hay un error

20 -> veinticero

Cambiar línea 122 por:
elif 21 <= numero <= 29:

Muchas gracias por la librería!

@jesus01x

This comment has been minimized.

Copy link

@jesus01x jesus01x commented Nov 13, 2017

Imagino que quisiste decir que modificara esta linea en especifico -->elif numero <= 29: por lo que comentaste es decir elif 21 <= numero <= 29: si asi en este codigo fuente esa linea es la 121 , no 122.

@robertowest

This comment has been minimized.

Copy link

@robertowest robertowest commented Jul 23, 2019

En la línea 132 también tienes un error:
if numero == 0:
debería ser:
if decena == 0:

Saludos.

@Gztabo21

This comment has been minimized.

Copy link

@Gztabo21 Gztabo21 commented Sep 5, 2019

se ve interesante la probare

@FabrizioMore

This comment has been minimized.

Copy link

@FabrizioMore FabrizioMore commented Feb 20, 2020

Hola! Muchas gracias por la librería, me ayudó mucho en un proyecto personal <3
Quería señalar que en la función leer_centenas (línea 130) debí reemplazar el código por:
Sin título
debido a que al ingresar un número distinto de 100.000 pero cuyo modulo fuera 0 (ej: 300.000), como respuesta recibía 'cien mil'.

@Gztabo21

This comment has been minimized.

Copy link

@Gztabo21 Gztabo21 commented Feb 20, 2020

@Septiembre19

This comment has been minimized.

Copy link

@Septiembre19 Septiembre19 commented Mar 16, 2020

Muchas gracias y de igual forma, gracias a las demas personas con las correciones.

@lfranc2

This comment has been minimized.

Copy link

@lfranc2 lfranc2 commented Jun 6, 2020

Hay un error. 100 -> Ciento.

@VictorVegaPintaComex

This comment has been minimized.

Copy link

@VictorVegaPintaComex VictorVegaPintaComex commented Oct 21, 2020

Hay error con los siguientes valores 100,200,300,400,500,600,700,800,900

@Pollux3

This comment has been minimized.

Copy link

@Pollux3 Pollux3 commented Nov 24, 2020

En la línea 132 también tienes un error:
if numero == 0:
debería ser:
if decena == 0:

Saludos.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment