Mis errores de principiante al programar

PeliPepper me preguntaba qué errores de principiante uno puede cometer cuando es un programador inexperto. Como estudiante de primero de carrera que se ha de enfrentar a Pascal, llegó hasta el blog, comentó una entrada y su pregunta me ha empujado a escribir esta nueva.
La he estructurado pensando en las cuatro etapas fundamentales de desarrollo (análisis, diseño, programación y depuración) y también he incluido algunos tips extra que no se encuadran en una fase en concreto o que tendrían cabida a lo largo de varias.
¡Ah! Y si tú también eres programador, por favor, comenta este post y cuéntanos tu experiencia o los errores de principiante que hayas cometido 🙂

Errores en el análisis del problema
– No ceñirse las especificaciones del problema
Es increíble la cantidad de veces que la gente empieza a programar algo a lo loco sin fijarse primero en que entienden a la perfección lo que le piden. Saber qué hay que hacer es lo más importante antes de teclear un solo “begin”.
Si se trata de un ejercicio o práctica para el instituto/universidad, lo mejor es leer el enunciado atentamente y en profundidad e ir anotando todos los casos especiales, no definidos o vagamente mencionados en él. Luego habrá que recabar más información y preguntar al profesor.
Una vez que entendemos y tenemos bien definidas las especificaciones, es importante ceñirse a ellas, no irse por los cerros de Úbeda. No se ha de añadir, cambiar o quitar funcionalidades, ni programar con vistas a algo que no haya sido pedido.
Quizás la explicación a que la gente se ponga a programar sin entender lo que han de hacer sea ésta noticia que acaba de aparecer en los medios (y que también explica cómo alguien se atreve a decir cosas así).

Errores en el diseño de la solución
– No definir objetivos y/o etapas del desarrollo y limites de tiempo
Es importante el concepto de objetivo, etapa y límite para organizarse. Una vez que hemos comprendido el problema en toda su magnitud, hay que hacer una especie de “roadmap” en el que a cada objetivo se le asigne una fecha límite.
Estos objetivos tienen que estar organizados por etapas, es decir, relacionados entre sí. Por ejemplo, la primera etapa de todas sería conseguir el diseño del programa: decidir cómo se va a hacer. Poner una fecha límite para las decisiones que tomemos a nivel abstracto, a partir de la cual no sean alterables (o al menos no en la metodología en cascada clásica) puede beneficiarnos porque a partir de ese momento se acata el diseño y simplemente resta traducirlo a código (en el lenguaje que sea).

– Hacer muchos cambios que desvirtúen la funcionalidad principal del programa
Quizás esto sucede más cuando uno trabaja por su cuenta, para un cliente, o siguiendo otras metodologías. A veces mientras se diseña una solución se llega a algún tipo de encrucijada, y un camino fácil puede ser alterar alguna característica del programa para que nos salve nuestro escollo. Como daño colateral, estaríamos desvirtuando el problema y esto a gran escala puede tener unas implicaciones demasiado graves.

Errores durante la programación
– No dividir el problema en partes más simples que podamos abordar por separado
Esto es fundamental. Siempre que programemos tenemos que pensar en hacer algoritmos. Y los algoritmos, por definición, son los pasos con los que se consigue un objetivo. Esos pasos han de estar a su vez subdivididos en algoritmos más pequeños. Por ejemplo:
Algoritmo para hacer cafe:
1. Preparar la cafetera
2. Poner al fuego
3. Servir cuando este listo
A su vez podemos hacer descomposiciones de estos:
1. Preparar la cafetera:
— 1.1 Abrir cafetera
— 1.2 Abrir paquete de cafe
— 1.3 Poner X gramos de café en el compartimento de cafe de la cafetera

Llegará un momento en que nuestro algoritmo contenga muchos pasos, pero todos serán operaciones “atómicas” o suficientemente sencillas como para programarlas sin dificultad.

– No hacer sucesivos refinamientos del código
Una vez que tenemos un código que funciona y cumple perfectamente la especificación, debemos preocuparnos también de optimizarlo. Que funcione no quiere decir que funcione bien. Hay que optimizar su velocidad y tener previsto cualquier error que pueda surgir. El control de errores marca la diferencia entre algo programado con un nivel aceptable y algo exhaustivamente programado, así que una vez que tengas tu prototipo, búscale las cosquillas.

– No comentar o comentar en exceso el código fuente
Se supone que el código fuente está escrito por programadores y para programadores, así que las operaciones sencillas no necesitan ser explicadas: tanto si lo leemos nosotros como otra persona, serán operaciones que se dan por entendidas de antemano.
Los fragmentos más grandes de código, sin embargo, sí que pueden necesitar ciertas aclaraciones. Por ejemplo, antes de escribir una función, podemos aclarar su objetivo, qué condiciones espera que se cumplan antes de ejecutarse y qué asegura que se cumple cuando termina.
Tampoco está de más el introducir líneas de comentarios sin texto, pero que sirvan para delimitar partes de un fichero, por ejemplo, una líńea como:
// -------------------
Puede ayudar a separar unas funciones que están muy directamente relacionadas entre sí, de otras que no lo están tanto.

– No distribuir el código
Es prácticamente obligatorio el saber trabajar con código muy cohesionado y poco acoplado. Así que es conveniente saber crear módulos/units/clases. En el caso de la programación orientada a objetos, esto es casi obligatorio y también mucho más intuitivo.

– No tabular el código correctamente
Sangrar el texto ayuda a visualizar fácilmente qué instrucciones se encuentran dentro de una sentencia mayor. Por ejemplo, las sentencias dentro de un “if” o de un bucle. De nuevo, el motivo principal es facilitar la lectura del código. Aunque por lo general no sea necesario hacerlo, existen lenguajes que también utilizan el sangrado como forma sintáctica (por ejemplo, Python).

– No escribir los símbolos o identificadores de aperturas y cierres a la vez
Si no te acostumbras a escribir la llave de cierre “}” despues de cada llave que abras “{“, entonces estás en serios apuros. Lo mismo para las parejas de “begin” y “end” o similares. A pesar de que los editores de código modernos se encargan de hacerlo por tí, necesitas acostumbrarte a hacerlo. También debes recordar que si estás trabajando en un lenguaje donde las sentencias terminan en punto y coma, has de acostumbrarte a escribirlo. La mayoría de veces que corriges errores en tiempo de compilación, son cagadas de este tipo.

– No respetar las convenciones de uso de Mayúsuclas, minúsculas, etc.
Por los mismos motivos que en casos anteriores: tu código debe ser legible y existen ciertas costumbres comunes a todo programador que ayudan a trabajar con código ajeno más ágilmente.

– No usar nombres de variables relevantes
Este error es muy común pero a la vez muy grave. Será muy complicado que alguien sepa a que te refieres cuando tus variables se llaman “a”, “n”, “i”.
Está mucho mejor darles identificadores que se asemejen a como nos referiríamos a ellas en lenguaje natural:
“articulo”, “cliente”, etc.

– Borrar en lugar de comentar
A veces uno quiere hacer una sustitución de un pequeño pedazo de código, para ver si los cambios introducidos surten efecto, probar una nueva variante, comparar rendimiento de una alternativa…
Nunca borres el código que sabes que funciona bien. Enciérralo en comentarios para hacer tus pruebas; así será fácil volver a un punto seguro si de repente todo falla.

Errores en la depuración
– No diseñar y pasar pruebas
Además de las pruebas simples que uno hace para verificar el funcionamiento de un código, hay que diseñar pruebas complejas que lleven a nuestro programa a su límite. Tan importante es esto que hay una metodología de desarrollo guiada por tests que el programa debe ir cumpliendo para verificar su validez.

– No habituarse a utilizar los depuradores
Un buen programador sabrá utilizar el debugger para encontrar ese esquivo error que aparece en tiempo de ejecución. No son las herramientas más atractivas, pero son fundamentales.

Otros errores
– No utilizar las herramientas adecuadas
Me refiero a no estar utilizando un buen editor, o incluso un entorno integrado (IDE) si es posible.
Es cierto que al principio no necesitaremos nada más que un editor de texto plano (gEdit, notepad, emacs, vi, pico, nano, y un larguísimo etcétera) pero cuando queramos afrontar programas de cierta complejidad tendremos que utilizar las herramientas que nos faciliten el trabajo lo máximo posible. En Java, por ejemplo, están NetBeans y Eclipse, que son los dos entornos más comunes para trabajar. Se encargan de resaltar el código, completarlo, ofrecer documentación, detectar errores, compilar, ejecutar, …
Trabajar con ellos es una ventaja frente a los editores clásicos, así que no está de más intentar acostumbrarse. También será positivo conocer algún sistema de control de versiones (por ejemplo, Subversion o git).
Lo mismo podríamos decir acerca del hardware del equipo: necesitas un teclado en el que puedas escribir rápido, donde las combinaciones de teclas sean de tu agrado y que no te provoque dolor tras largas sesiones de escritura. Siempre pongo el símil de que probablemente un carpintero no utilice martillos de 3 €. Probablemente su martillo cueste 50 €, pero es su herramienta de trabajo y uno tiene que tener ciertos estándares de calidad mínima para no estar peleándose con la herramienta y poder centrarse en trabajar de forma productiva. Tamaño y resolución de pantalla, sistema operativo, … busca siempre tu productividad, no pierdas el tiempo en cosas que no deberías. En definitiva: compórtate como un verdadero profesional.

– No hacer ejercicios simples que aportan soltura a la hora de escribir buen código
Tal vez hoy no tengas que programar nada. Pero eso no quiere decir que no debas. Estar siempre en activo te ayudará a mejorar continuamente, sobretodo si haces tareas especificas como practicar sintaxis, conocer una librería, etc.

– No almacenar los “snippets” de código que sean útiles, reutilizables y correctos
Si tienes algo que funciona bien y en lo que has invertido el tiempo suficiente como para obtener un resultado que merezca la pena, entonces guárdalo a buen recaudo. Existen programas que te permiten guardar fragmentos de código, categorizarlos y etiquetarlos para encontrarlos rápidamente y poder recurrir a ellos de forma inmediata siempre que los necesites. Los mejores hasta incluyen ya una pequeña biblioteca con contenidos genéricos muy útiles.

– Permitir que alguien altere nuestro código y luego no revisar, estudiar y comprender los cambios/mejoras introducidos, y cómo afectan al funcionamiento interno de la aplicación
Es evidente porqué esto es un error: no nos ayudará en absoluto a aprender a programar e incluso nos puede conducir a algún aprieto si en algún momento tenemos que defender un código que no hemos escrito, no comprendemos/recordamos su funcionamiento o que no está escrito como debiera. ¡Y eso ya es dando por supuesto que funciona bien!

En definitiva, programar bien es una tarea que requiere mucha práctica pero que, como he descrito en algunos de los ejemplos anteriores, puede ser más sencilla si contamos con herramientas apropiadas y adoptamos algunas “buenas prácticas”.
Según tu experiencia encontrarás más útiles unos u otros consejos. Por ejemplo en el caso de un estudiante de primero de carrera, quizás los más interesantes sean los consejos de programación “pura y dura” mientras que uno de segundo quizás ya pueda preocuparse del análisis y el diseño.

La mayoría de lo que he repasado está también en dos entradas que escribí hace tiempo sobre escribir buen código (1 y 2), así como en mi respuesta al comentario de PeliPepper.
Esta entrada ha tardado algo más de lo normal en llegar (definitivamente más de lo que había previsto) pero creo que ha quedado lo suficientemente completa como para publicarla ahora, y me gustaría que siguiese viva a través de vuestros comentarios.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s