GUÍA PARA ESCRIBIR PROGRAMAS ÚTILES Autor: Keith Gregson Traducción: Alfredo Carrillo Es motivo de mucha investigación el encontrar estrategias para la producción de software preciso y confiable. Sin embargo, el tema es poco alentador cuando uno encuentra en la literatura un mar de términos: Programación estructurada, Programación orientada a objetos, etc. En este documento, se ofrece al programador nuevo (que no escribirá código todo el día o diario) de información que pudiera auxiliarle para producir software útil, confiable y fácil de acceder. Bajo el esquema comercial de procesamiento de datos, se requiere buscar métodos eficientes y consistentes para producir software. En particular, la producción de programas grandes (de miles de días-programador) que utilizan muchos archivos, requieren de una metodología bien definida y disciplinada. Pero es poco probable que el programador casual dedicará mucho tiempo aprendiendo éstas técnicas. Además, la mayoría de los programas creados fuera del ambiente comercial son relativamente simples en términos de manejo de archivos y estructura. Sin embargo, de acuerdo a los programadores experimentados, es conveniente que un buen programa sea: 1. 2. 3. 4. Correcto Fácil de usar Fácil de mantener Eficiente De estas propiedades, la tercera es la que requiere de mayor esfuerzo si se espera que el programa sea aceptado por el público. Este es el aspecto de programación más ignorado, especialmente fuera del ambiente comercial. La siguiente sección describe brevemente estos cuatro aspectos, junto con algunos puntos relevantes a considerar. QUÉ TAN CORRECTO ES UN PROGRAMA Esta propiedad es evidente. Sin embargo, se debe considerar que la verificación de un programa no trivial es virtualmente imposible; esto se debe a que si uno conociera todas las respuestas entonces no se necesitaría el programa. Es importante también notar que la mayoría de los usuarios aceptan como válidos los resultados de la computadora independientemente si son correctos o no. • Verifique la validez de los datos de entrada e imprímalos. • • Detecte posibles errores e imprima los mensajes de error. Pruebe todas las opciones de su programa, inclusive los casos triviales (por ejemplo, cuando un bucle se efectuará cero veces). QUÉ TAN FÁCIL ES UN PROGRAMA DE USAR En general, los programas se escriben para un grupo específico de usuarios relacionados con una área específica, así que uno debe usar un lenguaje apropiado y de conocimiento común para ese grupo. Además, debe uno ser apropiado en el programa cuando se solicita información al usuario. Operación • • • • • • ¿Es el programa fácil de usar? ¿Requiere el programa de hardware específico? ¿Se tiene disponible documentación apropiada para ayudar a la ejecución del programa? El ingreso de datos es fácil y a prueba de tontos? ¡No tomen este punto muy lejos, ya que a nadie le gusta ser tratado como tal! No hay que olvidar al tipo que se pasa de listo, quién instantáneamente hace que el programa pare su ejecución cuando teclea “afirmativo”, “tres”, en vez de teclear la letra O para cero, etc., siempre que se hace una pregunta (¡él es probablemente su jefe!) ¿El programa tiene buena apariencia para el usuario cuando se muestran resultados, menús en pantalla o cuando se hacen preguntas? Si usted quiere vender su programa, entonces este es un punto esencial. Tranquilice al usuario durante periodos de inactividad aparente, a través de mensajes que indiquen el nivel de avance del proceso. Ofrezca mensajes de error útiles. Evite comentarios tales como: “ERROR 456444 DEL PROGRAMA” Salida de datos • • • ¿Tiene el usuario control sobre las variables de salida? ¿Puede el usuario obtener información sin necesidad de sumergirse en otra serie de menús? ¿Tiene la interfase de salida de resultados una apariencia agradable con representaciones gráficas apropiadas y sin errores ortográficos? Puede el usuario obtener una copia impresa de los datos de salida? Documentación externa • ¿Se requiere documentación externa? Algunas veces es más fácil tener un documento de referencia impreso que una ayuda en línea. ¿La información es fácil de leer, comprender y es precisa? FACILIDAD EN EL MANTENIMIENTO Muchos de nuestros programas son escritos para resolver problemas eventuales y no se requiere trabajar mucho en el estilo y mantenimiento del código. Sin embargo, el hábito de escribir programas legibles se paga así mismo. La tendencia actual es construir modelos computacionales más grandes y complejos; en ese contexto se necesita ser disciplinado en la escritura, y concentrarse en la producción de buen código desde el principio. Si el programa creado será desarrollado posteriormente por el programador original o por otros científicos (¿Cooperación entre científicos?), es imperativo que éste sea bien construido y documentado. La atención a este aspecto de la programación es vital si la simulación con computadora será un camino para el desarrollo e intercambio de ideas. Es también importante si su programa será usado a largo plazo o será desarrollado comercialmente. En cualquier situación, la producción de programas legibles debe ser alentada debido a que última instancia, la persona que tendrá que leerlos o modificarlos será usted mismo. El mantenimiento de los programas es sinónimo de legibilidad y comprensión. Un buen programa debe ser tan informativo y estructurado como la información en el documento que describe el proceso que se está modelando. De hecho, un código bien presentado debe inclusive ser más descriptivo del proceso que su equivalente en la literatura. • • • Use sangrías para organizar bucles, etc. Un programa debe verse bien mientras se escribe. En el proceso de depuración de los modelos es cuando se tendrá que leer el código más frecuentemente. Hágase la vida fácil. No tome atajos cuando escriba constantes de números reales. En este caso, siempre incluya el punto decimal (ejemplo: 6.0 y no 6). Inicialice variables o constantes al principio de las subrutinas del programa o en módulos separados, a través de los comandos convenientes de acuerdo al lenguaje de programación (por ejemplo DATA y BLOCKDATA en FORTRAN, CONST en PASCAL, #define en C). Use raramente variables globales, pero sea sensible al usarlas. Muchas variables globales pueden conducir a errores debido a efectos colaterales inesperados; por ejemplo, cuando se cambia accidentalmente el valor de • • • • • • • • • esa variable en una subrutina. Mantenga los datos relacionados con ciertas variables globales en archivos por separado, de tal forma que se puedan insertar en puntos relevantes del programa; cualquier cambio de esas variables debe hacerse en el interior de esos archivos. Ponga comentarios significativos en todo el programa. Es recomendable incluir un encabezado y un prólogo en las subrutinas, en los cuales se declare quién escribió el software, la dirección del programador y una breve descripción de lo que hace el código. También, cuando se desarrollan programas muy grandes, es útil mantener un diario del diseño y añadir el número de versión en el encabezado del programa para mantener el rastro de las modificaciones. Utilice nombres significativos para las variables. Nunca deje valores por omisión, es decir, variables sin definir. Haga uso de las estructuras de datos (objetos) para mantener datos relacionados juntos. Use las facilidades de los sub-programas. Asegúrese de que los parámetros son relevantes y que el uso de cualquier variable global sea obvio. No cambie los valores de las variables globales sin decir que es muy necesario y quede completamente claro. Si se usan variables locales, entonces las funciones pueden ser usadas más generalmente, debido a que dependen menos de los valores externos. Siempre que sea posible, los subprogramas se deben comunicar entre sí a través de los parámetros. Siempre asegúrese de que los módulos se auto contengan y que todos los parámetros estén comunicados vía la lista de parámetros. Aísle las secciones del programa que requieran ser constantemente actualizadas. Siempre utilice las facilidades de compilación estándar (ANSI, etc.) cuando sea posible. Si utiliza las facilidades dependientes de la computadora, aíslelas en módulos separados y haga comentarios cuidadosamente. Cuide la información alfanumérica. Los juegos de caracteres cambian dependiendo de la configuración de la computadora. Use identificadores preferentemente en vez de constantes. Ejemplo “pi” es mejor que 3.14 EFICIENCIA En la actualidad, es común ignorar la evaluación de la eficiencia de un programa, debido a la constante mejora de la velocidad de procesamiento de las computadoras. ¡Si una computadora no produce resultados rápidamente, entonces se procede a comprar un procesador mejor! Esta actitud en gran parte se debe a que las computadoras son más baratas que el trabajo hora-hombre. Sin embargo, hay ciertas consideraciones que pueden aumentar la eficiencia numérica de un programa y obtener respuestas precisas. Frecuentemente, algunos programadores están resolviendo problemas con algoritmos inadecuados. La elección del método numérico o la técnica de proceso de datos debe ser tomada en serio. Procesos elementales tales como la clasificación de datos pueden ser de diez a cientos de veces más rápido y eficiente si se usan algoritmos bien conocidos, utilizados y probados (Con este fin, es tiempo de que la clasificación de datos con el método del a burbuja debe desaparecer de la literatura). Tiempo de procesador • • • • • • • • • • • Almacene frecuentemente los elementos de un array en variables locales. Reemplace expresiones o ecuaciones redundantes con variables temporales. Factores de expresiones polinomiales. Ahorra multiplicaciones redundantes y mantiene la precisión. Elimine conversiones innecesarias. Use exponentes enteros cuando sea posible. Reemplace 2 con x, etc. Use “pointers” cuando sea posible (En leguaje C). El acceso a arrays consume tiempo. Reduzca el número de dimensiones de los array donde sea posible (Ejemplo, úsese EQUIVALENCE en FORTRAN). Elimine todos las expresiones dependientes de los bucles. Combine bucles con el mismo límite (loop jamming). Termine los bucles Elimine condicionales en los bucles cuando sea posible. Entrada y salida de datos Utilice lo menos posible variables I/O, y los comandos Write and Read. Capacidad de almacenamiento de la computadora Instrucciones innecesarias • • • • Elimine comandos innecesarios Optimice las operaciones aritméticas Evite inicializar variables innecesarias Evite llamar funciones innecesariamente Almacenamiento de datos • Re-use el espacio de almacenamiento mediante equivalencias. • • • Diseñe estructuras de arrays eficientes y evite espacios sin usar. Almacene matrices como vectores con pointers y elementos. Compacte los juegos de datos pequeños. REFERENCIAS Bentley, J. 1986. Programming Pearls. Addinson-Wesley, New York Dahl, Dijkstra. Structured Programming. Ingevaldson, L. 1986. A practical Method of Program Desing. Chartwell-Bratt. Bromley, England. Jensen, K., and Wirth, N. 1978. Pascal User Manual and Report. SpringerVerlag, New York Kernighan, B.W., and Plauger, P.J. 1981. Software Tools in Pascal. AddisonWesley. New York.