viernes, 22 de abril de 2011

Python: Numeros romanos a decimales

Hoy mi hermana me preguntó por una fecha en números romanos, y después de recordar las reglas básicas me decidí a realizar un pequeño programa en Python para automatizar la conversión.

No es tremendamente complicado, de hecho no verifica la validez del formato del número ingresado, sino que solo verifica que no haya caracteres extraños. Funciona desde linea de comando, usando el parámetro número 1 para el ingreso del dato.

Lo más interesante que tiene, para los que están aprendiendo, es el uso de un simple diccionario, llamado roma en este programita, para convertir directamente las letras en números, cosa que simplifica muchísimo la lógica del programa.

Lo segundo interesante es el uso de upper() para no tener que duplicar las entradas del diccionario para mayúsculas y minúsculas. No es que fuera un esfuerzo muy grande en este caso, pero es una técnica que les puede servir mucho para desarrollos más complejos.

Noten que además de tomar la entrada desde linea de comando también devuelve dos estados diferentes de salida de error. Esto hace que a futuro sea sencillo agregar una interfase gráfica que use este mismo programa para realizar la conversión, ya que no solo puede recibir el resultado sino consultar el estado de error para verificar si tiene que mostrar eso o informar algo al usuario.

Por supuesto que estos chequeos pueden agregarse en la interfase gráfica, pero al agregarlos a nivel del programa de linea de comando se facilita que el programa pueda usarse de las dos formas, y en ambos casos emita resultados correctos o errores.

#!/usr/bin/python
import sys

arg = len(sys.argv)
if arg == 1:
print 'Modo de uso: Romanos.py numero_romano'
sys.exit(1)
roma = {'M': 1000, 'D':500, 'C':100, 'L':50, 'X':10, 'V':5, 'I':1}
romano = sys.argv[1].upper()
letras = list(romano)
resultado = 0
anterior = 0
for letra in letras:
if letra in roma:
if roma[letra] > anterior:
resultado = resultado - anterior * 2
resultado = resultado + roma[letra]
else:
resultado = resultado + roma[letra]
anterior = roma[letra]
else:
print 'Letras desconocidas'
sys.exit(2)
print resultado

2 comentarios:

  1. Interesante manera de calcular los números. Solo cambiaría algo:
    La sentencia "resultado = resultado + roma[letra]" se ejecuta dentro del IF y dentro del ELSE. Siendo que en este caso en particular no importaría el cambio de orden yo la pondría antes del IF una sola vez. Luego en caso de ser roma[letra] > anterior podés restar el doble del anterior y no cambia el resultado.

    Saludos.

    ResponderEliminar
  2. Es verdad, gracias por hacerlo notar, es una modificación sencilla que simplifica aún más el código.

    Si en algún momento encuentro alguna forma mejor de postear código en el blog, lo voy a corregir en ese momento.

    ResponderEliminar