viernes, marzo 23, 2007

Python morphing o Pythonizando programas


Estoy llevando una clase de programación orientada a objetos con python, y bueno al igual que en muchos otros lenguajes, se nos esta pidiendo que procuremos aprovechar las ventajas o el poder de python; se usa el termino pythonizar para entender que usando las caracteristicas propias del lenguaje podemos ahorrar pasos y hacer las cosas mas rapido.


Yo no comparto para nada esa idea, sin embargo me parece muy interesante el fenómeno que se observa al pythonizar.


Ejemplo: Tenemos un programa que calcula la diferencia en dias, entre dos fechas. Lo que hago es cambiar la fecha a dias, para hacer la resta. Mi estrategia es un poco rudimentaria, cambiar la fecha de formato dd/mm/aaaa al formato aaaammdd. Luego para calcular los dias multiplico aaaa por 365 el mes hago la suma de dias correspondientes hasta el mes actual menos uno y a continuación le sumo el dia. Por ultimo calculo los años bisiestos y le agrego un dia por cada uno. El programa queda como sigue.





dias_mes = [31,28,31,30,31,30,31,31,30,31,30,31]

def calcDias(fecha):
year = int(fecha[1:4])
_mes = int(fecha[4:6])-1
mes = 0
for i in range(_mes):
mes += dias_mes[i];

dias = year * 365 + mes + int(fecha[6:8])


for i in range(year):
if i % 4 == 0:
dias = dias + 1

return dias

#fec1 = raw_input("Fecha1:")
fec1 = "01/01/2007"
#fec2 = raw_input("Fecha2:")
fec2 = "15/03/2007"

def dateToSAAAAMMDD(fecha):
return fecha[6:10] + fecha[3:5] + fecha[0:2]


f1 = dateToSAAAAMMDD(fec1)
f2 = dateToSAAAAMMDD(fec2)

print "Entre " + fec1 + "y " + fec2 + "hay " + str(calcDias(f2) - calcDias(f1)) + "dias"



Esta solución es al mas puro estilo del programador cavernícola, que todo lo quiere resolver desde cero y por si mismo, aunque redescubra el hilo negro (asi como yo). Sin embargo, buscando un poco en nivel de ayuda, nos encontramos con una funcion llamada toordinal() que forma parte de la case date, la cual pasa la fecha a dias en el calendario gregoriano. Con ella el programa se comprime considerablemente.





#fec1 = raw_input("Fecha1:")
fec1 = "01/01/2007"
#fec2 = raw_input("Fecha2:")
fec2 = "15/03/2007"

def strToDate(fecha):
return date(int(fecha[6:10]) , int(fecha[3:5]) , int(fecha[0:2]))

f1 = strToDate(fec1)
f2 = strToDate(fec2)

print "Entre " + fec1 + "y " + fec2 + "hay " + str(f2.toordinal() - f1.toordinal()) + "dias"



En fin, esto lo podemos hacer en la mayoria de los lenguajes que consideramos "decentes", y no necesariamente es una ventaja. Además de que con un sencillo "refactoring" tal vez lleguemos a una solucion mas elegante, visible, o porque no decirlo, artistica. Como dice Kernighan en "La práctica de la programación" un programa debe estar tan bien escrito que debe dar gusto leerlo. Para este caso, en aplicaciones mas complejas el ahorro de cientos de lineas de código puede tener un impacto considerable en el desempeño de los programas. Eso es innegable.






Technorati : , , ,

No hay comentarios.:

Publicar un comentario