21 de julio de 2011

Ponencia-Taller de Dr. Metrics


El pasado día 19 de Julio del 2011, me pasé por una Ponencia-Taller que realizaba Dr. Metrics (Enric Quintero), organizado por Iniciador Barcelona, sobre Web Anlytics (Análisis Web) para ver que podía sacar de allí para abrir mi mente a futuras ideas, expectativas profesionales, absorber algo más de conocimiento y si se daba la ocasión, hacer algo de networking.

En el anunció del “Taller” se indicaba que Dr. Metrics era un crack de los productos Google Analytics y Optimizer, así que me hizo pensar que spamearia bastante de estos productos, algo que ya me parecía bien, por eso asistí, porque seguro que siempre se puede aprender algo; no obstante la ponencia me sorprendió porque el nivel de SPAM sobre Google fue bajo, además de ser crítico con lo que estos productos aportan y no aportan.

Dr. Metrics, claramente, anunció que el analizar el éxito de tu site no solo se trata de el número de visitas, que páginas se han visitado y cuanto tiempo se ha visitado cada página, sino que al final toda esa información es importante si puedes ligarla con otros aspectos que te puedan describir el comportamiento de los visitantes y del porque de sus interacciones.

Lo que espera todo el mundo cuando consulta las métricas de su site, es ver que beneficio le está aportando, definiendo beneficio como venta de productos, venta de servicios, presentación de la empresa para posterior contacto, fama, etc.

Dr. Metrics dejó claro que las métricas son importantes, pero solo son una pieza de un puzzle, es decir que sin relacionarlas con otros aspectos, se puede decir que no sirven para nada. Entre las otras piezas del puzzle mencionó aspectos como análisis de lo que sucede en tu backend (por ejemplo las transacciones interesantes realizadas en la BBDD, como sería el cierre de un proceso de compra), encuestas al usuario cuando decide abandonar tu site en procesos importantes no finalizados (por ejemplo en medio de el pago con tarjeta de crédito de una compra o contratación de servicio) y algunos aspectos más que mencionó.

Me entusiasmo la idea que recalcó sobre de buscar “los tres pies al gato” cuando ves que las visitas de tu site son bajas o que hay bastantes abandonos en páginas que no tiene mucho sentido (por ejemplo en medio del proceso de compra); lo primero que dijo sobre este aspecto es que antes de ponerse a cruzar datos como un loco es que revises la infraestructura donde se organiza todo este circo, es decir si tu/s servidor/es a lo largo del mundo, plataforma y horario tienen un adecuado rendimiento, tienen una disponibilidad adecuada y todo tu site funciona bien y no van errores 400, 500, … Resumiendo que primero empieces la casa por los fundamentos y no por el tejado, así que primero a invertir en un desarrollo con un nivel adecuado de calidad (incluyendo seguridad) y óptimo, eso si desde mi punto de vista no te pases con lo de óptimo, que luego el desarrollo, llamemos código, es un Jeroglífico solo entienden los iluminados que lo han creado y como esto se larguen de la empresa ya verás los dolores de cabeza que tendrás; y una vez tengas un desarrollo de calidad aceptable te va a tocar invertir en servidor/es, comunicaciones, y buen sys admin que sepa configurar y optimizar, y no nos olvidemos de securizar, los cabr... que van a servir tu site.

Sobre los sistemas/servicios/implementaciones de análisis de métricas, también habló, y no solo de Google Analytics, sino de otros como Yahoo Analytics, u otros sistemas de uso privado como el archiconocido, no gratuito, Urchin; no obstante finalizó este apartado venerando a Google Analytics por su facilidad de uso para usuarios no técnicos, es decir que Google, parece tener “la madre del cordero” en usabilidad dando la importancia que tiene en el hecho de sacarle provecho, ya que tener muchas funcionalidades no sirve de nada si luego no sabes usarlas.

Finalmente llegó el tuno de las preguntas, se preguntaron unas pocas, pero realmente solo recuerdo la mía, así que la voy a dejar aquí, que para eso es mi blog:
¿Te has planteado como va a cambiar todo este mundo de analizar a los usuarios ahora que los gobiernos se están poniendo las pilas en legislaciones de privacidad y que se están realizando, por fin, unas campañas de concienciación sobre la privacidad de los datos en la red? (bueno no fue exactamente así, pero similar)

Y la conclusión de al respuesta fue que la información no es gratis, aunque lo parezca, así que si vas a querer que tus usuarios dejen en tu site tu rastro tendrás que recompensarlos, por ejemplo, descuentos, sorteos, etc; algo que deberían tomar no ta muchos de los explotadores que corren por este país, que parece que todo los tiene que salir gratis, es decir a cambio de nada.

Podéis consultar el resumen de la ponencia realizado por Iniciador Barcelona, junto con slides de la presentación, aquí (y si queréis verme a mí, lo podéis hacer en la foto que hay al público).


Hasta la próxima enfermos.

8 de julio de 2011

[PHP] Verificación de entradas en arrays multidimensionales (2/2)

conjuntoEntradas() {
  [PHP] Verificación de entradas en arrays multidimensionales (1/2)
  [PHP] Verificación de entradas en arrays multidimensionales (2/2)
}


Llegado al punto que al no ser las dos opciones comentadas en el primer post de esta serie de mi gusto por el motivo que ya expuse, además estar desfavorecidas frente a otras, por su menor rendimiento en velocidad de ejecución, podría haber optado por tirar por el derecho y decidir utilizar la función isset(), es decir la que en el comentario de la documentación de función is_null(), se dejaba claro que era la más óptima entre estas tres opciones.

No obstante, durante mi búsqueda de como hacer la verificación de la existencia de claves dentro de los arrays multidimensionales, me tope con otra función, que por nombre y definición (Verifica si el índice o clave dada existe en el array) debería ser la más apropiada para realizar dicho menester; estoy hablando de la función array_key_exists().

No obstante, en los comentarios de la documentación de array_key_exists(), alguien y había comentado la diferencia de velocidad de ejecución con isset(), siendo de nuevo, favorable para ésta última.

Aún habiendo este comentario, yo quería hacer mis pruebas, ya que al final del comentario, se menciona que la diferencia de rendimiento no es tan grande en un sistema operativo Mac o Linux, como lo es un MS Windows; además la prueba del comentario se realiza sobre un array unidimensional y no multidimensional, que son con los que yo me iría encontrando en mis implementaciones y por otra parte, me entró la vena friki por realizar la prueba sobre un profiler, y como ya había utilizado en una vez anterior, el elegido fue Xdebug, utilizando, con el mismo motivo, el visor KCachegrind; así que manos, la obra.

Primero la implementación de las funciones que me permitirán discernir entre las dos distintas formas de verificar la presencia de claves en arrays multidimensionales con la función array_key_exists().

function aa_verificacion_a_una_instruccion_fallo_2d($var1) {
   for ($i = 0; $i < 10000; $i++) {
        if (@array_key_exists('clave2.5', $var1['clave1.3'])) {
        }
    }
}

function ab_verificacion_por_dimension_fallo_2d($var1) {
    for ($i = 0; $i < 10000; $i++) {
        if (array_key_exists('clave1.3', $var1) && 
                (array_key_exists('clave2.5', $var1['clave1.3']))) {
        }
    }
}

function ba_verificacion_a_una_instruccion_fallo_3d($var1) {
   for ($i = 0; $i < 10000; $i++) {
        if (@array_key_exists('clave4.1', $var1['clave1.3']['clave2.1'])) {
        }
    }
}

function bb_verificacion_por_dimension_fallo_3d($var1) {
    for ($i = 0; $i < 10000; $i++) {
        if (array_key_exists('clave1.3', $var1) && 
                array_key_exists('clave2.1', $var1['clave1.3']) &&
                array_key_exists('clave4.1', $var1['clave1.3']['clave2.1']) ) {
        }
    }
}

function ca_verificacion_a_una_instruccion_fallo_4d($var1) {
   for ($i = 0; $i < 10000; $i++) {
        if (@array_key_exists('clave4.1', $var1['clave1.3']['clave2.1']['clave3.0'])) {
        }
    }
}

function cb_verificacion_por_dimension_fallo_4d($var1) {
    for ($i = 0; $i < 10000; $i++) {
        if (array_key_exists('clave1.3', $var1) && 
                array_key_exists('clave2.1', $var1['clave1.3']) &&
                array_key_exists('clave3.0', $var1['clave1.3']['clave2.1']) &&
                array_key_exists('clave4.1', $var1['clave1.3']['clave2.1']['clave3.0'])) {
        }
    }
}


function da_verificacion_a_una_instruccion_fallo_3d_sobre_4d($var1) {
   for ($i = 0; $i < 10000; $i++) {
        if (@array_key_exists('clave4.1', $var1['clave1.3']['clave2.1']['clave3.1'])) {
        }
    }
}

function db_verificacion_por_dimension_fallo_3d_sobre_4d($var1) {
    for ($i = 0; $i < 10000; $i++) {
        if (array_key_exists('clave1.3', $var1) && 
                array_key_exists('clave2.1', $var1['clave1.3']) &&
                array_key_exists('clave3.1', $var1['clave1.3']['clave2.1']) &&
                array_key_exists('clave4.1', $var1['clave1.3']['clave2.1']['clave3.0'])) {
        }
    }
}
Aunque se podía intuir con total certeza que la verificación a una instrucción, directamente haciendo referencia a la clave en la dimensión que se quiere verificar, será más óptima que la verificación dimensión por dimensión hasta llegar a la profundidad de la dimensión que realmente se quiere comprobar; opté por realizar la prueba y así poder ver de manera cuantificable la diferencia que había, y tener que tragarme mis gustos y optar por hacer la comparación con isset(), haciendo referencia a posiciones de memoria inexistentes si las dimensiones de menor profundidad a al que se quiere verificar, ya no existen, como a comenté en la primera entrada de esta serie. Los resultados obtenidos fueron estos:

 Diagrama de llamadas a funciones de comparación de la dos maneras de utilizar array_key_exists()

Diagrama de llamadas a funciones de comparación de la dos maneras de utilizar array_key_exists() de menos a mayor % utilizado 

Bueno, una vez hecho un poco el ganso, tocaba realizar la comprobación definitiva, comparar la eficiencia de ejecución entre array_key_exists() e isset(), así que esté fue el script que utilicé:
function aa_usando_array_key_exists($var1) {
   for ($i = 0; $i < 10000; $i++) {
        if (@array_key_exists('clave4.1', $var1['clave1.3']['clave2.1']['clave3.0'])) {
        }
    }
}

function ab_usando_isset($var1) {
   for ($i = 0; $i < 10000; $i++) {
        if (isset($var1['clave1.3']['clave2.1']['clave3.0']['clave4.1'])) {
        }
    }
}

function ba_usando_array_key_exists_fallo_dimension_anterior($var1) {
   for ($i = 0; $i < 10000; $i++) {
        if (@array_key_exists('clave4.1', $var1['clave1.3']['clave2.5']['clave3.0'])) {
        }
    }
}

function bb_usando_isset_fallo_dimension_anterior($var1) {
   for ($i = 0; $i < 10000; $i++) {
        if (isset($var1['clave1.3']['clave2.1']['clave2.5']['clave4.1'])) {
        }
    }
}
Y los resultados obtenidos fueron estos:


Diagrama de llamadas a funciones de comparación entre la utilización de array_key_exists() e isset()


Diagrama de llamadas a funciones de comparación entre la utilización de array_key_exists() e isset() de menos a mayor % utilizado

Así que como dice el dicho, “una imagen vale más que 1000 palabras”, la eficiencia queda demostrada.

Para concluir solo me queda aclarar un aspecto que alguno le debe descuadrar; se trata de ¿porqué en el caso de la utilización de isset() no tengo ninguna pega por lo que he comentado con el resto? Me refiero al hecho de no gustarme hacer referencias a posiciones de memoria inexistentes. Pues bien, el caso de isset() lo veo sustancialmente distinto, ya que por definición la función sirve para “determinar si una variable esta definida y no es NULL”, así que aparte de considerar que lo que va a hacer es verificar la existencia o inexistencia de una posición de memoria (en términos de definición de posiciones de memoria alocadas en tu programa), si la posición no existe no aparece ningún mensaje de notificación informando de ello, claro está sin anteponer @ a la llamada de la función; así que no me da la sensación de estar realizando algo que no es del todo correcto.


Hasta la próxima enfermos.

1 de julio de 2011

Un poco de colaboración y organización de equipos de trabajo sobre SharePoint 2010


Esta semana, concretamente el martes, he terminado las jornadas de formación de SharePoint que ha realizado Gepesa.

A lo largo de los tres días me enterado del potencial de está herramienta, que hasta el momento lo único que sabía es que permitía trabajar con archivos en un entorno compartido por múltiples usuarios controlando los accesos y gestionando el acceso concurrente, bloqueado y/o detectando conflictos.

Ahora ya sé que no solamente ofrece esa funcionalidad sino muchas más, las cuales aumentan la productividad de los entornos de equipos de trabajo o, incluso, de una organización al completo.

No obstante, después de todo lo que tiene la herramienta, sigue sin proporcionar las necesidades del entorno que tiene la empresa donde prestó mis servicios. Actualmente y desde hace ya un largo tiempo la empresa utiliza una herramienta, desarrollada íntegramente dentro de esta misma, que hace la funcionalidad de explorador de ficheros sobre carpetas compartidas en los servidores, pero controlando y garantizando que sólo un usuario puede estar modificando un documentos al mismo tiempo, es decir lo que viene ha hacer SharePoint, pero aquí no hay copia del documento al disco local de la estación de trabajo sino que se trabaja directamente sobre el documento almacenado en el servidor (Esto, por lo que me contaron, sólo se da de serie en SharePoint sobre ficheros de MS Word y utilizando Office 2007 hacia arriba).

En el entorno que se da actualmente en la empresa, realmente, no se accede a los servidores de ficheros directamente sino que se hace a través de un DFS junto con su servicio de replicación (DFSR), replicando los archivos en los distintos servidores de las distintas sedes de la empresa.

En el entorno mencionado, los usuarios se quejan constantemente de la lentitud de acceso a los ficheros, y llevan razón si lo comparamos con un acceso a un fichero en el disco local, pero si lo comparamos con un acceso remoto no lo es tanto, con ciertas excepciones, justificada por la inversión en hardware que se hace y el tiempo y recursos que se asignan a “los informáticos” para optimizar los sistema.

En fin, que tal y como está ahora, sí le pedimos a los usuarios que tiene que descargar cada vez que tiene que modificar un fichero (se trabaja con ficheros de distintos tipos, ficheros de programa de cálculo, planos de Autocad, ofimáticos y bastantes más) y luego volverlo a subir y desbloquearlo, nos montan una revolución, y no sería sin razón, ya que estarían empleando más tiempo en hacer lo que ahora hacen, aunque quedaría por analizar si empezar a usar este entorno aportaría ciertos beneficios que compensasen el tiempo de más que tendrían que emplear cada usuario, es decir ver la relación entre el tiempo empleado en los procedimientos de trabajo y la productividad obtenida en global, por ejemplo, este proceso es más costoso pero se obtiene beneficios por otra parte que optimizan el tiempo de otros procesos, aumenta la satisfacción del cliente, etc.

Además de la funcionalidad comentada, que es la que justifica mi asistencia a las jornadas, y como ya he dicho, SharePoint ofrece otras funcionalidades que ahora he podido ver que en la empresa se realizan a través de Lotus Notes (principalmente me refiero a la funcionalidad de BBDD documentales y “flujos” de trabajo (Workflows)) pero ni de lejos se llega al nivel de funcionalidad requerido y menos todavía a la sencillez de parametrización; que conste que con esto no estoy diciendo que IBM no tenga una herramienta o complemento de Lotus Notes que permita ponerse al mismo nivel que SharePoint, y tampoco estoy diciendo que nosotros estemos utilizando correctamente la herramienta, pero con el nivel de conocimiento actual y con los recursos que se asignan al Dpo. de TI, ya es mucho lo que se consigue, y llegar más allá requería una inversión, aún más, de nuestro tiempo libre, el cual nunca será valorado y mucho menos recompensado de algún modo.

Bueno dejando de parte la precaria situación, quiero mencionar que SharePoint ofrece (a mi parecer) de manera sencilla la definición de flujos de trabajo, no obstante su sencillez, no quiere decir que los "flujos” se crean automáticamente, sólo es una herramienta, la lógica la pone una persona con conocimiento del negocio"; espero que este último comentario no ofenda a nadie debido a su trivialidad, pero hay muchos que están ahí, en las cumbres directivas, que viendo una demo de esto, como yo he visto, ya se piensan que todo esto se hace automáticamente o con sólo 5 minutos del tiempo de uno de los "frikis" del Dpo. de TI, y con este erróneo concepto, se limitan a comprar una licencia del producto, creyendo que con esto ya lo tienen todo; y aún peor pasa cuando existe una versión que no se paga, porque el día que se enteran te sueltan que “los del Dpo. de TI de la empresa son unos apalancados, no innovan nunca, sino ¡mira!, ¡mira! Esto es gratis y ¿porqué no lo tengo en mi empresa?, La empresa tal (la de un colega suyo) tienen un sistema que hace todo esto, y yo no acabo de entender porque no lo tengo en la mía, blabla blabla”.

En conclusión, SharePoint, como muchas otras que habrán pero que no he tenido la ocasión de ver en una demostración, es una potente herramienta para entornos de equipos de trabajo, ofrece múltiples funcionalidades que permiten controlar accesos a los recursos compartidos, organización de la información, definición de flujos de trabajo, creación de espacios para compartir el conocimiento, y todo eso que favorece (no hace, eso lo hace la dirección creando políticas organizativas) que un equipo y en general una empresa, sea lo que por definición es: una ORGANIZACIÓN.

Para finalizar, quiero agradecer a Gepesa por el buen trabajo que ha hecho organizando estas sesiones, ya que han sido de muy buena calidad, demostrando a nivel práctico un buen conjunto de las funcionalidades y posibilidades que ofrece SharePoint 2010.

Hasta la próxima enfermos.