Microsoft lanza una nueva web donde pone a mano todos sus recursos y proyectos open source

13/08/2020
Artículo original

Microsoft lanza una nueva web donde pone a mano todos sus recursos y proyectos open source

Microsoft Open Source es el nuevo sitio de la empresa de Redmond en el que el público puede navegar a través de todo el ecosistema de código abierto que han estado construyendo en los últimos años.

La web no solo muestra los proyectos open source de Microsoft sino que cuenta con secciones para colaborar con la comunidad, descargar herramientas, explorar su código, y hasta encontrar oportunidades de trabajo.

Todo el sitio web también es open source y su código está en GitHub

Microsoft Open Source

Las dos partes más importantes de este nuevo sitio son las secciones "Get involved" y "Explore projects". En la primera puedes revisar toda la actividad reciente en los proyectos open source de Microsoft alojados en GitHub, y además cuentas con una larga lista de recursos para aprender a colaborar con proyectos de código abierto, y no necesariamente con solo los que mantiene Microsoft.

La segunda sección importante es la lista de proyectos, y ahí te vas a encontrar los principales proyectos open source mantenidos por los ingenieros de Microsoft y la comunidad.

Esto incluye herramientas como Accessibility Insights, .NET, los nuevos PowerToys de Windows 10, la nueva Terminal de Windows 10, TypeScript, y Visual Studio Code.

Pero esos no son los únicos, solo los más importantes. La lista completa es más larga, y en este sitio también te vas a encontrar nuevos proyectos open source de los empleados de la empresa patrocinados a través del Microsoft FOSS Fund.

El mismo Microsoft Open Source, es open source, es decir, puedes encontrar el código en GitHub.

Java: Introducción a los tipos genéricos (vídeo)

11/08/2020
Artículo original

Además del polimorfismo, una característica que permite a la plataforma Java tratar homogéneamente objetos heterogéneos, de los que habitualmente no se conoce su tipo concreto, el lenguaje Java cuenta con otro mecanismo con el mismo fin: los tipos genéricos.

Al definir una clase genérica, o bien una interfaz, en realidad estamos definiendo un meta-tipo, una especie de plantilla a partir de la cual se crearán posteriormente clases/interfaces que actuarán como tipos concretos

El objetivo principal de los tipos genéricos es evitar que tengamos que utilizar la clase Object como tipo para ciertos atributos, parámetros o valores de retorno, como se hacía tradicionalmente en las primeras versiones de Java, al ser Object el ascendiente común de todos los tipos por referencia y, por tanto, un mínimo común denominador. En el siguiente vídeo, nuestro tutor Francisco Charte te ayuda a conocer los aspectos esenciales sobre la definición de clases/interfaces con tipos genéricos, así como la posterior instanciación de tipos concretos. También comprobarás la utilidad de esta funcionalidad de Java:

[youtube:SQSPIb8zvdA]

Transcripción del vídeo

 

En este vídeo vamos a conocer la utilidad de los tipos genéricos de Java definiendo una clase de tipo genérico y viendo cómo podemos utilizarla con diferentes tipos concretos.

Los tipos genéricos de Java son similares, en cuanto a funcionalidad se refiere, a las plantillas de C++ y lenguajes similares. El objetivo es definir una clase, una interfaz o un método cuyos tipos de datos son parametrizables. Los tipos genéricos están estrechamente vinculados a las estructuras de datos clásicas como pueden ser las colas y las listas, etc.

En lugar de definir una clase "Pila" para trabajar con números enteros, otra para trabajar con números en punto flotante, una tercera para trabajar con cadenas y así sucesivamente, es mucho más sencillo definir una clase que sea capaz de tratar con datos de diferentes tipos. En Java esto inicialmente implicaba utilizar el tipo Object, pero esto conlleva una serie de problemas.

Al definir los atributos de una clase como Object es necesario realizar posteriormente conversiones a los tipos concretos que el usuario desea utilizar. Asimismo, es un peligro, puesto que sería potencialmente posible introducir datos de diferentes tipos dentro de esa estructura de datos.

Con los tipos genéricos estos inconvenientes se evitan, puesto que el tipo concreto de dato con el que va a trabajar es un parámetro de entrada más.

Vamos a utilizar, como es habitual, Netbeans y vamos a crear un nuevo proyecto que contará inicialmente con una clase "Plano". El objetivo de esta clase será representar planos cuyas coordenadas podrán ser de diferentes tipos. Podrán ser números enteros de diferentes tamaños o números en punto flotante.

Lo primero que vamos a hacer en esta clase es agregar detrás del nombre de la clase el parámetro T que es el que va a actuar como tipo de dato parametrizable. En lugar de T podríamos asignarle cualquier otro nombre (otro identificador), pero es habitual utilizar esta notación. Completamos la documentación asociada a la clase y, dentro de la definición de la clase, ya podemos utilizar este tipo parametrizable T. Por ejemplo, para definir los atributos con los que va a contar cada uno de los planos, vamos a tener un mínimo y un máximo para el eje X, y un mínimo y un máximo para el eje Y. Observa que el tipo de estos cuatro atributos, de estas variables, es T. No conocemos en este momento cuál va a ser el tipo concreto.

De igual forma, al definir el constructor de esta clase, definimos la lista de parámetros utilizando este mismo tipo y guardamos los datos recibidos en los correspondientes atributos.

Análogamente podemos implementar el habitual método toString() para mostrar el plano, las coordenadas del plano, por la consola y también implementamos los getters y setters, que todos ellos utilizarían el tipo T como parámetro.

Vamos a comprobar cómo podríamos crear objetos de esta clase plano especificando un tipo concreto para este parámetro T.

Nos vamos a nuestra clase principal donde tenemos el habitual método en el que vamos a introducir el código.

Vamos a comenzar declarando una variable Plano<Integer>.

Fíjate que al especificar el tipo ya entre los símbolos menor y mayor, especificamos cuál será el tipo concreto.

Este ha de ser necesariamente un tipo por referencia.

No podemos utilizar tipos primitivos de Java.

Una vez hemos declarado la variable podemos crear un objeto de esa clase y especificar los parámetros.

El objeto podemos mostrarlo por consola.

Si ejecutamos la aplicación aquí podemos comprobar que tenemos un plano con coordenadas enteras.

Análogamente podríamos definir un segundo plano cuyas coordenadas sean de un tipo numérico en punto flotante: Plano<Double> Aquí especificamos cuáles son sus coordenadas.

Suponemos que es un plano virtual con centro en (0,0) y que va de -1 a +1 en los dos ejes.

Mostramos también que este plano por consola, y aquí tenemos las coordenadas.

Partiendo de una única definición para la clase Plano de tipo genérico, estamos creando objetos de una clase Plano que trabaja con enteros y de una clase Plano que trabaja con números en punto flotante.

De hecho, este sistema es tan flexible que podríamos llegar a introducir cualquier tipo de dato como coordenada.

Por ejemplo, vamos a crear una variable de la clase Plano especificando como tipo concreto TiposGenericos.

Observa qué TiposGenericos es esta misma clase.

No es un tipo numérico que podamos utilizar para establecer las coordenadas de un plano pero esto, la clase que hemos definido, Plano, no lo sabe, con lo cual nos permite declarar la variable y a la hora de crear el objeto observa que en este punto no he especificado el tipo.

Podría introducirlo pero no es necesario.

La notación "diamond" que así se denomina en Java, infiere el tipo a partir del tipo de la variable.

Como decía, aquí creamos una variable de tipo Plano<TiposGenericos> y puesto que el constructor espera cuatro parámetros de este tipo TiposGenericos lo que hacemos es crear cuatro instancias de esta clase completa y las facilitamos como parámetro.

No hay ningún problema.

Si ejecutamos el programa veremos cómo funciona.

Lo que ocurre es que las coordenadas de este hipotético plano son objetos que no tienen un sentido para esta funcionalidad concreta.

Para evitar este problema, lo que podemos hacer es establecer una restricción en la definición de la clase Plano, del tipo genérico Plano, especificando que este tipo que hemos indicado aquí, T, ha de ser necesariamente un subtipo de la clase Number, que es la clase que actúa como superclase de todos los tipos numéricos por referencia de Java, incluyendo Integer, Long y Double.

Una vez que hemos introducido esta modificación, si volvemos al código del proyecto podemos comprobar cómo esta sentencia directamente ya genera un error.

No podemos ejecutar el programa.

Vemos que ese error lo impide de tal forma que la única manera de crear variables de tipo Plano sea especificando alguno de los tipos numéricos que ya conocemos.

En resumen, lo que nos permiten los tipos genéricos es facilitar una sola definición de una funcionalidad que posteriormente se aplicaría a diferentes tipos concretos, lo cual en definitiva nos ahorra mucho trabajo de codificación.

Cómo crear checkboxes personalizados espectaculares con tan solo CSS

10/08/2020
Artículo original

Los checkboxes son un tipo de control muy útil. Se trata de esos pequeños cuadraditos que nos permiten marcar opciones para decidir si las activamos o las desactivamos, y que llevan entre nosotros décadas sin apenas cambios:

Un control input de tipo checkbox

Su mayor problema es que son pequeños y no son especialmente bonitos. Y para acabar de denigrarlos, cuando Apple lanzó el iPhone hace ya más de una década cambió el aspecto de este tipo de selectores para que, en vez de ser una simple caja, se comportasen como una clavija, deslizándose de un lado a otro:

Control switch de iOS

Ahora la gente está acostumbrada a este y otros aspectos alternativos y es muy difícil volver atrás.

El caso es que en HTML no están disponibles controles como este switch de iOS, y nos tenemos que conformar con el humilde pero efectivo checkbox. Es también una pena que no exista una manera estandarizada de acceder al aspecto de estos controles para poder cambiarlos como queramos. Así que si queremos darles un aspecto diferente y más moderno tenemos que recurrir a la imaginación y una buena dosis de paciencia.

En este artículo te voy a explicar paso a paso y con detalle cómo conseguir el aspecto que desees. Nosotros haremos este:

Aspecto del checkbox personalizado que vamos a crear

pero podría ser cualquier otro aspecto alternativo. Todo depende de tu imaginación porque los pasos explicados valen para cualquier diseño.

Personalmente me gusta que se muestren el Sí y el No y porque muchos de estos diseños personalizados dejan mucho que desear en cuanto a usabilidad (muchas veces a propósito, como en muchos diálogos de permisos para cookies que podemos encontrar por ahí), y de este modo siempre se ve claramente si están activados o desactivados.

¿Cómo podemos cambiar el aspecto de un checkbox usando tan solo CSS?

Pues como digo, con un poco de habilidad y paciencia. Y conocer muy bien cómo funciona CSS.

El primer paso es ocultar totalmente el control checkbox original. Dado que queremos cambiar su aspecto y CSS no nos proporciona forma de hacerlo directamente, tenemos que ocultarlo para que no se vea:

input[type=checkbox] {
	visibility: hidden;
}

Pero claro, si ocultamos el control ¿cómo podemos pulsarlo para cambiar su valor?

El truco está en sacarle partido a la etiqueta <label> de HTML que está pensada precisamente para eso. Las etiquetas <label> tienen un atributo llamado for que si lo establecemos con el identificador de un control de formulario (en este caso de nuestro checkbox) pulsar sobre ellas es lo mismo que si pulsásemos sobre el propio control. Así, si tenemos esto:

<label for="miCheck">¿Opción activada?:</label>
<input type="checkbox" id="miCheck"/>

Lo que conseguiremos es que al pulsar sobre el texto "¿Opción activada?" de la <label>, cambiaremos el valor del checkbox.

Vamos a aprovechar este hecho para hacer que la etiqueta <label> se comporte como activador/desactivador de la opción.

Para darle el aspecto a nuestro nuevo control vamos a jugar con dos elementos básicos:

  • La etiqueta <label>, que será la que nos permita cambiar el estado del control subyacente, que estará siempre oculto en realidad.
  • Un envoltorio de ambas etiquetas, <label y <input type="checkbox">, que nos permitirá darle un aspecto a su fondo y a su recuadro, de modo que nos quede como necesitemos. Este envoltorio será una etiqueta <div> o similar que encierre a ambos controles. Necesitamos hacerlo así para las partes avanzadas, en concreto los textos a mostrar.

Es decir, en nuestro flamante control personalizado estos dos elementos son los que se observan en esta figura:

Esquema de nuestro control

El código HTML para nuestro "control" checkbox personalizado sería el siguiente:

<div class="checkbox-JASoft">
    <input type="checkbox" id="checkAvanzado" value="Valor"/>
    <label for="checkAvanzado">TEXTO QUE NO DEBERÍA VERSE</label>
</div>

Como vemos, el <div> contiene al checkbox (que estará oculto) y al <label> que sirve para activarlo y desactivarlo, ya que está asociado con el atributo for del mismo.

El contenedor/envoltorio, nos dará el fondo

Lo primero va a ser establecer el <div> contenedor para conseguir ese fondo gris oscuro con bordes redondeados que apreciamos en la figura anterior. Este sería el selector + propiedades CSS que vamos a utilizar:

.checkbox-JASoft {
	display: inline-block;
	position: relative;
    width: 70px;
	height: 30px;
	background: #555;
	border-radius: 15px;
	box-shadow: inset 0px 1px 1px rgba(0,0,0,0.6), 0px 1px 0px rgba(255,255,255,0.3);   
}

Como ves, establecemos su modo de visualización como inline-block para que se muestre en la misma línea que el texto que lo precede, que será su encabezado (y no el <label> que sería lo normal). Por otro lado le establecemos un modo de posicionamiento relativo simplemente para crear un marco de referencia en el que luego podamos posicionar a sus elementos "hijo", en este caso, como veremos enseguida, la etiqueta asociada al control. Por lo demás hay propiedades CSS muy simples para darle un tamaño, los bordes redondeados y una pequeña sombra que le de un aspecto más realista al "control" que estamos creando.

El label nos dará el control de deslizamiento

Bien. Lo siguiente que necesitamos es conseguir que la etiqueta <label> tome la forma de la figura, es decir, un pequeño botón rectangular de bordes redondeados, que será el que pulsemos para activar o desactivar el checkbox. Este sería el CSS para conseguirlo:

.checkbox-JASoft label {

    /* aspecto */
    display: block;
    width: 34px;
	height: 20px;
	border-radius: 17px;
	box-shadow: 0px 2px 5px 0px rgba(0,0,0,0.35);
	background: #fcfff4;
	background: linear-gradient(to top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
    cursor: pointer;
    
    /* Posicionamiento */
    position: absolute;
    top: 5px;
	left: 5px;
    z-index: 1;
    
	/* Comportamiento */
    transition: all .4s ease;
    
    /* ocultar el posible texto que tenga */
    overflow: hidden;
    text-indent: 35px;  
    transition: text-indent 0s;
}

Con estas propiedades perseguimos varios objetivos. En primer lugar darle el aspecto mencionado, para lo cual usamos las propiedades de ancho y alto, bordes, sombreado, el aspecto del cursor al pasarle por encima, y el color de fondo, que en este caso incluye también un degradado lineal de arriba a abajo, bastante sutil para darle un aspecto menos plano (pero para gustos...). Con esto toma el aspecto de "pastilla" con los bordes ovalados que se ve en la imagen de antes.

También necesitamos posicionarlo. Para ello lo colocamos de manera absoluta dentro del <div> (que como recordarás tenía un posicionamiento relativo precisamente para poder hacer esto). Como nuestro control checkbox por defecto no está seleccionado, vamos a hacer que en ese estado este "label" esté colocado en el lado izquierdo, así que lo posicionamos a 5 píxeles de la esquina superior izquierda con left y top. Evidentemente, si el tamaño que le diésemos al elemento de fondo fuese otro recalcularíamos esta posición, pero en nuestro caso, como el "padre" mide 30px de alto y a esta etiqueta le hemos puesto 20px de alto, dejando 5px desde arriba hace que quede perfectamente centrado, y los 5px desde la izquierda lo dejan encajadito en el borde redondeado de su contenedor.

También establezco explícitamente el índice en Z por un motivo que veremos en un momento.

Le establezco una transición para sus propiedades de forma que cambien paulatinamente (en algo menos de medio segundo) y no de golpe. Enseguida veremos por qué.

Finalmente, como puede que el <label> contenga algo de texto y en este caso no podemos permitir que se vea, lo quitamos de la vista indentándolo más allá del ancho (le podríamos poner text-indent:9999px o algo así "exagerado" para no tener que preocuparnos de esta medida si cambiásemos su ancho), lo que se salga de la parte visible no se verá (overflow:hidden) y para que no se vea la animación de este movimiento por culpa del transition anterior, le ponemos una transición inmediata al indentado del texto. Así logramos que aunque haya texto (de hecho le he dejado uno a propósito) que nunca llegue a verse.

De acuerdo, Con esto ya tenemos el botón que activa o desactiva el control checkbox subyacente (porque, recuerda, es un <label> conectado con éste y por tanto pulsándolo lo maneja) colocado en su posición "Off", o sea, no activado.

¿Cómo lo colocamos/definimos en su posición "On", o sea, activado?

Cuando está desactivado y pulsamos sobre la etiqueta, el checkbox cambia de estado aunque no lo veamos, y "se marca". Para detectar esta situación, CSS nos proporciona la pseudo-clase :checked, que toma el control checkbox automáticamente cuando está activado. Como además la <label> está situada justo a continuación del checkbox en el código de nuestro "control", podemos usar este selector + propiedades para cambiar lo que necesitemos, en este caso su posición:

.checkbox-JASoft input[type=checkbox]:checked + label {
	left: auto;
    right: 5px;
}

Fíjate en que lo que hace este selector es seleccionar las etiquetas (<label>) que estén situadas justo a continuación (+) de cualquier <input> de tipo checkbox (input[type=checkbox]) que esté seleccionado (:checked), el cual a su vez debe ser hijo (incluso podríamos poner directo con >) de un elemento con la clase de nuestro "control" aplicada (.checkbox-JASoft). Léelo con calma y verás que es sencillo. Bien, pues una vez seleccionadas lo único que hacemos es moverla al otro extremo del padre, anulando el valor de posición respecto a la izquierda y ahora alineándolo a la derecha, también 5px, claro. Al no cambiar ninguna otra propiedad, su aspecto y comportamiento quedan igual que en el restado desactivado de antes.

¡Estupendo! Ya tenemos el control funcionando y podemos pulsar sobre el elemento <label> para que se active y se desactive y que además se cambie de sitio:

El control personalizado con el aspecto actual, sin textos

Pero aún nos falta algo: los textos para indicar más claramente en qué estado se encuentra.

Cómo le añadimos los textos

Seguro que ya te lo imaginas: sacando partido a los pseudo-elementos :after y :before. En efecto. Es muy sencillo conseguir esos textos combinando éstos con un posicionamiento absoluto dentro de su "padre" y un poco de estilo para darle un aspecto agradable.

El código CSS sería el siguiente:

.checkbox-JASoft:after {
	content: 'NO';
	font: 12px/30px Arial, sans-serif;
	color: #AAA;
	position: absolute;
	right: 10px;
    z-index: 0;
	font-weight: bold;
	text-shadow: 1px 1px 0px rgba(255,255,255,.20);
}

.checkbox-JASoft:before {
	content: 'SÍ';
	font: 12px/30px Arial, sans-serif;
	color: lime;
	position: absolute;
	left: 10px;
	z-index: 0;
	font-weight: bold;
}

Como ves los añadimos dentro del elemento "padre" después y antes respectivamente de los demás elementos.

De este modo tenemos un elemento con el contenido NO con un tamaño de letra adecuado y un alto de línea igual a la altura del padre (30px), de color blanco, posicionado de manera absoluta par que quede un poco separado del borde derecho. También le damos una pequeña sombra para que se vea como "recortado" en el fondo. Hacemos lo mismo con el sólo que ahora lo colocamos en el otro lado, a la izquierda, y no le damos sombreado porque va a ir de color verde-lima que ya destaca lo suficiente.

Cuando el checkbox esté desactivado el <label> se queda pegado a la izquierda y tapa el texto , mientras que cuando está activado se mueve a la derecha y tapa al NO. Es por esto que antes le dimos a la etiqueta un z-index de 1, y a estos dos elementos le hemos dado un z-index de 0. Dado que forman parte del mismo contexto de apilamiento nos aseguramos de que la etiqueta siempre quede por encima de los textos tapando el que corresponda según el estado actual del checkbox.

¡Listo!

Tenemos un control mucho más atractivo y funcional que podemos personalizar fácilmente y que podemos reutilizar en donde lo necesitemos con tan solo replicar la estructura HTML del principio.

Es una pena que HTML/CSS no nos proporcionen una manera más directa y estándar para lograr lo mismo, pero lo cierto es que una vez que lo entiendes es muy sencillo de hacer.

Te dejo aquí (ZIP, 1,39KB) una descarga con el ejemplo para que veas el código completo y puedas jugar con ello.

Si quieres aprender bien y no con "recetas" a dominar HTML y CSS, no te olvides de mi curso sobre el tema, que es probablemente el más completo que vas a encontrar y me tendrás a mi para responder todas tus dudas.

¡Espero que te sea útil!

El lenguaje Prolog: un ejemplo del paradigma de programación lógica

09/08/2020
Artículo original

El lenguaje Prolog: un ejemplo del paradigma de programación lógica

La programación lógica es una variedad de lo que conocemos con programación declarativa, un paradigma opuesto a prácticamente todos los lenguajes de programación populares, desde ensamblador a Python pasando por BASIC, C o Java, a los que agrupamos en la categoría de la programación imperativa.

En dichos lenguajes, la labor del programador es establecer cómo se resuelve un problema mediante sentencias. Sin embargo, la programación lógica no gira en torno al cómo, sino al qué: se trabaja de forma descriptiva, estableciendo relaciones entre entidades, lo que obliga a los que los lenguaje tengan un alto nivel de abstracción.

Este paradigma se basa en la fórmula "algoritmos = lógica + control" (la llamada Ecuación Informal de Kowalski), lo que significa que un algoritmo se crea especificando conocimiento mediante axiomas (lógica) y el problema se resuelve mediante un mecanismo de inferencia que actúa sobre el mismo (control).

Entre los lenguajes de programación lógica podemos destacar Prolog, Lisp o Erlang. Utilizaremos el primero de ellos como ejemplo:

¿Qué es Prolog?

Prolog (derivado de "PROgrammation en LOGique") nació a comienzos de la década de los 70, de la mano de un investigador de la Universidad de Marsella (Alain Colmerauer), mientras dirigiía en un proyecto de tratamiento algorítmico de lenguajes naturales.

Inicialmente se trataba de un lenguaje interpretado hasta que, una década más tarde, se creó un compilador capaz de traducir Prolog en un conjunto de instrucciones de una máquina abstracta denominada WAM ("Warren Abstract Machine"), lo que lo convirtió desde entonces en un lenguaje semi-interpretado.

Su creador, Alain Colmerauer, explica que

"Prolog nació de un desafío: crear un lenguaje de muy alto nivel, aun cuando fuera ineficiente para los informáticos de la época.

La eficiencia consistía entonces en que una máquina ejecutara muy rápidamente programas laboriosamente escritos. El reto consistía en poder escribir rápidamente los programas dejando a la máquina su laboriosa ejecución".

Los ámbitos de la computación donde más se usa Prolog son los de la inteligencia artificial y aspectos relacionados con la misma como el machine learning, procesamiento de lenguaje natural, construcción de sistemas expertos, etc.

Visual Prolog Captura de pantalla del IDE Visual Prolog. Imagen: Prolog Development Center A/S, Denmark (vía Wikipedia).

Sintaxis de Prolog

Un programa Prolog se compone de un conjunto de hechos (afirmaciones simples) y de reglas (que sirven para afirmar la veracidad de un hecho en base a otros). El conjunto de hechos de un programa viene a ser el equivalente a contar con una base de datos, aunque en este contexto se habla de 'base de conocimientos'.

Ejemplo de hechos

es_hijo(Juanito, Juan)

suma(10,5,15)

Una vez definidos estos hechos (el primero significa "Juanito es hijo de Juan" y el segundo "15 es la suma de 10 y 5"), se pueden realizar preguntas al programa, que terminarán siempre en un punto, como el siguiente:

?es_hijo(x,Juan).

Dicha pregunta significa "¿Existe un X que sea hijo de Juan?"; la respuesta del programa sería positiva, y nos arrojaría todas las respuestas posibles ("Juanito"... y el resto de sus hermanos, si los hubiera y los hubiéramos definido como hechos).

Igualmente, a partir de lo anterior, podemos también establecer reglas, que definen nuevas relaciones a partir de relaciones ya dadas. Por ejemplo:

es_padre(X,Y) :- es_hijo(Y,X), es_varón(X).

Este código Prolog se correspondería con la fórmula lógica "∀x ∀y ((es_hijo(y,x) ∧ es_varón(x)) → es_padre(x,y))".

Prolog cuenta también con objetos estructurados:

en_stock( libro(harry_potter_1, autor(j.k., rowling)) ).

Lo anterior nos permite preguntar al programa por varios elementos de la entidad: "¿Tenemos 'harry_potter_1' en stock?", "¿Tenemos algún libro de 'j.k. rowling' en stock?", etc.

No pretendemos con este artículo más que echar un leve vistazo a un enfoque minoritario de la programación y a uno de sus principales ejemplos. Prolog es mucho más complejo y potente que lo que dejamos entrever aquí: si te pica la curiosidad estás de enhorabuena, porque una visita rápida a Google te revelará grandes cantidades de documentación al respecto.

El operador de "unión nulosa" o "nullish coalescing" de ECMAScript: parámetros opcionales y valores por defecto en funciones

05/08/2020
Artículo original

Imagen ornamental de la portada

Una necesidad muy habitual a la hora de programar es la de obtener valores por defecto para los parámetros de las funciones.

Al contrario que en otros lenguajes como C# o Java, en JavaScript no hay manera de forzar la definición de una función y sus parámetros. Podemos definir una función con tantos parámetros como deseemos, pero eso no significa que luego los otros programadores nos los vayan a pasar siempre.

Por ejemplo, en C# defines una función tan simple como esta:

int Sumar(int a, int b)
{
    return a+b;
}

Que suma dos enteros y siempre tienes que pasarle dos enteros para que funcione. Es decir, intentar una llamada a Sumar(5) daría un error inmediato, sin posibilidad ni de compilar.

Esto parece una obviedad, pero en JavaScript eso no es así en absoluto. Si defino la misma función en este lenguaje:

function sumar(a, b) {
  return a+b;
}

Podría llamarla de la manera obvia: sumar(5,4), pero también podría hacer: sumar(5) o incluso sumar() sin pasarle parámetro alguno. Y funcionaría en todos los casos, sólo que si no le paso algún valor obtendría un NaN (un resultado que no es un número).

Y es que en JavaScript todos los parámetros de una función son opcionales.

En otros lenguajes podemos prever esta necesidad especificando el valor que queremos otorgarle a un parámetro opcional cuando no se pasa. Por ejemplo, en el caso de C# la función anterior podríamos definirla así:

int Sumar(int a = 0, int b = 0)
{
    return a+b;
}

Y ahora sí, podría llamarla como quisiera: pasándole dos, uno o ningún parámetro. En caso de que falte alguno, su valor sería el especificado por defecto, en este caso un 0.

Pero en JavaScript no tenemos nada similar a esto en la sintaxis. Aunque eso no significa que no se pueda hacer.

Simulando valores por defecto para parámetros opcionales en JavaScript "clásico"

En JavaScript podemos sacar partido de los valores "verdadosos" y "falsosos" (truly y falsy) generados por conversiones implícitas a booleanos (ver el enlace para detalles), para así especificar valores por defecto para parámetros de funciones en caso de que falten.

Como seguramente sabrás, el operador lógico OR (||) se evalúa con cortocircuito de expresiones lógicas de la siguiente manera:

  • Si el primer operando de la comparación es true devuelve ese mismo primer operando.
  • Si el primer operando es false, entonces se devuelve automáticamente el segundo operando.

Sacando partido a esto es muy fácil definir valores por defecto para los parámetros sin tener que escribir condicionales ni código largo que "embarre" la definición de nuestra función.

Por ejemplo, si tenemos una función test que toma dos parámetros, a y b, y queremos asegurarnos de que ambos tienen sendos valores por defecto, aunque no se hayan especificado, podemos definirla así:

function sumar(a, b) {
  a = a || 0;
  b = b || 0;
  return a+b;
}

Por el efecto que acabo de explicar, lo que se consigue con la primera línea del cuerpo de la función, es que si no se le pasa a la misma el parámetro a (es decir, se recibe un undefined) se le asignará automáticamente un 0 como valor por defecto. Y lo mismo con b. Al evaluarse el operador OR (||) el primer parámetro se convierte en un booleano. Si no está definido esto es equivalente a un "falsoso" (o sea, se convierte implícitamente en un false) y por lo tanto se asigna en la propia variable el segundo operando del OR (el valor por defecto).

Si se le pasa una cadena o un objeto de cualquier tipo se evaluará como true y por lo tanto se devolverá el propio objeto (se reasignará a sí mismo).

Pero esto tiene algunos fallos. Por ejemplo, si el parámetro que esperábamos es un booleano y queremos que el valor por defecto sea true, si usamos esta técnica, cuando se le pasase un false como valor para el parámetro, el efecto que obtendríamos es que se cambiaría su valor a true y, en la práctica, no lograríamos nunca pasarle un false como valor efectivo. Y si esperásemos una cadena de texto y nos valiesen también cadenas de texto vacías, al hacer algo como esto:

function test(p) {
  p = p || 'Hola';
  return p;
}
console.log(test(''));

veríamos por la consola la cadena 'Hola', y no una cadena vacía, como quizá podríamos haber pensado. El motivo es que las cadenas vacías al forzar su conversión a booleano (con el ||) se interpretan como "falsosas", o sea, con false, por lo que nunca podríamos recibir de este modo una cadena vacía. Lo mismo ocurre, por ejemplo, con el número 0 y otros valores "falsosos".

Existen, por supuesto, formas de lograr lo mismo en estas situaciones, pero añaden complejidad a algo que debería ser más sencillo.

Cómo hacerlo bien con ECMAScript

El resumen de lo anterior es que, con JavaScript "clásico" (ECMAScript 5) es posible definir parámetros opcionales con valores por defecto, pero como no tengamos cuidado podemos meter la pata bien a fondo.

Por suerte, en ECMAScript hay una manera mucho mejor de lograrlo: el operador de unión nulosa, más conocido por su extraño nombre en inglés operador nullish coalescing.

Este operador se representa por una doble interrogación ?? y sirve precisamente para lograr de manera sencilla y directa lo que acabamos de describir: ofrecer un valor por defecto cuando un elemento al que necesitamos acceder no existe, es nulo o está sin definir (undefined).

Este operador lleva existiendo en otros lenguajes desde hace mucho tiempo (en C#, por ejemplo, desde hace 15 años al menos), pero en JavaScript/ECMAScript es una propuesta que hace poco tiempo ha pasado a fase 4 y se ha adoptado por todos los navegadores modernos "evergreen".

Su uso es muy sencillo: se pone a continuación de un valor que creamos que puede ser nulo o no definido y, en caso de que lo sea, devolverá lo que pongamos a su derecha, es decir, esto: var resultado = valor ?? valorXDefecto.

Con él, nuestra función de suma con parámetros opcionales quedaría así:

function sumar(a, b) {
  a = a ?? 0;
  b = b ?? 0;
  return a+b;
}

En este caso siempre va a funcionar bien, no como ocurría con la técnica convencional, que debemos vigilar mucho más de cerca.

Lo importante a considerar aquí es que el valor a la izquierda del operador ?? se comprueba para ver si es null o undefined, o lo que es lo mismo: "nuloso" (nullish). Así que actúa como el operador || pero comprobando si es "nuloso", y no "falsoso", por lo que estas expresiones que con || son problemáticas:

var res = false ?? true; // --> false
res = '' ?? 'Hola'; // --> ''
res = 0 ?? 1; // --> 0

no lo son para el operador de nullish coalescing.

Paréntesis obligatorios

¿Qué ocurre si combinas este operador ?? con otros operadores de tipo lógico? Por ejemplo, ¿cuál sería el resultado de esto?:

var a = 0;
var b = false;
var res = a || b ?? true;

El resultado es que se produce un error: Unexpected token ??:

El error que se produce

El motivo es que, al combinar este tipo de operadores, hagas lo que hagas con la precedencia no puedes evitar que la interpretación que hace el programador de lo que está escribiendo entre en conflicto con lo que el diseñador del lenguaje haya decidido. Por ejemplo, en el fragmento anterior, eso se puede interpretar como:

  • (a || b) ?? true
  • a || (b ?? true)

y en ambos casos tiene sentido.

Así que los diseñadores de esta característica decidieron que no puede utilizarse con || o && salvo que especifiquemos claramente la precedencia mediante paréntesis. De este modo se fuerza a que el programa tome la decisión sobre cómo interpretarlo y además facilita su lectura inequívoca por parte de cualquiera.

Cortocircuito de expresiones

Un último detalle sobre el operador: al igual que sus "hermanos" lógicos, implementa cortocircuito de expresiones. Esto quiere decir que si el elemento a la izquierda no es "nullish" y por lo tanto no se va a devolver el valor por defecto, nunca se llega a evaluar el elemento de la derecha:

var res = "algo" ?? funcionValorPorDefecto();

En este ejemplo, como el operando de la izquierda no es null ni undefined (es una cadena) y por lo tanto no se va a devolver el valor por defecto de la derecha (tras el ??), la llamada a la función no se producirá porque no es necesaria. Así que si cuentas con que se debe llamar siempre a esta función (por ejemplo para inicializar algo), tendrías un problema.. Tenlo en cuenta.

Además esto tiene una aplicación interesante: poder generar una excepción en caso de que falte un parámetro indispensable y al que no se le pueda dar un valor predeterminado:

function transformaObjeto(obj) {
	obj = obj ?? function() {throw 'Debes pasar un objeto!!'}();
  //Resto del código
  console.log(obj);
}

En este caso, si no se le pasa un objeto a la función se produce una excepción que podemos capturar. En caso de pasar un objeto se ejecutaría el código de la función.

Esta función anónima, obviamente, podría ser una función cualquiera a la que se llamaría, y de hecho podría también devolver un valor, el cual se asociaría a la variable obj para asignarle un valor predeterminado siguiendo reglas tan complejas como necesitásemos, encapsuladas en esa función a la que llamamos tras el ??.

 

En resumen

El operador doble interrogación, conocido como de nullish coalescing o de "unión nulosa", es muy simple, pero al mismo tiempo un gran añadido al arsenal de herramientas del programador JavaScript. En especial, a la hora de lidiar con argumentos de funciones, ya que en JavaScript éstos siempre son opcionales, pero sin poder especificar un valor por defecto.

Aunque oficialmente forma parte de ECMAScript 2020, aparecido este mismo mes de junio, está soportado hace ya meses por la práctica totalidad de los navegadores modernos excepto Internet Explorer y en concreto lo soportan:

  • Chrome 80+ y todos los que usan Chromium por debajo (Opera, Microsoft Edge, Brave, Vivaldi...)
  • Firefox 72+
  • Safari 13.1+ para macOS
  • Safari 13.5+ para iOS
  • Chrome 84+ para Android
  • WebView de Android 81+

Así que puedes usarlo con bastante seguridad de que no tendrás problemas, salvo en entornos corporativos o donde no te puedas permitir el lujo de prescindir de usuarios de IE o de otros navegadores de móvil como el de Samsung, el de Xiaomi y similares (aunque probablemente lo incorporen pronto).

¡Espero que te resulte útil!

IMMUNE lanza un curso online gratuito de introducción a Python enfocado a jóvenes

31/07/2020
Artículo original

IMMUNE lanza un curso online gratuito de introducción a Python enfocado a jóvenes

Python es, sin duda, el lenguaje de programación más popular del momento. El lenguaje de programación desarrollado por Guido van Rossum hace 30 años es fácil de aprender, muy versátil (se usa en videojuegos, desarrollo web, inteligencia artificial...) y, además, es multiplataforma.

Pero nada de eso sería demasiado importante si no fuera por su 'tirón' laboral. Así, sólo en España, en los últimos meses ha habido más de 2.300 ofertas de trabajo para especialistas en Python. Y fuera de nuestro país es usado en producción por muchas grandes compañías, como Google, Facebook, Spotify o Netflix.

Desde IMMUNE, un hub de educación en tecnología y generación de 'talento STEM' con sede en Madrid, se declaran movidos por su convencimiento

"de que la programación es una herramienta esencial en la creación de soluciones en la era post COVID-19 y del papel fundamental que juega Python en el ámbito tecnológico y profesional del futuro".

Otra opción de formación gratuita en programación

Por ello, acaban de anunciar la puesta en marcha de un curso 100% online de introducción a Python, enfocado a jóvenes y con apoyo tutorizado (da la opción, en caso de que el alumno tenga dudas, de contactar con su tutor una vez a la semana). Dicho curso está dirigido

"a todos aquellos a los que les apasione la tecnología […] los estudiantes aprenderán a su ritmo programación, robótica y 3D a través de la construcción de aplicaciones y juegos, como la creación de una smart city con proyectos de desarrollo sostenible".

Si ya tienes nociones de programación, IMMUNE te ofrece, en primer lugar, la opción de realizar un test cuyo resultado te enviarán por e-mail y te permitirá conocer cómo de preparado estás y así saber desde qué nivel comenzar:

  • Nivel I: "Iniciación a Python. Aprende desde cero y a tu ritmo a programar juegos".
  • Nivel II: "Python para programadores junior. Si ya sabes algo de programación, comienza en este nivel con los retos que tenemos preparados para ti".

Los alumnos trabajarán usando Processing (un proyecto open source que permite a estudiantes, artistas y diseñadores realizar prototipos sencillos), y cada uno de los niveles están compuestos de 4 módulos que contienen los videos explicativos (que IMMUNE define como "píldoras de 5 minutos"), ejercicios y un reto final:

"Aquellos que entreguen el reto del último módulo podrán entrar en la Comunidad Tech de IMMUNE, participar en los concursos y en nuevos retos de programación".

Mi página Web Forms con UpdatePanel elimina el hash (#) de la dirección

29/07/2020
Artículo original

Imagen ornamentalBueno, esto es tecnología viejuna pero que está en uso en miles (o millones) de Web de todo el mundo, incluyendo este blog en el momento de escribir esto en 2020. La maravillosa tecnología ASP.NET Web Forms fue un invento de Scott Guthrie (sí, ese Scott del polo rojo que manda tanto en Microsoft y parece un tipo tan majo) que permitía crear aplicaciones Web orientadas a datos aunque no tengas mucha idea de la Web. Y de hecho aún lo permite, viene incluida de serie en Windows junto con la plataforma .NET, y sigue siendo muy interesante para ciertos tipos de aplicaciones.

Precisamente lo mejor que tiene, es también lo peor: es tan fácil crear algunas aplicaciones sin entender bien qué está ocurriendo que luego "pasan cosas". Esta tecnología se basa en la inclusión de un formulario envolviendo toda la página, que además tiene que ser único, y que ante cualquier acción se envía al servidor y vuelve a la misma página (postback), transfiriendo entre llamadas unos datos llamados ViewState que, como su propio nombre indica, contienen el estado de la página. Este ViewState si no lo controlas puede llegar a pesar muchísimo y a ralentizar las páginas, pero se puede y se debe controlar si conoces bien la tecnología. Más adelante le añadieron soporte para llamadas AJAX de modo que ni siquiera la página tenía que recargarse, para lo cual introdujeron el ScriptManager y el UpdatePanel, dos piezas clave de esta tecnología.

Bien, el caso es que hay un efecto secundario del uso de estas tecnologías que puede volverte loco, aunque no se da con frecuencia. Si utilizas algún tipo de hash en tu URL (esas direcciones que terminan en un # con algo a continuación y que sirven para navegación interna en la página) de modo que permitas saltar directamente a alguna parte de la página, tanto los Web Forms "puros" como los UpdatePanel para AJAX se lo cargan.

El típico ejemplo es una página con varios "tabs" para mostrar información diferente según el que pulses. Puedes cambiar  de uno a otro pulsando en las cabeceras y mantienes cuál es el que está abierto simplemente anotando el identificador con un hash: mipagina.aspx#tab1 y similares.

Bien, el problema es que al actualizar la página con un UpdatePanel, ese #tab1 desaparece, y no puedes mantener la interfaz en donde estaba: te va a cambiar el hash y te dejará tan solo un #, moviéndote la página para arriba del todo, por lo que si tus tabs estaban hacia abajo, pierdes el estado del scroll también. Un horror.

¿Cómo lo solucionamos?

El problema lo produce una función de la infraestructura del Update Panel que se llama _setState y cuyo código es el que se ve en esta figura:

El código del método _setState

Este código por algún motivo toquetea el contenido de la URL actual y en concreto su hash. Sinceramente no tengo ni idea de lo que hace ni he logrado encontrar por ahí información, ya que es código no documentado e interno de cómo funcionan el ScriptManager y el UpdatePanel, pero por lo que se ve es alguna manera de guardar un histórico de interacciones con el panel o algo así. En la práctica, sinceramente, no parece que haga nada útil.

Si para nuestra página es importante que se conserve el hash que hemos puesto tenemos dos opciones:

  1. Redefinir ese método metiendo una comprobación al principio de modo que si hay un hash en nuestra dirección, directamente que no haga nada.
  2. Ir "a saco" y directamente redefinir el método para cargártelo y que no haga nada.

Yo, las veces que me ha pasado (una de ellas muy reciente) lo que he hecho ha sido ir por la segunda opción, que e la vía fácil. Y no he notado problema alguno para poder utilizar las páginas cambiadas con total normalidad. Pienso que el script hace efecto e ocasiones muy poco frecuentes y que no pasa nada por eliminarlo. Pero tienes que probarlo en tu caso concreto.

El código para eliminarlo es muy sencillo. Simplemente tienes que poner esta línea en un script posterior al del ScriptManager:

Sys._Application.prototype._setState = function(){};

Vamos, que directamente le asignas una función vacía, que no hace nada de nada. Así, a lo bestia.

Esto puede ir simplemente en un script justo antes de cerrar el body de la página o bien en el evento DOMContentLoaded de la página o la función $() de jQuery si estás usando esta biblioteca. Lo dejo a tu elección.

Tu página no volverá a perder el hash.

¡Espero que te resulte útil!

Nueva funcionalidad "Informe CSS" en Chrome

29/07/2020
Artículo original

Ya he hablado en otras ocasiones sobre cómo podemos averiguar qué partes de las hojas de estilo de una página no se están usando y también de cómo podemos, incluso, limpiarlas automáticamente. Google Chrome y los navegadores basados en él (Edge, Opera, Brave...) ofrecen de serie algunas herramientas, como la de cobertura, para poder lograr esto.

Hace unos meses que en las versiones preliminares (Canary , Dev y Beta) se incluye una característica experimental que nos ayuda todavía más a comprender cómo funcionan nuestras hojas de estilo (¡o las de otros!): el Informe CSS.

Este informe, una vez cargada una página, se puede solicitar con un clic y nos permite obtener, en una fracción de segundo, un completo informe sobre nuestro CSS:

 

 

Es decir:

  • Un resumen estadístico de las hojas de estilo
  • Todos los colores utilizados, para que no se nos "vayan de madre". Pulsando sobre ellos, además, podemos ver en qué selectores CSS en concreto se están aplicando, por lo que podremos localizarlos fácilmente para corregir lo que necesitemos.
  • Información sobre las fuentes tipográficas empleadas (o con posibilidad de serlo). Lo mismo: si pulsas sobre ella te dice qué selectores la usan y puedes ir directamente a la línea del código fuente en donde están.
  • Selectores que no se utilizan: útil para complementar a lo del enlace del principio e identificar cosas que sobran, aligerando la página.
  • Media queries: para conocer mejor en dónde cambian las visualizaciones y qué selectores están involucrados.

Muy útil.

Este informe, en el momento de escribir esto, es todavía como digo una característica experimental y la tenemos que activar.

Para ello abre las herramientas del desarrollador, vete a la configuración, dentro de ahí a las características experimentales y actívala:

Activación de la característica

Tendrás que cerrar las herramientas del desarrollador y volver a abrirlas para poder ver la nueva pestaña.

Es posible activarla también en los demás navegadores modernos basados en Chromium, o sea, todos excepto Firefox y Safari (en Mac). Por ejemplo, aquí lo tienes en Microsoft Edge para Windows, que además tiene la ventaja de estar en español:

La opción experimental en Microsoft Edge

¡Espero que te resulte útil!

Así puedes aprender a usar PyTorch, la herramienta más accesible para crear redes neuronales

29/07/2020
Artículo original

Así puedes aprender a usar PyTorch, la herramienta más accesible para crear redes neuronales

PyTorch es una librería open source basada en Python, enfocada a la realización de cálculos numéricos mediante programación de tensores, lo que facilita su aplicación al desarrollo de aplicaciones de aprendizaje profundo. La sencillez de su interfaz, y su capacidad para ejecutarse en GPUs (lo que acelera el entrenamiento de los modelos), lo convierten en la opción más asequible para crear redes neuronales artificiales.

Estas redes neuronales se han convertido, quizá, en la rama más prometedora de la inteligencia artificial, siendo la base de otras tecnologías como los sistemas de traducción automática, de reconocimiento de imágenes, facial, de voz...

Originalmente desarrollado por FAER (siglas de Facebook AI Research), PyTorch ha sido a su vez una pieza fundamental en el desarrollo de relevantes aplicaciones de inteligencia artificial, como el Autopilot de Tesla y el Pyro de Uber.

Con el tiempo, y gracias a una facilidad de uso no reñida con su uso en el ámbito industrial, PyTorch se ha convertido en uno de los frameworks de Deep Learning más populares del mundo, al que sólo hacen sombra Tensorflow y Keras, ambos respaldados por el patrocinio de Google.

Instalación de PyTorch

Si quieres ponerte ya mismo a trabajar con PyTorch, el primer paso es instalarlo en tu equipo. Para ello deberás contar con un entorno Conda o con el gestor de paquetes Pip ya instalados. Luego deberás acceder a la web de PyTorch, y en la sección "Quickstart Locally" hacer uso del selector de opciones que se nos ofrece, que nos proporcionará la secuencia de comandos precisa para instalar PyTorch en nuestro PC.

Pytorch

Así, en el ejemplo de la imagen, vemos que hemos seleccionado la versión estable de PyTorch para Windows, para su uso con Python en un entorno Conda y con la versión 10.2 de CUDA, y que la secuencia de instalación en ese caso es la siguiente:

"conda install pytorch torchvision cudatoolkit=10.2 -c pytorch"

Una vez completada la instalación sólo deberemos iniciar nuestro intérprete Python y teclear las siguientes opciones para comprobar que todo se ha instalado correctamente (para lo cual, no deberemos recibir ningún mensaje de error):

">>> import torch"

">>> import torchvision"

Recursos formativos para PyTorch

Pero, una vez instalado, ¿cómo empezar a aprender a usar PyTorch? Estamos de suerte, porque Internet ofrece un buen puñado de recursos formativos gratuitos muy útiles. La primera opción, por supuesto, es la propia web de PyTorch: desde la habitual guía de referencia de la API, hasta un útil videotutorial de 60 minutos explícitamente enfocado a los debutantes en el uso de esta herramienta.

Por su puesto, ambos recursos (como le ocurre también a los tutoriales y a las recetas de ejemplos de código) los encontraremos únicamente en inglés (como también está en inglés el manual "Deep Learning with PyTorch" que la web oficial ofrece 'por tiempo limitado').

Por otra parte, si lo que buscas son videotutoriales en español, el canal de YouTube Not CSV tiene disponible una interesante introducción a PyTorch (dividida en dos vídeos de una hora cada uno).

Fuera de la web de PyTorch, podremos encontrar otros recursos muy útiles, como el curso "Intro to Deep Learning with PyTorch", ofrecido por Facebook Artificial Intelligence a través de Udacity: gratuito, de nivel 'intermedio' y pensado para ser cursado en dos meses; o "PyTorch Basics for Machine Learning" y "Deep Learning with Python and PyTorch", dos cursos consecutivos ofrecidos por IBM en la plataforma edX, también gratuitos y pensado para una duración de 5-6 semanas.

Pero si hay que destacar un recurso formativo gratuito en materia de deep learning, ése debe ser la plataforma de cursos Fast.AI, que ofrece un total de cinco cursos todos ellos basados en el uso de PyTorch.

Usa su propia librería, por lo que no aprenderemos 'PyTorch puro', pero muchos alumnos valoran positivamente su enfoque, centrado en empezar a hacer 'cosas emocionantes' con PyTorch casi desde el primer momento, al contrario que las alternativas de Facebook e IBM que optan por sentar primero las bases teóricas y no aplicarlas a la práctica hasta el final de la formación.

RRHH: Cómo gestionar a programadores en prácticas en tu empresa

29/07/2020
Artículo original

Imagen ornamental

Hay empresas y departamentos de recursos humanos que por política no contratan a programadores en prácticas. El principal motivo suele ser que no saben gestionar a este tipo de perfiles (o no han sabido en el pasado), y no quieren volver a tener que vivir este tipo de experiencias, que en muchos casos derivan en situaciones poco agradables para las personas implicadas. Este artículo va dirigido a esas empresas.

Desde mi punto de vista es un error no darles la oportunidad a los programadores en prácticas siempre y cuando se sepa gestionar dentro de la empresa a este perfil de trabajador.

Si la empresa necesita personas que entren y empiecen a "producir" desde el primer día, evidentemente no deberían contratar a programadores en prácticas con este objetivo.

Ahora bien, si la empresa desde recursos humanos tiene un plan a medio plazo para desarrollar el talento y obtener un retorno a 2 años vista, tiene que aprender a gestionar este tipo de perfiles. Y, evidentemente, enseñar a alguien a trabajar no es fácil -ni agradable- en todos los casos y hay que estar preparados.

¿Qué es un programador con un contrato en prácticas?

Antes de entrar en el fondo del artículo, me gustaría aclarar que en España para poder acceder a un contrato en prácticas como programador hay que estar en posesión de un título universitario o de formación profesional de grado medio o superior, de títulos oficialmente reconocidos como equivalentes o de un certificado de profesionalidad específico.

La duración mínima del contrato será de 6 meses y máxima de 2 años, aunque dentro de estos límites y a través de Convenio Colectivo podrán establecerse distintas duraciones del contrato.

No existe un límite de edad. El único requisito fundamental es que el programador no haya finalizado su titulación hace más de 5 años si éste tiene más de 30 años, o 7 años si posee alguna discapacidad. Si es menor de 30 años, no se aplica ninguno de estos plazos.

La retribución del programador será la fijada en convenio colectivo, sin que, en su defecto, pueda ser inferior al 60% o al 75% durante el primer o el segundo año de vigencia del contrato, respectivamente. En ningún caso el salario será inferior al salario mínimo interprofesional.

No sé cómo se regula esta figura en otros países, pero, en mi opinión, cualquier persona con una titulación o formación acreditada y un contrato debería recibir siempre una remuneración digna a cambio de su trabajo. Trabajar gratis o mal pagado cuando se realiza un trabajo válido no es trabajar, es otra cosa: formación, un favor personal o, directamente, explotación laboral...

IMPORTANTE: existen otras figuras parecidas, como las prácticas no remuneradas, que forman parte del proceso formativo de los programadores, pero en concreto en este artículo me refiero a los programadores con un contrato en prácticas.

Es, en definitiva, un proceso de gestión de expectativas y de evaluación continua. Ni más, ni menos.

¿Qué esperar de un programador en prácticas?

La gestión de las expectativas es clave a la hora de trabajar con programadores en prácticas:

  • ¿Qué espera la empresa del programador?
  • ¿Qué espera el programador de la empresa?
  • ¿Son realistas las expectativas de ambas partes?
  • ¿Se acuerdan por escrito en un plan de desarrollo profesional?
  • ¿Se orientan o traducen dichas expectativas a objetivos o a tareas concretas medibles?
  • ¿Se hace un seguimiento periódico semanalmente de los progresos?
  • ....

Suena a mucho trabajo porque lo es y, además, sin retorno en el corto plazo.

El objetivo principal de los programadores en prácticas remuneradas es ofrecer al programador experiencia a cambio de la realización de una serie de tareas.

Al principio de este tipo de relaciones laborales es importante evaluar qué es capaz de hacer cada persona en ese momento, y tomarlo como punto de partida o "referencia base" para trabajar a partir de ahí.

El objetivo a corto plazo es ver que cada día que pasa estén más capacitadas que cuando llegaron. Con cada tarea que completan, hay que reevaluar sus habilidades actuales y ampliarlas esperando siempre un poco más, subiendo el listón.

Por supuesto, existe un estándar mínimo en función del trabajo que van a hacer, que es para lo que sirven las entrevistas. Se debe contratar a programadores en prácticas que tengan las capacidades básicas para empezar a trabajar y capacidad de aprender lo que no saben.

Aquí incluyo una pequeña lista de las cualidades que son de esperar de un programador en prácticas (y de cualquier persona con las que me gustaría trabajar, la verdad) al empezar:

  • Voluntad y la capacidad de aprender.
  • Conocimiento básico del tipo de trabajo que harán (por ejemplo, "Tendré que escribir código en C# que utilice Internet para enviar mensajes, lo que significa que necesito saber/aprender C# así como los protocolos de mensajería pertinentes").
  • Que tenga iniciativa propia, y proactividad.
  • Que en realidad quiera estar haciendo el trabajo: que se toma el trabajo en serio.

La selección de los candidatos

Para la empresa, la selección de este tipo de perfiles se debe tomar tan en serio como la de los demás puestos "permanentes". Como empresa no se puede llegar a la conclusión de que los programadores en prácticas no funcionan si no tomamos a los candidatos en serio desde el principio, y eso incluye la selección.

Conozco a muchas empresas que contratan en prácticas a los hijos de un conocido o de un cliente, por quedar bien y porque en realidad no tienen ningún tipo de expectativa fijada en el candidato en cuestión.

Meter a una persona en la empresa siempre tiene un impacto en la organización y en la cuenta de resultados. Mejor tomárselo en serio y dar y exigir cosas.

Si saben en lo que se están metiendo y están dispuestos a aprender y mejorar, entonces puedes esperar básicamente cualquier cosa de ellos con el tiempo y la práctica.

Hacerlo así no garantiza que la experiencia vaya a salir bien, pero si minimiza la posibilidad que salgan las cosas mal.

Plan formativo y objetivos

Por un lado, los objetivos de los programadores en prácticas deben centrarse más en la realización de tareas que en ratios o porcentajes. Y por otro, dentro de los objetivos también deberían poder realizar un plan formativo que le interese a la empresa en un plazo determinado.

En campusMVP tenemos cursos para programadores de calidad que son perfectos para trabajar y estudiar a la vez.

Si quieres contar tu experiencia como programador en prácticas remunerado o como empresa, no dudes en compartirla en la sección de comentarios.

 

Página Siguiente