viernes, 13 de abril de 2012

(n+1)*n/2

La suma de los N primeros números naturales es
S = (N+1)*N/2

Utilidad aplicada:

Supongamos un modelo de datos (una tabla) en el que hay un atributo para ordenar, un entero correlativo que empieza en 0. Para garantizar la coherencia de los datos, tenemos que asegurarnos que cada operación de modificación deja la tabla bien:

Aquí tenemos un ejemplo de datos coherentes:
+--------+-------+
| _order | id    |
+--------+-------+
|      0 | 18685 |
|      1 | 21971 |
|      2 | 21979 |
|      3 | 21977 |
|      4 | 21975 |
|      5 | 21973 |
|      6 | 22047 |
+--------+-------+


Y aquí uno de datos no coherentes: se ha borrado un dato pero no se ha actualizado bien el _order en la tabla:

+--------+-------+
| _order | id    |
+--------+-------+
|      0 | 18685 |
|      1 | 21971 |
|      2 | 21979 |
|      3 | 21977 |
|      4 | 21975 |
|      6 | 21973 |
|      7 | 22047 |
+--------+-------+


¿Cómo comprobar en una tabla estas incoherencias? Aquí entra en juego nuestra fórmula.

Si todo está bien, la suma de los _order + 1 debe ser igual a la suma de los n enteros hasta los N registros que tengamos en la tabla.



SELECT COUNT(id), 
cliente,
SUM(_order+1) AS suma_order,
ROUND((COUNT(id)+1)*COUNT(id)/2, 0) AS suma_buena
FROM tabla
GROUP BY cliente
HAVING ROUND((COUNT(id)+1)*COUNT(id)/2, 0) != SUM(_order+1)
ORDER BY COUNT(id);

martes, 27 de marzo de 2012

Estableciendo navegador por defecto en Debian/Ubuntu

Tenemos diferentes sistemas para establecer el navegador por defecto, y cada programa y/o escritorio tiene su "preferida".

Las alternativas de /etc/alternatives:

$ update-alternatives --display x-www-browser 
$ update-alternatives --display gnome-www-browser 

Los ajustes de XDG:
$ xdg-settings get default-web-browser

También tenemos la variable de entorno BROWSER y el "wrapper" sensible-browser que lee los alternatives y/o esta variable:
# Lanza el definido en alternatives:
$ sensible-browser
# Lanza el definido en BROWSER, firefox en este caso:
$ BROWSER=firefox sensible-browser

Supongo que además, Gnome y KDE tendrán más variables o configuraciones adicionales (GConf, etc). Ya no tengo ganas de probarlo, bastante me ha costado que mi XFCE me responda.

Está bien lo de poder elegir y tal, pero a veces se pasan :-P

Actualización:

  • En la configuración de Gconf también hay una variable que establece el navegador por defecto:
    /desktop/gnome/applications/browser
  • Evolution ignora directamente mis ajustes e insiste en abrir los enlaces en Firefox. He hecho un strace y esto es lo que me encuentro:
    $ strace -o evolution.debug evolution
    $ cat evolution.debug  | grep firefox
    open("/home/xxxxxxx/.local/share/applications/firefox.desktop", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/xfce/applications/firefox.desktop", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/local/share/applications/firefox.desktop", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/applications/firefox.desktop", O_RDONLY) = 44

    Al parecer directamente intenta abrir Firefox. No he encontrado ninguna opción en Evolution para cambiarlo. Solución: engañar a Evolution.
    ln -s  /usr/share/applications/google-chrome.desktop /home/xxxxxxx/.local/share/applications/firefox.desktop



martes, 17 de enero de 2012

Jugando con HTML5

El otro día escribía una anotación sobre HTML5 y criticaba un poco el "buzz" que se le está dando. Sin embargo, HTML5 tiene algunas características totalmente nuevas y geniales.

Como músico aficionado que soy, una de las que más me ha llamado la atención es la posibilidad de incorporar audio de forma nativa (tag ) y poder controlar el audio mediante Javascript.

En la siguiente página he puesto un sencillo metrónomo como prueba de concepto:

http://html5experiment.sourceforge.net/metronome/

Veamos las partes más relevantes de este experimento:






Lo primero es cargar el fichero de audio. No todos los navegadores soportan todos los formatos, así que hay que dar alternativas (me faltaría un OggVorbis).

Desde Javascript podemos acceder al elemento audio y controlarlo (invocando play, stop, etc) En este ejemplo he utilizado jQuery. Por ejemplo, para lanzar la reproducción:


$('#down').trigger('play');


Así de sencillo. El resto del código Javascript se limita a establecer un temporizador para ir lanzando periódicamente la reproducción del audio.

Es sólo un experimento, para hacer esto realmente útil tendríamos que controlar bien que la ejecución de un Javascript no fluctúe.

jueves, 12 de enero de 2012

Desmitificando HTML5

Cliente: [...] y quiero que la web corporativa se haga en HTML5.
Desarrollador: ¿Necesita algún elemento nuevo de HTML5 en concreto?
Cliente: Uh... Esto... Bueno, quiero que tenga vídeo, gráficas interactivas, todo lo que trae HTML5.
Desarrollador: Sin problema, pero el precio del desarrollo subirá. Los gráficos en HTML5 hay que programarlos igualmente, lo único que en vez de Flash utilizaremos Canvas. Si queremos que el vídeo se vea en todos los navegadores, habrá que hacer diferentes codificaciones: necesitaremos más almacenamiento y hardware más potente para la codificación si hay mucho volumen de vídeos.
Cliente:¿Pero eso no viene ya de serie con el HTML5 ése?
Desarrollador: No, hay que hacerlo igualmente.
Reconozco que esta esta conversación ficticia está un poco traída por los pelos, pretende ser más satírica que otra cosa, pero ilustra un poco la sensación que tengo respecto al HTML5: parece que es la panacea y la solución a todo, la tecnología que finalmente hará de la web un lugar idílico, normalizado y estandarizado,... pero sigue haciendo falta alguien que programe.

Hay muchas novedades y aportaciones en HTML5 que ya han analizado en multitud de sitios, así que no voy a decir nada nuevo. Lo que quiero transmitir con este artículo es que HTML5 no es un milagro tecnológico ni nada similar (se oye demasiado a menudo "¡... y está hecho con HTML5...!", como si fuese lo más de lo más de la innovación y la solución a todos los problemas). Es una evolución (con muchos aciertos y posiblemente, limitaciones) del HTML y así es como los técnicos debemos verla. No nos dejemos llevar por el "hype" de las siglas y de los departamentos de Marketing ;-)

Algunas cosas que me parecen interesantes (en la Wikipedia viene un buen resumen):
  • Mejoras semánticas (en mi opinión, casi la novedad más importante). En versiones anteriores, cada bloque en una página no tenía sentido semántico. Es decir, la cabecera, menú, pie de página, etc... eran siempre un
    . Con HTML5 tenemos , , , ...
    Esto parece una tontería, pero es muy importante y tiene muchas aplicaciones:
    • Los buscadores pueden identificar rápidamente qué partes de la página son relevantes.
    • Los agentes de usuario (navegadores) pueden presentar la página de acuerdo a las instrucciones que le de el usuario, por ejemplo: "ocultar la barra de menús" o "destacar el contenido del artículo", etc.
      Imaginemos un navegador/lector para personas con problemas de visión: cada vez que pasen de página no les leerá el interminable menú de navegación, ni la cabecera, etc. Directamente les leerá el contenido del artículo.
    • Se facilita enormemente el intercambio de contenidos entre sitios web (y el "robo" también, todo hay que decirlo). Nuestros scripts ya sabrán qué hay que recoger en una página y qué no.
  • Por fin se puede mostrar vídeo en el navegador sin necesidad de utilizar un plugin (típicamente, Flash). El problema está en los navegadores: cada uno soporta un formato/codec diferente. Si queremos garantizar que todos los navegadores podrán tratar con nuestro vídeo, hay que preparar múltiples fuentes.
    Ejemplo (c&p de la Wiki ;-)

    <video poster="movie.jpg" controls>
    <source src='movie.webm' type='video/webm; codecs="vp8.0, vorbis"'/>
    <source src='movie.ogv' type='video/ogg; codecs="theora, vorbis"'/>
    <source src='movie.mp4' type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'/>
    <p>This is fallback content</p>
    </video>

    Si queremos dar soporte a navegadores antiguos que no entiendan el tag , debemos preparar un mecanismo para mostrarles el vídeo a través de un plugin.

  • Lo mismo es aplicable para el audio. Cada navegador funciona diferente.
  • Gráficos 2D: se estandariza el tag y su API. Un bloque canvas sólo define una región que puede ser "pintada" a través de un script (típicamente Javascript). Nada más (y nada menos).
    Últimamente se ven algunas maravillas como juegos, pruebas de concepto, etc, "programados en HTML5". Error de concepto: están programados en Javascript y se muestran en una página HTML5.
    Hacer cosas en un no es una tarea trivial. En la especificación se definen funciones o métodos de bajo nivel y nada más. Existen bastantes "librerías" de Javascript que facilitan la tarea, pero no son parte de la especificación.
  • Por fin se simplifican los DOCTYPE (se queda un simple ) y los atributos del tag .

lunes, 12 de diciembre de 2011

"Trackeando" iframes en DFP

Llevaba un tiempo pensando cómo se podía hacer esto, es decir, que un anuncio tipo "iframe" pudiese contener en sus URLs el código de seguimiento de Google DFP.



Antecedentes:
Supongamos que tenemos una "creatividad" (que poco me gusta este término) del tipo "terceros" en nuestra cuenta de DFP. El código corresponde a un iframe que sale de nuestro servidor:

http://miservidor.com/anuncios/anuncio1

Y la página http://miservidor.com/anuncios/anuncio1 devuelve el siguiente HTML:





Si creamos en DFP el banner del tipo "terceros" y ponemos el iframe, DFP podrá controlar las impresiones del banner, pero no los clicks, puesto que en ningún sitio hemos insertado la macro correspondiente, típicamente %%CLICK_URL_ESC%%



La solución:

Al llamar al iframe, añadimos como parámetro la macro, esto es:

<iframe src="http://miservidor.com/anuncios/anuncio1?macro=%%CLICK_URL_ESC%%">





Cuando DFP lance una impresión de nuestro banner, la macro será sustituida por el correspondiente código de seguimiento y desde el script que genera el banner, capturar el la url de seguimiento de DFP.

Supongamos que trabajamos con PHP, la modificación sería la siguiente en la página http://miservidor.com/anuncios/anuncio1:

<?php
$enlace = urldecode($_GET['macro']);
?>

<a target="_top" href="http://miservidor.com/articulos/articulo1">


Y eso es todo. En enlace que sale en el iframe ahora tendrá el código de seguimiento de Google DFP, contabilizará el click y redigirá al enlace final, http://miservidor.com/articulos/articulo1


Por supuesto, hay que tomar todas las medidas de seguridad oportunas para evitar problemas (comprobar y sanear el parámetro que llega, etc).