TEMA 5 Diseño de algoritmos . Elementos de Programación I Contenido del Tema TT EE M M A A 5.1.- Programación Modular y desarrollo de Programas 5.2.- Diseño de interfaces. 5.3.- Notación algorítmica. 55 Elementos de Programación I Programación Modular No usar una metodología de diseño conlleva: • Rigidez e inflexibilidad en los programas • Pérdida excesiva de tiempo en corrección de errores • Documentación insuficiente o nula • Imposibilidad de Reutilización Diseño descendente. Normalmente las componentes que van surgiendo son bastante independientes del algoritmo principal (y unas de otras), en el sentido de que pueden ser diseñadas sin considerar el contexto en el que van a ser usadas. Metodología de Programación Programación Modular • Módulo es un algoritmo autocontenido, que puede ser diseñado independientemente del contexto en el que va a ser usado. • Los procedimientos y funciones son los mecanismos más comunes que ofrecen los lenguajes de programación para permitir esta modularidad. Algunos lenguajes consiguen un nivel superior de modularidad, permitiendo agrupar procedimientos y funciones en entidades mayores. Metodología de Programación Programación Modular Ventajas: • Simplificación del diseño. • Programación aislada (encapsulamiento). • Conocimiento de lo que hace el subprograma, no cómo lo hace (Abstracción procedimental o de Operaciones). • Reutilización del módulo en otro contexto. • Simplificación de la comprensión del algoritmo (mantenimiento). • Transportabilidad, agrupando las operaciones dependientes de la máquina en un módulo. • Trabajo en equipo. Cada programador se encarga de desarrollar un módulo. • Compilación separada. No es necesario recompilar todo el programa sino sólo el módulo que se ha modificado. Metodología de Programación Programación Modular Encapsulamiento: • Si el método para solucionar una tarea T cambia, cualquier otra tarea Q no se ve afectada. T. 1ª implementación Llamada a T Q T. 2ª implementación • Ejemplo: Cambio del algoritmo de ordenación. Metodología de Programación Programación Modular Especificaciones: • Conjunto de condiciones que deben cumplirse para que se ejecute un módulo correctamente. Q debe saber: -Lo que hace T. Llamada a T Q -En que condiciones lo ejecuta. T • Ejemplo: Paso del array a ordenar. Metodología de Programación Programación Modular Criterios de Modularización. • No existe un algoritmo formal para descomponer un problema en módulos. • Criterios a seguir: – Minimizar el acoplamiento (los módulos deben ser lo más independientes posible). – Maximizar la cohesión (relación entre las diferentes partes internas de un módulo). Metodología de Programación Programación Modular Ejemplo: A lg oritm o d e p roc e s o d e n ó m in as P roc e s ar N ó m in a C a lc u lar In g res os C alc u la r R eten c ió n A n tes d e Im p u es to s C alc u lar Im p u e s to C alc u lar Im p u e s to A u ton ó m ic o C alc u lar R e te n c ió n D es p u é s d e Im p u es tos C alc u lar Im p u e s to E s tatal Metodología de Programación Diseño de Interfaces Un programa constará de: • El programa principal • Uno o más módulos de biblioteca: – Una parte de definición pública. – Una parte de implementación privada. Metodología de Programación Diseño de Interfaces En un módulo se puede declarar: • Constantes. Se pueden declarar en la parte de: – Definición. Cualquier Módulo o programa la podrá importar y utilizar. – Implementación. Local al Módulo. No es importable. (Las constantes declaradas en la parte de Definición son visibles en la parte de Implementación). • Variables. Se pueden declarar en la parte de: – Definición. Cualquier Módulo o programa la podrá importar y utilizar. Solo es recomendable en casos fuera del ámbito de la asignatura. – Implementación. Local al Módulo. No es importable. Actúa como una variable global dentro del módulo. No es aconsejable. (Las variables declaradas en la parte de Definición son visibles en la parte de Implementación como variables globales). Metodología de Programación Diseño de Interfaces En un módulo se puede declarar: • Procedimientos y Funciones. – Definición. En esta parte solo se declara la cabecera del algoritmo. Estos algoritmos podrán ser importados y llamados por cualquier otro módulo o programa. Se deben especificar todos los parámetros y, en el caso de una función, el tipo devuelto. – Implementación. Por cada cabecera declarada en la parte de definición, se debe escribir el subalgoritmo correspondiente. Su cabecera debe coincidir en el número y tipo de los parámetros. Además, se pueden declarar otros algoritmos, pero estos no podrán ser importados por otros módulos ni programas. (Estos Estos algoritmos pueden servir para descomponer los algoritmos exportables). exportables Metodología de Programación Diseño de Interfaces En un módulo se puede declarar: • Tipos. • Definición. Se define el tipo de la misma forma que se ha visto hasta ahora. Cualquier Módulo puede importarlos y utilizarlos como si fuesen suyos. • Implementación. Los tipos declarados en la parte de definición son visibles en la de implementación, por tanto no se pueden volver a declarar. – En un diseño apropiado, por cada tipo definido en un módulo se definirán también las operaciones que se pueden realizar con las variables declaradas de ese tipo. Metodología de Programación Notación Algorítmica Módulos. • Comenzarán con la palabra Módulo seguida del nombre del módulo. • Tanto el programa principal como los módulos podrán importar de otros módulos. • Parte de Definición. Visible a los algoritmos que la importen. • Parte de Implementación. Local al módulo. Metodología de Programación Notación Algorítmica EJEMPLO: • Programa que calcula el tercer lado de un triángulo. Tercer Lado GradosARadines Conversión El módulo Tercer Lado (en este caso el programa principal) utiliza la función GradosARadianes del módulo Conversión Metodología de Programación Módulo Coversión (* Módulo para pasar de grados a radianes y viceversa *) Definición FUNC GradosARadianes (↓grados : REAL) : REAL ángulo en radianes*) (* Devuelve el FUNC RadianesAGrados (↓radianes : REAL ) : REAL (* Devuelve el ángulo en grados *) Implementación Constantes Pi = 3.1416 FUNC GradosARadianes (↓grados : REAL) : REAL (* Devuelve el ángulo en radianes*) Inicio RESULTADO ← grados * Pi / 180.0 Fin FUNC RadianesAGrados (↓radianes : REAL ) : REAL (* Devuelve el ángulo en grados *) Inicio RESULTADO ← 180.0 * radianes / Pi Fin (* Conversión *) Fin Algoritmo TercerLado (* Calcula el tercer lado de un triángulo a partir de los otros dos y del ángulo entre ellos *) Desde Conversión Importa GradosARadianes Variables lado1, lado2, lado3, ánguloGrad, ánguloRad : REAL Inicio Escribir (“Introduce la longitud de un lado”) Leer (lado1) Escribir (“Introduce la longitud del otro lado”) Leer (lado2) Escribir (“Introduce el ángulo (en grados) “) Leer (ánguloGrad) ánguloRad ← GradosARadianes (ánguloGrad) lado3 ← Sqrt ( lado1* lado1 + lado2 * lado2 - 2.0 * lado1 * lado2 * cos (ánguloRad)) (* cos devuelve el coseno del ángulo *) Escribir (“La longitud del tercer lado es “, lado3) (* TercerLado *) Fin Notación Algorítmica • Ejemplo: Tipo de Datos Complejo. • Definición: Tipo de datos capaz de guardar la información de un numero complejo. NumeroComplejo. • Operaciones: – Asignación: Toma la parte real y la imaginaria y devuelve un número complejo. FUNC Asignación(↓r, ↓ i:REAL) : NumeroComplejo – Real: Toma un número complejo y devuelve su parte real. FUNC Real(↓c : NumeroComplejo) : REAL – Imaginaria: Toma un Numero Complejo y devuelve su parte imaginaria. FUNC Imaginaria(↓c : NumeroComplejo) : REAL – Suma: Toma dos Números Complejos y devuelve su suma. FUNC Suma(↓c1, ↓c2 : NumeroComplejo) : NumeroComplejo – Producto: Toma dos Números Complejos y devuelve su producto. FUNC Producto(↓c1, ↓c2 : NumeroComplejo): NumeroComplejo Metodología de Programación Notación Algorítmica • En el módulo que lo usa basta con la Definición del Tipo y de sus Operaciones para poder trabajar con él. (No necesitamos saber cómo esta implementado) Metodología de Programación Algoritmo SumaComplejos (* Lee y suma dos números complejos *) Desde Complejos Importa NumeroComplejo, Asignación, Suma, Real, Imaginaria Variables c1, c2, resultado : NumeroComplejo real, imag : REAL Inicio Escribir (“Introduzca la parte real y la imaginaria del primer número”) Leer (real, imag) c1 ← Asignación (real, imag) Escribir (“Introduzca la parte real y la imaginaria del segundo número”) Leer (real, imag) c2 ← Asignación (real, imag) resultado ← Suma (c1, c2) Escribir (“El resultado es: “) Escribir (Real (resultado), “+“,Imaginaria (Resultado), “i”) Fin Algoritmo ArrayComplejos (*Multiplica una array de complejos *) Desde Complejos Importa NumeroComplejo, Asignación, Producto, Real, Imaginaria Constantes TamañoVector = 1000 Tipos VectorComplejos = ARRAY [1..TamañoVector] DE NumeroComplejo Variables vComplejos: VectorComplejos resultado : NumeroComplejo índice : NATURAL Inicio Leer_Vector (vComplejos) (* Lee el vector de Complejos *) resultado ← Asignación (1.0, 0.0) PARA índice ← 1 HASTA TamañoVector HACER resultado ← Producto (resultado, vComplejos[índice ]) FINPARA Escribir (“El resultado es: “) Escribir (Real (resultado), “+ “, Imaginaria (Resultado), “i”) Fin Notación Algorítmica • Nivel de Implementación. – Definimos un módulo donde se implementan sus operaciones. Metodología de Programación Módulo Complejos (* Implementación del tipo NumeroComplejo *) Definición Tipos NumeroComplejo = REGISTRO parte_real, parte_imag : R FINNREGISTRO FUNC Producto(↓c1, ↓c2 : NumeroComplejo): NumeroComplejo FUNC Asignación(↓r, ↓ i:REAL) : NumeroComplejo (* Toma la parte real y la imaginaria y devuelve un número complejo. *) FUNC Real(↓c : NumeroComplejo) : REAL (* Toma un número complejo y devuelve su parte real. *) FUNC Imaginaria(↓c : NumeroComplejo) : REAL (* Toma un Numero Complejo y devuelve su parte imaginaria.*) FUNC Suma(↓c1, ↓c2 : NumeroComplejo) : NumeroComplejo (* Toma dos Números Complejos y devuelve su suma *) FUNC Producto(↓c1, ↓c2 : NumeroComplejo): NumeroComplejo (* Toma dos Números Complejos y devuelve su producto. *) Implementación FUNC Asignación(↓ r, ↓ i:REAL) : NumeroComplejo Variables c : NumeroComplejo Inicio c.parte_real := r c.parte_imag := i RESULTADO ← c Fin FUNC Real(↓ c : NumeroComplejo): REAL (* Toma un número complejo y devuelve su parte real. *) Inicio RESULTADO ← c.parte_real Fin FUNC Imaginaria(↓c : NumeroComplejo) : REAL (* Toma un número complejo y devuelve su parte imaginaria. *) Inicio RESULTADO ← c.parte_imag Fin FUNC Suma(↓c1, ↓c2 : NumeroComplejo) : NumeroComplejo (* Toma dos Números Complejos y devuelve su suma *) Variables res : NumeroComplejo Inicio res.parte_real ← c1.parte_real + c2.parte_real res.parte_imag ← c1.parte_imag + c2.parte_imag RESULTADO ← res Fin FUNC Producto(↓c1, ↓c2 : NumeroComplejo): NumeroComplejo (* Toma dos Números Complejos y devuelve su producto. *) Variables res : NumeroComplejo Inicio res.parte_real ← c1.parte_real * c2.parte_real c1.parte_imag * c2.parte_imag res.parte_imag ← c1.parte_real * c2.parte_imag + c1.parte_imag * c2.parte_real RESULTADO ← res Fin Fin (* Módulo Complejos *) Notación Algorítmica • La implementación se separa de la utilización. • La implementación del tipo se puede hacer de muchas formas: – NumeroComplejo = ARRAY [1..2 ] DE REAL – NumeroComplejo = REGISTRO Módulo, Argumento : REAL FINREGISTRO • Un cambio en la implementación no debe suponer cambios en la utilización. Metodología de Programación Notación Algorítmica • Ejercicio: Ejercicio Realizar la implementación de NumeroComplejo como un registro donde se guarda módulo y argumento. El algoritmo de multiplicación del vector de complejos será más eficiente sin haber sido modificado Metodología de Programación Bibliografía ! " . C. Galán. Paraninfo. 1987 ! # $ % $ # & ' # # ( Wirth N Ed. Ed del Castillo. ) * + > 0 , ? 3 - 1 @ . 5 + A / 0 B 7 1 @ , + 1 5 C . 2 3 - 3 D - E 0 4 0 F G - H 5 2 I . J 1 G 6 I 2 5 3 H K . / . 7 8 9 , : ; < 6 2 5 8 1 / 2 3 = . L. Joyanes. McGraw-Hill. 1996 . N. Dale & S. Lilly. F L M L K G N F O McGraw-Hill. 1992 Hellman, Veroff.. Ed. Benjamin/Cummings Series. 1988. P Q R R S Q T U V W X X Y X S Z [ Y U \ R Q ] ^ _ U W ` W Y T a Metodología de Programación