Excepciones, helpers y refactoring
¡Bienvenid@s a la quinta entrega de Aprender Python Programando! En el capítulo de hoy, nos vamos a poner más técnicos como verdaderos programadores. Mejoraremos no solo la funcionalidad externa de nuestro programa, sino que además, emplearemos técnicas de refactoring (refactorización) que nos ayuden a mejorar el rendimiento interno del programa.
¡Bienvenid@s a la quinta entrega de Aprender Python Programando!
En el capítulo de hoy, nos vamos a poner más técnicos como verdaderos programadores. Mejoraremos no solo la funcionalidad externa de nuestro programa, sino que además, emplearemos técnicas de refactoring (refactorización) que nos ayuden a mejorar el rendimiento interno del programa.
¿Qué haremos hoy?
- Agregaremos nuevas funcionalidades al programa y mejoraremos otras existentes:
- Haremos que tanto la fecha actual como la de caducidad de nuestro presupuesto, se calculen de forma automática.
- Al finalizar la carga de un presupuesto, tendremos la opción de abrirlo directamente en el navegador para visualizarlo.
- Mejoraremos el funcionamiento de la elección del plan a presupuestar, validando que el dato ingresado sea correcto. De no serlo, se nos volverá a pedir que ingresemos una opción.
- Haremos un refactoring del código, a fin de:
- Hacer nuestro código más legible.
- Lograr que el programa tenga un mejor rendimiento.
- Facilitar el mantenimiento y evolución del sistema.
Ingredientes
Nuestra “receta” del capítulo hoy, necesitará nuevos archivos e incorporará modificaciones. Lo primero que haremos es:
Descargar archivos modificados:
presupuesto.py
Descargar los archivos nuevos:
Si lo deseas, puedes modificar el nombre de la carpeta “capitulo3” por el nombre que desees otorgarle al programa, o dejarlo sin cambios y guardar los siguientes archivos, dentro de ella.
constantes.py
helpers.py
Helpers: una forma de agrupar funciones genéricas
Hemos creado un nuevo archivo: helpers.py. En este archivo, hemos agrupado funciones de uso común, que si bien hoy, son utilizadas por nuestro módulo Presupuesto, al ser funciones genéricas (no son “acciones” propias del objeto presupuesto, sino que aplicarían a cualquier otro objeto), el día de mañana, podríamos utilizarlas en otros módulos de nuestro sistema.
Helper
En la programación, un helper es una forma de agrupar funciones de uso común, destinadas a servir de ayuda a otros procesos.
Un Helper se compone de funciones genéricas que se encargan de realizar acciones complementarias, aplicables a cualquier elemento de un sistema.
Es importante mencionar, que un Helper, pueden ser, tanto funciones “sueltas” como la abstracción de un “objeto helper” (es decir, una clase).
class Helper: def helper_1(self): # algoritmo def helper_2(self): # algoritmo
Es tan (o más) válido que:
def helper_1(self): # algoritmo def helper_2(self): # algoritmo
Por lo tanto, nuestro archivo helpers.py, es un módulo que contiene “ayudantes”, comunes a cualquier otro módulo de nuestro sistema.
Docstrings y la función help() en Python
¿Quieres saber de qué trata el archivo helpers.py?
- Abre una terminal
- Navega hasta el directorio donde tienes almacenados los módulos del sistema
- Ejecuta el intérprete interactivo de python (escribe: python)
- Una vez en el intérprete, escribe:
import helpers help(helpers)
¿Haz visto el resultado? ¡Sorprendente! ¿no es cierto?
Los docstrings, no son algo nuevo. Ya los habíamos visto al comienzo de la guía. Los Docstrings no son más que el comentario de nuestro código. Y si haz probado hacer un help(helpers), habrás podido notar la importancia de comentar nuestro código.
La función help(), al igual int(), raw_input() y tantas otras que hemos visto, es una función nativa de Python, es decir una función interna o función built-in. Si lo deseas, es muy recomendable ver la lista completa de las funciones built-in de Python (en inglés).
help() ha sido diseñada para ejecutarse en modo interactivo. Cuando le es pasado como parámetro, el nombre de un módulo, objeto, clase, método, función, etc., help() devolverá la documentación que hayamos especificado, así como toda información adicional sobre el elemento pasado como parámetro.
Consideraciones para escribir docstrings
Cuando documentes un método o función en Python, deberás escribir los docstrings teniendo en cuenta lo siguiente:
La documentación se escribe entre triple comillas dobles en la misma línea, justo después de la definición def
Correcto:
def mi_funcion(): """Aquí la documentación"""
Incorrecto:
def mi_funcion(): """ Aquí la documentación """
def mi_funcion(): """ Aquí la documentación """
Definitivamente un homicidio que amerita prisión perpetua:
def mi_funcion(): """ Aquí la documentación """
Una buena documentación, debe incluir la acción que realiza, lo que retorna y los parámetros que acepta.
En estos casos, se utilizan docstrings multilínea, siguiendo el próximo esquema:
"""Hace X retorna Y Argumentos: arg1 -- descripción de arg1 arg2 -- descripción de arg2 """
Las especificaciones para los docstrings se encuentran oficialmente documentadas por Python en las PEP 257.
Trabajando con fechas en Python
Una de las modificaciones que incorporamos hoy, consiste en gestionar las fechas de confección y caducidad del presupuesto, en forma automática. Para ello, incorporamos dos helpers:
def get_fecha_actual(): hoy = datetime.datetime.now() fecha_actual = hoy.strftime("%d/%m/%Y") return fecha_actual
y
def sumar_dias(dias=0): fecha = datetime.datetime.now() + datetime.timedelta(days=dias) nueva_fecha = fecha.strftime("%d/%m/%Y") return nueva_fecha
Las fechas, podemos generarlas automáticamente, gracias al módulo datetime de Python:
import datetime
El método now() de datetime, retorna la fecha y hora actual:
hoy = datetime.datetime.now()
La función strftime() convierte la fecha a cadena de texto, con el formato pasado como parámetro:
hoy.strftime("%d/%m/%Y")
Con la función timedelta() podemos calcular fechas, ya sea restando, como sumando, dividiendo o multiplicando N cantidad de días:
fecha = datetime.datetime.now() + datetime.timedelta(days=dias)
El módulo datetime
Este módulo, nativo de Python, nos permite realizar diferentes manejos con fechas.
Para utilizar el módulo debe importarse:
import datetime
Obtener la fecha y hora actual:
datetime.datetime.now()
Sumar, restar, multiplicar o dividir N días a una fecha:
fecha operador_aritmético datetime.datetime.timedelta(days=N)
Donde N debe ser un número entero (representa la cantidad de días a sumar, restar, multiplicar o dividir). Sumar (+), Restar (-), dividir (//), multiplicar (*).
Dar formato a una fecha:
fecha.strftime(string_formato)
Donde string_formato será la cadena de texto que defina el formato deseado, con las directrices indicadas.
Para dar diversos formatos de fechas, las directrices disponibles, son las siguientes:
Refactoring
Hemos realizado algunos cambios a nuestro código, pero que sin embargo, no se reflejan al momento de utilizar el programa.
Refactoring
Refactoring (o refactorización / refactorizar) es una técnica de programación, que consiste en efectuar cambios al código fuente, sin alterar el funcionamiento externo del programa.
¿Qué cambios hemos hecho?
Eliminar de la clase todo aquello que no esté relacionado de forma directa con la lógica propia del objeto. Para ello, recurrimos a:
Refactoring #1: Eliminar la directiva print del módulo presupuesto, moviéndola a un helper.
Refactoring #2: Todos los textos a mostrar en los raw_input(), así como otros mensajes del sistema, fueron movidos a variables de acceso global, definidas en el archivo constantes.py. Es muy importante hacer la salvedad, de que Python, no posee el concepto de constantes como otros lenguajes.
Hablar de constantes en Python, es una cuestión lingüística pero no técnica. A los fines del lenguaje, decir “constante” en Python, simplemente hace referencia a variables cuyo valor, se encuentra predefinido sin necesidad de requerir modificar dinámicamente dichos datos.
Limpiamos el módulo, moviendo un método genérico que podría utilizarse en cualquier otro módulo (no necesariamente Presupuesto). Para ello, recurrimos a:
Refactoring #3: mover el método leer_plantilla() del módulo Presupuesto, a un helper llamado leer_archivo() logrando que éste, pueda ser reutilizado desde cualquier otro módulo.
Tratamiento de excepciones: validando los datos ingresados
Cuando se nos pedía ingresar el código de plan, se nos daban tres opciones: 0, 1 y 2. Pero ¿qué sucedía si por error, en vez de 0, 1 ó 2 ingresábamos otro dato?
Si ingresábamos un dato no numérico, nos generaba un error, al intentar convertirlo de literal a entero con int(). Pero, también podía suceder que se ingresara un número mayor que 2. En ese caso, la conversión a entero no fallaría, pero al momento de intentar acceder al plan elegido mediante self.planes[plan_elegido] nos daría un error, ya que el índice, estaría fuera del rango de la lista.
A fin de evitar estos errores, incorporamos un algoritmo de validación, mediante el tratamiento de excepciones.
Excepciones
Una excepción es un error inesperado que se produce durante la ejecución de un programa.
Las excepciones en Python, cuentan con dos instancias obligatorias: try y except, donde el código contenido en try intentará ejecutarse, y se falla, el error será capturado por except, lanzando otra acción.
try: # intentar esto except: # Si lo anterior falla, capturar el error # y hacer esto otro
Opcionalmente, en Python, pueden agregarse otras dos instancias, pero opcionales: else y finally. Mientras que else, se encarga de ejecutar el código indicado solo si no ha fallado nada, finally, se llamará siempre (falle o no), siendo su finalidad, la de ejecutar “acciones de limpieza”.
def probar_excepciones(): dato = raw_input("Ingresar numero para pasar, letra para fallar: ") try: int(dato) except: print "ejecutando execpt, try ha fallado" else: print "ejecutando else, try se ha logrado" finally: print "finally se ejecuta siempre"
Hecha esta introducción, vayamos a nuestro módulo Presupuesto (líneas 53 a 63):
try: elegir_plan = int(elegir_plan) self.plan = self.planes[elegir_plan]
Intenta convertir a entero el plan elegido en el raw_input() y después, intentará obtener self.planes[elegir_plan] (elegir_plan actúa como número de índice). Pero esta última, solo se llevará a cabo, si la primera, no genera una excepción.
except (ValueError, IndexError): mostrar_texto(DATO_INCORRECTO) self.seleccionar_plan()
Si se genera una excepción, se muestra un mensaje de error y se realiza una llamada recursiva.
Pero ¿Qué hay allí entre paréntesis?
ValueError e IndexError son dos tipos de excepciones. ValueError se produce cuando el valor tratado, no corresponde al tipo de dato esperado (por ejemplo, se ingresa un caracter no numérico). E IndexError es el error lanzado cuando se intenta acceder, por ejemplo, a un ítem inexistente de una lista o tupla, es decir, cuando como número de índice se pasa un valor fuera del rango (es decir, mayor a la cantidad de ítems en la tupla o lista).
Si se desea capturar cualquier excepción, se puede utilizar:
except:
Si se desea capturar únicamente un tipo de excepción, se puede utilizar:
except TipoDeExcepcion:
Si se desean capturar varias excepciones en un mismo paso, se utiliza:
except (TipoExcepcion1, TipoExcepcion2, TipoExcepcion5):
Es posible también, capturar distintas excepciones en varios pa<strongsos:
except TipoExcepcion1: #... except (TipoExcepcion2, TipoExcepcion3): #... except TipoExcepcion4: #...
Una alternativa muy útil, es recoger la descripción del error para poder mostrarla:
except TipoExcepcion, error_capturado: print error_capturado except (TipoExcepcion1, TipoExcepcion2), error_capturado: print error_capturado
Finalmente, ejecutaremos el resto del script, si ninguna excepción ha sido lanzada:
else: datos_servicio = self.lista_precios[self.planes[elegir_plan]] self.servicio = datos_servicio[0] importe = datos_servicio[1] self.importe = float(importe)
Webbrowser: abriendo el navegador desde Python
# Mostrar presupuesto en navegador def mostrar_presupuesto(self, archivo): respuesta = raw_input(MOSTRAR_PRESUPUESTO) if respuesta.lower() == 's': webbrowser.open(BASE_DIR + "/" + archivo)
(líneas 103 a 107)
Con el módulo webbrowser nativo de Python, es posible abrir el navegador y cargar en él, cualquier archivo HTML o dirección Web. Solo basta importar el módulo webbrowser import webbrowser
y cargar la URL mediante webbrowser.open(URL)
Un nuevo desafío
En este capítulo, hemos aprendido dos conceptos fundamentales, indispensables en la vida de cualquier programador experto: la técnica de refactoring y el manejo de excepciones. Y ninguna de las dos, es poca cosa, ni mucho menos, pueden etiquetarse como “básicas”. Los programadores que recién se inician (e incluso, puedo asegurarles que muchos programadores con años de experiencia), no suelen refactorizar el código fuente de sus programas, y son muy pocas las veces que manejan excepciones dentro del código.
La tarea que nos toca hoy, es animarnos a programar como verdaderos profesionales. ¿Cuál es el desafío entonces?
Hacer un refactoring de TODOS los archivos de nuestro sistema
¿Cómo? Muy simple. Python, tiene una serie de recomendaciones para la escritura de código, llamada “Style Guide for Python Code”, definida en la PEP 8 – de la cual hemos hablado sutilmente en capítulos anteriores -. Los verdaderos programadores Python, debemos respetar esta guía de estilos al pie de la letra, ya que hacerlo, nos garantiza que nuestro código pueda ser fácilmente mantenible, legible, evolutivo y por sobre todo, es una forma de respetarnos entre colegas. Escribir código desprolijo o con “estilo propio”, dificulta la lectura. Ergo, hace que entender el código escrito por otro programador, nos lleve más trabajo.
Entonces:
- Lee las PEP 8 (en inglés) o las PEP 7 (disponibles en español)
- Revisa cuidadosamente los archivos constantes.py, helpers.py y sobre todo, presupuesto.py (tiene violaciones a las PEP 8 de forma ex-profesa)
- Haz todas las modificaciones que sean necesarias, para estandarizar el código fuente según las PEP
Si no entiendes algo de las PEP ¡pregúntalo! No te quedes con la duda. Si te aburre, o no te apasiona hacerlo o lo consideras sin sentido, ten en cuenta que hacerlo será fundamental para tu crecimiento profesional. Te lo garantizo!.
Es muy importante que aproveches este reto para trabajar en equipo. Puedes utilizar los comentarios para compartir con otros programadores, las líneas de código que hayas refactorizado, así como también, intercambiar opiniones sobre cómo sería mejor refactorizar tal o cual otra línea. ¡Aprovecha esto para entrenarte! La capacidad para trabajar en equipo, no solo la da la buena predisposición, sino también la práctica y el intercambio con otros programadores. Y ten en cuenta, que a la hora de buscar trabajo, sumará puntos a tus fortalezas.
Lo dije la semana pasada y lo tengo que repetir, esta guía definitivamente gatilló mi comienzo en Python. Han pasado 7 días desde que leí los 4 primeros capítulos y ya tengo una aplicación corriendo en Google App Engine que recolecta información de emergencia a través de RSS, Atom y Web Scraping. También comencé a trabajar con la API de Streaming de Twitter para filtrar y almacenar contenido relevante en tiempo real a una base de datos en Google Cloud SQL… ¡y todo en Python! ¡Gracias Eugenia!
Que belleza de guia, semana a semana la sigo sin perderla, yo aun tengo apps medio arcaicas pero bueno ahi vamos, como semana a semana muchas felicidades por todo este material que nos compartes.
Gracias por compartir…….Sigo aprendiendo dia tras dia semana tras semana con este material…. (*_*)
Genial Felipe! ¿Y tienes pensado liberar el código? Sería fantástico poder compartirlo con la comunidad
Incluso podríamos agregarlo al anexo de co-autores de la guía, qué dices? 😉
Gracias Ellery! ¿Y cómo te ha tratado este capítulo?
Genial Gume!! Y haber como sale ese refactoring 😉
Pues la verdad aun no he hecho la “tarea” de esta entrega pero en cuanto la haga les comento, y yo opino que Felipe libere su codigo…digo :p, cada vez se pone mas complicado, pero ni de loco hubiese entendido nada de lo que se expone en este capitulo y si bien en lo personal me parece un poco complicado este capitulo, me siento mas confiado y tranquilo =). Nuevamente gracias
Estudiaré con calma los archivos…Yo si quiero programas como un profesional….
@Felipe, me interesa mucho lo que estás haciendo de web scrapping de twitter vía google apps. Nos compartes algo del código que estás trabajando para que podamos jugar con él?
Solo alcance a leerla por encima, pero todo me indica que estara buenisima :D.. fijate que precisamente ayer me preguntaba si en Python se podian controlar las excepciones asi como en Java jaja.
Buenisimoo de verdad! graciasss 😀
1 saludo!
Genial Pablo!
Y hay mucho más sobre excepciones
Si quieres, puedes ver más sobre excepciones en la documentación oficial. Aquí hay una traducción al español realizada por la comunidad Python Argentina: http://docs.python.org.ar/tutorial/errors.html 😉
ahh que bueno! muchas gracias
[…] el mantenimiento y evolución del sistema. Pueden acceder mediante este enlace. Etiquetas: Desdelinux, Guia, Maestrosdelweb, manual, Python, […]
Eugenia, tengo otra duda tambien, aunq no tiene que ver con este capitulo.
Me pregunto como puedo hacer interfaces graficas de usuario con Python, si existe algun IDE de arrastrar y soltar (con viseual basic 6.0 o visual basic.net).
Si ivas a comentar esto en capitulos proximas, pues me espero a ello
1 Saludooo y graciass de nuevo por está genial guia 😀
Hola Pablo!
Efectivamente veremos algo de interfaces gráficas más adelante. Mientras tanto, si querés podes ir viendo algo en http://python.org.ar/pyar/InterfacesGraficas
Un abrazo!!
Hola Eugenia, gracias por el otro capitulo del curso, cada vez aprendo mas cosas nuevas 😀
después de este y el anterior capitulo no me va a dar miedo trabajar con archivos y excepciones (siempre los evitaba por no complicarme :/ )
Esta vez dejo el comentario acá y no en google porque voy a dejar la respuesta del reto (espero me halla quedado bien)
El archivo corregido de presupuesto.py seria este http://pastebin.lugmen.org.ar/7005
Los comentarios de las correcciones serian estos http://pastebin.lugmen.org.ar/7006
(los números de linea es basándome en el archivo original)
los puse en pastebin por acá en los comentarios quedaría muy largo, y no puse los otros dos archivos por que las correcciones son muy pocas
Saludos… y otra vez gracias por esta genial guía!!!.. cada vez esta todavía mejor
Geniaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal Rafael!!!!!!!!!!!!!!!!!!!!!!!!!! *suenan trompetas* 😀
EXCELENTE TRABAJO!!!!
hola eugenia aca dejo mis archivos ….. a ver como me fue en este desafio
presupuesto.py
http://pastebin.lugmen.org.ar/7010
helpers.py
http://pastebin.lugmen.org.ar/7011
constantes.py
http://pastebin.lugmen.org.ar/7012
espero tu respuesta con las correcciones, gracias.
tengo una pregunta cuando abro una nueva ventana .. se le pueden pasar parametros como en javascript, que le puedo pasar el ancho, alto, si tiene scroll
Hola José!
Te cuento que hay algunos errores conceptuales sobre la interpretación de las PEP8.
Línea 5: uso de __all__
Aclaro que es largo de explicar, te pido que tengas paciencia 😀
En Python un método o variable puede ser público o privado.
Público significa que puede ser accedido desde cualquier ámbito de la aplicación, mientras que privado, significa que podrá ser accedido solo desde el ámbito donde se haya declarado.
Para indicar que un método, variable (o constante) es de ámbito privado, su nombre debe comenzar por un guión bajo:
_privado = 100
publico = 150
Sin embargo, puede utilizarse un mecanismo para prevenir el uso de elementos de ámbito privado que no hayan sido declarados con un guión bajo al comienzo. Ese mecanismo, es __all__.
__all__ se utiliza de esta manera:
Imaginate el archivo constantes.py
Supone que de todas las constantes allí declaradas, solo quieres permitir el acceso a 3: CONSTANTE_1, CONSTANTE_2 y CONSTANTE_3
Entonces, en el mismo archivo, al principio, utilizarás __all__ para indicar en una lista, esas tres constantes “públicas”:
__all__ = ['CONSTANTE_1', 'CONSTANTE_2', 'CONSTANTE_3']
CONSTANTE_1 = 100
CONSTANTE_2 = 150
CONSTANTE_3 = 400
CONSTANTE_4 = 500
A CONSTANTE_4 no podrá accederse fuera del archivo constantes.py, pues con el mecanismo __all__ la haz exceptuado.
Cuando tu colocas from constantes import __all__, estás llamando a una constante llamada __all__ que no solo no existe, sino que además, tampoco podrías crearla ya que es un nombre reservado.
Modificación de nombre de constantes (archivo constantes.py)
La convención para nombres de constantes en las PEP 8, se indica de la siguiente manera:
Constants
Constants are usually defined on a module level and written in all
capital letters with underscores separating words. Examples include
MAX_OVERFLOW and TOTAL.
“written in all capital letters with underscores separating words” escritas en letras mayúsculas con guiones (guiones bajos) separando las palabras.
Las constantes DEBEN ir en mayúsculas y no en minúsculas.
Docstrings (archivo helpers.py)
Las PEP 8, se refieren a los docstrings diciendo:
Write docstrings for all public modules, functions, classes, and
methods. Docstrings are not necessary for non-public methods, but you
should have a comment that describes what the method does. This comment
should appear after the “def” line.
La última oración del párrafo dice claramente:
“This comment should appear after the “def” line.” Este comentario debería aparecer después de la línea “def”.
La PEP 257, que es donde se encuentran “inmortalizadas” las convenciones para los docstrings, muestra un ejemplo claro de como realizar comentarios multilínea en este enlace: http://www.python.org/dev/peps/pep-0257/#multi-line-docstrings
Si hay algo que no haya quedado colgado, no te quedes con la duda y preguntame!!
Un abrazo!
PD: fíjate el comentario anterior de Rafael Laverde para comprar el código si decides hacerle otro refactoring. E insisto: si te quedan dudas, preguntame!!
¿Te refieres a cuando abres una ventana del navegador? En ese caso, nope
hola eugenia, gracias por las aclaraciones, pero ahi un error en la pagina donde explican las PEP7 copio el texto “Escribe docstrings para todos los módulos, functiones, clases, y métodos públicos. Los docstrings no son necesarios para métodos no públicos, pero deberías tener un comentario que describa lo que hace el método. Este comentario debería aparecer antes de la línea “def”.”
Y la sexta entrega??????? He refactorizado todo mis codigos…Este fue el reto mas grande y mas dificil..MIL GRACIASSSSSS…
Hola a todos, disculpen un poco tarde mi tarea pero la hice (aunque me llevo un poco de tiempo leer las reglas que se deben aplicar al momento de esquematizar los programas)
***
presupuesto.py
http://pastebin.com/PxK4aUuq
helpers.py
http://pastebin.com/EFHnmep7
constantes.py
http://pastebin.com/Gu0QsvQW
***
Si fallo en algo les agradeceré me lo digan….. ahora a seguir….
Hola Eugenia, yo agarre esto ayer recién.! y la verdad que es impresionante lo fácil y tan potente que este Python, había escuchado hablar de él, pero lo veía como algo imposible la verdad. Antes que nada muchas gracias por estos capítulos que la verdad que aprendí mucho, muy bien y en poco tiempo.
Mi pregunta es si ya salio otra mas ademas de este capitulo.. o vamos por aca??
Nueva mente muchas gracias y muchos Exitos.!
uy! José! Menos mal que avisas!
La verdad es que leí la traducción por arriba y de haber visto tamaño error, no las hubiese colocado como referencia.
Voy a tratar de hacer una traducción de las PEP8 para colocarla en la guía
Bien Gume!!!
La sexta entrega saldrá el próximo martes. Por motivos personales, no pude tenerla lista para ayer.
Excelente drick! Solo esto:
presupuesto.py líneas 49 y 79: deben ir espacios antes y después del operador
helpers.py línea 8: luego del import dos líneas en blanco (hay una sola, pero no es para nada grave)
Hola Adrián! En el transcurso de la tarde-noche de hoy seguramente ya se publicará el sexto capítulo
Gracias nuevamente Eugenia, por tan buen material. Además, debo agradecerte también porque gracias a ti el día de hoy he aumentado un grado en mi cultura general, ya que el nombre de tú máquina me ha llamado la atención y decidí buscarlo en la red, ahora ya sé lo que es un cocochito XD.
¡Saludos!
Ansioso de ver lo que viene en la sexta entrega…
¡Santos Dios! No puedo esperar más por el sexto capítulo estoy que reviento de la desesperación jejeje.
La verdad es que esta ha sido una de las mejores guías que he leído, no sabia nada de python y ahora se puede decir que puedo hacer mi primer algoritmo de complejidad media
Gracias Eugenia, es para mi un gusto aprender un lenguaje de programación por parte de una fémina.
Hola Eugenia tienes razón, se me fue por alto lo de los espacios en los signos, y lo la línea en blanco.. bueno ya lo corregí……
presupuesto.py
http://pastebin.com/G3y5r1yP
helpers.py
http://pastebin.com/hmxSxmMD
Gracias por la corrección….
Uff he trabajado con archivos en c++ pero este es un nuevo nivel para trabajar con ellos todo lo que me han enseñado se a quedado corto Gracias por la enseñanza esta clase si la estudiare bien toda la semana porque si esta bueno y vamos a ver el final como terminamos porque si es una gran ayuda y espero que al final del curso ya pueda hacer una mi aplicacion profesional.
He diseñado varios programas que si me han llevado tiempo pero esto es otr onivel entonces a hecharle ganas jejeejeje espero que entre de ocho entender todas las lineas de codigo del programa,
[…] capítulo: Excepciones, helpers y refactoring → […]
yo lo que he cambiado es también la linea donde pone:
# Mostrar presupuesto en navegador
def mostrar_presupuesto(self, archivo):
respuesta = raw_input(MOSTRAR_PRESUPUESTO)
if respuesta.lower() == ‘s’:
webbrowser.open(BASE_DIR + “/” + archivo)
he cambiado la palabra “archivo” por la palabra “filename” porque sino salia un error y no abria la pagina html
Hola Euge.
Sigo trabajando en ello. Muchas gracias por tú dedicación y empeño.
Saludos desde España, Andalucía, Granada. Te invito a que vengas de vacaciones cuando quieras =)
Saludos…
[…] Excepciones, Helpers y Refactoring http://www.maestrosdelweb.com/editorial/guia-python-excepciones-helpers-refactoring/ […]