Recomendaciones sobre legibilidad en el código

Anuncio
METODOLOGÍA Y TECNOLOGÍA DE LA PROGRAMACIÓN I Ingeniería Informática Curso Primero. 2008‐09 Notas sobre legibilidad en el código1 Programming is best regarded as the process of creating works of literature, which are meant to be read. ‐‐ Donald Knuth, Literate Programming 1. Estilo de codificación 1.1 La sintaxis de identificadores y palabras reservadas debe seguir un mismo criterio. Así, aunque Pascal no es sensible a los cambios de may./min., se debe emplear siempre el mismo criterio para el mismo tipo de identificador. Ej. Correcto Incorrecto Program abs; program ABS; Var vAr a: integer; a: INTeger; Begin BegiN read(a); READ(a); If (a > 0) Then IF (A > 0) then writeln(a) writeln(a) Else elSE writeln(‐1*a); writeln(‐1*A); End. EnD. 1.2 Realizar un sangrado correcto del programa. Hay que asegurarse que la indentación de las sentencias refleje fielmente la estructura del programa, de manera que sea fácil de identificar si un bloque se encuentra dentro de otro. Ej. Correcto Incorrecto Program bucle; Program bucle; Var Var a: integer; a: integer; Begin Begin read(n); read(n); for i:= 1 to n do for i:= 1 to n do write(i, ‘ ‘); write(i, ‘ ‘); writeln; writeln; End. End. 1 Los criterios y restricciones especificados en este documento se puede relajar en situaciones muy concretas, pero en MTP‐1 asumen que siempre son válidos. 1
METODOLOGÍA Y TECNOLOGÍA DE LA PROGRAMACIÓN I Ingeniería Informática Curso Primero. 2008‐09 2. Comentarios 2.1 No comentar lo obvio! (véase TPOP). El propio código que escribimos debería ser en gran medida autoexplicativo. Si una parte del código requiere un comentario, intentar comentar bloques, no sentencias aisladas. Tan peligroso es no comentar nada, como comentar en exceso. Pensar siempre si es necesario reescribir el código, antes de comentar un código mal escrito. Ej. Incorrecto Begin write('Introduce tu edad:'); readln(edad); { lee la edad de la persona } write('llevas viviendo unos:'); writeln(edad *365, ' dias'); End. 2.2 Comentar funciones y variables globales Cada función o procedimiento debe tener un comentario de cabecera con información de: • Qué acción realiza. • Sus parámetros de entrada y de salida, así como el significado de cada uno de ellos. • El valor devuelto. • Los requisitos o precondiciones en los valores de los parámetros. • Las condiciones de error tratadas dentro de cada acción. 2.3 No contradecir el código (véase TPOP). Hay que tener cuidado de mantener coherentes los comentarios con el código. Es posible que se cambie el código y no se actualice el comentario, lo que da lugar a confusión cuando se vuelve a revisar el código pasado un tiempo. Un ejemplo típico de este tipo de error son las cabeceras de las funciones y procedimientos. Ej. Incorrecto (*calAreaTriangulo Devuelve el área del triángulo según de su base y altura. Entrada: base y altura números enteros. Salida: número real que representa el área del triángulo. Si base o altura son menores que cero se devuelve cero. *) function calAreaTriangulo(base, altura: real): real; begin calAreaTriangulo:= base*altura/2; end. 2
METODOLOGÍA Y TECNOLOGÍA DE LA PROGRAMACIÓN I Ingeniería Informática Curso Primero. 2008‐09 3. Declaración de Variables 3.1 Nombres descriptivos para variables globales, nombres cortos para locales. 3.2 Seguir la nomenclatura que otros programadores han empleado. Existen una serie de convenios a la hora de nombrar variables que están bastante extendidos. Estos son útiles cuando no se tiene un nombre específico para una variable • Variables temporales: tmp o aux. • Contadores: i, j, k, l ... • Número enteros: a,b,c ... • Números reales: x, y ,z • Carácter: c • Cadena de caracteres: s 3.3 Ser consistente (véase TPOP). Es importante mantener una cierta coherencia en la elección de los nombres de variable. De esta manera, será más fácil entender para qué sirve una variable y su relación con el resto. 3.4 Usar verbos para las funciones: verbo + sustantivo (véase TPOP). Un criterio que nos puede ayudar a nombrar un función es emplear un verbo en activo + un sustantivo que indique la acción que realiza la función. Ej, esPrimo(n), leeAlumnos(tabla), calculaDistancia(p1, p2) ó calDistancia(p1,p2)… 3.5 Economía de variables. Intentar ajustar el número de variables que se emplean. Nunca dejar declaradas variables en el código que no se empleen. Un par de criterios que nos pueden ayudan a decidir si necesitamos una variable o no: • Si una misma expresión se emplea para calcular un valor en determinados puntos del código, mejor emplear una variable para realizar el cálculo una sola vez. • Si mejora la legibilidad del código el realizar cálculos intermedios empleando más variables. 3.6 Asegurarse que todas las variables tienen un valor inicial antes de utilizarlas. Hay que revisar el código para comprobar que todas las variables tienen asignado un valor (ya sea porque se lee, o porque se calcula) antes de emplearlas. No asumáis que las variables se inicializan a un valor por defecto (ej, cero). 3.7. Declaración de constantes. En general, las constantes se nombran siguiendo los mismo criterios que una variable global, pero con el nombre en mayúsculas. De esta manera será sencillo distinguirlas en el código. Todos los números mágicos del código tendrán que sustituirse por constantes. 3
METODOLOGÍA Y TECNOLOGÍA DE LA PROGRAMACIÓN I Ingeniería Informática Curso Primero. 2008‐09 5. Funciones 5.1 Se prohíbe modificar/utilizar una variable global desde una función. Dentro de una función sólo se pueden modificar/utilizar variables locales, o parámetros. Si se quiere emplear el valor de variables globales en subprogramas, entonces habrá que pasarlas como parámetros por valor. Se debe considerar que las variables globales son variables locales al programa principal. 5.2 Parámetros por valor. Los parámetros de una función se pasaran por valor si: ‐ Son valores de entrada (EXCEPCIÓN: estructuras de datos muy grandes) ‐ No se modifican dentro de la función. 5.3 Parámetros por referencia. Los parámetros por referencia deberían emplearse para indicar parámetros donde se espera guardar un resultado de la ejecución del procedimiento (excepcionalmente como parámetros de entrada/salida). 5.4 Sentencias de escritura dentro de funciones. Si una función/procedimiento no se emplea específicamente para imprimir datos, no incluyáis sentencias de escritura de datos (write, writeln). Si no, cuando se quiera emplear la función en un programa distinto al que se había concebido, se incluirá en la salida del programa texto indeseado. EXCEPCIÓN: por motivos de depuración, pero siempre deshabilitándolas en la versión definitiva. Ej. Correcto Incorrecto program cal_cubo (input, output); program cal_cubo (input, output); function cubo(x: real): real; begin function cubo(x: real): real; cubo:= x*x*x; var tmp: real; end; begin tmp := x*x*x; var x: real; writeln('El cubo de ', x, ' es ', tmp); cubo:= tmp; begin end; read(x); writeln('El cubo de ', x, ' es ', cubo(x)); begin end. read(x); cubo(x); end. 5.6 Control de errores. Siempre que se reciba un dato del usuario, independientemente de cómo se reciba (por teclado, por fichero, etc) se debe validar que tiene el valor esperado. 4
METODOLOGÍA Y TECNOLOGÍA DE LA PROGRAMACIÓN I Ingeniería Informática Curso Primero. 2008‐09 Ej. En un programa que genere facturas, si se pide al usuario que introduzca el porcentaje de IVA a aplicar, se deberá comprobar que el valor indicado pertenece al intervalo [0, 100]. De la misma forma, para facilitar la reutilización de funciones y procedimientos, todos los parámetros que reciban también deben estar sujetos a un control de errores para verificar que son válidos. Si alguno de los parámetros no es válido se devolverá a la función llamadora un código de error. 6. Uso del if 6.1 Emplear if­else en vez de if­if. Si tenemos dos condiciones de manera que una es la contraria de la otra, se empleará if­else, en vez de realizar dos if. Ej. Correcto Incorrecto if (distancia <= radio) then if distancia <= radio then writeln('PUNTO INTERIOR') writeln('PUNTO INTERIOR’) else if distancia > radio writeln('PUNTO EXTERIOR'); writeln('PUNTO EXTERIOR'); 6.2 Anidar if: Esta regla es una generalización de la anterior. Si tenemos tres o más condiciones autoexcluyentes se empleará if­else if, en vez de realizar varios if. 6.3 Condición en positivo en vez de en negativo: En general, queda más claro el código si se comprueba que se cumpla que la condición sea verdadera en vez de comprobar que sea falsa. Ej. Correcto Incorrecto if distancia <= radio then writeln('PUNTO INTERIOR') else writeln('PUNTO EXTERIOR'); if not distancia <= radio then writeln('PUNTO EXTERIOR') else writeln('PUNTO INTERIOR'); 5
METODOLOGÍA Y TECNOLOGÍA DE LA PROGRAMACIÓN I Ingeniería Informática Curso Primero. 2008‐09 6.5 Extraer partes comunes. Aquellas partes que sean comunes a las dos ramas que define la condición deberían sacarse fuera de la sentencia condicional en vez de repetirse en cada rama. Ej. Correcto Incorrecto if x > y then max:= x else max:= y; writeln(max); if x > y then begin max:= x; writeln(max); end else begin max:= y; writeln(max); end; 6.6 No emplear if para realizar asignaciones a variables booleanas. Si se quiere asignar el resultado de una expresión booleanas a una variable, se hará directamente. Ej. Correcto Incorrecto esParPositivo:= (x > 0) and (not odd(x)); if (x > 0) and (not odd(x)) then esParPositivo := true else esParPositivo := false; end; 7. Uso de sentencias de repetición 7.1 En bucle For no modificar la variable de iteración dentro del bucle. Ej. Correcto Incorrecto For i:= 1 To 50 Do Begin write(2*i‐1); End; For i:= 1 To 100 Do Begin write(i); i:= i + 2; End; 6
METODOLOGÍA Y TECNOLOGÍA DE LA PROGRAMACIÓN I Ingeniería Informática Curso Primero. 2008‐09 7.2 En general, tratar de no implementar un bucle indefinido utilizando For, ni un bucle definido empleando while o repeat. Ej. Correcto Incorrecto While ((i < N) and (res < UMBRAL)) Do Begin ……… End; For i:= 1 To N Do Begin ……… End; For i:= 1 To N Do Begin …… if res > UMBRAL Then i:= N; (* o break *) End; While (i < N) Do Begin …… i:= i + 1; End; 7
METODOLOGÍA Y TECNOLOGÍA DE LA PROGRAMACIÓN I Ingeniería Informática Curso Primero. 2008‐09 7.3 En los bucles While y Repeat indicar todas las condiciones de parada en <condición>. Si es necesario incluir banderas para identificar el momento en el que debe finalizar el bucle. Ej. Correcto Incorrecto While (i < N) and (NOT ganado) Do Begin …… If (……) Then ganado:= true; End; While (i < N) Do Begin …… If (……) Then Begin ganado:= true; i := N; (* o break *) End; End; 7.4 Duplicidad del código (bucles y funciones). Evitar la duplicidad de código. Siempre que en un programa exista un fragmento de código que se repita un número determinado de veces, dependiendo del caso concreto: • Tratar de convertir ese código en una función que se invoque siempre que sea necesario. • Convertir el código en el cuerpo de un bucle que se repite tantas veces como sea necesario. (ej. programa que calcule 104, se puede calcular un bucle for para el cálculo. Ver también siguiente ejemplo). 8. Arrays 8.1 No acceder a posiciones fuera de un array. 8.2 Para acceder a los elementos de un array lo habitual es utilizar un bucle y no hacerlo de forma estática. Ej. Programa que lea tres números enteros y calcule su suma. Correcto Incorrecto program sumas(input, output); var valores : Array[1..3] of Integer; suma : Integer; i : Integer; begin { Entrada de datos } writeln('Introduce los tres valores a program sumas(input, output); var valores : Array[1..3] of Integer; suma : Integer; i : Integer; begin { Entrada de datos } writeln('Introduce los tres valores a 8
METODOLOGÍA Y TECNOLOGÍA DE LA PROGRAMACIÓN I Ingeniería Informática Curso Primero. 2008‐09 sumar:'); for i := 1 to 3 do begin write('v[', i, '] = '); readln(valores[i]); end; { Procesamiento } suma := 0; for i := 1 to 3 do begin suma := suma + valores[i]; end; { Salida } writeln('El resultado de la suma es: ', suma); end. sumar:'); write('v[1] = '); readln(valores[1]); write('v[2] = '); readln(valores[2]); write('v[3] = '); readln(valores[3]); { Procesamiento } suma := valores[1] + valores[2] + valores[3]; { Salida } writeln('El resultado de la suma es: ', suma); end. 9. Programación estructurada Los programas deben seguir un flujo secuencial estructurado que evite el llamado “código espagueti”. Para evitar este tipo de código NO SE DEBEN UTILIZAR las sentencias goto, exit y halt. Bibliografía TPOP. B. W. Kernighan and R. Pike. The Practice of Programming, Addison‐Wesley, 1999. Existe edición traducida al castellano. 9
Descargar