miércoles, 16 de junio de 2010

Eiffel: forma iterativa cómo expresión lógica

En el artículo anterior vimos la nueva sintaxis para los ciclos llamada forma de iteración. Esta forma más compacta de expresar el ciclo (loop) tiene la ventaja de no evitar efectos laterales mediante la utilización implícita de un cursor nuevo.  Está característica hace a esta forma ideal para usarla como expresión lógica y por ende incorporarla a los contratos.

La forma de lograr expresiones lógicas a partir del ciclo es usando alguna de las dos notaciones alternativas para el cuerpo del ciclo en lugar de la palabra loop:

  • some expresión_lógica
  • all expresión_logica

Por ejemplo:

across mi_lista as  ic   all  ic.item.count > 3 end

En este caso tenemos un ciclo que recorre la lista y consulta cada elemento para ver si la propiedad count es mayor a 3. En caso de cumplirse para toda la lista el ciclo cómo expresión lógica es verdadero. En el caso de usar some en lugar de all el ciclo será verdadero si al menos un elemento cumple la condición.

La utilización de all o some como cuerpo del ciclo sólo es permitido si no hay parte de inicialización en el mismo (from).

Evidentemente esta nueva facilidad sintáctica soportada por contratos (por ejemplo no es posible modificar una estructura recorrida por la forma iterativa across, para ello debe usarse la forma tradicional loop) brinda muchas facilidades a los desarrolladores Eiffel.

martes, 1 de junio de 2010

Nueva construcción para ciclos en Eiffel: across

En el libro Algoritmos, Objetos y Estructuras de Datos se explica detalladamente la estructura de ciclo en Eiffel. Posteriormente a la publicación del libro el lenguaje se vio ampliado con la introducción de una variante que permite un modo de programación seguro,  mas conciso, mas abstracto sin perder las cualidades del calidad de la sentencia loop (invariante y variante de ciclo).
Describiremos entonces lo que llamamos forma de itereación (across), el cual nos permite especificar iteraciones en forma mas compacta. La única condición es que la iteración se debe realizar sobre una estructura que herede de la clase ITERABLE. Todas las estructuras significantes de EiffelBase se han modificado para heredar de ITERABLE.
Para ir al grano vemos como sería la iteración sobre una lista:

Este mismo ejemplo usando la forma tradicional se escribe:

across mi_lista as lc loop print (lc.item) end

from my_list.start until my_list.off loop print (my_list.item) my_list.forth end

Analicemos las partes en que se divide la forma de iteración. Comienza con la "parte de iteración”:


across mi_lista as lc

Esta parte establece cual es la estructura sobre la que va a iterar (mi_lista) y además el cursor a usar (lc). La forma de iteración utiliza un cursor externo creado especialmente para la iteración y cuyo alcance  es sólo en la iteración.
Luego de la parte de iteración tenemos la parte del cuerpo de la iteración:

loop print (lc.item)

Esta parte utiliza el cursor para acceder al elemento apuntado en cada momento de la iteración. Nótese que no hay referencia a mover el cursor para adelante ni a controlar el fin de la lista (mi_lista.off). cómo en el caso tradicional . Todo esto es abstraído por la construcción y evita de esta manera errores de programación al respecto.
Una diferencia muy importante es que la forma de iteración utiliza un cursor externo mientras la forma tradicional (cómo la hemos escrito) usa un cursor interno. La generación automática de un cursor externo es ventajosa porque permite que la iteración no cambie el estado de la lista. Eso nos permite tener activos varios recorridos al mismo tiempo sin  afectarse entre si.
Si el cursor se crea automáticamente ¿cómo atravesamos la lista al revés?, es decir de atrás para adelante.. Una característica importante de la clase ITERABLE es la rutina new_cursor la cual devuelve un cursor nuevo recién creado asociado a la estructura. Este cursor es de tipo ITERATION_CURSOR que a su vez hereda de ITERABLE por lo cual podríamos escribir:

across mi_lista.new_cursor.reversed as c loop print (c.item) end

En el próximo artículo veremos el uso de la forma iterativa como expresión lógica.

jueves, 13 de mayo de 2010

Ciclos y Gráficos usando Matlab

En este artículo saldremos un poco de la estructura del blog para referirnos a una herramienta muy utilizada para el procesamiento de imágenes y el cálculo y manipulación de datos matriciales.  Lo interesante es que permite comunicarse con otros lenguajes (como C#, Java, etc) a través de funciones de librería específicas que facilitan el trabajo

El tipo de datos fundamental en Matlab (y en Octave) es la matriz y existen muchísimas funciones que manipulan este tipo de dato. Pero hoy nos vamos a ocupar de algo menos común y más algorítmico: como realizar ciclos en Matlab/Octave y como aprovecharlos para realizar gráficos de diferentes funciones.

Algunos conceptos previos:
Operador ‘:’
Se trata de una de las formas de definir vectores y matrices más usada y más fácil de utilizar, dada la rápida visualización de la salida sin necesidad de ver el resultado:

octave> x=1:1:10;
octave> x

x =
1 2 3 4 5 6 7 8 9 10

De alguna manera, el : representa un rango, en este caso desde 1 hasta 10 y en el centro se coloca el paso (o sea con que incremento se llega desde 1 hasta 10). Por defecto el paso es 1 pero puede ser cualquier número entero o real, positivo o negativo:


octave> x=10:-1:1
x =
10 9 8 7 6 5 4 3 2 1


Gráficos
plot() crea un gráfico a partir de vectores y/o columnas de matrices, con escalas lineales sobre ambos ejes.
Por ejemplo, vamos a hacer un gráfico de la función 0.1 * |x| * sin(x)
Graficaremos usando valores para x entre -2pi y 2pi

  • Generamos el vector x entre -2p y 2pi

octave> x = -2*pi:0.1:2*pi;

  • Dibujamos:

octave> plot(x, abs(0.1*x) .* sin(x));


.* Recordar que * es el producto de matrices. No funcionará con vectores, mientras que .* es el producto miembro a miembro de los elementos de cada vector

fig1

Generalicemos nuestra función: a * |x| * sin(x) y graficamos dando 3 diferentes valores a la variable a. Por ejemplo:


octave> plot(x, abs(0.1*x) .* sin(x));
octave> plot(x, abs(0.2*x) .* sin(x));
octave> plot(x, abs(0.3*x) .* sin(x));

¿Cómo hacemos si queremos ver los tres gráficos en una misma pantalla?


octave> hold on;

hold es una función que permite agregar gráficos a una figura ya existente, respetando su contenido

Otras funciones útiles:

  • grid: Muestra una cuadrícula en la pantalla del gráfico. Usando grid  on se activa y con off se desactiva
  • title(‘titulo’): Coloca un título al gráfico
  • xlabel(‘leyeda x’): Coloca una leyenda al eje x
  • ylabel(‘leyeda y’): Coloca una leyenda al eje y


Por defecto, el color de las líneas del gráfico es rojo, pero eso se puede cambiar, así como también el estilo de las líneas. En las siguientes tablas se muestran las posibilidades de colores y estilos de líneas:

Símbolo

Color

y

Amarillo

m

Magenta

c

Celeste

r

Rojo

g

Verde

b

Azul

w

Blanco

k

Negro (por defecto)

Símbolo

Tipo de línea

.

Puntos

o

Con círculos

x

Marcas en x

+

Marcas en +

*

Marcas en *

s

Marcas cuadradas

d

Marcas en diamante

^

Triangulo apuntando arriba

Dibujemos, finalmente las 3 funciones en la misma hoja gráfica:

octave> hold on;

octave> plot(x, abs(0.1*x) .* sin(x));
octave> plot(x, abs(0.2*x) .* sin(x),’r+’);
octave> plot(x, abs(0.3*x) .* sin(x),’mo’);

 

fig2

En la siguiente entrega, nos ocuparemos de los ciclos y tendremos más ejemplos.

jueves, 29 de abril de 2010

Novedades en C# 4.0

El lenguaje de programación C# sigue evolucionando junto con el framework .Net. A la par del lanzamiento de la nueva versión de .NET  del VisualStudio 2010 surge la nueva versión de C# la 4.0.

El lenguaje sigue evolucionando con nuevas características, en este artículo mencionaremos algunas de ellas.

Se introduce una nueva palabra clave dynamic, utilizada para definir tipos dinámicos. Los tipos dinámicos son utilizados cuando, por ejemplo, se quiere acceder a código creado con un lenguaje dinámico como Iron-Python . Esta palabra clave le dice al compilador que el tipo de  los objetos se definirá en tiempo de ejecución y puede de esa manera responder a invocaciones dinámicas de métodos.

El siguiente código nos muestra un ejemplo:

dynamic miObjeto = ObtenerObjetoDePython();
miObjeto.Propiedad = “dato”
miObjeto.MetodoDinamico();

En tiempo de ejecución se definirá el tipo de “miObjeto” y el ambiente de run-time descubre las propiedades y genera el enlace dinámico al código correspondiente. El peligro, como con todo lenguaje sin tipificación fuerte, es que el método invocado no este definido en cuyo caso se produce una excepción en tiempo de ejecución. El uso que debería descartarse por completo para este tipo de declaración es usar una misma variable para diferentes tipos de objetos. Eso si que es feo.

Otra de las novedades son los parametros con nombre y variables en métodos. Es posible darle nombre a los parámetros y hacerlos opcionales. Por ejemplo:

public void unMetodo(int par1, String par2="valordefecto", decimal par2=99.85){

//Hacer algo

}

En la declaración precedente hay dos parámetros con nombre y además con valores pode defecto. Esto permite transformarlos en opcionales.

Si tenemos un objeto digamos objetoA que sea de la misma clase que unMetodo, podemos realizar las invocaciones de la siguiente forma

 

objetoA.unMetodo(4,”unvalor”,19.98);

objetoA.unMetodo(4,”unvalor”);

objetoA.unMetodo(4,par2:19.98);

En el último caso se nombra explícitamente el parámetro ya que en esa posición el método tiene declarado un parámetro de tipo string. Es decir los parámetros con valores por defecto son opcionales en la invocación pero si hay diferencia de orden o se saltea alguno deben nombrarse explícitamente para evitar errores de compilación.

Otra novedad es la covarianza de estructuras genéricas pero eso daría para un artículo entero.