CC 1002: Introducción a la Programación Datos compuestos Nelson Baloian, José A. Pino
Representación interna de valores float Los números “reales” se almacenan internamente en el computador con dos partes: Mantisa: parte con dígitos. Ejemplo con 4 bits: 1001 representa en realidad 0.1001 en binario, que equivale en decimal a 1x2-1 + 0x2-2 + 0x2-3 +1x2-4 , o sea 1x0.5 + 0x0.25 + 0x 0.125 + 1x0.0625 = 0.5625 (en decimal) En computadores usuales, la mantisa contiene 24 bits Exponente: un número entero con signo. La mantisa se debe multiplicar por 10 elevado al exponente. Por ejemplo, si el exponente es +5, la mantisa debe multiplicarse por 105
Representación interna de valores float En resumen, un número float se representa entonces con dos elementos: Con una mantisa aproximando la parte fraccionaria Con un exponente que da la “escala”. Ejemplo: 335.26 se representa con una mantisa binaria aproximando el decimal 0.33526, y un exponente +3 Otro ejemplo: 0.0000987 se representa con una mantisa binaria aproximando el decimal 0.987, y un exponente -4 → Los float son una aproximación a valores reales
Fracciones # sumaFracciones : int int int int -> float Escribir una función que sume dos fracciones: a/b con c/d # sumaFracciones : int int int int -> float # calcula suma de dos fracciones a/b y c/d # ej.: sumaFracciones(1,2,3,4) devuelve 1.25 def sumaFracciones (a,b,c,d): return (a*d + b*c) * 1.0 / b*d # Test epsilon = 0.000001 assert cerca(sumaFracciones(1,2,3,4),1.25, \ epsilon)
No es una buena solución Resultado no es una fracción Nos gustaría manejar fracciones como tales en python… Pero no existe un tipo de datos “fracción”… ¿Qué podemos hacer entonces?
Estructuras Struct: tipo de datos para encapsular un conjunto fijo de valores para constituir un valor único compuesto Los valores pueden ser de uno o más tipos Los valores están representados por atributos Ej.: Fracción: numerador y denominador
Otros ejemplos Número complejo: parte real y parte imaginaria Persona: Nombre de pila, apellido paterno, apellido materno, género, edad
Usando structs import estructura estructura.crear("nombre", \ "atributo1 atributo2... atributoN") En nuestro caso: estructura.crear("fraccion","numerador denominador")
Una vez creada “fraccion” >>> f = fraccion (5, 3) --> fraccion(numerador=5, denominador=3) >>> f.numerador --> 5 >>> f.denominador --> 3
Receta de diseño Diseñar estructuras Plantilla que especifique las combinaciones de atributos a operar Cuerpo de la función
Diseño de estructuras import estructura # Disenno de la estructura # fraccion: numerador (int) denominador (int) estructura.crear("fraccion","numerador denominador") # Contrato # sumaFracciones: fraccion fraccion -> fraccion # Proposito # crear nueva fraccion que corresponda a la suma # de dos fracciones f1 y f2 # Ejemplo: # sumaFracciones(fraccion(1, 2), fraccion(3, 4)) # devuelve fraccion(10, 8)
Plantilla “Comentario” que lista todas las posibles combinaciones con las entradas de una función No se dice nada sobre las salidas La plantilla se puede usar para todas las funciones que tengan mismo tipo de parámetros
Plantilla de fracciones # Plantilla # def funcionConFracciones(fraccion1, fraccion2): # ...fraccion1.numerador...fraccion2.numerador ... # ...fraccion1.numerador...fraccion2.denominador # ...fraccion1.denominador...fraccion2.numerador #...fraccion1.denominador... fraccion2.denominador
Cuerpo def sumaFracciones(f1,f2): num = f1.numerador * f2.denominador \ + f1.denominador * f2.numerador den = f1.denominador * f2.denominador return fraccion(num, den) # Tests f12 = fraccion(1, 2) f34 = fraccion(3, 4) assert sumaFracciones(f12,f34) == fraccion(10,8)
Otro ejemplo: producto # Contrato #productoFracciones: fraccion fraccion -> fraccion # Proposito # generar fraccion que es resultado de multiplicar # dos fracciones f1 y f2 # Ejemplo # productoFracciones(fraccion(1,2),fraccion(3,4)) # devuelve fraccion(3,8)
Cuerpo de productoFracciones def productoFracciones(f1,f2): num = f1.numerador*f2.numerador den = f1.denominador*f2.denominador return fraccion(num,den) # Tests f12 = fraccion (1,2) f34 = fraccion (3,4) assert productoFracciones(f12,f34)==fraccion(3,8)
Otro ejemplo # Contrato # esMayorQue: fraccion fraccion -> bool # Proposito #generar True si primera fraccion es mayor que # la segunda # Ejemplo # esMayorQue(fraccion(1,2),fraccion(4,9)) # devuelve True
Cuerpo de esMayorQue def esMayorQue(f1,f2): return f1.numerador*f2.denominador > \ f1.denominador*f2.numerador # Tests f12 = fraccion (1,2) f49 = fraccion (4,9) assert esMayorQue(f12,f49)
Ejercicio para la casa Programar restaFracciones(f1,f2) Programar divisionFracciones(f1,f2) Programar mcd(i,j), que retorna el máximo común divisor de los enteros i y j. Programar simple(f), que simplifica la fracción f (sugerencia: use mcd() )
Leer capítulo 9 del apunte, secciones 9.1, 9.2, 9.3 Para la próxima clase (jueves) Leer capítulo 9 del apunte, secciones 9.1, 9.2, 9.3