jueves, 26 de septiembre de 2013

Quince Años después


En mi post anterior (Leer y Comprender... o Morir) reflexionaba sobre las habilidades para leer y, más importante aún, comprender lo que se lee, en base a un estudio que había realizado el Consejo de la Cultura y que indicaba que "El 84% de los chilenos no entiende lo que lee".

Esta semana se publicó un nuevo estudio que aborda el tema. Realizado por el Centro de Microdatos de la Universidad de Chile, y que concluye que "un 44 por ciento de la población en Chile se encuentra en un nivel de analfabetismo funcional en textos, un 42 por ciento en documentos y un 51 por ciento en el área cuantitativa.". En términos simples, 44% de los chilenos no entiende lo que lee.

Este estudio ha de tener fundamentos estadísticos, metodológicos y técnicos diferentes al anterior, por lo que los resultados podrían no ser comparables, es decir, tengo la impresión que no se puede concluir que hemos mejorado, es decir, pasar de 84% a 44%. En ambos casos la situación es preocupante. Simplemente, cifras malas, más aún, considerando que el analfabetismo funcional implica que las personas saben leer, es decir, pronunciar las palabras y entenderlas de manera aislada tal vez, pero, no son capaces de entender el contenido del texto. Adicionalmente, no deja de ser aún más deprimente, constatar que el estudio es el mismo que se aplicó hace 15 años atrás (1998). Lo que, en términos simples, implica que no ha habido ningún impacto ni avance tangible de todas las políticas públicas aplicadas.

Mi impresión, y sin ningún fundamento científico por cierto, es que se deben fomentar espacios de "competencia" en los colegios que motiven a los estudiantes de otra manera que la regla básica del tipo clase-tarea-examen. Concursos inter-escolares de Matemáticas, Scrabble, Lectura Veloz, Comprensión, etc., que realmente permitan a los estudiantes sentirse desafiados con el resto, con sus pares.



 

martes, 20 de agosto de 2013

Logos... Logobook... Logorama...


Cuando estaba terminando el colegio y tenía que elegir una carrera para estudiar en la Universidad, mi primera opción era estudiar Diseño Gráfico.

Desde niño me han producido fascinación los logotipos y las tipografías (fonts). Cuando era niño, me tocó vivir un tiempo en la casa de mi hermana y me pasaba horas mirando y revisando logotipos. Mi cuñado tenía una colección compuesta por cinco libros con la recopilación de los mejores logos del mundo. Realmente era una colección increíble. Al igual que los microcuentos, los taglines y/o los graffitti´s, los logotipos logran transmitir una idea, valores, estrategias, objetivos, etc., fácil y rápidamente además de, en muchos casos, hacerse inolvidables.

Precisamente, la enorme presencia que tienen los logos (y las marcas) en el mundo contemporáneo, es lo que motivó a Ludovic Houplain, fundador de H5, a realizar un cortometraje llamado Logorama que el año 2009 ganó el Oscar al mejor Cortometraje Animado en la 82a edición.

La película, que dura 16 minutos, se puede ver en el siguiente link de Vimeo.


Para la confección de la película, Houplain y su equipo juntaron más de 50.000 logotipos. Los analizaron, ordenaron y clasificaron para ver cómo y dónde los podían utilizar en la película, es decir, como personajes, animales, decorados, objetos, vehículos, etc. (Dato Freak: hay dos logos de Chile en el libro ¿Sabes cuales son?)

Similar al juego LogoQuiz, ver la película es un ejercicio visual extremadamente interesante ya que permite apreciar el resultado de este trabajo y la utilización de los logos para contextos específicos.

Y, además de obtener un éxito enorme con la película, Houplain editó un libro recientemente, de la mano de Taschen, llamado Logobook y que contiene la colección de todos los logos que recopilaron para hacer la película. El libro está disponible, obviamente, en Amazon.com y, en Chile, en la librería Contrapunto.


Aún cuando no terminé estudiando Diseño Gráfico, sigo maravillándome con los logotipos y las tipografías razón por la que ya me compré el libro. Ahora tengo mi propia colección y podré recordar mi infancia hojeando los libros en la casa de mi hermana y de mi cuñado.

jueves, 15 de agosto de 2013

American Breakfast

Hace algún tiempo comenté sobre la noticia (Primera B) de que iba a comenzar la expansión en Chile de la cadena de comida rápida Denny's y, al parecer, llegó el momento.

El viernes pasado tuve una reunión a unas cuadras de mi oficina y cuando terminó, en vez de tomarme un taxi, decidí devolverme caminando y aprovechar el precioso día posterior a las lluvias. A medio camino, donde antiguamente estaba la Piccola Italia, está el que probablemente sea el primer local de la cadena. Remodelado completamente y con el inconfundible letrero luminoso en la parte superior. Me acerqué a ver si ya estaba abierto. Al parecer, están en las últimas etapas de capacitación interna, habilitación del local, etc., porque sólo había algunas personas almorzando en su interior las que, me imagino, serán las que próximamente trabajarán en él.

Y hoy, para mi sorpresa, salió en el diario la noticia de que a fin de mes (Agosto) se abriría el local lo que terminó de confirmar mis sospechas e, inevitablemente, se convirtió inmediatamente en una nueva tarea en mi lista de pendientes y de futuros Check-In´s en Foursquare. Para los curiosos, el local está ubicado en Isidora Goyenechea 3275 y el menú se puede ver online accediendo al sitio web de Denny's.

La última vez que fui a este restaurant me comí nada más y nada menos que un Fried Cheese Melt. Un delicioso sandwich que figuraba con 895 calorías en el menú, compuesto por "cuatro palitos de mozarella fritos, envueltos en queso cheddar y envuelto entre dos pedazos de pan tostado a la plancha, acompañado de papas fritas y salsa marinara". Honestamente, no recuerdo la salsa, pero recuerdo perfectamente el sándwich. Una delicia.


Por lo pronto, después de revisar el menú, creo que mi primera opción será desayunar un Blueberry Pancake Breakfast y, obviamente, no comer nada el resto del día.

¡Buen provecho!

sábado, 10 de agosto de 2013

La Motivación me Desmotiva

El otro día, un amigo me contó una historia increíble.

En la empresa que trabaja, todos los meses le depositan su sueldo el último día hábil del mes. Esto funcionaba perfectamente hasta el mes pasado en que no fue así. Mi amigo, como siempre, se dispuso a realizar la habitual gimnasia bancaria de principios de mes y pagar todas sus cuentas, cuando se percató que no le habían depositado su sueldo. Ante su sorpresa, envió un mail al área de RR.HH. y de Finanzas pidiendo una explicación, la cual no llegó nunca. Esperó unas horas y, al no tener respuesta, fue a hablar con el Gerente de Finanzas para exigírsela personalmente (no es una empresa muy grande por lo que esto todavía se puede hacer).

Llegó a la oficina y la secretaria le pidió que esperara un momento porque el Gerente estaba ocupado. Unos minutos después, salió alguien de la oficina y la secretaria lo hizo ingresar. Cuando entró, la secretaria cerró la puerta y los dejó solos. El diálogo a continuación:

- Hola. ¿Me dijeron que querías hablar conmigo?
- Bueno, sí, efectivamente. Tengo un problema.
- ¿Cuál? ¿Cuéntame?
- Bueno, el tema es que no me depositaron mi sueldo y necesito pagar mis cuentas.

El Gerente se quedó pensando un momento y luego le contestó:

- Si, es cierto, te pido disculpas por eso, pero la verdad no he estado bien.

Mi amigo, desconcertado, no podía creer lo que estaba escuchando.

- Lo lamento mucho pero eso... ¿Qué tiene que ver con mi sueldo?
- Bueno, sí, lo sé, lo que pasa es que he andado un poco desmotivado últimamente y se me olvidó hacer el rescate.
- ¿Desmotivado? ¿Cuál rescate?
- El rescate de los Fondos Mutuos para pagar los sueldos. Pero no te preocupes ya lo hice y, a más tardar el lunes que viene, tendrás tu sueldo depositado en tu cuenta.
- ¡Pero yo necesito mi sueldo hoy!
- Si, lo sé. Como te expliqué, el lunes contarás con él en tu cuenta.

¿Increíble cierto?

Si revisamos el diálogo, un error como la no realización del rescate es algo que, tal vez, se podría aceptar. Un error lo puede cometer cualquiera. Otro error importante, probablemente, es que no se les haya avisado a las personas que esto iba a ocurrir. También, algo que se puede mejorar. Sin embargo, ¿Es aceptable que la causa del problema sea la desmotivación? ¿Se puede considerar que la obligación de pagar los sueldos está supeditada al estado de ánimo del Gerente de Finanzas?

¿Sería razonable, por ejemplo, pensar que la vida de los pasajeros de un avión está en riesgo porque el piloto está desmotivado?

Claramente no. Pero aún cuando esto puede ocurrir, es decir, que el piloto pueda sentirse en algún momento desmotivado, los pasajeros del avión confían en que es un profesional y que, por lo tanto, seguirá los procedimientos y protocolos necesarios para no poner en riesgo la vida de las personas, independiente de su estado de ánimo. En términos simples, cumplir con sus obligaciones.

La motivación, según su definición, es un motor interno que permite lograr ciertos objetivos y metas, pero, no hay que confundir esto con el logro y el cumplimiento de obligaciones.

En el contexto del trabajo diario, se refuerza siempre la motivación como un elemento fundamental para lograr objetivos, sin embargo, hay que tener claridad respecto al alcance de ella. Es algo así como el déficit atencional que, hoy por hoy, es la excusa para todo.

Consideremos un trabajo determinado y dos escenarios hipotéticos. Pintar una pieza. Una persona motivada probablemente: lo pinte más rápido, se fije en todos los detalles, etc. Una persona desmotivada probablemente: lo pinte más lento, no se fije en los detalles, etc. Pero, considerando que en los dos casos se ha "contratado" el servicio de un "maestro", es decir, un pintor, ¿Es razonable o atribuible que en el primer caso la pieza quede bien y en el segundo no? Y no me refiero a los detalles, me refiero a la tarea "pintar la pieza". Lo esperable es que en los dos casos la pieza quede bien pintada y, en el caso de la persona más motivada, quede mejor. Pero, la tarea inicial, se debe realizar de todas maneras.

La motivación nos permite movernos hacia nuevos estadios, innovar, empujar y, utilizando la palabra tan de moda, emprender. Pero no debe usarse como una excusa para no hacer y/o no cumplir con aquellas cosas que son mínimos necesarios para poder, en el más simple de los casos, cumplir con las obligaciones en un trabajo. Hay cosas que, lamentablemente, se deben hacer.

Dado este escenario, y considerando que la rutina siempre agota, la motivación debe ser el motor que permita movernos hacia lograr objetivos que vayan más allá de las obligaciones y, esto, no sólo aplica al mundo laboral. Los hobbies son un buen ejemplo. Otro ejemplo, son las obligaciones de ser papá, que no se pueden evitar. Hay que cumplir con ellas (ojalá).

La magia, entonces, está en cumplir con las obligaciones de la mejor manera posible para poder, después, dedicarse a otras cosas. Aquellas que, a la larga, llenarán el espíritu. Aquellas en donde realmente se pueda innovar, mejorar, crecer, etc. A la larga, no sirve de nada tener pendientes.

Entonces, el tema de fondo es dónde quieres estar...

¿Cuestionándote las obligaciones o con tiempo para realizar cosas nuevas?


NOTA: Por si acaso, la historia del principio no es real y sólo es un ejemplo para reforzar el objetivo de este post.

domingo, 2 de junio de 2013

Filtros de Tomcat - Parte II

En el post anterior (Filtros de Tomcat - Parte I) expliqué los fundamentos de los filtros en Tomcat. En este segunda parte mostraré un ejemplo práctico de cómo utilizar un filtro.

El código fuente de referencia está disponible aquí.

1. Ejemplo Práctico: Filtro de Autenticación
El objetivo del filtro es asegurar que las páginas sólo estén disponibles para usuarios que han superado exitosamente el proceso de autenticación. Sin un filtro, este requerimiento implica la intervención de todas las páginas .jsp de la aplicación (asumamos por un momento que no se está trabajando con ningún framework específico que ya provea esta funcionalidad).

Para efectos del ejemplo, consideraremos un sitio web muy simple, en adelante "minisitio" (como dicen los abogados), que tiene una página con contenido (index.jsp) y una página de ayuda (ayuda.jsp). La página index.jsp está restringida para los usuarios autenticados correctamente. La página ayuda.jsp no requiere usuarios autenticados para acceder a ella. El flujo típico de autenticación de usuarios es el que se muestra en el siguiente diagrama. Las páginas del lado izquierdo requieren usuarios autenticados. Las páginas del lado derecho no.
2. Autenticación
Hay múltiples maneras de resolver la autenticación de usuarios. Para efectos de este ejemplo, la autenticación exitosa será registrada utilizando las variables de sesión del contexto. En términos simples, si un usuario se autenticó correctamente, se marcará la variable "logged" de la sessión con el valor "true".

Considerando el diagrama anterior, el flujo es como sigue:
  1. Usuario ingresa a la página login.jsp, ingresa su usuario y password y pulsa el botón Ingresar.
  2. Los datos son enviados a la página checkLogin.jsp que valida si el usuario es válido contra algún sistema (base de datos, archivo, etc.)
  3. Si no es válido, reenvía al usuario al paso 1 con un mensaje descriptivo del error. 
  4. Si es válido, se registra el valor "true" en la variable "logged" de la sesión. 
  5. El usuario puede acceder a la página de contenido index.jsp
  6. Cuando el usuario quiere salir del sistema, es enviado a la página logout.jsp que invalida la sesión.
  7. El usuario es redirigido a la página login.jsp
3. Validación sin Filtro
Sin el uso de un filtro, la validación de los usuarios autenticados en las páginas restringidas implicaría agregar el código para validar la información de la sesión en cada página. Si bien es cierto esto se puede hacer reutilizando código por medio de includes, funciones, bibliotecas, etc., no es una estrategia que permita crecer en el tiempo. Un ejemplo simple de este enfoque es que la responsabilidad de agregar la validación queda en manos del desarrollador. Si el desarrollador olvida incorporar el código que valida la sesión, la página quedará expuesta a usuarios no autenticados.

4. Validación con Filtro
Veamos ahora cómo implementar un filtro para validar el acceso a las páginas restringidas del minisitio descrito anteriormente.

4.1 Configuración del Filtro
Considerando el flujo de autenticación descrito previamente (algo así como los requerimientos), hay algunas páginas que deben tener autenticación y otras que no. La página ayuda.jsp es, por definición, una página que no requiere usuarios autenticados, sin embargo, las páginas login.jsp, checkLogin.jsp y logout.jsp tampoco requieren usuarios autenticados. No tiene mucho sentido exigir un usuario autenticado para la página de login por ejemplo. Lo mismo sucede con las otras. Por otra parte, cuando el filtro detecte el acceso de un usuario no autenticado a una página restringida, debe saber a qué página debe enviar al usuario para que se autentique. En el caso del minisitio, la página es login.jsp, sin embargo, podría ser necesario modificar esta página dinámicamente.

Para cumplir con lo anterior, se considera la definición de dos parámetros (exclude y loginPage) en la configuración del filtro para permitir modificar este comportamiento dinámicamente. La configuración, será como sigue en el archivo web.xml.

  <filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>cl.abertini.filters.LoginFilter</filter-class>
    <init-param>
        <param-name>exclude</param-name>
        <param-value>/login.jsp ... /ayuda.jsp</param-value>
    </init-param>
    <init-param>
        <param-name>loginPage</param-name>
        <param-value>/login.jsp</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>


4.2 Construcción del Filtro

Como se mencionó en la primera parte, el filtro se construye heredando de la clase javax.servlet.Filter y se deben implementar los métodos siguientes init(...), doFilter(...) y destroy(). A continuación se describe la implementación realizada en el contexto del ejemplo.
  • init(FilterConfig filterConfig)

    El método, básicamente, lee la configuración del archivo web.xml y rescata la información de los parámetros exclude (páginas que no requieren usuarios autenticados) y loginPage (la página que permite a un usuario autenticarse).

    La configuración se almacena en las variables sExclude y sLoginPage de la clase para ser utilizadas en el método doFilter(...).
  • doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

    Este es el método principal y que será ejecutado cada vez que se acceda a una página del contexto.

    En términos simples, primero se valida que la página a la que se está accediendo no sea una página excluida. En caso de serlo, se pasa el control al siguiente filtro de la cadena (secuencia) por medio de la instrucción chain.doFilter( request, response ).

    En caso de no ser una página excluida, se valida si el atributo "logged" está en la sessión. Para efectos del ejemplo, sólo se valida que exista y no necesariamente que tenga el valor "true".

    Si el atributo no existe, se redirige la respuesta a la página configurada como loginPage. Notar que en este caso, no se traspasa el procesamiento a ningún filtro de la cadena una vez que se reenvió al usuario a la página indicada.

    En caso contrario, es decir, que el atributo "logged" existe, simplemente se traspasa el control al siguiente filtro como se explicó anteriormente.
  • destroy()

    En este ejemplo, dado que la información que administra el filtro (parámetros exclude y loginPage) no consumen muchos recursos, no se realiza nada. Si el filtro que se esté implementado, requiriera administrar grandes cantidades de memoria y/o estructuras de datos complejas y/o cachés o similares, entonces, en este método se debieran implementar los procedimientos para asegurar una correcta destrucción (y almacenamiento tal vez) de la información.
5. Pruebas
Para probar el código anterior, se requiere tener instalado Tomcat 6.X ó superior. Se debe habilitar el contexto en el directorio webapps y levantar el servidor. Una vez levantado, se debiera poder ver el sitio en la siguiente URL:

http://localhost:8080/testSite/login.jsp

Para probar que el filtro está operativo, se puede intentar acceder a la página restringida, con la siguiente URL:

http://localhost:8080/testSite/index.jsp

Si es que no se ha realizado el proceso de autenticación, el filtro debiera bloquear el acceso y reenviar el browser a la página de login. Por el contrario, si se accede a la página de ayuda, no debiera haber problemas ya que está definida como una página sin acceso restringido. Para acceder a esta página, se debe utilizar la siguiente URL:

http://localhost:8080/testSite/ayuda.jsp

Para probar la autenticación, se debe usar la palabra "prueba" como usuario y password en la página de login. Si se ingresan los datos correctos, se debiera poder acceder a la página index.jsp sin problemas.

6. Más Filtros y Extensiones
La distribución estándar de Tomcat 7 incluye varios filtros. En términos generales, los filtros provistos proveen funcionalidades destinadas a mejorar la seguridad del sitio (XSS, CSRF), algunos para depuración y otros para manipular aspectos del HTML entregado al cliente (encoding por ejemplo).

En la siguiente página de Oracle hay una muy buena descripción de la infraestructura de filtros y algunos ejemplos interesantes.

The Essentials of Filters

De todos los ejemplos que he visto al respecto, el siguiente me parece el mejor para demostrar las capacidades de los filtros. El filtro descrito permite reducir el tamaño del HTML entregado al cliente eliminando algunas secuencias como espacios, líneas en blanco, etc. Es interesante porque muestra un truco para poder "capturar" la respuesta (HTML) que va a ser entregada al cliente, como parte del flujo de salida de la cadena (secuencia) de filtros (ver punto 3.2 de la primera parte). Una extensión de este mecanismo sería la construcción de un modelo simple de templates.

Minifying HTML in the Servlet container

7. Conclusiones
La próxima vez que se vaya a implementar una funcionalidad transversal a un sitio, es recomendable analizar si aplica al construcción de un filtro o no. En esta consideración, más allá de las cosas operativas y las precauciones que se pudieran tomar como parte del proceso de desarrollo, la más importante es la posibilidad de asegurar que ciertas funcionalidades se apliquen sin necesidad de depender de la "buena voluntad" de los desarrolladores. Esto, a la larga, no sólo simplifica el proceso si no que, además, asegura que los desarrolladores se focalicen en el desarrollo de las páginas y sus objetivos. Las condiciones higiénicas asociadas ya van a estar implementadas.

sábado, 25 de mayo de 2013

Filtros de Tomcat - Parte I

Supongamos por un momento que es necesario cortar un árbol y se poseen las siguientes herramientas: un Hacha y un Serrucho.

¿Cuál herramienta es la más eficiente?

La mayoría de las personas considerarán el serrucho como la más eficiente. ¿Por qué? Básicamente porque todos conocemos las capacidades de un serrucho y podemos compararla con el hacha. Supongamos ahora que no conocemos ninguna de las herramientas y debemos elegir. La elección no es tan simple porque no conocemos las capacidades de cada una. El sentido común no nos permitiría hacer una elección correcta tampoco.

Lo anterior es un ejemplo muy simple de lo importante que es conocer (y tener) las herramientas adecuadas para realizar una tarea.

Hace algunas semanas atrás, un cliente solicitó una modificación a uno de los productos de la empresa en la que trabajo. La modificación implicaba modificar todas las páginas .jsp de la aplicación y, obviamente, había un plazo que cumplir, por lo que, la intervención manual de todas las páginas no era una opción. Había que buscar otra alternativa. ¿La solución? Filtros de Tomcat.  

1. Filtros de Tomcat
El servidor web Apache Tomcat provee una infraestructura denominada Filtros que permite interceptar el flujo de entrada y salida desde y hacia una página (.jsp) e intervenirlo. La gracia es que el filtro se programa una vez y permite realizar la tarea en todas las páginas existentes en el contexto.

La infraestructura de filtros está disponible desde la Servlet API 2.3 y fue mejorada en la versión 2.4, permitiendo que los filtros sean aplicados incluso en el traspaso de las solicitudes entre las páginas (por medio de las directivas forward o include). Los diagramas siguientes muestran cómo operan los filtros en el flujo de procesamiento de una página en las dos versiones.



2. Ejemplos de Filtros
Considerando el flujo anterior, un Filtro se puede construir para realizar diversas tareas. Algunos ejemplos simples son los siguientes:
  • Validaciones de Seguridad. Validar que cada página cumpla una condición determinada, por ejemplo, que el usuario esté autenticado.
  • Compresión de Salidas/Entradas. Comprimir un archivo automáticamente para minimizar el tiempo de descarga.
  • Registro de Eventos. Generar un log de auditoría respecto con la información de los accesos a las páginas de la aplicación.
  • Modificación/Intervención de Salidas/Entradas. Eliminación de caracteres especiales, sobrantes, limpieza de HTML, etc.
La implementación de un filtro implica las siguientes actividades:
  • Construcción de la clase que implementará el filtro con la funcionalidad deseada.
  • Configuración del filtro en Tomcat para que realice su tarea
Obviamente, la construcción del filtro debe realizarse primero que la configuración, sin embargo, voy a describir la configuración primero porque es relevante para entender el "encadenamiento" de los filtros en el procesamiento y la construcción correspondiente.

3. Configuración del Filtro
La configuración del filtro se realiza en el archivo web.xml del contexto (dentro de la carpeta WEB-INF/). Se debe agregar una configuración como la siguiente para cada filtro que se quiera habilitar:

<filter>
  <filter-name>NOMBRE</filter-name>
  <filter-class>CLASE</filter-class>
  <init-param>
    <param-name>PARAM_1</param-name>
    <param-value>VALOR_1</param-value>
  </init-param>

  :
  <init-param>
    <param-name>PARAM_n</param-name>
    <param-value>VALOR_n</param-value>
  </init-param>
</filter>


<filter-mapping>
  <filter-name>NOMBRE</filter-name>
  <url-pattern>PATRON</url-pattern>
</filter-mapping>


3.1 Sección <filter>.
Permite configurar un filtro en el contexto.
  • NOMBRE. Corresponde a un nombre lógico que identifica la acción/objetivo que realiza el filtro. Por ejemplo: LoginFilter, RegExFilter, HitCountFilter, etc.
  • CLASE. Corresponde al nombre de la clase que implementa el filtro. Obviamente, debe ser una clase que esté disponible para el contexto de la aplicación.
  • PARAM_i y VALOR_i. Se pueden agregar parámetros de configuración relevantes para el filtro agregando nodos del tipo <init-param>. Cada nodo contiene un nombre (PARAM_i) y un valor (VALOR_i).
3.2 Sección <filter-mapping>.
Permite configurar a qué páginas se aplicará el filtro.
  • NOMBRE. Corresponde al nombre lógico del filtro que se indicó en la sección anterior. Debe ser el mismo para que aplique correctamente.
  • PATRON. Corresponde al patrón de páginas para las cuales se desea que se aplique el filtro. Un ejemplo es /* que indica que aplica a todas las páginas del contexto.
Un aspecto importante de la configuración en el archivo web.xml es que el orden en el que se declaran los filtros. Por ejemplo, supongamos que tenemos dos filtros: HitCountFilter y LoginFilter. El primero registra el número de accesos a las páginas del sitio y el segundo valida que un usuario esté autenticado. Veamos dos configuraciones posibles en el web.xml:


La configuración a) implica que primero se registrarán los accesos y luego se validará al usuario. La configuración b) implica que primero se validará al usuario y luego se registrarán los accesos.

Lo anterior se denomina encadenamiento de filtros (Filter Chain) y establece el orden en el que se deben aplicar los filtros. Lo importante de esto es que los filtros se aplican en cadena sobre la entrada y, luego, de manera inversa sobre la salida. Considerando el ejemplo a) anterior, se produce la siguiente secuencia:


La entrada (E1) es recibida y procesada por HitCounter. El resultado (E2) es entregado a LoginFilter quien la procesa. El resultado (E3) es entregado a la página.jsp para su procesamiento. A esta altura, la ejecución de la página.jsp es similar a la ejecución que se realizaría si no hubiera filtros configurados, es decir, la página.jsp se programa como una página normal, independiente de los filtros que podrían haber sido configurados previamente. El flujo de salida opera de la misma manera permitiendo realizar acciones sobre el resultado (output) de la página.jsp. Ejemplos de acciones posibles a este nivel son la compresión del HTML (eliminando espacios en blanco) o el reemplazo de contenido por otro utilizando expresiones regulares.

4. Construcción del Filtro 
Un filtro se construye heredando de la clase javax.servlet.Filter y, en él, se deben implementar tres métodos:
  • init(FilterConfig filterConfig).
    Este método se ejecuta cuando el contexto es cargado por el servidor y sólo se ejecuta una vez. El parámetro filterConfig permite acceder a las configuraciones que se hayan realizado para el filtro en el archivo web.xml por medio de la secciones <init-param/>. 
  • doFilter(ServletRequest request, ServletResponse response, FilterChain chain).
    Este método se ejecuta cuando se requiere aplicar el filtro a la entrada (request) y a la salida (response). El parámetro chain es el que permite traspasar el control al siguiente filtro en la cadena. En casos específicos, se puede interrumpir el flujo programáticamente. Por ejemplo, si el filtro LoginFilter identifica que el usuario no está autenticado, no es necesario ejecutar la página .jsp correspondiente.
  • destroy(). Este método se ejecuta cuando se baja el contexto y puede/debe ser utilizado para liberar recursos que se hayan utilizado para la operación del filtro. Por ejemplo, cachés, contadores, etc.
En la próxima parte describiré un ejemplo práctico de cómo hacer un filtro de autenticación de usuarios que permita validar, de una manera simple y centralizada, que el acceso a las páginas lo realicen únicamente usuarios que se hayan autenticado correctamente.

viernes, 17 de mayo de 2013

Servicios Tecnológicos o Tecnología a su Servicio

Hace algunos días atrás fui a almorzar a un restaurant italiano que está cerca del Hotel Plaza San Francisco en la Alameda (más pistas no puedo dar por ahora). Era la primera vez que iba a ese local, previamente había ido a otros locales en otras partes de Santiago.

Al entrar al local, lo primero que me llamó la atención fue lo que se puede apreciar en la siguiente foto:


Efectivamente, un iPad al borde de cada mesa. Al principio miré con sorpresa esta situación y recorrí todo el local para ver si, efectivamente, todas las mesas tenían uno. Y, bueno, todas las mesas tenían lo mismo: un atril telescópico tipo micrófono, un soporte de metal para el iPad y un cable de corriente que, curiosamente, estaba "integrado" al iPad por la parte posterior. Cuando digo integrado me refiero a que el iPad tenía un agujero en la parte posterior por el cual entraba el cable. No había ninguna posibilidad de desconectarlo de la corriente, a menos que se rompiera o cortara el cable, como hubiera sido posible en el caso de la alimentación tradicional a través del Dock Connector.

Me senté en la mesa y comencé a apretar los botones. En la pantalla aparecía un teclado tipo calculadora que, obviamente, era la clave para habilitar la estación. Como ninguna clave me funcionó, y no me atendían, comencé a buscar mi plato en el menú. En las primeras páginas del menú aparecía una descripción del nuevo sistema, llamado Garzón Virtual desarrollado por la empresa D2 PAD. En ella, se indicaba cómo se debía utilizar, las funcionalidades básicas, ventajas, etc., ninguna de las cuales pude experimentar.

Después de un buen rato, se acercó un garzón y me tomó el pedido. Le pregunté por qué no lo podía hacer por el sistema y me indicó, literalmente, "sólo lo usamos para pedir la cuenta". Se fue con el pedido y dejó el iPad como estaba, es decir, bloqueado. Me puse a jugar con mi iPhone mientras me esperaba el almuerzo. Cuando terminé de almorzar, le hice un gesto a otro garzón, indicándole que necesitaba la cuenta. Volvió unos minutos después con la cuenta y el POS transbank para el pago con tarjeta. Pagué siguiendo el protocolo de seguridad para evitar clonación de tarjetas y luego me fui. El iPad no lo utilizaron nunca en mi presencia.

Hay dos cosas que me llamaron la atención de este sistema, como describo a continuación.

Inversión Tecnológica
En el local debe haber unas 180 mesas. Si cada mesa tiene un iPad, estamos hablando de una inversión aproximada de $44 millones de pesos o US$ 91.000, aproximadamente. Esto considerando el modelo más barato del iPad y sin considerar los "costos" adicionales de implementación (atril, cable, etc.). Si consideramos esto, el costo total debiera bordear los US$ 100.000.

Ahora bien, en el local debe haber unos 50 mozos. Si consideramos el hecho de que, obviamente, no hay un mozo para cada mesa, proveer un iPad a cada mozo, equivale a una inversión aproximada de $12 millones de pesos o US$ 26.000, aproximadamente. Considerando que el mozo transporta el iPad, no se requieren más "costos" de implementación.

Si consideramos la segunda opción, la inversión es un 72% menos que la primera opción.

Entonces, la pregunta obvia es ¿Porqué no se le entregó un iPad a cada mozo en vez de habilitar uno en cada mesa? Yo quiero pensar que hay alguna otra razón por la cual se eligió el primer escenario de inversión respecto al segundo porque, económicamente hablando, no tienen comparación.

Tecnología por Tecnología
Mi experiencia como cliente fue que la solución no se usó nunca. Puede ser que esté destinado a horarios peak y/o a momentos en los cuales no hay tantos mozos disponibles, sin embargo, hecha la inversión, no hay una razón de peso para no hacer uso de la tecnología de manera permanente.

Esto es similar a lo que sucedió, hace algunos años atrás, con los cobradores automáticos de las micros amarillas. La solución era tan ineficiente que, rápidamente, se buscaron mecanismos alternativos de cobro, llegando incluso a implementar los recordados "cobradores-humanos". En este caso, la tecnología sólo sirvió para hacer millonario al que vendía las máquinas y no para resolver el problema.

Ahora bien, si el sistema se usa y permite, efectivamente, agilizar los pedidos desde las mesas sin la asistencia de lo mozos, la pregunta inmediata es si la cocina está preparada para atender todos los requerimientos de manera correcta, esto es, según el orden del pedido, tiempo de los platos, etc. Si la cocina no está preparada y/o no tiene los mecanismos para administrar ese flujo constante de pedidos, entonces, como comenté en mi post anterior, la solución se implementó a medias.

Por lo pronto, tendré que ir nuevamente al restaurant para ver si puedo usar el sistema y vivir la experiencia virtual de atención.

martes, 14 de mayo de 2013

La Solución a Medias

Hace algunos días tuve un "siniestro" (como se denomina en la industria de las aseguradoras un robo o hurto). Para los que no han pasado por una situación así, el proceso es relativamente, engorroso:
  1. Sobreponerse al "siniestro", es decir, acordarse de la mamá de todo el mundo y, después de un rato, calmarse. 
  2. Ir a la comisaría más cercana.
  3. Hacer la denuncia lo que implica, en términos simples, tratar de responder a preguntas imposibles (¿Hay testigos? ¿Tiene algún sospechoso?) y, luego, verificar que los "hechos" han quedado correctamente descritos en español del siglo pasado.
  4. Recibir un comprobante de la denuncia con el número de la Fiscalía correspondiente.
  5. Llamar al día siguiente al número indicado y solicitar el "número de parte". 
  6. Registrar el número de parte en el comprobante para no olvidarlo. 
Hasta ahí el proceso es relativamente estándar. Dependiendo de la compañía de seguros con la que se tenga contratado el seguro, el procedimiento siguiente comprende el ingreso de los datos del siniestro vía web y/o una llamada al call-center para informar los antecedentes. El objetivo final de esto es recibir la autorización para llevar el auto a algún taller para su reparación.

En esta oportunidad me tocó realizar el ingreso de los datos vía web. Una vez terminado el trámite, recibí una confirmación de que el proceso había concluído y que recibiría, posteriormente, las instrucciones de cómo seguir por mail.

Pasaron unos días y recibí un mail de la compañía que indicaba que había algún antecedente que no estaba bien informado. Como lo que faltaba era relativamente simple, instintivamente, respondí el mail inmediatamente con la información pendiente.

Pasaron algunos días y no había recibido ninguna noticia de la compañía de seguros. Tenía el recuerdo que la vez anterior (efectivamente me ha pasado más de una vez), había sido mucho más rápida la respuesta, razón por la cual, revisé el correo enviado previamente sólo para asegurarme que no se me hubiera escapado algún detalle.

Al leer el correo de nuevo encontré el error. Al final, había una frase que decía:
"Por favor, agradecemos No Contestar a esta casilla"
Eso explicaba la demora. No había que responder "por correo", el correo que indicaba que faltaba información. En el mail venían indicados los teléfonos a los que había que llamar para continuar el proceso.

En términos simples, el proceso estaba cojo. Se solicita el ingreso por mecanismos virtuales de la información, sin embargo, no se completa el proceso de la misma manera. Es cierto que hay excepciones pero ésta, claramente, no lo era. Es similar a tener que ir a pagar físicamente a la tienda, después de haber realizado la elección y la compra de algun producto vía web.

En el contexto de la experiencia de usuario y de la transición (lenta pero segura) del modelo de atención de clientes a mecanismos 100% virtuales, es necesario y fundamental, asegurarse de que los trámites/procesos que se vayan a habilitar de manera virtual, efectivamente, se puedan realizar completamente de manera virtual.

Cualquier otro escenario será, símplemente, una ilusión que es necesario evitar ya que, a la larga, los clientes se darán cuenta.

(Fuente: Twitter)

viernes, 10 de mayo de 2013

El Dilema de las Porciones y el Desarrollo

Considere los siguientes avisos:


¿Cuál de las promociones conviene más?

Obviamente la a), pero... ¿Siempre se cumple esto?

El otro día fui al cine con mi familia a ver Los Croods. Nada espectacular la película, sin embargo, mis hijas se morían de ganas de verla. Como es habitual, antes de entrar a ver la película, compramos algo para comer. Me acerqué al mostrador y le pedí a la cajera lo siguiente:

 
En respuesta a mi pedido, la cajera me ofreció lo siguiente:

¿Cuál de las promociones conviene más?
 
Por precio, obviamente, la segunda promoción es la mejor, sin embargo, en términos alimenticios, no tienen relación. Veamos las calorías de cada una de las ofertas anteriores.
 
Promoción 1 = 500 calorías
Promoción 2 = 3.000 calorías
 
Considerando lo anterior... ¿Ahora cuál de las promociones conviene más?

Chile es un país en el que la tasa de obesidad es cada vez más alta. Según los estudios, el 33% de la población entre 20 y 30 años tiene obesidad. Se han realizado diversos programas para intentar frenar esto enseñándole a la gente a comer sano, esto es, comer frutas y verduras de manera habitual en reemplazo de la comida chatarra o rápida. McDonalds, incluso, ha incorporado en sus menús de la Cajita Feliz (que la siguen vendiendo con los juguetes aún cuando se supone estaba prohibido) un postre de manzana en trozos. Algo así como 1/4 de manzana en pedacitos y la posibilidad de reemplazar la bebida por un jugo de naranja "natural".

Más allá de estos esfuerzos, mi impresión es que el problema no es sólo lo que la gente come, sino que, cuánto come. Cuando una persona piensa en comer galletas, no se come una o dos, se come el paquete entero. Si se pide una pizza a domicilio, en términos proporcionales, sale infinitamente más conveniente pedir una promoción con pizza XL que una promoción con pizzas más pequeñas. Situación idéntica a la que ocurre en el cine. La oferta es demasiada y, el problema, es que la gente se acostumbra a comer demasiado o, dicho de otra manera, a no comer lo justo.

Según los estudios realizados en Estados Unidos, las porciones han aumentado en un 69% en el último milenio. El objetivo principal, además de comer variado, es que las personas aprendan a comer la cantidad justa (ver Lifesize). A diferencia de nuestros antepasados, el desarrollo y el progreso nos permiten tener al alcance de la mano, casi de manera permanente, alimentos en cantidades superiores a lo que realmente necesitamos. Esto no sólo es un problema desde el punto de vista de la obesidad, si no que lo es también desde el punto de vista del uso racional de los recursos.

Adicionalmente, si consideramos la carga genética que nos hace fanáticos del azúcar y las grasas, la situación es peor. Un pobre Brócoli, Tomate o Lechuga (7 calorías) tiene la batalla perdida contra un Pollo Frito (560 calorías), una trozo de Torta de Milhojas (380 calorías) o un Sundae con Salsa de Manjar (315 calorías). La opción es evidente (vinculada al placer). Si a esto le sumamos los precios y las promociones, la situación es peor: Una Hamburguesa con Queso, lista para comer, cuesta $500 pesos. Un Pimiento Verde cuesta $400, un pimiento rojo cuesta $800. Una lechuga cuesta $600.

Considerando la interminable oferta y el acceso permanente a alimentos existente, las estrategias de alimentación orientadas a comer sano están destinada al fracaso a menos que se aborde, en paralelo, la concientización respecto al tamaño adecuado de las porciones y lo que es recomendable para evitar el "desequilibrio positivo" (acumulación de calorías) como resultado de consumir más calorías de las que se gastan.

Para las personas con obesidad, la dieta y el ejercicio es el único camino para intentar reducir si IMC. La "dieta" siempre se asocia con restricciones y cambios de hábitos en la alimentación que, casi siempre, resultan imposibles de cumplir: desayunar liviano, almorzar ensalada todos los días, etc. Considerando esto, una estrategia alternativa es reducir el tamaño de las porciones. Si se va a comer pizza, no pedir la XL. Si se va a tomar bebida, un vaso normal (y light). Si se va a tomar once, una marraqueta únicamente, etc. Mi estrategia personal (y que me ha dado resultado) es simple: privilegiar las proteínas y dejar la mitad de la porción que me sirven. De esta manera, en términos simples, como menos y sin restricciones y, aún cuando he intentado en múltiples oportunidades que me sirvan menos en los restaurantes, no hay caso, las porciones son grandes.

El objetivo principal es que la alimentación cumpla su objetivo y no se convierta en una batalla... como en el programa Man vs Food, en que el protagonista, Adam Richman, recorre diversos lugares para comer e intenta romper los records más absurdos del planeta.



lunes, 29 de abril de 2013

Comentar el Código... o la Magia de Ponerse en el Lugar del Otro

En el ámbito del desarrollo de Software, se denomina Código Fuente a una secuencia de instrucciones de computador escritas en un lenguaje comprensible por un ser humano, típicamente, como texto. Haciendo la analogía con el mundo real, el Código Fuente es similar a la descripción de un procedimiento. Por ejemplo, consideremos el siguiente procedimiento de control de acceso:

1. Acérquese a la puerta.
2. Digite su número de identificación.
3. Coloque su mano en el lector biométrico.
4. Espere la validación exitosa.
5. En caso de ser exitosa, abra la puerta.
6. En caso contrario, reingrese su código y comience nuevamente desde el paso número 2.

En el caso del Código Fuente, éste describe (similar a un procedimiento) lo que debe hacer el computador para lograr un objetivo. Está diseñado para facilitar el trabajo de los programadores o desarrolladores de software, que son los profesionales responsables de "traducir" las necesidades de los usuarios en Código Fuente. Una vez que el Código Fuente está listo, es traducido en lenguaje de bajo nivel (lenguaje comprensible por el computador) utilizando un Software denominado Compilador. El compilador actúa como un traductor Inglés-Español, por ejemplo, traduciendo desde el lenguaje procedural (Código Fuente) comprensible por un humano (desarrollador), al lenguaje de máquina comprensible por el computador. El resultado del compilador es lo que se denomina un Ejecutable o Aplicación, y es lo que, finalmente, usan las personas.

En términos generales, el Código Fuente siempre va a estar en fase de Desarrollo y/o Mantención. La fase de Desarrollo corresponde a la fase de construcción inicial de una aplicación, es decir, desde cero. La fase de Mantención corresponde a la fase posterior al término de la aplicación y que, básicamente, se dedica a la tarea de corregir pequeños errores e incorporar funcionalidades nuevas a la misma. En este sentido, es importante tener presente que, a menos que se esté desarrollando una tarea y/o una aplicación muy pequeña, siempre el Código Fuente estará siendo manipulado por varios desarrolladores al mismo tiempo. En el mejor de los casos, desarrolladores en una misma ubicación geográfica. En el peor de los casos, desarrolladores distribuidos globalmente.

En cualquiera de las fases, desarrollar Código Fuente requiere tener capacidad lógica, conocer el lenguaje de programación, ser ordenado, metódico y creativo, aunque suene contradictorio. Y, adicionalmente, exige ser capaz de incorporar Comentarios al Código Fuente que permitan aclarar, declarar, ejemplificar y/o documentar alguna condición particular o específica que no sea evidente para un tercero. Incluso, debiera realizarse en aquellos casos en que no participe nadie más en el desarrollo.

Los Comentarios cobran mayor relevancia cuando se está en un proceso de Mantención. En general, la Mantención implica ser capaz de arreglar y/o mejorar algo sin generar nuevos problemas. Haciendo una analogía con el mundo físico, es como intentar cambiar una rueda con el auto andando. La Mantención es una tarea compleja, en especial, para aquellas aplicaciones que han sido desarrollados hace ya mucho tiempo y/o que han sido mantenidos por variadas personas y, peor aún, para aquellos que no tienen ningún tipo de documentación disponible.

Cuando se realiza mantención de un Código Fuente, un desarrollador debería ser capaz de entender la lógica de la aplicación fácilmente. Cualquier detalle, dependencia y/o vinculación que no sea detectada a tiempo, implicaría de inmediato la posibilidad de incorporar nuevos problemas al intentar hacer una corrección.

La primera manera de evitar esto es, como mencioné antes, incorporando Comentarios al Código Fuente. La segunda manera, y más importante aún, es incorporar Comentarios que realmente hagan sentido. Esto, claramente, es lo más difícil de lograr.

Veamos algunos ejemplos.

1. Tiempo Verbal
Es fundamental comprender que al momento de comentar el código fuente, lo que se requiere es describir lo que hace el código (procedimiento), no lo que "yo he decidido hacer", desde el punto de vista del desarrollador. En este contexto, los comentarios, siguientes son incorrectos.

// Recorro el arreglo
for( int i = 0; i < 10; i++ )
...

// Valido el largo del texto
if( sText != null && sText.length() == 0 )
...

La solución consiste en escribir los comentarios anteriores como sigue (aún cuando siguen siendo incorrectos como se describe en el siguiente punto):

// Recorrer el arreglo
// Validar el largo del texto

2. Comentarios con Sentido
Los comentarios deben incorporar información relevante. El comentario siguiente, no entrega ningún antecedente que un desarrollador con algo de experiencia no pueda identificar de inmediato.

// Recorro el arreglo
for( int i = 0; i < 10; i++ )
...

Ahora bien, si recorrer el arreglo anterior es importante, el comentario se debe reescribir adecuadamente:

// Recorrer el arreglo para determinar la fecha
// de ingreso menor de los documentos elegidos
for( int i = 0; i < 10; i++ )
...

3. Inicialización de Variables
Probablemente, el comentario más inútil y más utilizado por los desarrolladores novatos. Cualquiera de las variantes siguientes son innecesarias.

Form oForm = new Form(); // Inicializo la variable

// Inicializar las variables
String name = "";
String region = "";

// Abro la Conexión con la Base de Datos
Connection oConn = db.GetConnection();

4. Comentar Omisiones Controladas
Durante el desarrollo del Código Fuente, hay condiciones que serán ignoradas. Las razones pueden ser variadas, pero, en aquellos casos en que no son obvias, debe dejarse por explícito la omisión. A continuación, algunos ejemplos.

switch( status) {
  case 1:
    mes = "Encendido";
    break;
  case 0:
    //Fall-Through - Cualquier otro valor
  default:
    mes = "Apagado";
}

En el caso anterior, se deja explícito que, cualquier valor distinto de 1, se considera "Apagado".

try {
  :
  :
}
catch( Exception ex ) {
  // Dummy, no se hace nada
}

En el caso anterior, se deja explícito que no se va a procesar ninguna Excepción ocurrida durante el procesamiento. Si no se incluye el comentario, un desarrollador podría considerar relevante el procesamiento de alguna excepción y romper el flujo normal del programa.

5. Yo Pensé que Tú Pensaste
El uso e inclusión de estructuras de datos, bibliotecas de terceros, etc., es casi una obligación hoy en día. Gracias a fundaciones como Apache y al movimiento OpenSource, no es necesario partir desde cero al momento de realizar un desarrollo, sin embargo, si es necesario documentar las razones por las cuales se realizaron las elecciones correspondientes.

Veamos un ejemplo para el uso de una estructura de datos determinada.

// Inicializo el Hashtable
Hashtable oHT<..., ...> = new Hashtable<..., ...>();

Un programador inexperto, podría considerar que es mejor usar un Hashmap que un Hashtable porque "básicamente proveen las mismas operaciones". El comentario, debe ser explícito para aclarar esto.

// Se usa un Hashtable para evitar problemas de
// concurrencia en el acceso a los datos
Hashtable oHT<..., ...> = new Hashtable<..., ...>();

En el caso de las bibliotecas de terceros, la situación es la misma.

// Recuperar la interfaz del Logger
static Logger log = Logger.getLogger(...);

En este caso, se requiere declarar que se está utilizando una versión de Log4j determinada.

// Se utiliza Log4j 2, para evitar problemas de rendimiento
static Logger log = LogManager.getLogger(...);

En el ejemplo anterior, probablemente el ambiente de desarrollo (IDE) declararía que el método no está presente con otras versiones, sin embargo, es necesario incorporar este tipo de comentarios cuando hay una razón explícita para utilizar una biblioteca determinada.

En términos generales, lo más importante al momento de incorporar Comentarios al Código Fuente, es tener presente que deben ser útiles para otra persona. No son comentarios para (desde el punto de vista del desarrollador) y, al momento de escribirlos, es fundamental ser capaz de ponerse en el lugar del otro, el que, probablemente, mantendrá el Código Fuente.

Como indican Kernighan & Plauger en el libro The Elements of Programming Style:

"No documentes código malo - reescríbelo"

Y, como dice Steve McConnell, en su libro Code Complete:

"Buenos comentarios no repiten el código ni lo explican. Clarifican su intención. Los comentarios debieran explicar, en un nivel de abstracción más alto que el código, lo que se está haciendo".

Incorporar comentarios en el Código Fuente es un proceso importante y, en muchos casos, el proceso de reflexión requerido para determinar qué y cómo incluir un comentario puede ser una ayuda, incluso, para determinar si el código está bueno o malo.

domingo, 28 de abril de 2013

El Esfuerzo


"Cristiano Ronaldo es el mejor, no sólo porque mete goles, sino porque se esfuerza permanentemente, es el primero en llegar y el último en irse" -- Emilio Butragueño en entrevista como director de relaciones institucionales del Real Madrid.

lunes, 22 de abril de 2013

Chile Amable

En el siguiente aviso, la rabia y la frustración, se transmite de una persona a otra sucesivamente.


Por el contrario, en el siguiente aviso, es la amabilidad la que se transmite de una persona a otra generando, obviamente, incertidumbre y sorpresa.



En un país "agitado, frenético y competitivo" como el nuestro,

¿Cuál ejemplo crees que vale la pena seguir?

lunes, 8 de abril de 2013

La Inteligencia

Qué sucede al escuchar la siguiente afirmación:

- Esta persona es muy inteligente... sabe sumar 2 + 5...

La primera impresión es que es una afirmación errónea, en términos de que cualquier persona debiera saber el resultado de la operación indicada. Veamos el mismo ejemplo pero con más información:

- Este niño es muy inteligente... sabe sumar 2 + 5...

¿Distinto cierto? En este caso, probablemente, se considere que la afirmación es verdadera y que, efectivamente, el niño es inteligente. Dependiendo de la edad del niño, probablemente, se tienda a minimizar o maximizar el atributo de la inteligencia de manera acorde: si el niño tiene quince años será muy distinto a si tiene tres.

Si omitimos el "juicio" existente por parte de la persona que emite la afirmación (mamá del niño, hermano, conocido, jefe, etc.) ¿Qué determina que una persona sea inteligente?

La palabra Inteligencia proviene de intellegere en Latín, término compuesto de inter (entre) y legere(leer, escoger), es decir, quien sabe escoger. El diccionario de la Real Academia Española define inteligencia como la "capacidad para entender o comprender" y como la "capacidad para resolver problemas". Otra definición es como "una capacidad mental muy general que permite razonar, planificar, resolver problemas, pensar de modo abstracto, comprender ideas complejas, aprender con rapidez y aprender de la experiencia".

Desde un punto de vista operativo, la inteligencia siempre se ha asociado con la medición de un número conocido como Coeficiente Intelectual (CI o IQ en inglés). El CI se mide por medio de un examen de alternativas (un ejemplo se puede ver aquí). Según este test, una persona normal debiera tener un CI cercano a los 100 puntos. Einstein tenía un CI de 150. Ahora bien, considerando una persona con un CI alto, ¿Es suficiente?

En el libro Outliers de Malcolm Gladwell, se describe un estudio realizado por Lewis Terman a partir de 1921 en los Estados Unidos. El objetivo principal del estudio era determinar cuánto influía el CI en la vida de una persona y en los logros que pudiera realizar a lo largo de su vida. La hipótesis era simple, un niño con el CI alto, debiera ser una persona exitosa, influyente, importante, etc., a lo largo de su vida y, en este sentido, el CI podría/debería actuar como un predictor del éxito. El estudio contempló la identificación de un grupo de niños años con un CI superior al promedio y el correspondiente seguimiento a lo largo de su vida.

De 250.000 niños examinados, se seleccionó a 1.470 con el CI sobre 140, denominados, de ahí en adelante, Termitas en el contexto del estudio en referencia a Lewis Terman. Durante años se acompañó a los Termitas para ver sus logros y avances y, casi al final del estudio, el resultado fue devastador. Si bien los Termitas publicaron libros, fueron exitosos en sus negocios y alcanzaron algunos puestos de cierta relevancia, pocos de estos genios eran conocidos a nivel nacional. La hipótesis no se cumplía. Posteriormente, incluso, el sociólogo Pitrim Sorokin, demostró que si Terman hubiera elegido al azar un grupo de niños con entornos familiares similares a las Termitas, habría reunido a un grupo autor de logros casi equivalente. Por otro lado, también se descubrió que dos estudiantes que habían sido descartados en la selección inicial de Terman porque su CI no era lo suficientemente alto, posteriormente habían ganado el premio Nobel (William Shockley and Luis Alvarez).

Dejemos de lado, por un momento, el problema en la definición de éxito. Los resultados del estudio arrojaron que la hipótesis no se cumplió y que, gran parte de esos niños, no había logrado resultados mejores que el promedio. En otro capítulo del libro se cuenta la historia de un niño superdotado, aficionado a la ciencia, el que, al no tener una beca, no había logrado seguir sus estudios y, por lo tanto, se había quedado a medio camino. ¿La razón? Básicamente, que no había tenido las oportunidades correctas para acceder a las becas pero, más importante aún, que no había tenido las habilidades sociales requeridas para conseguirla. En términos simples, su inteligencia le había jugado en contra en cosas de ámbitos más superficiales.

Veamos un ejemplo relacionado. Considere el siguiente ejercicio:
Escriba todos los usos diferentes que se le ocurran para los siguientes objetos: un ladrillo y una manta.
El anterior es un ejemplo de lo que se denomina "prueba de divergencia". El objetivo principal, a diferencia de las pruebas de CI, es hacer que la imaginación se diriga (diverja) en todas las direcciones posibles. Una prueba de este tipo no mide inteligencia. Lo que mide, en cierta medida, es la creatividad. No hay una respuesta correcta, obviamente, lo que importa es la cantidad y singularidad de las respuestas. Veamos las respuestas de dos estudiantes diferentes:

Respuesta A
(usos de un ladrillo) Hacer la compra cuando la tienda está cerrada. Ayudar a sostener en pie las casas. Para jugar a la ruleta rusa y mantenerse en forma al mismo tiempo (diez pasos ladrillo en mano, media vuelta y lanzamiento; prohibida toda acción evasiva). Para poner encima de la manta y que ésta no se caiga de la cama. Para romper botellas de Coca-Cola vacías. O llenas.
 
(usos de una manta) Para tapar una cama. Para practicar sexo ilícito en el campo. Como tienda de campaña. Para hacer señales de humo. Como vela para un barco, carro o trineo. Como sustituto de una toalla. Como blanco de tiro para miopes. Como salvavidas para gente que salta de rascacielos en llamas.

Respuesta B
(usos del ladrillo) Construcción. Lanzamiento.
 
(usos de una manta) Proteger del frío. Sofocar un fuego. Como una hamaca o parihuela improvisada.

Mirando las respuestas anteriores... ¿Cuál corresponde a una persona con el CI superior? ¿La A? ¿La B?

La respuesta que corresponde es la B. Esto es lo que respondió uno de los estudiantes con el CI más alto de una escuela. Se puede apreciar que la respuesta es extremadamente concreta a diferencia de la anterior. Ahora, olvidando el CI, ¿Cuál respuesta permite identificar a una persona más creativa? Obviamente la A.

Si volvemos a la definición de inteligencia anterior, ¿Es la creatividad un atributo requerido para una persona inteligente? ¿O simplemente basta que sepa aplicar lo que ha aprendido sin errores?

La inteligencia, como atributo medible única y exclusivamente por el CI, no me parece adecuado. Al final, el CI por sí solo, no sirve si es que la persona no tiene otros elementos necesarios para, por ejemplo, comunicarse, convivir en sociedad, respetar a los otros, etc. No sirve que una persona sea un experto en matemáticas si no puede, por ejemplo, hacer algo tan básico como comunicar y compartir sus resultados con el resto del mundo.

Hay diversos atributos que se podrían considerar relevantes para complementar el concepto de inteligencia. Además de la Creatividad, uno de los atributos que siempre me ha parecido característico de personas denominadas "inteligentes", es la Flexibilidad. No desde un punto de vista corporal si no, más bien, que tengan la habilidad de adaptarse a situaciones o escenarios cambiantes. Que no sean rígidos en su manera de ver el mundo.

Conectado con esta reflexión, el otro día me enviaron el siguiente video que muestra una mirada, muy particular, de la Inteligencia y otro atributo relacionado.


¿Qué otro atributo crees que es importante para considerar a una persona inteligente?

Nota: En YouTube, los comentarios del video son realmente sorprendentes. Vale la pena mirarlos y, nuevamente, reflexionar acerca de la denominada "inteligencia" de las personas.

lunes, 1 de abril de 2013

¿El Producto o el Servicio?

La Sustentabilidad es un tema que desde hace mucho tiempo permea las declaraciones respecto a la manera de producir y exportar productos. Frases como las siguientes son repetidas una y otra vez:
  • Debemos hacer un desarrollo sustentable de los recursos naturales.
  • Es necesario dejar de exportar productos básicos y comenzar a exportar valor agregado.
En todas estas afirmaciones, el mensaje subyacente es que es necesario tomar las precauciones para que el proceso productivo sea permanente en el tiempo y, además, las consecuencias no sean peores que las ganancias. En términos simples, si se va a talar un bosque para hacer madera, un proceso sustentable se preocuparía de plantar otro bosque similar para asegurar la disponibilidad del recurso en el futuro. Además de, obviamente, preocuparse de los temas medioambientales.

La segunda afirmación, además, incorpora el concepto de valor agregado. En términos económicos, el Valor Agregado se define como "una característica o servicio extra que se le da a un producto o servicio, con el fin de darle un mayor valor comercial, generalmente se trata de una característica o servicio poco común, o poco usado por los competidores, y que le da al negocio o empresa, cierta diferenciación". En general el Valor Agregado se ve reflejado en el precio. A mayor valor agregado, mayor precio. Por ejemplo, la diferencia entre exportar Silicio o exportar procesadores de computador. El gran desafío, entonces, es poder generar productos y servicios con el mayor valor agregado posible.

Este verano decidimos ir al sur de vacaciones, precisamente a Chiloé, Puerto Varas y sus alrededores. Hace 10 años que no íbamos al sur ya que, aunque suene un poco "snob" y por razones que no vale la pena detallar, decidimos tomar nuestras vacaciones en el extranjero.

Las realidades de Chiloé y Puerto Varas fueron muy distintas. En Chiloé nos quedamos en unas cabañas en la isla Lemuy, un poco más al sur de Castro, en un lugar que se llama Parque Yayanes. Un lugar muy tranquilo y que vale la pena conocer. La Isla, para mi sorpresa, está llena de caminos que unen distintos pueblitos lo que permite recorrerla fácilmente. Es un lugar que permite bajar las revoluciones al mínimo y disfrutar los estímulos de la naturaleza, además de disfrutar de la rica cocina del restaurant del lugar atendido por su dueña. Por ejemplo, un increíble Pastel de Papas con Centolla... una delicia.

En Puerto Varas, por el contrario, nos quedamos en el Hotel del Casino Dreams. Es un hotel cinco estrellas y que, según yo, se las merece. Está ubicado frente al lago y ofrece una vista privilegiada del volcán y la bahía. Está a pasos de la plaza de armas y del centro. Las habitaciones son lujosas y llenas de detalles. Es el ritmo de la ciudad en un paisaje espectacular.





El viaje nos permitió, obviamente, descansar y desconectarnos. Nos permitió apreciar los maravillosos paisajes del sur: los volcanes, los lagos, los bosques, etc. También pudimos comer cosas distintas y disfrutar los sabores típicos de esos lados: Kuchen y Mariscos principalmente. En general, el entorno, la infraestructura y la comida, estuvieron espectaculares. Pero hay algo que, definitivamente, no estuvo a la altura y que, claramente, no ha progresado en los últimos diez años: el Servicio.

Volviendo a la discusión de la sustentabilidad y aplicándola al contexto del turismo, me parece que realmente se debe hacer un esfuerzo por pasar de una oferta centrada en la Oferta (Producto) a una oferta que ofrezca una Experiencia (Servicio + Producto) de primer nivel. Esto, en el contexto de la experiencia del Cliente (turista), realmente lo haría sustentable, es decir, permanente en el tiempo. Todos sabemos que un cliente satisfecho no sólo va a recomendar el lugar si no que, además, probablemente va a volver.

Veamos el siguiente video realizado por Sernatur para promocionar Chile como destino turístico.


El video es realmente excelente. Tiene un mensaje claro y preciso y, además, una dosis de humor. Pero si revisamos el video con un poco más de calma, se puede apreciar que la "oferta" está basada en productos: un entorno precioso, Curanto en Chiloé, Termas en Puerto Natales, Cordero Magallánico y Trekking por los Glaciares. Paisajes y productos espectaculares, sin embargo, no se hace mención al Servicio. Sería ideal que en algún momento el mensaje incluyera una frase del tipo "Y el servicio fue simplemente espectacular". Pero, lamentablemente, no es así.

Mi impresión es que si realmente queremos convertir a Chile en un destino turístico de primer nivel, es necesario que el Servicio suba de nivel también, porque, honestamente, si no fuera por la geografía y los paisajes que son sencillamente espectaculares, el turismo no tendría ninguna posibilidad.

Es un hecho que al salir de vacaciones, uno de los objetivos es conocer lugares y hacer cosas que típicamente no se pueden hacer durante el año: trekking, escalar, nadar, bucear, etc., y mil cosas más, sin embargo, si estas actividades no están acompañadas de un Servicio acorde, es decir, un nivel de atención que realmente permita mantenerse relajado, toda la experiencia no vale la pena.

¿De qué sirve, por ejemplo, hacer alguna actividad y pasarlo bien si al momento de ir a comer la experiencia será desastrosa? 

Experiencia = Producto + Servicio

En términos simples, la Experiencia (desde el punto de vista de un consumidor) se define como la combinación de un producto y un servicio que satisfaga sus necesidades. Hoy, gracias a la globalización y a la democratización de la información, los consumidores están más informados y, por lo tanto, son, y debieran ser, más exigentes.

Hay cinco atributos que diferencian a un Producto de un Servicio:
  • Intangible. Un servicio antes de ser comprado, no se puede ver, oler, degustar, palpar ni sentir. La principal consecuencia de este atributo es que el cliente requerirá referencias concretas del servicio para tomar una decisión: encuestas de satisfacción, comentarios de otros clientes, etc.
  • Inseparable. Un servicio se produce y consume al mismo tiempo. Los productos son fabricados, almacenados, distribuidos por múltiples vendedores, distribuidores, etc.
  • Variable. A diferencia de un producto, los servicios dependen de quién, cuándo y dónde se provean. La principal consecuencia de este producto es la dificultad para ofrecer una calidad permanente en el tiempo.
  • Perecible. Los servicios no se pueden almacenar ni inventariar. Si no se utilizan cuando se ofrecen se pierden. La principal consecuencia de este atributo, al igual que en el caso de los productos, es que es necesario equilibrar la oferta con la demanda.
  • Interacción. Dado que el proveedor y cliente están juntos cuando se produce el servicio, es fundamental cuidar esta relación. En el caso de un producto, el fabricante no necesariamente debe preocuparse de cómo se realiza la venta de su producto por parte de los distribuidores.  
Este último atributo, probablemente, sea el más importante y el que explica la diferencia fundamental entre "vender un producto" o "entregar un servicio". La necesidad de "evaluar" constantemente la calidad de servicio y realizar una mejora continua.

Hoy todas las empresas están intentando ofrecer Experiencias como una manera de diferenciarse. La competencia es muy intensa y, por lo tanto, el producto por si solo no es suficiente. Un ejemplo concreto: Starbucks. Los que han tenido la posibilidad de ir saben que lo que vale en este lugar no es el café, sino la experiencia: el lugar, la atención, la posibilidad de "fabricar" el café, etc. Otro ejemplo, es la variación de los hoteles, que pasaron de ofrecer símples habitaciones a paquetes All-Inclusive o los Cruceros que, también, ofrecen una experiencia completa (sería una muy mala experiencia ir a un Crucero y tener que llevar la comida por ejemplo).

Me gustan los paisajes del Sur, pero, más me gustaría si el Servicio fuera acorde. Ojalá los esfuerzos se enfoquen en producir un cambio para que dejemos de ser un país orientado al Producto y pasemos a ser un país orientado al Servicio. En el caso del Cobre, por ejemplo, sabemos que es una tarea urgente y pendiente.

Para esto, aunque parezca extraño, se requiere que las empresas consideren el Servicio como una variable importante de su oferta pero, tanto o más importante aún, es que las personas comunes y corrientes (clientes, consumidores) estén informadas y sean capaces de exigir un Servicio como corresponde... como decía la famosa frase, "Sin odio. Sin violencia. Sin miedo...".

lunes, 25 de marzo de 2013

Priorización de Actividades - Parte II

En mi post anterior respecto a la Priorización de Actividades, expliqué una forma simple de priorizar las actividades según su Importancia y Urgencia. El problema es que al terminar el proceso de priorización, en cada Zona habrá un listado grande de actividades que deberán ser priorizadas nuevamente. Por la definición de las Zonas, este proceso no se puede aplicar, nuevamente, en cada Zona ya que, por ejemplo, no habría ninguna razón para mantener en la Zona 1 (Urgente, Importante) algo que, en la segunda iteración, fue clasificado como Zona 4 (No Urgente, No Importante). Entonces, la pregunta es cómo hacer una priorización de las actividades de una misma Zona de una manera coherente.

Cada persona tiene su propio proceso para evaluar y determinar el orden en el que realizará un conjunto de actividades. Este orden depende de varios factores o dimensiones (variables) que, obviamente, se deben ponderar simultáneamente para lograr asignar una prioridad (peso) a cada actividad y, como consecuencia, priorizar adecuadamente.

Los factores y/o dimensiones que típicamente influyen en la asignación de la prioridad (peso) son los siguientes:

T = Trabajo/Esfuerzo/Duración. Vinculado principalmente al esfuerzo, horas hombre, trabajo, etc., y cualquier otra dimensión que refleje el tiempo requerido para terminar una actividad. Este factor tiene la complejidad que requiere estimar el esfuerzo, sin embargo, una vez que eso está hecho (y siempre se debe hacer), la priorización es relativamente simple. Por ejemplo, si tenemos 45 minutos y 2 actividades que requieren 30 minutos cada una, es claro que sólo podremos realizar una. Si tenemos 1 hora y tenemos DOS actividades de 30 minutos y UNA de 1 hora ¿Qué habría que hacer? Mi sugerencia es que es mejor tener una lista pequeña de pendientes que una lista grande por lo que, según el ejemplo, sería mejor realizar las DOS actividades de 30 minutos y quedar con UNA actividad pendiente. Claro, esto dependerá de los factores que se describen a continuación.

I = Impacto/Consecuencia. Vinculado principalmente a las consecuencias o el impacto de tener la actividad pendiente. El impacto se debe evaluar respecto al contexto, pero, lo más importante es analizar esta dimensión desde el punto de vista del servicio entregado. Por ejemplo, si una actividad que está pendiente pone en riesgo la calidad de servicio percibida por un cliente, el impacto es alto y, por tal razón, según esta dimensión, debiera tener una prioridad alta.

D = Dependencia/Secuencia/Cadena. Vinculado principalmente a la dependencia de otras actvidades y/o personas de la actividad pendiente. Por ejemplo, supongamos una actividad pendiente que consiste en entregar una parte de un documento para una licitación que cierra a las 13:00 y otra en que se debe terminar de hacer la instalación de un software en un PC. Según esta dimensión, la entrega del documento sería más prioritaria porque el no hacerlo implicaría quedar fuera de la licitación y, por el contrario, la instalación en el PC se puede realizar en cualquier momento.

S = Satisfacción/Realización/Placer. Vinculado principalmente a la satisfacción de ejecutar la actividad. Esta dimensión, similar a la dimensión de trabajo, tiene la complejidad que es personal (e intransferible...) y que debe ser evaluada. Antes de realizar la priorización de actividades según esta dimensión, es necesario definir si se está trabajando en la modalidad "postre", es decir, "lo más rico al final". Hecha esta decisión, la priorización es simple, realizar una actividad que entrega algún tipo de satisfacción siempre va a ser más atractivo que una que no entrega ningún tipo de satisfacción. Si estamos trabajando en la modalidad "postre", se priorizarán las actividades menos satisfactorias al principio y las más satisfactorias al final.

Consideremos algunos ejemplos para aplicar las dimensiones anteriores.

Ejemplo #1 - Restaurant, usted es el mesero
  • Una mesa que ya terminó de comer pide la cuenta
  • Al mismo tiempo, una mesa que llegó hace 2 minutos pide el menú. 
En este contexto, las dimensiones T, D y S se pueden considerar 0. La única dimensión relevante en esta situación es el Impacto. En la primera actividad, el Impacto de no entregar la cuenta pronto o entregarla unos minutos después es casi 0 dado que las personas no se pueden ir sin pagar (por lo menos las honestas). En la segunda actividad, no entregar el menú pronto puede hacer que las personas que estaban esperando las atendieran se vayan. El impacto es alto: se pierde una venta.

Ejemplo #2 - Problema con un Cliente
  • Un compañero de trabajo está esperando una parte para entregar la propuesta de una licitación.
  • Un cliente importante reporta la caída del sitio web.
En este contexto, la dimensión S se puede considerar 0. Respecto a la dimensión T, probablemente es menor para el primer caso que para el segundo (probablemente costará más determinar y corregir el error que responder o entregar lo que se requiere para la propuesta). Respecto a la dimensión D, las dos actividades debieran tener dependencias similares: en los dos casos va a haber personas esperando una respuesta para continuar con su trabajo. Respecto a la dimensión I, el análisis es un poco más complejo porque se requiere comprender bien las consecuencias de la segunda actividad. Si el error impacta la continuidad operacional es muy distinto a si el error ocurre en una funcionalidad que es "opcional" y que no produce ningún impacto. Por el contrario, el impacto de la primera actividad debiera ser siempre el mismo: si no se cumple, no se puede participar en la propuesta.

A niveles estratégicos, las prioridades deben mantenerse para asegurar la obtención de las metas y objetivos planteados. A nivel individual, la lista de actividades habitualmente está influenciada por factores externos por lo que, aún considerando la posibilidad de realizar la identificación de las variables T, I, D y S para un conjunto de actividades en algún momento dado del tiempo, ésta debe ser revisada constantemente.

Al igual que las cartas Gantt, no sirve de nada pegarlas en la pared al inicio del proyecto si no se realiza la "tarea" de actualizarlas durante la ejecución del proyecto. Otro tema es si sirve o no la Gantt pero eso, como en Conan el Bárbaro... "es otra historia".