domingo, 2 de octubre de 2011

Expresiones lambda para torpes

Creo que somos muchos (me incluyo) los que usamos las expresiones lambda por inercia y sin saber de dónde salen y cómo sarles su jugo.


Recordemos que una expresión lambda es algo así:

Ctx.articulos.where(art=>art.codigo==’40’)

Pues bien, las expresiones lambda no son más que funciones empaquetadas como un parámetro de una función.
En este ejemplo estamos diciendo que del ienumerable artículos, por cada artículo, devuelva una lista con los elementos que la ejecución de la función "art.codigo=='40'" sea True.

¿De dónde salen las expresiones lambda?

Seguro que este caso os es muy familiar:

static void main() 
{
   int resultado=multiplica(5,2); // ejecutamos la función
}

static int multiplica(int a, int b)  
{
   return a * b;
}

Pues bien,  compliquemos un poco esto.

Un delegado es un puntero a una función; es decir, a una variable de tipo “delegado” le asignamos una función.  El delegado debe de tener los mismos parámetros tanto de entrada como de retorno.
Vamos a usar un delegado para llamar a la función “multiplica”.

delegate int miDelegado(int a, int b);  //declaramos el delegado

static void main()
{
   miDelegado deleg = multiplica;  // asignamos la función al delegado
   int resultado = deleg(5, 2);    // ejecutamos el delegado
}

static int multiplica(int a, int b)  
{
   return a * b;
}


Podemos simplificar un poco esta función llamando a Func<>, que es una nueva forma genérica de crear delegados. (apareció en el Framework 3.5)

static void main()
{
   Func<int,int,int> miMetodo = multiplica;   // asignamos la función al delegado
   int resultado = miMetodo(5, 2);   // ejecutamos el delegado
}

static int multiplica(int a, int b)  
{
   return a * b;
}


En la función Func<int,int,int>, el 1er y el 2º int corresponden a los parámetros de entrada de la función Multiplica, y el último int es la variable de retorno.

Ahora declaremos la función dentro del método Main
static void main()
{
   Func<int, int, int> miMetodo = delegate(int a, int b) { return a * b; };  
   int resultado = miMetodo(5, 2);   // ejecutamos el delegado
}


Esto se puede traducir a una expresión lambda.

static void main()
{
   Func<int, int, int> miMetodo = (a, b)=> { return a * b; };  
   int resultado = miMetodo(5, 2);   // ejecutamos el delegado
}

Y como el cuerpo de la función es sencillo, podríamos incluso resumirlo de esta manera:
static void main()
{
   Func<int, int, int> miMetodo = (a, b)=> a * b ;  
   int resultado = miMetodo(5, 2);   // ejecutamos el delegado
}


Uso de expresiones lambda

Expresiones lambda como parámetros


En este ejemplo tenemos 4 funciones de operaciones básicas, y en la función “opera” le pasamos una expresión lambda como parámetro, tanto declarada como “al vuelo”
static void main()
{
   Func<int, int, int> suma = (x, y) => x + y;
   Func<int, int, int> rest = (x, y) => x - y;
   Func<int, int, int> mult = (x, y) => x * y;
   Func<int, int, int> divi = (x, y) => x / y;

   int result=opera(5, 2, mult);
   int result2=opera(5, 2, (x,y)=>x*y);
}

static int opera(int x, int y, Func<int, int, int> operacion)
{
   return operacion(x, y);
}


Otro ejemplo: contamos y obtenemos los múltipos de 3
static void main()
{
   int[] numeros = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
   int divisiblesx3 = numeros.Count(x =>x % 3 == 0);
   IEnumerable<int> lista = numeros.Where(x => x % 3 == 0);
}

Aquí fijémonos en el intellisense de la función Count.

Nos dice que devuelve un entero, que Count cuelga de un IEnumerable<int> (array números) y que admite una función que probará cada elemento. Esta función admite un int y devuelve un bool, que si cumple la condición,  será un count acertado.

El where lo mismo; nos devolverá una lista con los múltiplos de 3.

Expresión lambda de una función sin parámetros de entrada


Aunque no hayan parámetros de entrada, debemos de poner los paréntesis.
static void main()
{
   Func<string> saludo= () => string.Format("Hola");
   string result = saludo();
}

Expresión lambda de una function compleja

En este ejemplo, vemos cómo la función no debe de ser una simple operación, sino que puede ser de cualquier tamaño

static void main()
{
   Func<string> ObtieneNombre = () =>
   {
       Console.WriteLine("Dime tu nombre");
     string nombre = Console.ReadLine();
     return nombre;
   };
   Console.WriteLine("Hola, " + ObtieneNombre());
}

Expresión lambda de una función que no devuelve datos

Para este caso, sustituyamos la instrucción “func” por “action”

static void main()
{
    Action Saludo = () =>
    {
         Console.WriteLine("Dime tu nombre");
       string nombre = Console.ReadLine();
       Console.WriteLine("Hola, " + nombre);
    };
    Saludo();
}

Espero que este artículo os ayude a que entendáis un poco más las expresiones lambda

Enlaces


Desmitificando las expresiones lambda, por el Maestro Jose María Aguilar.
http://www.variablenotfound.com/2009/03/c-desmitificando-las-expresiones-lambda.html 
Expresiones lambda
http://msdn.microsoft.com/es-es/library/bb397687.aspx

Libro C# 3.0 y LINQ, de Octavio Hernández.
http://www.campusmvp.com/catalogo/Product-C-3.0-y-LINQ_1.aspx



jueves, 22 de septiembre de 2011

Diseñando mediante prototipos (Mocking, prototyping)

Es recomendable, a la hora de montar una interfaz, de sentarte delante de un papel y un lápiz y empezar a pensar en cómo organizar la información de una web o de un formulario.

La inmensa mayoría de los programadores siempre nos hemos llevado mal con el diseño, pero al final nos hemos tenido que meter en él. Un truco que tengo para lidiarme con colores, fuentes, márgenes, etc... es el truco de los sombreros.
  • Me pongo el "sombrero de diseñador" y, sin entrar en código, monto un prototipo con alguna herramienta (gimp, photoshop, excel...) que quede bien organizado y cuya estética sea agradable.
  • Acto seguido, me pongo el "sombrero de programador" y trato de plasmar ese diseño en la herramienta de desarrollo.

Herramientas de prototipado
Mediante un prototipo se consigue, por una parte, centrarte en el "qué quiero", organizar los contenidos e incluso poder acercar al cliente la solución que se le va a entregar.

Para organizar contenidos, con un programa tipo Visio o Word que te proporcionan formas de controles con los que puedes ir montando un borrador de lo que quieres.

Para trabajos más de diseño gráfico, es bueno apoyarse en Gimp o Photoshop e ir montando el diseño a base de capas

Unas herramientas que he descubierto y que facilitan mucho el prototipado son:

Evolus Pencil
http://pencil.evolus.vn/
Proyecto GPLv2 bajo Linux y Windows (parece que también estará pronto para MAC).
También se puede instalar como complemento para Firefox 3.







iPLOTZ
http://iplotz.com/
Producto comercial con una versión libre pero limitada. El acceso libre limita a 1 proyecto y 5 páginas.

Tiene versión offline.


MockFlow
http://www.mockflow.com/
Producto comercial con una versión libre pero limitada a 1 proyecto y 4 páginas.

Tiene también versión descargable.




miércoles, 21 de septiembre de 2011

Publicar entradas en las redes sociales.

Si has venido a este blog a través de un enlace de Twitter, Facebook o Linkedlin, este ha sido mi propósito y el de esta entrada.

Hay una herramienta que "publica" tus entradas de blog en Twitter, Facebook, Linkedlin, StatusNet u HelloTxt.

Se trata de TwitterFeed. http://twitterfeed.com/

Los pasos son muy simples:

  • Te creas una cuenta (gratuita).
  • Añades el feed de tu blog.
  • Añades las redes sociales en las que quieres que se publique la entrada de tu blog.
Puedes configurar el retardo con el que TwitterFeed busca actualizaciones y el comentario con el que anuncias tu entrada en twitter.

Con esto, junto a los botones de las redes sociales, seguro que aumentas el tráfico en tu blog.

Happy blogging!!

Actualización a 21/11/2011:
Otra herramienta online que publica tu blog en las redes sociales es dlvr.it