Mi blog personal sobre investigación y divulgación
Tag Archives: programación
Usando wget, awk, paste, cut y sed para tener datos en tiempo real en la web

En agosto de 2014 escribí en este blog sobre cómo representar gráficas en una web usando Dygraphs, una librería en Javascript que es ampliamente utilizada para publicar representación gráfica de datos en internet. En esa ocasión mostré un ejemplo cargando unos cuantos datos directamente en el código que hace la representación de la gráfica, pero comentaba que se puede hacer dándole directamente la ruta de un fichero .csv. Esta semana he estado trabajando un buen número de horas para ir un poquito más allá con esta herramienta. La idea era mostrar en la sección “predicción polvo africano” de este blog, datos en tiempo real (promedios horarios de las últimas 24 horas) de las concentraciones de polvo en diferentes puntos de Canarias.

Los datos provienen de la web de la Red de Control y Vigilancia de la Calidad del Aire del Gobierno de Canarias. Son datos que pueden consultarse libremente en dicha web pero, curiosamente, solo pueden verse en formato tabla. Se pueden descargar en formato .csv, en excell y en pdf, pero no te los representan en una gráfica. Mi idea era realizar yo la gráfica automáticamente, totalmente actualizada, y que se pudiese consultar en mi blog. Todo lo hice desde un ordenador con sistema operativo Linux.

grafica con dygraphs

La primera tarea, lógicamente, fue ingeniármelas para bajar los datos. En teoría debería ser lo más sencillo del mundo: un wget apuntando al enlace donde están los datos y listo. El problema es que en la web fuente de los datos no hay links fijos, sino que llaman a algún tipo de script para generar los datos. Además, todos los ficheros bajan con el mismo nombre. Dos días estuve (estuvimos, que conté con ayuda) intentando averiguar cómo hacerlo. Al final lo conseguimos, y lo que voy a mostrar aquí es el comando básico de wget para bajar un fichero y renombrarlo. Sería así:

wget -C “http://www.nombredelaweb.loquesea/rutaalfichero/” -O fichero1

El -O al final es lo que usas para renombrar el fichero que bajas. Como yo tenía que bajar muchos ficheros, ya que publican los datos por zonas de las islas, y los ficheros originales tienen todos el mismo nombre, tengo que usar esta opción sí o sí.

A partir de aquí lo que tenía eran 11 ficheros (csv en mi caso) con un montón de datos. Los ficheros .csv son como ficheros de excell (datos en filas y columnas), donde las columnas están separadas por una coma. Yo quería combinar los 11 ficheros en uno y quedarme con solo las columnas que me interesaban. Para ello usé el comando awk desde una terminal de mi distribución de linux.

Esta es la instrucción para combinar los ficheros (todos los que quieras).

paste -d , fichero1 fichero2 fichero3 fichero4 > ficherocombinado

Es importante que dejes un espacio entre la d y la coma. Luego vienen todos los nombres de los ficheros individuales, separados por espacios, y tras el > viene el nombre del fichero resultado de la combinación.

Una vez tienes el fichero combinado, con muchísimos datos, para quedarte solo con las columnas que necesitas tienes que hacer esto:

cut -d , -f 1,2,3,5,7,9,11 ficherocombinado > ficherorecortado

Lo que le hemos dicho al ordenador con esta instrucción es que se quede con las columnas 1,2,3,5,7,9 y 11 del fichero que creamos antes, y que el resultado lo escriba en el fichero resultante. Ojo, que aunque la instrucción se llame cut (cortar), lo que hay que darle es el número de las columnas con las que nos queremos quedar, no las que queremos eliminar.

Una vez tenía este nuevo fichero con justo los datos que necesitaba (fecha, hora y PM10 en diferentes estaciones de medida que elegí) yo me encontré con un problema: la librería Dygraph solo admite las fechas en formato yyyy-mm-dd hh:mm, y en los ficheros originales lo que tenía era dd-mm-yyy en la primera columna, y hh:mm en la segunda columna. Necesitaba entonces cambiar de formato la primera columna y, una vez hecho, unir la primera y la segunda con los datos de fecha y hora separados por un espacio. Para ello usé el comando awk:

awk -F , ‘{split($1, a, “-“)$1=a[3]”-“a[2]”-“a[1]” “}1’ OFS = , ficherorecortado > ficheroconfechaok

Fíjate en lo que hice ahí. Le he dicho que en la columna 1 hay algo que tiene tres valores separados por un guión, y lo que quiero hacer es que lo sobreescriba con los elementos cambiados de orden, es decir, el año (que aparecía en tercer lugar en el formato original dd-mm-yyy) lo quiero delante, el mes se queda donde está, y el día (que aparecía en primer lugar) lo llevo al tercero. Luego le doy el nombre del fichero (el de antes, el que recorté para quedarme con los datos que necesito) y al final le doy el nombre del fichero resultado.

Ahora vamos con la combinación de la fecha y la hora en una misma columna. Vuelvo a usar el comando awk para ello:

awk -F , ‘{($1=$1″ “$2)}1’ OFS = , ficheroconfechaok > ficherofinal

Lo que he hecho es decirle que en la columna 1 escriba lo que era la 1 combinada con la 2 y separadas por un espacio, que se encontraban en el fichero que escribimos antes, y el resultado de ello lo escriba en un nuevo fichero.

Ya está, con esto ya tendría todo lo necesario para subir este fichero por ftp a alguna carpeta de mi web, darle la ruta al Dygraphs y que él solito haga la representación gráfica.

Cuando lo hice me encontré un pequeño detalle más que quise corregir. Resulta que algunos de los nombres de las estaciones de medida de donde provienen los datos, que salen en la leyenda de la gráfica, tienen letras con tilde o contienen una ñ. En ese caso el Dygraphs no es capaz de escribirlos bien. Entonces decidí aprovechar para cambiar los nombres de las estaciones en el fichero final (primera fila del .csv), añadiendo además el nombre de la isla en la que están. Para ello primero tuve que cambiar la codificación del fichero, de iso-8859-15 a utf-8. Si no lo hacía, el paso siguiente no me funcionaba.

iconv -f iso-8859-15 -t utf-8 ficherofinal > ficherofinal_utf8

Ahora ya solo queda el paso final, que es usar el comando sed para sustituir palabras. Aquí tienes un ejemplo:

sed -i ‘s/Tefía-Puerto del Rosario/Tefia-Puerto del Rosario (Fuerteventura)/g’ ficherofinal_utf8

Lo que hace el comando sed ahí es buscar en el fichero ficherofinal_utf8 dónde aparece la cadena de texto Tefía-Puerto del Rosario. Una vez la encuentra, la sustituye por la cadena Tefia-Puerto del Rosario (Fuerteventura). Esto lo hice con todos los nombres de estaciones que contenían algún caracter que el Dygraphs no es capaz de representar en la leyenda.

Estas y más instrucciones, para representar también mapas de predicción e imágenes de satélite, están una detrás de otra en scripts que ejecuto cada hora en segundo plano en mi ordenador gracias al administrador de tareas Cron. El ordenador está encendido y conectado a internet las 24 horas del día, bajando y procesando los datos, subiéndolos por FTP a mi web, y a partir de ahí puedes verlos desde cualquier lugar.

Ya ya está, el resultado final puede verse en esta página. Espero que esta explicación te sea útil para trabajar con datos para representar gráficamente en tu web.

De MATLAB a R

Desde hace muchos años trabajo en MATLAB. Comencé en IDL, que es muy similar, pero luego fue necesario adaptarme al lenguaje de programación que usaban (y usan cada vez menos) en el que por aquel entonces era mi nuevo centro de trabajo.

MATLAB es un entorno muy potente para trabajar con grandes cantidades de datos. Puede usarse en Windows, Mac y Linux, aunque en alguna ocasión me he encontrado con alguna pequeña diferencia en las versiones de Windows y Mac, teniendo que hacer pequeñas adaptaciones a scripts que ya tenía hechos. En este blog he escrito varias entradas relacionadas con MATLAB, y hasta ahora no había sentido la necesidad de cambiar de lenguaje de programación (si es que a estos paquetes estadísticos donde trabajamos con scripts se le puede llamar “lenguaje de programación”). El caso es que MATLAB, frente a sus competidores, tiene algunas desventajas muy llamativas que me han invitado a probar con otros. La gran desventaja es que es de pago, con un precio muy elevado, mientras que otros como OCTAVE o R son gratuitos. Por otro lado, y esto puede ser ya cuestión de gustos personales, las gráficas y mapas que se generan con MATLAB me parecen horrendas. Otra desventaja es que puedes necesitar una toolbox en MATLAB que no tienes instalada, o que no existe en la versión que tú estás utilizando, y entonces empiezan los problemas. Un detalle más: guardar una gráfica de MATLAB como fichero gráfico no es más que esperar a que el propio programa haga una captura de pantalla, por lo que esa captura depende de la configuración de tu tarjeta de vídeo + pantalla. Generar una misma gráfica (o un mapa) con el mismo script pero en dos ordenadores distintos puede dar resultados diferentes. Eso me parece una chapuza.

Tomar una decisión sobre qué otro lenguaje usar no fue difícil, pues la tentación estaba muy cerca. Algunos de mis colegas ya se habían pasado hace tiempo a R. Me gusta el resultado de las salidas gráficas que consiguen. La sintaxis de este lenguaje no parece muy difícil si ya se está familiarizado con otros lenguajes. Además, es gratis, multiplataforma, y hay una gran comunidad de usuarios en internet. Traducir mis scripts de MATLAB a R me parece una pérdida de tiempo, pero tener que abordar un problema nuevo sí es una buena excusa para empezar en R. Este es el caso y por fin lo he instalado y estoy tratando de correr mis primeros programas. También instalé un IDE, el RStudio (también gratis y multiplataforma), para que el entorno me sea un poco más familiar y contar con unas cuantas funcionalidades interesantes.

R Studio

Pues eso, de la directora de “Me olvido de Windos y me paso a Linux” llega la nueva entrega “De MATLAB a R”. ¡A ver en qué termina la película! 🙂

Programando aplicaciones móviles con App Inventor

¿Cómo se programa una app móvil? Es una pregunta que muchos de nosotros nos hemos hecho, especialmente aquellos que siempre estamos queriendo aprender cosas nuevas. En la era de las apps, ¿quién no ha tenido una buena idea para hacer una? ¿Quién no ha dicho eso de “si supiera hacer una app”…?

Yo me pregunté todo eso hace alrededor de tres años. En ese momento mis dispositivos móviles eran Apple y busqué información sobre cómo programar apps para ellos, pero hubieron cosas que me desanimaron. El lenguaje de programación a primera vista no me gustó (ahora lo han mejorado muchísimo). Pero lo que más me desanimó fue el hecho de que para poder hacer mis apps tenía que hacerme una cuenta de developer por la que tenía que pagar creo recordar que unos 90 euros al año. Ahí se quedaron mis ganas de hacer apps y me olvidé del tema.

cómo programar apps

En un momento dado cambié de móvil y, nada convencida, me compré uno con sistema operativo Android. Sigue sin gustarme tanto como el iOS, pero….la cuestión de la programación sí me convenció. Para hacerte developer (es decir, poder distribuir tus apps en la tienda Google Play) solo hay que pagar 20 euros una sola vez, y hay muchas opciones para programar.

Después de probar diferentes opciones, yo me quedé con la más sencilla. Se llama App Inventor y es un recurso que creó Google pero que finalmente adoptó el MIT. Puedes encontrarlo aquí. Se trata de un entorno de programación en el que no hay que instalar nada en el ordenador, sino que todo se hace vía web. Además, se caracteriza porque apenas hay que escribir, sino que toda la aplicación se construye como una especie de puzzle, juntando unas piezas con otras para construir lo que sería el código. Si sabes programar en cualquier lenguaje, te va a resultar fácil usar MIT App Inventor. Y si no sabes programar todavía, puede ser una buena manera de empezar a entender cómo suelen ser las partes básicas de un código.

En App inventor los elementos fundamentales del código se llaman bloques. Tú puedes ir diseñando el interface de tu app en el modo Designer (añadir botones, imágenes, navegadores web y un montón de cosas más) y luego en el modo Blocks indicar qué debe hacer cada cosa. Aquí pongo un ejemplo de la pinta que tiene el modo Blocks.

Appinventor

Como ves, a la izquierda tienes todos los tipos de bloques disponibles, clasificados por tipos (control, logic, maths, text, lists, colors, variables y procedures). Debajo de ellos tienes cada uno de los elementos que previamente has añadido a tu pantalla (puedes crear tantas pantallas en la app como quieras), y desde ahí accedes a los bloques disponibles para esos elementos. Tendrías una pantalla de este tipo para cada pantalla que crees en la app. Armando el puzzle, con esas piezas de colores que ves, construyes el programa.

Una vez que tienes tu app tienes varias opciones para probarla. Puedes instalar el emulador de móvil android en el ordenador y verla ahí. También puedes instalar en el móvil la aplicación MIT App Inventor Companion (gratis en Google Play) y usar el escáner de códigos para probar la app en el propio móvil. Para hacerlo así tendrías que estar conectado con el móvil a la misma red wifi que el ordenador. Por último, desde la web de App Inventor puedes generar un fichero descargable con la aplicación, de extensión .apk, que puedes guardar en el móvil si lo conectas con cable USB al ordenador, e instalar la app desde el móvil buscando el fichero con el explorador de archivos y haciendo pulsando sobre su nombre.

Las apps hechas con App Inventor están listas para poder ser distribuidas en Google Play, pero también puedes usarlas tú solo en tu móvil o pasarle el fichero .apk a otras personas.

En próximas entradas espero entrar más en detalle con App Inventor.

Programar es el nuevo inglés

Hace unas semanas leí en Twitter esta frase que he puesto en el título: “Coding is the new English”. Efectivamente, hasta hace poco tiempo saber inglés podía ser el elemento diferenciador entre dos personas con similar currículum. Saber inglés como lengua extranjera no solo aumenta nuestros conocimientos y nuestras posibilidades, sino que demuestra que hemos sido inquietos y hemos querido ir más allá de lo que nos enseñaron en el colegio/instituto/universidad.

Libros de programación

El caso es que, como ya se asume que el inglés es el idioma para todo (al menos en ciencia así es) y debemos utilizarlo sí o sí, este idioma ya no es el elemento diferenciador. Todo el que se dedique a ciencia, ingeniería y seguramente cualquier profesional en cualquier otra área, se supone que se defiende razonablemente bien en inglés. En ciencia, por ejemplo, no se concibe que no sepas leer bien en inglés, pues todas las publicaciones internacionales y muchísima de la información que necesitas está en ese idioma. Y no solo leer, porque cuando tienes que escribir lo que llamamos un “paper”, es decir, un artículo científico, o un poster para un congreso internacional, también tienes que ser capaz de hacerlo en inglés. Hablar en inglés también es fundamental para dar una charla en un congreso o para relacionarte con colegas de otros países. Como todo esto se asume como normal y ya forma parte de la vida diaria de casi todos, el inglés ya tiene que venir en nuestra configuración por defecto 🙂 y hay que diferenciarse por otras cosas. La clave ahora, estoy de acuerdo con el que formuló la frase que da pie al título de esta entrada, es la programación de software.

Programar, o “picar código” como siempre han dicho los programadores, es algo que deberías tener en tu lista de cosas que aprender si estás empezando en esto de la ciencia. En algún momento puede que necesites hacer un análisis estadístico de datos que podrías hacer de manera más rápida y eficaz (puedes usar el código para otra ocasión) si escribes un programa en cualquier lenguaje de programación (Fortran, Phyton, Java….el que quieras) o un script en un entorno de los pensados para este fin (Matlab, R y similares). Podrías incluso necesitar hacer software que no fuese específicamente para tratamiento estadístico relativamente sencillo, sino modelos de cualquier tipo, redes neuronales, reconocimiento de patrones, programas para tratamiento de imágenes (muy típico, por ejemplo, en medicina), simulaciones de biofísica, …. seguro que se te ocurren cientos de problemas que podrías resolver haciendo tu propio programa. Los economistas y analistas de todo tipo también se benefician del saber programar. Con esto último quiero decir que no solo es deseable que sepan programar los científicos, por supuesto los informáticos, o los ingenieros, sino que todo esto es aplicable a muchísimas profesiones, incluidas las “de letras”.

Hoy en día, en mi opinión, no puedes permitirte llegar a un trabajo y, a la hora de necesitar programar, decir eso de “es que no me enseñaron en clase”, o “es que a mí no me gustan los ordenadores”. He visto gente en ciencia decirme que no sabe descomprimir un archivo, que no sabe instalar un programa, o que solo sabe usar Excel para tratar datos. Esto no debería ocurrir porque hoy en día todos tenemos un ordenador con conexión a internet y una fuente inagotable de recursos gratuitos (no ilegales, sino libres) a nuestra disposición. Lo que hace falta son ganas de aprender a usar las herramientas. Ganas de aprender de manera individual. Inquietud por aprender cosas nuevas por nuestra cuenta. Si esas ganas de aprender las focalizamos, al menos en parte, a aprender a programar, nos va a ser muy útil en el mercado laboral y nos va a diferenciar de otros. Yo no soy una experta programadora, pero me defiendo y suelo ser capaz de crear los programas que necesito para trabajar. Si no lo pudiese hacer entorpecería mucho mi trabajo, lo ralentizaría mucho, y además no me habrían surgido algunos bonitos retos laborales que he vivido.

Si no lo has hecho ya, te invito a que busques información sobre lenguajes de programación, elijas uno y aprendas a programar algo. Poco a poco, según las necesidades que vayas teniendo, irás buscando más información y aprendiendo más. La programación es como un edificio que empieza siempre con el típico “Hola mundo!” en pantalla y puede acabar siendo un rascacielos con vistas maravillosas.

Mi próximo reto es aprender Python. Ya estoy en ello. Sabiendo programar en otros lenguajes el reto no parece extremadamente complicado. Lo anterior fue aprender a hacer apps para móviles, que además de útil es muy divertido. ¿En qué lenguajes de programación hablas tú?

Guardar una matriz formateada en un archivo de texto en MATLAB

Este post debería en realidad llamarse algo así como “Cómo guardar una matriz con formato en un archivo de texto con MATLAB, y no morir en el intento”.

Es muy posible que si usas MATLAB y tienes un set de datos guardados en una matriz, quieras guardar esa matriz en un fichero de texto. Esto puede servirte para cargarlos en MATLAB posteriormente, o usarlos con otro programa como puede ser Excel. Hay muchas maneras de hacer esto, pero cuando queremos guardar cada columna con un determinado formato la cosa se complica un poco. Se complica porque hay que empezar a lidiar, por un lado, con la definición del formato y, por otro lado, con las formas aveces poco lógicas de trabajar en MATLAB. Que sí, que es un software fantástico, pero aveces tiene detalles y caprichos que dan ganas de tirar la toalla con él.

Una de las formas de guardar nuestra matriz de datos en MATLAB es usar el comando fprintf. Con pfrintf puedes especificar el formato con el que quieres escribir cada columna de la matriz (puede que una columna sea un número con 4 decimales, otra sea un número entero, otra sea una cadena de texto…). Las normas para aplicar el formato deseado son las que encontrarás aquí. El caso es que, una vez escrito el formato, podrías encontrarte con una desagradable sorpresa como me ha pasado a mí, y es que siguiendo el típico ejemplo que Mathworks escribe en web o en la ayuda de MATLAB, solo consigues escribir valores de la primera columna pero ordenados en filas hasta que se acaban y comienzan a escribirse valores de la segunda columna y así sucesivamente. Voy a poner un ejemplo para que se entienda mejor lo que quiero decir:

Supongamos que tenemos un set de datos que consta de 4 columnas con 4 filas. La primera columna es temperatura dada con un decimal, la segunda es año, la tercera es mes y la cuarta es día (en estas tres últimas columnas todos los valores son enteros). Entonces, nuestra definición de formato sería algo así: formato=’%5.2f %d %d %d\n’    Tenemos 4 filas, lo que quiere decir que lo que queremos guardar es un registro de cuatro medidas de temperatura con su correspondiente fecha. Podría ser algo así:

temperatura=[10.25; 40.36; 28.50; 3.32]

agno=[2003; 2003; 2003; 2003]

mes=[12; 12; 12; 12]

dia=[25; 25; 25; 25]

datos=[temperatura, agno, mes, dia]

Muy bien, pues es muy posible que para grabar este set en un fichero y con el formato que queremos probemos con esto:

formato=’%5.2f %d %d %d\n’

fid=fopen(‘ficherodatos.txt’,’w’);

fprintf(fid,formato,datos);

fclose(fid);

————–

La \n es para empezar a escribir en una nueva línea tras escribir los primeros valores de cada columna. %d es para escribir números enteros, y el %5.2f lo hemos puesto para escribir la temperatura con dos decimalos. El 5 en %5.2 significa que pueden haber 5 caracteres de texto en total, contando la parte entera, el punto y los dos decimales.

La desagradable sorpresa es que fichero de texto que se ha grabado tiene esta pinta:

Fichero de texto MATLAB

Como ves, ha escrito cuatro columnas pero con los valores de la temperatura primero, luego los años, luego mes y finalmente día, eso sí, con el formato que le pedimos. Pero no es el orden en el que queremos los datos!

La solución es escribir un pequeño código con un sencillo loop, como este:

fid=fopen(‘ficherodatos.txt’,‘wt’);

formato=’%5.2f %d %d %d\n’ ;

for i=1:size(datos,1);

    fprintf(fid,formato,datos(i,:));

end

fclose(fid)

Ahora sí, si abrimos el fichero de texto resultante nos encontramos con esto:

Archivo de texto MATLAB

Esto sí es justo lo que queríamos. En el código de arriba verás que en la instrucción fid he puesto ‘wt’ en vez del ‘w’ que teníamos al principio. Esto es para indicarle que queremos escribir en un fichero que es un fichero de texto y que debe adaptarse a las directrices seguidas por los ficheros de texto en el sistema operativo donde estés ejecutando este código. Esto puede interesarte o no. Lo que he hecho es comprobar cuáles son las dimensiones de la matriz datos y hacer un loop desde 1 hasta el número de datos en cada columna (esto es, el número de filas). Dentro del loop he ordenado a MATLAB que escriba las filas de la matriz datos, una a una, en el archivo ficherodatos.txt con el formato deseado.

Ahí queda este tip por si lo necesitas en algún momento. A mí además me sirve escribirlo aquí para no perder estos apuntes entre cientos de papeles. 🙂