Category Archives: Uncategorized

Ejemplo de proyecto en Python con OO y recomendaciones

El siguiente post contiene un ejemplo de desarrollo de un pequeño proyecto con Python. Este proyecto hace uso de algunos de los elementos de la orientación a objetos en Python, asi como de algunas recomendaciones en el desarrollo con Python.

Que cocinamos

Un pequeño proyecto con Python que incluye lo siguiente:

  • Clases
  • Módulos
  • Paquetes
  • Ficheros de log
  • Tests
  • Documentación autogenerada

El proyecto se puede descargar integro desde https://github.com/luisalbertogh/oopython.git.

Ingredientes

Los requisitos para este proyecto son los siguientes:

Paso a paso

Creamos una estrcutura para el proyecto con el siguiente diseño:

<proyecto>

|__ <config> [ficheros de configuración]

|__ <doc> [documentación]

|__ <proyecto> [código fuente]

|__ <test> [tests de unidad e integración]

Vease el conteido del proyecto a modo de ejemplo.

Código fuente

El código se estructura de la siguiente manera (de más básico a más complejo):

1. Creamos un módulo base que contiene una serie de clases que incluyen nuestro modelo y nuestra lógica de negocio [oopython\mypackage\module01.py]. Aquí encontramos:

Superclases

Clases con diferente tipos de métodos (estáticos, constructores (__init__), sobrecargados (métodos especiales que empiezan con __. etc))

Lazy properties, setters y getters

Clases estratégicas (sin estado, sólo lógica)

2. Incluimos este módulo en un paquete. Esto no es necesario en Python pero puede ser una buena recomendación para modular un poco más y aportar un nivel adicional de granularidad al código desarrollado. Los paquetes estarían compuestos por módulos y estos se podrían usar desde otros módulos y/o paquetes.

Para esto, simplemente creamos el directorio oopython\mypackage, incluimos el módulo recien creado dentro y añadimos un fichero __init__.py. Adicionalmente podemos incluir en el fichero __init__.py otros módulos o paquetes externos o indicar que módulos internos queremos habilitar desde el paquete, de tal manera que sea más sencillo invocarlos cuando se usen desde otros módulos externos. Si añadimos lo siguiente:

Podremos usar el contenido del paquete mypackage desde otros módulos externos simplemente haciendo:

De otra manera tendriamos que especificar el módulo, etc.

3. Creamos un nuevo módulo [oopython\oopython.py] que haga uso del paquete anteriormente creado.

Ficheros de log

Para disponer de una serie de loggers que permitan crear ficheros de log e imprimir mensajes por pantalla, usamos paquetes estandar de logging de Python y YAML como lenguaje para los ficheros de configuración de los mismos.

En caso de que YAML no esté instalado, usar:

En el módulo principal incluimos el siguiente código:

El fichero de configuracion de los logs se encuentra en la ruta config/log_config.yaml. Contiene los valores necesarios para crear differentes tipos de loggers, configurar salidas por consola, formato de los logs, etc.

Tests

Tal y como ocurre en otros lenguajes de programación, aqui también podemos crear tests de unidad y de integración que se ejecuten de forma automática dentro de un proceso de integración continua.

En un directorio separado dentro del proyecto llamado test, creamos diferentes ficheros (módulos) con diferentes grupos de tests. Cada módulo podría ser considerado como un test suite diferente, por ejemplo.

Dentro de cada módulo incluimos diferentes tests unitarios usando el módulo de Python para implementar tests de unidad:

Para que los tests puedan hacer uso de los módulos y paquetes internos del proyecto, se setea la ruta principal del proyecto relativa al test:

Los tests unitarios son métodos del siguiente TestCase:

Los test unitarios se cargan en un único test suite:

Y se ejcutan:

Una manera sencilla de lanzar todos (o los seleccionados) tests es usando el siguiente comando:

Se indica el uso del módulo de testeo de Python y se le indica que ejecute todos los tests unitarios que encuentre en el directorio test correspondiente. También se pueden lanzar como un scrupt de Python sin más.

Generación automática de documentación

La generación automática está basada en el uso de la herramienta Sphinx, que es una de las más extendidas. Los pasos para ejecutarla son basicamente los siguientes:

Instalar Sphinx

http://www.sphinx-doc.org/en/stable/install.html

Ejecutar Sphinx quickstart

Se recomienda seguir este tutorial para concer las opciones más relevantes de este comando. Es importante activar la generación automática de documentación si queremos que la herramienta convierta los comentarios incluidos en el código en Python como texto dentro de la documentación.

http://www.sphinx-doc.org/en/stable/tutorial.html

Revisar valores en conf.py

Antes de lanzar la generación automática de documentación conviene revisar el fichero de configuración autogenerado por el paso anterior. Éste se encuentra en oopython\doc\source\conf.py.

Una de las modificaciones que tenemos que aplicar al fichero recien creado es indicar la ruta en la que se encuentra el código de Python para que los pasos siguientes puedan autogenerar documentación:

De esta manera se añade a la ruta en la que Python busca los módulos y paquetes la ruta que contiene nuestro código.

Sphinx apidoc

Nos permite de forma automática generar los ficheros RST que se usaran para dar formato a la páginas de la documentación que se incluirá asi como su contenido. Normalmente se creara un fichero RST por módulo/paquete y se añadirá información sobre las clases y miembros.

Más información aqui: http://scriptsonscripts.blogspot.com.es/2012/09/quick-sphinx-documentation-for-python.html

El comando de ejecución sería el siguiente. doc/source sería el directorio en el que se generarán los RST y oopython el directorio que contiene el código fuente en Python.

Crear la documentación

Se lanza el siguiente comando:

Y se genera el formato de salida deseado, en este caso en HTML:

 

Simple, Seguro y Elegante

¡FELIZ 2015! (Un poco tarde…)

Tras un tiempo sin añadir posts a nuestro blog retomamos la actividad. Empezamos deseando un feliz 2015. Este post además es un tanto especial, ya que no esta relacionado con ningun tema técnico en particular, si no que es más bien una reflexión personal acerca de como deberían ser, desde mi humilde punto de vista, los desarrollos de software, y en particular el producto o el código generado a partir de ellos.

Creo que no voy a redescubrir la rueda con esto, pero simplemente quiero afirmarme y afianzarme en unas creencias que toman cada vez más sentido para mi. Cuanto más trabajo como desarrollador y en más proyectos y trabajos estoy, más me convezco de la necesidad de inculcar a todas las personas involucradas en un desarrollo de estas ideas que para mi han de ser una máxima en dicho desarrollo. Han de ser intocables, seguirse al pie de la letra y respetarlas por encima de todo, de cualquier incertidumbre, problema o alteración interna o externa que pueda sufrir el proyecto. Es decir, no importa lo nos venga impuesto, estas ideas han de respetarse POR ENCIMA DE TODO.

Este POR ENCIMA DE TODO no es un capricho. No se trata de imponer nuestro pensamiento. Se trata simple y llanamete de HACER LAS COSAS BIEN. Esto que parece una obviedad, en ocasiones puede parecer más bien lo raro, lo escaso. Por diferentes causas, las cosas no se hacen todo lo bien que se deberian hacer. Para mi estas causas no son más que excusas. Como he dicho antes, no existe nada, absolutamente nada dentro de un proyecto, que nos impida hacer las cosas como es debido. No puede haber nada más importante que hacer las cosas de forma correcta. Es preferible gastar más dinero, invertir más tiempo y retrasar los proyectos lo que haga falta, antes que hacer las cosas mal.

Porque a la larga, el hacer las cosas bien es un beneficio para TODOS. Es una situacion win-win, ganamos todos. Los que usan los productos, los que los mantienen, los que los venden, los que los desarrollan, etc. En cambio hacer las cosas mal no es más que una fuente de problemas continuos, disgustos, desgastes, errores, etc.

Bien, ya explayado todo esto, para mi, ¿qué es hacer las cosas bien? Pues algo muy pero que muy sencillo (o no, no lo sé). Basicamente se trata de aplicar lo que son para mi las tres máximas de cualquier desarrollo: que sea SIMPLE, SEGURO y ELEGANTE. ¿Y qué es lo que significa esto? Pues para mi significa lo siguiente:

SIMPLE – Keep it simple!

En la simplicidad esta la belleza. Cualquiera (o eso creo) puede entender este concepto. La mayoria de las ciencias buscan la simplicidad en sus soluciones. Un matemático o un físico pueden resolver un problema muy complejo de múltilples formas, pero si lo hacen de una forma simple y elegante, entonces es el culmen de la resolución.

Resolver un problema, o implementar su solucion, es lo que normalmente hacemos en un desarrollo de software. El problema es la funcionalidad que queremos implementar, con todas sus casuisticas y alternativas. Y se puede implementar de mil maneras. Hacer de forma sencilla, simple, que cualquiera de un solo vistazo entienda como funciona de forma interna, que todas sus partes esten bien diferenciadas, que no haya subterfugios ni trucos ni parches ni malas prácticas. Eso es hacerlo simple. Que si podemos usar una clase en vez de tres lo hagamos, pero que si en esa clase vamos a generar un espagueti-codigo inmantenible, entonces es preferible tener las tres clases.

Por norma general, el uso de buenas prácticas de desarrollo, de patrones, de frameworks de trabajo bien conocidos, de metodologias altamente aplicadas, etc. nos ayudará y nos encaminará hacia esto.

SEGURO

Con el concepto de SEGURIDAD no me refiero tan solo a “Seguridad informática”. Me refiero a ésta. pero sobre todo me refiero a SEGURIDAD en la correcta ejecución del software.

Esta claro que la seguridad informática es importante, y en los tiempos que vivimos y viviremos, cada día mas crucial. Es importante tenerla en cuenta para minimizar cualquier riesgo. Aplicar dicha seguridad dependerá mucho del tipo de software que estemos desarrollando y de los riesgos que conlleve su uso. No es lo mismo una aplicación de escritorio que solo se va a usar en un equipo informático, que una aplicación web conectada a Internet y donde cualquiera puede acceder. Usar los protocolos de seguridad, criterios recomendades y tecnologias asociadas nos garantiza un minimo de seguridad. Esta claro que este es un tema delicado y que siempre existiran agujeros por los que un buen hacker se pueda colar, pero lo importante es que al menos el 90% de ellos no tenga los conociemientos necesarios para hacerlo.

La otra “seguridad” es quizas más importante para mí, porque afecta por igual a cualquier tipo de aplicación y no es tan obvia de aplicar. Es el hecho de intentar desarrollar pensando en que cualquier error o problema puede surgir dentro de la aplicación y el objetivo es intentar minimizar el impacto que puedan tener esos errores. Pueden darse problemas que causen perdidad de conexiones, conexiones mal cerradas, descriptores abiertos, hilos huérfanos, procesos sin finalizar, etc. Y estas causas puede derivar en problemas más serios que paralicen el completo funcionamiento del software desarrollado y que impacten en el hardware y otras aplicaciones. Desarrollar intentando preveer todos estos problemas es complicado, pero no está demás ponernos siempre en lo peor e intenar proteger al máximo situaciones en las que, un posible error cause que no se liberen recursos o no se finalicen procesos de forma correcta. De esta manera, aunque se de el error, la aplicación podra seguir operando de forma óptima y no causará mayores daños.

Igualmente, aplicar mecanismos tradicionales como capturas de excepciones y uso de frameworks bien conocidos, nos ayudará a hacer las aplicaciones más seguras en este sentido.

ELEGANTE

Este puede ser un concepto dificil de interpretar pero que es igual de importante que los anteriores. Puede incluso llegar a chocar con el concepto de SIMPLICIDAD en cierto modo, pero es igual de importante, por lo que al final se tendrá que buscar un equilibrio entre la SIMPLICIDAD y la ELEGANCIA, que por otro lado sulen ir de la mano, ya que lo simple puede ser elegante y la elegancia ayuda a la simplicidad.

Cuando pienso en este concepto, no me refiero a un tema estético, que también, si no a aplicar soluciones a la resolución de problemas que sean “elegantes”. Explicando el concepto de SIMPLICIDAD comenté que no es lo mismo soucionar un problema de una manera compleja, con multiples subterfugios y condiciones, que de una forma simple, que facilite la comprensión de la solución y su mantenimiento. Con la elegancia pasa lo mismo. No es igual resolver el problema usando múltiples funciones, parámetros y elementos, que resolverlo con un solo elemento y una sencilla función.

De ahi que el concepto de ELEGANTE esté relacionado con la SIMPLICIDAD, lo simple suele ser elegante, porque se limita a hacer las cosas sencillas y eso deriva en una resolución del problema clara y limpia. No tiene porque ser siempre asi, una solución sencilla puede estar repleta de elementos, cosa que no sería elegante. Y la elegancia suele derivar en simplicidad, ya que una solución con pocos elementos y bien estructurados suele derivar en una solución sencilla de comprender y mantener, aunque igualmente en este caso no tiene porque ser siempre así. Un problema complejo resuelto mediante una solución elegante puede llevar una síntesis de su solución tan compleja que el resultado, aunque de pocos elementos, pueda ser altamente complejo, con estructuras de datos y funciones con multiples variantes, aunque comprimidas en unas pocas lineas de código.

Por lo general, como se ha mencionado antes, habra que buscar un equilibrio entre la SIMPLICIDAD y la ELEGANCIA, para que la solución sea lo más simple posible, pero con la mayor elegancia disponible. Si a eso le añadimos el hecho de que esa SIMPLICIDAD y ELEGANCIA conllevarán sin duda una mayor SEGURIDAD, tendremos la mezcla perfecta para nuestro coctel.

CONCLUSIÓN

El desarrollo de software, al igual que otras labores en otras profesiones más o menos metódicas, requiere de unas formas de trabajo depuradas que faciliten el mismo. Además en este caso, la importancia cada vez mayor de esta labor asi como sus demandas requieren de unas metodologías cada vez más estrictas pero flexibles a la vez.

Independientemente de la forma en la que se trabaje, creo necesario respetar unos principios que han de conservarse bajo cualquier concepto, para asegurar el éxito en esta labor. No solo depende que el producto desarrollado sea bueno, si no que sea útil, que ayude a resolver los problemas y proporcione los servicios para los que ha sido creado, y que facilite la vida tanto a sus usuarios como a sus creadores y a las personas que los mantienen.

Los conceptos fundamentales para mí han de ser la SIMPLICIDAD, o aplicar la solución más sencilla, la SEGURIDAD, o minimizar los riesgos al máximo aunque se den errores, que se darán, y la ELEGANCIA, o aplicar la solución más elegante, más flexible, reducida y práctica.

No es fácil aplicar estos conceptos. Algunos de ellos incluso pueden chocar, como es el caso de la SIMPLICIDAD y la ELEGANCIA. Pero usando buenas prácticas, frameworks y técnicas bien conocidas se podrá conseguir una buena aproximación a ellas, redundando con total seguridad en un gran beneficio para todos.

Un saludo