A blog about data, information and Tech by Mario Alberich

        

ago. 12
2013

mysqldump, backup comprimido con gzip

En algunas ocasiones el espacio disponible para almacenar copias de seguridad de la base de datos es escaso, por lo que quizá no disponemos del espacio para realizar un volcado completo de la base de datos, y en segunda fase comprimir ese resultado. También puede ser que queramos acortar el proceso evitando la escritura en disco (que puede ser lento), y al disponer de un cierto margen de CPU, podemos comprimir al vuelo.

Pipes


Suponiendo que el comando básico de mysqldump sea como sigue:

mysqldump --opt -u [usuario] -p[clave] [base_de_datos] > [copiaseguridad.sql]

Sabemos que mysqldump devuelve por stdout todo el texto de las sentencias SQL que conforman la base de datos. Eso se guarda en el archivo copiaseguridad.sql.  Lo que se puede hacer es añadir un pipe hacia gzip, y que éste programa sea el que realmente genera el archivo de backup:

mysqldump -u [usuario] -p[clave] [base_de_datos] | gzip > [copiaseguridad.sql.gz]

En este caso, gzip capturará todo el contenido que antes enviábamos a copiaseguridad.sql y lo comprimirá. Una vez hecho esto, ahora sí, lo guardamos en un archivo. Por convención se le añade el sufijo ".sql.gz", ya que de este modo queda claro que está comprimido y del contenido.  Además, al descomprimir desaparece el ".gz", por lo que nos queda la extensión ".sql".

Importar el archivo comprimido


Llega el fatídico día que requiere recuperar la base de datos.  ¿Cómo procedemos? Vamos a incorporar a gunzip, la utilidad de descompresión.  Como en el caso anterior, podríamos ejecutar gunzip y luego mysql. Pero la idea es economizar la escritura en disco, así que seguiremos usando pipes:

gunzip < [copiaseguridad.sql.gz] | mysql -u [usuario] -p[clave] [base_de_datos]

Simplemente:

  • Enviamos a gunzip el contenido del archivo gz.
  • gunzip envía el resultado por stdout.
  • Este resultado es recogido por la pipe de mysql, que lo importa a base_de_datos.

Ratios de compresión


Los archivos SQL son ni más ni menos que archivos de texto. En estos casos los ratios de compresión (tamaño del archivo comprimido en comparación al archivo normal) son bastante notables, y pueden variar según el nivel de compresión. La contrapartida es que a mayor nivel de compresión, más uso de CPU (y más lento).

Sin embargo, si lo tuyo es una necesidad apremiante de espacio en disco, puedes añadir el nivel de compresión (entre 1 y 9, siendo 6 el valor por defecto) al ejecutar gzip:

mysqldump -u [usuario] -p[clave] [base_de_datos] | gzip -9 > [copiaseguridad.sql.gz]

Puedes hacer pruebas para revisar los ratios de compresión. La decisión final depende de todos los factores (CPU disponible, espacio/velocidad de disco, etc.).

En último término, también puedes usar bzip2, aunque la relación entre velocidad y compresión respecto a gzip puede desmotivarte.

Read more »

ago. 8
2013

Ripple - Emulador para móviles

A estas alturas ya no resulta difícil disponer de un dispositivo móvil con prestaciones de smartphone para revisar o testear una página web. Para echar un vistazo rápido, es más que suficiente.

Sin embargo, salvo que tu tarea sea dedicarte al desarrollo de aplicaciones móviles, no dispondrás de varias BlackBerry, los dos o tres últimos modelos de iPhone o iPad, y varios modelos de Android, con sus variaciones en tamaños de pantalla, versiones de sistema operativo, etc. Y si el trabajo a entregar requiere una revisión más o menos exhaustiva con dispositivos móviles, la tarea es compleja.

Revisar con Ripple en Chrome


A partir del proyecto Ripple que actualmente está en la incubadora de Apache (código bajo Licencia Apache), se ha desarrollado una extensión para Google Chrome, disponible gratuitamente en la Chrome Web Store.

Al instalar la aplicación, aparecerá un botón con la imagen del logo de Ripple. Al navegar por una página (funciona con páginas http://, pero no con accesos locales vía file://, por lo que hay que poner las páginas tras un servidor http), se puede clicar sobre el botón y seleccionar la opción enable.

En la primera carga de una determinada URL se solicitará qué plataforma se quiere utilizar para hacer la simulación. Esto se puede modificar en cualquier momento desde el entorno de emulación.

En ese momento aparecerá un interfaz en la que se identifican claramente tres apartados:

  • En la parte izquierda, la configuración del dispositivo y de algunas de sus características, además de la orientación y la opción de "shaking". También se puede cambiar la plataforma.
  • En la parte central, una interfaz emulada del dispositivo escogido a la izquierda. La página que estabas visualizando debería mostrarse dentro.
  • A la derecha, algunas características de la conexión del dispositivo, así como la posibilidad de simular geoposicionamiento.


Con la variedad de opciones, se puede jugar un rato largo y ver, por ejemplo, la interacción para realizar scroll en la página, o el ajuste en ancho y alto del dispositivo, entre otras opciones.

¿Es la solución definitiva?


Está claro que no. El proyecto aún está en fase Beta, y eso se nota cuando se comparan ciertos detalles. Aunque en el aspecto de renderizado los resultados son bastante similares (aunque se nota un poco la diferencia de densidades de pantallas), la interacción y la navegación presentan diferencias de comportamiento. Es decir, que por ahora no está de más (léase es necesario) revisar el resultado final con un dispositivo de al menos cada sistema operativo.

Sin embargo, en lo relativo a revisar el responsive design, los efectos en el cambio de orientación del dispositivo, ya ayuda bastante. Y para el resto de funcionalidades (simular GPS y otros detalles) no lo he probado, pero seguro que simplifica las pruebas más rutinarias.

En fin, ahí queda, por si a alguien le interesa.

 

Read more »

jul. 20
2013

Phing (IX) filterchains

Existen algunas tareas que se pueden encadenar unas tras otras, y cuyos resultados intermedios no son de nuestro interés.  En Unix estas operaciones se realizan normalmente con pipes. Pues bien, en Phing tenemos las filterchains, un conjunto de aplicaciones de filtros sobre una serie de contenidos que se pueden encadenar para generar un resultado final, y que el input de un proceso es el output del proceso anterior.

Incluir la cabecera de información legal


Supongamos que queremos que todo archivo de nuestro código fuente incluya la habitual cabecera de código, pero sólo lo queremos en el momento de empaquetar y publicar nuestro proyecto.

En ese caso, podemos seleccionar los archivos a modificar (con un fileset), y utilizar entonces filterchain para ejecutar la operación ReplaceTokensWithFile:

...




...

Vale sí, pero ¿esto qué hace? Pues te permite poner un texto en tu código equivalente a:

#!copyright!#

Y que, en caso que exista el archivo plantillas/copyright.php, el contenido de éste quedará automáticamente insertado en el lugar donde ha encontrado la cadena anterior.

Limpieza básica del código


Supón, por ejemplo, que te ha llegado un código fuente (o un CSV, o cualquier otro contenido textual) plagado de saltos de línea del tipo Windows (\n\r) y quieres convertirlos a saltos de línea tipo Unix (\n). Podrías hacer lo siguiente:


...






En el fondo podrías eliminar directamente "\r" (dejando replace vacío), pero de este modo te aseguras que no hay sorpresas ni cambios.

Read more »

jul. 17
2013

Complejidad visual

Leí hace ya un tiempo un artículo (no tengo la referencia) sobre el diseño gráfico de escenarios en videojuegos. La lectura fue casual, algo que leer mientras se espera algo o a alguien. En sí nada importante.

El caso es que en esa lectura recuerdo un detalle interesante que vuelve a mí constantemente: la variedad de formas y colores del escenario debe tener un grado de complejidad equilibrado, dependiendo del ambiente que se quiera crear. Poco complejo aburrirá al usuario, que inconscientemente lo tachará de falso, y demasiado complejo puede distraer al usuario, a quien le puede diferenciar los elementos activos del simple decorado.

En el fondo, creo yo, aún nos llama el instinto por buscar algún tipo de alimento en esos colores. Quizá en la naturaleza, la complejidad visual es un indicio de que existe algún tipo de vida; una vida que no permite (por interés propio) que ese entorno se degrade y se erosione hasta ser desierto. Y eso, para nosotros como depredadores, puede equivaler a alimento.

Aquí, reflexionando, mientras recuerdo momentos pasados revisando documentos intragables. You know...

Read more »

jul. 15
2013

Simular un valor binomial

Un proceso binomial es aquel que sólo puede tomar dos valores: uno o cero, sí o no, blanco o negro... En estadística, el proceso básico es denominado experimento de Bernouilli en honor al matemático (que por cierto, vaya familia). El experimento se refiere a cualquier experimento que tenga esta característica.

Este proceso otorga una probabilidad p a que tenga lugar un suceso (por ejemplo, que alguien responda "Sí" a una pregunta), y por contraposición otorga la probabilidad q al suceso contrario (alguien responde "No"). Lo importante es que siempre p + q = 1. Esto quizá te sonará del post de p = q = 0,5.

Los procesos de simulación estadística parten siempre de los recursos que proporciona la informática.  Para el caso, se utilizan los generadores de valores aleatorios (en concreto, los generadores pseudoaleatorios). Estos generadores devuelven un valor entre 0 y 1, pero es un valor continuo.

Conversión de continuo a discreto


Entonces, cómo convertimos ese valor a un valor 0 ó 1? Este caso es sencillo, pero se puede extrapolar a otros casos más complejos. El algoritmo es:

  • Iniciamos un experimento de Bernouilli para determinar el valor de X
  • Se genera un valor aleatorio U entre 0 y 1
  • Si U es menor que p, X valdrà 1. En caso contrario, valdrá 0.


Si lo que queremos es simular una distribución binomial con n repeticiones, lo que debemos hacer es ejecutar el proceso anterior n veces y sumar los valores de X. Este proceso, ejecutado un número de veces lo suficientemente grande, y representado gráficamente, nos mostrará un diagrama cercano a la distribución teórica del modelo Binomial.

Pero eso ya queda para otros momentos.

Read more »

jul. 11
2013

Calcular la variancia sin recorrer dos veces los datos

El cálculo de la variancia (o varianza, según la literatura) implica a la media.  Dado que para calcular la media necesitamos todos los datos (bueno no siempre, pero en este caso sí), el algoritmo más básico nos obligaría a recorrer dos veces la muestra de datos:

  • Recorremos la primera vez sumando los valores, y acabamos calculando la media.
  • Recorremos una segunda vez la muestra, y para cada valor calculamos el cuadrado de su distancia respecto a la media.
  • Finalizamos dividiendo el segundo resultado entre el número de datos de la muestra.


Este proceso es harto costoso en términos de tiempo. Recorremos dos veces una muestra (que pueden ser miles de datos) y eso ya es motivo para pensar si podemos reducirlo.

Por suerte, la varianza se puede exponer, en términos de esperanza matemática, de otra forma. Extraído directamente de Wikipedia:

Desglose de la varianza en términos de esperanza matemáticaLo que está indicando esta fórmula es que podemos separar el cálculo de la media del de sus valores al cuadrado.

¿Esto mejora lo anterior? Sí, porque al poderlo diferenciar, lo podemos paralelizar, y por lo que podemos utilizar un solo recorrido por los datos para calcular la varianza.

 

 

 

Algoritmo de cálculo

  • Recorremos los datos, generando dos variables: X y M.
  • Para cada valor de los datos
    • sumamos el valor a M.
    • Elevamos el valor al cuadrado y lo sumamos a X.


  • Al finalizar el cálculo dividimos ambos valores por el número de datos de la muestra.
  • restamos X-M, y tenemos la varianza.

Calcular la varianza como flujo


Relacionado con el post sobre el algoritmo de cálculo de la media, y viendo la optimización anterior, ¿Crees que es posible calcular la varianza al vuelo?

Read more »

jul. 8
2013

Lecturas veraniegas: James Gleick - La Informacion

Ya he publicado algunas reseñas de libros en el blog, y aunque me encanta hacerlo como ejercicio de resumen y de anclaje de ideas, es una tarea que consume el tiempo de una manera bárbara. Eso al final lleva a no escribir nada, y al final, pues... todos perdemos un poquito.

Es por eso que hoy me decido a hacer un pequeño comentario sobre el libro "La información" de James Gleick.  Ya lo han comentado Cory Doctorow, y hay una reseña en El País, La primera edición apareció en Febrero del 2012, por lo que es un libro nuevecito.

Leí buenas críticas de él, pero quise comprobarlo en primera persona.  Lo pude leer entre Septiembre y Noviembre del año pasado, y no puedo menos que recomendarlo. Pocas veces he tenido la sensación de leer un libro tan fundamentado, con tantas referencias, y a la vez tan sugerente...

... Porque esa es la palabra: es un libro sugerente e inspirador. Obliga a parar un momento y a pensar, tratar de relacionar ideas, relacionar temas comentados en capítulos anteriores, especular... Quizá, por comparar, la sensación que tuve durante la lectura es similar a la que me apareción leyendo "No Logo" de Naomi Klein. Una lectura que te agarra. No es ligera, pero no te aburres porque te parece estar aprendiendo por momentos.

¡No me dirás que no es un libro ideal para las vacaciones! Con ese rato de la siesta que no acaba de pasar, mientras afuera hace calor...

El libro no es lectura ligera. Pero ese peso, lo veo totalmente justificado.

Feliz lectura.

Read more »

jul. 4
2013

Phing (VIII) filesets, filedirs, includes, excludes

Otra de las potentes características de Phing es la posibilidad de procesar en bloque un conjunto de archivos que coincida con un determinado patrón de nombre, ruta, o una combinación de ellas. Por ejemplo, la siguiente instrucción:





Permite recoger todos los archivos dentro de /etc/httpd/ (incluyendo subdirectorios), y también el archivo php.ini.




En este segundo caso  recoge todos los archivos .php que existieran en cualquier directorio dentro de "/ruta/a/mi/proyecto/php", y excluye todos los archivos que contengan en su nombre la palabra "Test" (los archivos con pruebas unitarias)

En ambos casos, el asterisco simple sirve para lo mismo que en la consola: como comodín. Sin embargo, el doble asterisco es una opción muy potente para buscar recursivamente en los subdirectorios y también dentro de los nombres. Así, la expresión:

...

...

Puede encontrar tanto un archivo denominado  test_nuevo.xml as well as to test/test_viejo.xml, por ejemplo. Es decir, el doble asterisco ** "supera la barrera" de los directorios y sirve como comodín en cualquier parte del path del archivo.

Read more »

jul. 1
2013

Phing (VII) - Operaciones con control de versiones

Si la automatización de tareas es uno de los grandes objetivos de Phing, la gestión del control de versiones es un objetivo importante. Las tareas de despliegues sistemáticos, principalmente para el testeo y la integración continua se pueden agilizar utilizando Phing.

Para el caso, veremos las tareas disponibles para las dos herramientas más populares de control de versiones: Git y Subversion. Salvo excepciones notables, las tareas de ambos casos permiten más o menos los mismos objetivos, pero dado que los dos sistemas tienen algunas diferencias estructurales y de nomenclatura, las tareas varían ligeramente.

Los siguientes apartados asumen que ya tienes unas nociones mínimas del concepto de control de versiones, así como de los comandos más habituales. Si no fuera así, visita la documentación de Git o el libro de Subversion.

Inicialización de repositorio


En el caso de git, tenemos GitInit:


Lo anterior inicializa un repositorio. La opción bare permite inicializarlo sin mostrar la estructura de directorios. Esto es especialmente apropiado al instalarlo en servidores que alojarán estos repositorios (al estilo Github o similares).

Subversion en este caso no tiene una rutina de inicialización de repositorios.

Registro de actividad (log)


En el caso de Git:


    since="Sun Jan 23 23:55:42 2013 +0300"
until="Mon Jan 24 09:59:33 2013 +0300"
outputProperty="logs"
repository="/ruta/al/repositorio" />

Y en el caso de subversion:


    svnpath="/usr/bin/svn"
workingcopy="/home/user/svnwc"
propertyname="svn.log"/>

En ambos casos tienen otras varias opciones, aunque hay que reconocer que Git ofrece más posibilidades de filtro y formatos de salida.

Obtener copias de repositorios ajenos


En git, esta función se cumple con git clone:


    repository="git://github.com/path/to/repo/repo.git"
targetPath="/ruta/al/repositorio"/>

En el caso de subversion, la operación es la de checkout:


   svnpath="/usr/bin/svn"
repositoryurl="svn://localhost/project/trunk/"
todir="/ruta/a/copia/de/trabajo"/>

Trabajo con ramas (branching y merging)


En el caso de Git, las operaciones son el GitBranch, GitMerge y GitCheckout:


    repository="/ruta/a/repo"
branchname="nombre-rama" />


    repository="/ruta/a/repo"
remote="nombre-rama-1 nombre-rama-2"
message="merging repos" commit="true" />


    repository="/ruta/al/repositorio"
branchname="mi-rama" quiet="true" create="true" />

En el caso de subversion, utilizamos SvnCopy y SvnSwitch:


   svnpath="/usr/bin/svn"
username="anony"
password="anony"
nocache="true"
repositoryurl="svn://localhost/project/trunk/"
todir="svn://localhost/project/tags/0.1"/>


   svnpath="/usr/bin/svn"
repositoryurl="http://localhost/project/tags/2.4.2"
todir="/ruta/a/copia/trabajo"/>

No existe tarea de Subversion para el proceso de merge.

Sincronización de repositorios


Git dispone de las tareas GitPush, GitPull, y GitFetch:


    repository="/ruta/al/repositorio"
refspec="master:foobranch" tags="true" />


    repository="/ruta/al/repo" all="true" />


    repository="/ruta/al/repo" all="true" />

Subversion dispone de las tareas SvnCommit, y SvnUpdate,


    workingcopy="/ruta/a/copia/local"
message="Comentario del commit" />


   svnpath="/usr/bin/svn"
todir="/ruta/a/copia/local"/>

 

Read more »

jun. 28
2013

Cálculo de la media con datos en flujo

En muchos casos disponemos de todo el conjunto de datos para poder calcular la media. En esas situaciones, la suma de todos los elementos divididos por el número de éstos, ya nos proporciona la media.

Datos en bloque y datos en flujo


Pero ¿qué sucede cuando los datos van surgiendo aleatoriamente, y además no sabemos ni la cantidad, ni el momento en el que dejarán de aparecer? Necesitamos un cálculo dinámico de la media. Y para más detalle, queremos mantener el mínimo volumen de datos.

Calcular la media cada vez


Dado que la media es la suma de los elementos divididos por la cantidad, podemos tener un valor que contenga la suma de todos los elementos anteriores, y otra variable con el número de elementos que han llegado.

Cada vez que llegara un nuevo valor, sólo sería necesario sumarlo a la primera variable, incrementar en uno el valor de la segunda, y luego dividir la primera por la segunda. Tendríamos así la nueva media.

De esta forma guardamos tres valores: el total, el número de ítems y la media.

Optimizando los recursos


Aunque en este caso parezca absurdo, pueden existir situaciones en el que el ahorro pueda ser significativo. Así que, ¿cómo podemos reducir el número de variables a guardar?

Para esas situaciones la fórmula clásica no sirve. Tenemos que echar mano de una versión generalizada, la media ponderada. En realidad, una media tal como la conocemos es un caso concreto de la media ponderada: es cuando todos los valores que queremos promediar tienen la misma importancia (el mismo peso, la misma ponderación).

Para el caso que nos ocupa, tendremos dos valores: el número de ítems y la media actual. Es decir, nos ahorramos la suma del total. ¿Cuál es el procedimiento?

  • Llega el primer valor. La media es éste mismo valor.
  • A partir del segundo valor, ponderamos la media existente por el número de elementos que han llegado, y el nuevo valor por uno.


A medida que se va incrementando el número de valores, el peso de la media es tan alto, que los nuevos valores deben ser muy altos para alterar la media.

Este proceso es algo más intensivo en recursos, pero más ligero en recursos que el anterior.

 

Read more »

© 2007 and beyond Mario Alberich, licensed under CC-BY-SA unless stated otherwise.