lunes, 29 de mayo de 2017

Cómo programar: datos simples (21) - Enumeración

Diseñar una definición de datos para representar las letras de calificaciones en un curso.  Estas letras son A, B y C, que significan bueno, regular y malo respectivamente.

Esta definición corresponde a una enumeración, debido a que tiene un número fijo de valores diferentes. Son datos de texto (strings) usados para presentar cada uno de los distintos casos.

El código para esta definición es el siguiente:

; LetterGrade es uno de:
; - "A"
; - "B"
; - "C"
;interpretación: la letra de calificación en un curso.

;Ejemplos: son redundantes en enumeraciones.

En la plantilla orientada por datos buscar por "one of", para tomar de allí la plantilla correspondiente:






Se toma la plantilla correspondiente:

;(define (fn-for-letter-grade lg)
;(cond [ Q  A]
;          [Q   A] ) )

;Regla de plantilla utilizada:
;- Uno de (one of): 3 casos
; - valor atómico distinto (atomic distinct value):  "A"
; - valor atómico distinto (atomic distinct value):  "B"
; - valor atómico distinto (atomic distinct value):  "C"

Finalmente, se refina un poco la plantilla:

(define (fn-for-letter-grade lg)
 (cond [(string=? lg "A") (...) ]
           [(string=? lg "B") (...) ]
           [(string=? lg "C") (...) ]))

Más adelante se vera como se sigue refinando esta plantilla para desarrollar la funciòn completa.

Anterior
Siguiente

Cómo programar: datos simples (20) - Intervalos

El intervalo es un tipo de datos que representa un rango de números.

Por ejemplo, se requiere diseñar una definición de datos que represente un número de silla en una fila, cada fila con 32 sillas.

1 2 3 ... 32

Recordando un poco, una definición de datos consta de cuatro o cinco partes:

1) Una posible definición de una estructura (no visto hasta ahora, más adelante se verá en detalle)
2) Un comentario de tipo que define un nuevo nombre para el tipo de datos y describe como formar datos.
3) Una interpretación que describe la correspondencia entre información y datos
4) Uno o más ejemplos de los datos.
5) Una plantilla de una función que opera sobre el tipo de datos antes definido.

Ahora bien, el ejemplo planteado corresponde a un tipo atomic non-distinct, el cual tambien tiene un "subtipo" llamado interval (intervalo). Si se busca en la plantilla orientada por datos, es el siguiente:




El tipo de datos tendrá el nombre SeatNum (Número de silla):

;SeatNum is Natural [1, 32]
;Interpretación: SeatNum es un número natural que representa los números de silla
;en una fila, desde la uno hasta la 32. 1 y 32 son sillas que dan al pasillo (sillas ubicadas 
;en los extremos de la fila).

[1,32] indica que el rango incluye tanto el 1 como el 32

Si se cambia la notación, tendría un significado diferente:

(1,32) indica que se excluyen 1 y 32, es decir el rango incluye 2 y va hasta 31.
[1,32) indica que incluye 1 pero excluye 32, por lo que el rango va desde 1 hasta 31.

Volviendo al ejemplo, la notación será [1,32]

Ahora se definen los ejemplos, los cuales deben incluir al menos: los extremos y un número cercano a la mitad:

;Ejemplos:
;(define SN 1) ; pasillo
;(define SN 12) ; mitdad de la fila
;(define SN 32); pasillo

Luego la plantilla asociada a los tipos de datos atomic non-distinct:

;plantillla de datos
;(define (fn-for-seat-num sn)
;  (... sn))

En adelante se indicará la plantilla de datos utilizada:

;Regla de plantilla utilizada:
; - Atomic non-distinct
;   Natural [1,32]  ; intervalo que representa un número natural entre 1 y 32.

Al final el código completo de la definición de datos quedará así:

;SeatNum is Natural [1, 32]
;Interpretación: SeatNum es un número natural que representa los números de silla
;en una fila, desde la uno hasta la 32. 1 y 32 son sillas que dan al pasillo (sillas ubicadas 
;en los extremos de la fila).

;Ejemplos:
;(define SN 1) ; pasillo
;(define SN 12) ; mitdad de la fila
;(define SN 32); pasillo

plantillla de datos
;(define (fn-for-seat-num sn)
;  (... sn))

;Regla de plantilla utilizada:
; - Atomic non-distinct
;   Natural [1,32]  ; intervalo que representa un número natural entre 1 y 32.

Anterior
Siguiente



sábado, 27 de mayo de 2017

Cómo programar: datos simples (19) - Plantillas orientadas por datos (2)

En el artículo anterior, se identificó la plantilla asociada al tipo de datos atomic non-distinct para propositos de diseñar una función asociada a una forma de datos llamada CityName.  En esta sección se desarrollará una función que produce true (verdadero) si la ciudad es la mejor del mundo:

;Firma (un tipo de datos llamado CityName produce un valor booleano):
; CityName -> Boolean

;Propósito:  producir true (verdadero) si la ciudad es "Hogmeade".

;(define (best? cn ) false) ; colilla (stub)

;Ejemplos:
(check-expect (best? "Boston") false)
(check-expect (best? "Hogmeade") true)

; Plantilla tomada de la definición de datos CityName (ver artículo anterior):
; (define (fn-for-city-name cn)
;   (... cn))

; Desarrollo de la función:
;(define (best? cn)
 ;(if (string=? cn "Hogmeade")
 ;     true
 ;     false))

;Simplificando la anterior función, quedaría así:
(define (best? cn)
  (string=? cn "Hogmeade"))

Las plantillas muestran lo que se puede usar, no lo que se debe usar.  En algunos momentos es posible que uno borre o ajuste parte de las plantillas.

Anterior
Siguiente

viernes, 26 de mayo de 2017

Cómo programar: datos simples (18) - Plantillas orientadas por datos

El curso proporciona unas plantillas de funciones que operan sobre distintos tipos de datos. Dependiendo del tipo de datos utilizado en la resolución del problema, se escoge la plantilla asociada a ese tipo de datos.

Ejemplo:

Se requiere diseñar la definición de datos para representar el nombre de una ciudad y así obtener la plantilla de la función que opera sobre dicho tipo de datos.

El dominio del problema es el siguiente:

Nombre de una ciudad

Información:
Vancouver
Boston

Datos:
"Vancouver"
"Boston"

Basados en lo anterior, se comienza haciendo un comentario para formar el nuevo tipo de datos. En este ejemplo el tipo de datos se llamará CityName (nombre de la ciudad), el cual es una cadena de texto (string):

; CityName is String
; interpretación: El nombre de una ciudad

Luego, se crean dos constantes que representan ejemplos:

(define CN1 "Boston")
(define CN2 "Vancouver")

Una vez creados los ejemplos, se ingresa al banco de plantillas orientadas por datos (data driven templates).

Allí se busca el siguiente cuadro:











El anterior cuadro proporciona una plantilla genérica  con el código:

(define (fn-for-type-name x)
  <body> )


Este código define una función con un solo argumento "x" y un cuerpo <body> . Dicho cuerpo se ajusta de acuerdo al tipo de datos que deseamos trabajar.

Ahora bien, para este caso, una ciudad como "Vancouver" corresponde a un tipo de datos atómico no-distinto (atomic non-distinct), es decir, es un tipo de dato que no puede descomponerse en otras piezas más pequeñas (irreducible).

Este tipo de datos se busca en la plantilla antes mencionada, y de allí se toma la plantilla del cuerpo de la función  (ver la tercer columna "body or cond answer"): 



De acuerdo a lo anterior, el cuerpo de la función para un tipo de datos atomic non-distinct es el siguiente:

(...x)


Ese código ahora debe incluirse en el formato genérico antes señalado:

(define (fn-for-type-name x)
  <body> )

Para ello, se reemplaza <body> con el cuerpo de la función para un tipo de datos atomic non-distinct, que es  (... x) , para asi obtener la siguiente plantilla de código asociada al tipo de datos atomic non-distinct, según se indica abajo:


(define (fn-for-type-name x)
(... x)  ) 

Se reemplaza "fn-for-type-name" por el nombre del tipo de datos definido, que en este caso es city-name. De igual manera el argumento "x" puede reemplazarse por cn (city name). Conforme a lo anterio, el código quedaría asi:


(define (fn-for-city-name cn)
(... cn)  )


En resumen, se puede decir que una definición de datos consta de cuatro o cinco partes:

1) Una posible definición de una estructura (no visto hasta ahora, más adelante se verá en detalle)
2) Un comentario de tipo que define un nuevo nombre para el tipo de datos y describe como formar datos.
3) Una interpretación que describe la correspondencia entre información y datos
4) Uno o más ejemplos de los datos.
5) Una plantilla de una función que opera sobre el tipo de datos antes definido.

Anterior
Siguiente

domingo, 21 de mayo de 2017

Cómo programar: datos simples (17) - Definición de datos

Se comenzará con un problema mas o menos planteado, el cual se refinará posteriormente:

El siguiente código sobre la simulación de las luces de un semáforo:

;Natural --> Natural
;Produce el siguiente color de un semáforo

;define (next-color c) 0) ; stub (colilla)

;Plantilla
#;(define (next-color c )
   (... c))

;Función
(define (next-color c)
  (cond [ (= c 0) 2 ]
            [ (= c 1) 0 ]
            [ (= c 2) 1 ] ))

;Ejemplos
(check-expect (next-color 0) 2)
(check-expect (next-color 1) 0)
(check-expect (next-color 2) 1)

Al ejecutarse el anterior código todas las tres pruebas pasan satisfactoriamente. Sin embargo, es poco lo que se entiende del mismo. Al examinar cada parte del código se observa lo siguiente:

- La firma indica que con un número natural se produce un número natural.
- El próposito dice que se produce el siguiente color de un semáforo. ¿que tiene que ver un color con - un número natural?
- La función "next-color" con un argumento 0 produce 2, con un argumento 1 produce 0, y con un argumento 2 produce 1. ¿que significa eso?

Para entender lo anterior, hay que conocer el dominio del problema.   El dominio se refiere al campo de aplicación, en este caso, la simulación de las luces de un semáforo.

El dominio tambien se compone de la información y de los datos que representarán esta información.

Por ejemplo:

Información:  Una luz roja de un semáforo
Datos: El cero representa  la luz roja del semáforo

La representación de la información se conoce tambien como definición de datos. En la definición de datos se colocan los comentarios que definen un nuevo tipo de datos. Estos comentarios muestran como formar tipos de datos.

En la definición de datos tambien se incluye la interpretación, la cual explica como interpretar los tipos de datos creados. Esto ayuda a crear una asociación entre la información y los datos que la representan.

De acuerdo a lo anterior, el código quedaría así:

; Definición de datos

;La siguiente línea es un comentario del tipo de datos llamado "TLColor" (traffic light color o color de luz del semáforo). TLColor es un tipo de datos "atomic non-distinct", es decir, un valor simple que representa información:

;TLColor es uno de:
; - 0
; - 1
; - 2

; Interpretación: TLColor representa un solo color de luz de un semáforo: 0 es rojo, 1 es amarillo y 2 es verde.

;Plantilla tomada de la definición de datos simples (data driven templates/atomic non-distinct):
#; (define (fn-for-tlcolor c)
   (cond  [ (= c 0) (....) ]
              [ (= c 1)  (...) ]
              [ (= c 2) (...) ] ) 

;Definición de la función
;La función ahora se alimenta del tipo de datos creado anteriormente:

;TLColor--> TLColor
; Produce el siguiente color de un semáforo.

;define (next-color c) 0) ; stub
;Plantilla tomada de TLColor: se cambia el nombre de "fn-for-tlcolor c" a "next-color c":
#; (define (next-color c)
   (cond  [ (= c 0) (....) ]
              [ (= c 1)  (...) ]
              [ (= c 2) (...) ] )

;Función completa:
(define (next-color c)
(cond  [ (= c 0) 2 ]
              [ (= c 1) 0 ]
              [ (= c 2) 1 ]))

;Ejemplos
(check-expect (next-color 0) 2) ;con un argumento 0 (luz roja), produce 2 (luz verde)
(check-expect (next-color 1) 0); con un argumento 1 (luz amarilla), produce 0 (luz roja)
(check-expect (next-color 2) 1); con un argumento 2 (luz verde), produce 1 (luz amarilla)


Esta función no puede utilizar el 3 como argumento!  Por ahora, dejémosla así.

En resumen:

 La definición de datos describe:
- Como formar datos de un nuevo tipo
- Como representar información como datos
- Como interpretar los datos como información
- Las plantillas que se utilizaran para operar sobre tipos de datos

La definición de datos simplifica la función:

- restringe los datos consumidos
- restringe los datos producidos
- Ayuda a generar ejemplos
- Proporciona plantillas


Anterior
Siguiente

sábado, 20 de mayo de 2017

Cómo programar: datos simples (16) - evaluación de la expresión COND

La expresión COND se evalua de la siguiente manera:

1) Si no hay parejas de pregunta / respuesta, señalar que hay error
2)  Si la primera pregunta no es un valor, evaluarla  y reemplazarla con el valor correspondiente. Es decir, reemplazar la expresión COND con una nueva COND en el que la primera pregunta sea reemplazada por su valor (falso o verdadero).
3) Si la primera pregunta es "true" o "else", reemplace toda la expresión COND con la primera respuesta.
4) Si la primera pregunta es "false", deje a un lado la pregunta / respuesta y siga con el siguiente condicional.
5) Si la primera pregunta no es falsa o verdadera, entonces señale un error.

Ejemplo:

(cond [ (> 1 2) "bigger"]
          [ (= 1 2) "equal"]
          [ (< 1 2) "smaller"] )

Evaluación:

La primera pregunta es si 1 es mayor que 2. De acuerdo al paso 2, hay que reemplazar la pregunta por su valor, es decir, por "false", puesto que es falso que 1 sea mayor que 2. El código queda así:

(cond [ false "bigger"]
          [ (= 1 2) "equal"]
          [ (< 1 2) "smaller"] )

Dado que la primera pregunta era falsa, el paso 4 indica que se debe avanzar hacia el siguiente condicional [ (= 1 2) "equal"]. El nuevo código quedaría así:

(cond  [ (= 1 2) "equal"]
          [ (< 1 2) "smaller"] )

Ahora la primera pregunta es si 1 es igual a 2. El paso 2 indica que hay que reemplazar la pregunta por su valor, es decir, por "false", dado que es falso que 1 sea igual a 2. El nuevo código queda así:

(cond  [ false "equal"]
          [ (< 1 2) "smaller"] )

Como la primera pregunta era falsa, el paso 4 indica que se debe avanzar hacia el siguiente condicional [ (< 1 2) "smaller] ). Despues de este cambio, el nuevo código es el siguiente:

(cond  [ (< 1 2) "smaller"] )

Ahora la  primera pregunta es si 1 es menor que 2, lo cual es verdadero.  El paso 3 indica que si la pregunta es verdadera, entonces reemplace toda la expresión COND con la primera respuesta, lo cual queda así:

"smaller"

Como se mencionó en un artículo anterior, no es necesario hacer esta evaluación de forma manual.  Esto es simplemente para ilustrar como DrRacket evalua las expresiones COND. Recuérdese que se puede evaluar esta expresión paso a paso utilizando el boton "paso" o "stepper".  

Anterior
Siguiente
 

Cómo programar: datos simples (15) - condiciones multiples con la expresión COND

Hay ocasiones en que la expresión IF no resulta suficiente, dado que algunas expresiones tienen multiples opciones. Para estos casos se utiliza la expresión COND.

El formato de la expresión COND es el siguiente:

(cond [ pregunta1 respuesta1 ]
          [ pregunta2 respuesta2 ]
          [ pregunta n respuesta n ] )

En el siguiente ejemplo se evalua si la imagen es alta, cuadrada o ancha. Para poner comentario en un bloque completo de código se utiliza #;

(require 2htdp/image)

(define I1 (rectangle 10 20 "solid" "red")) ;se crea la constante I1 que representa un rectángulo de 10x20
(define I2 (rectangle 20 20 "solid" "red")) ;se crea la constante I2 que representa un rectángulo de 20x20
(define I3 (rectangle 20 10 "solid" "red")); se crea la constante I3 que representa un rectángulo de 20x210

;colilla (stub): se crea la función "aspect ratio", cuyo argumento es una imagen (img) y su resultado es un texto.
;(define (aspect-ratio img) " ")

;Plantilla
#;(define (aspect-ratio img)
    (... img))

;creación de la función completa:
(define (aspect-ratio img)
 (cond [ (> (image-height img) (image-width img) ) "tall"]
           [ (= (image-height img) (image-width img) ) "square"]
           [ else "wide"] ))

;Firma: Image --> String 
;Próposito: produce la forma de una imagen, que es una de las siguientes: "alta" (tall), "cuadrada" (square) o "ancha" (wide)
;ejemplos:
(check-expect (aspect-ratio I1) "tall")
(check-expect (aspect-ratio I2) "square")
(check-expect (aspect-ratio I3) "wide")






Cómo programar: datos simples (21) - Enumeración

Diseñar una definición de datos para representar las letras de calificaciones en un curso.  Estas letras son A, B y C, que significan bueno,...