miércoles, 13 de octubre de 2010

Parámetros Opcionales en C# 4

La nueva versión del lenguaje C# agrega la posibilidad de establecer métodos con parámetros nombrados opcionales. De esta forma puede evitarse tener que definir métodos sobrecargados que en realidad hacen los mismo.

Por ejemplo, para definir un método que recibe un string y un entero podemos tener el siguiente código:

public void recibedos(string cadena, int entero){

…..cuerpo del método

}

Ahora supongamos que queremos que el entero sea optativo. Para ello basta con asignarle un valor por defecto:

public void recibedos(string cadena, int entero=0){

…..cuerpo del método

}

De esta manera podemos invocar

recibedos(“una cadena”);

o

recibedos(“una cadena”, 7);

En el primer caso el parámetro entero toma el valor 0 indicado en su declaración (puede indicarse cualquier valor). En el segundo el parámetro recibe el valor 7.

C# 4 soporta también argumentos nombrados. Algo muy útil cuando se tiene por ejemplo un método como el siguiente:

public void haceralgo(int x=0, int y=1){

….cuerpo del método

}

En este caso tenemos dos parámetros opcionales la x y la y.  Es posible que quiera invocarse el método con sólo un valor para la x, con sólo un valor para y o con ambos o sin ninguno.

haceralgo(x:2);
haceralgo(y:3);
haceralgo(y:2,x:3);
haceralgo();

Todas las invocaciones anteriores son válidas, en el primer caso se usa el valor por defecto de y, en el segundo el valor por defecto de x, en el tercero se invirtió el orden (algo no recomendable pero posible) la y recibe 2 y la x 3. En el cuarto caso no se pasan parámetros y la rutina ejecuta con x e y usando sus valores por defecto.

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.