Split a Latex Beamer file by frame

Sometimes, when a presentation is getting too big for a file, I try to split the frames on several files, usually one file per slide. Being tired of doing this by hand, I’ve written a Perl script for doing that:

#!/usr/bin/perl -w
# Split a beamer file into several files, with one slide on each
#           Ruymán Reyes Castro
use strict;
use warnings;
use utf8;
my $slide_num = 0;
my $ACTUAL;
my $inside = 0;
while  (<>;) {
 if ( /begin{frame}/ ) {
   # new file begins
   $slide_num++;
 } elsif (/frametitle{(.*)}/) {
    $inside = 1;
   # Extract file name
   my $filename = filenamize($1);
   print "Writing: ".$slide_num."_".$filename." \n";
   # create file
   open ACTUAL, ">;", "R".$slide_num."_".$filename.".tex" or die $1;
   print ACTUAL "\\begin{frame} \n";
   print ACTUAL $_;
 } elsif ( /end{frame}/ ) {
    print ACTUAL $_;
    # End file
    print "Done. \n";
    close ACTUAL;
    $inside = 0;
 } else {
    # Write to file
    print ACTUAL $_ if ($inside) ;
 }
}

Filenamize translates the frame title to a string suitable for naming a file

sub filenamize {
   use Encode;
   my $in = Encode::decode('utf-8', shift);
   $in =~ tr/ /_/;
   $in =~ tr/áéíóúñ/aeioun/;
   $in =~ tr/:/_/;
   return $in;
}

It’s only a quick-solution, but maybe it’s useful for someone over there…

Uncategorized

Comments (0)

Permalink

pssh-copy-id

ssh-copy-id[1] is a well-known command for system administration, specially for those deeply involved in the clustering field. It is common, in a cluster environment, to use ssh keys instead of  passwords on multiple machines, so we can move from one machine to another without the need of typing a password. Even you can use a key for limiting the access of the user to an specified command, instead of allowing the user to spawn a full shell (as you may see in [1] or [2]) .

SSH key pairs are composed by two keys: the public key and the private key. For ssh keys to work, you will need to publish the public key on the remote machine, so it can check if you has the correct private key when accessing. Never publish or make public your private key, as this is an enormous security risk. To publish without risk, you can use the shell script ssh-copy-id, supplied with the openssh package, that will connect to a remote machine  and write the public key.

When you have multiple machines, as in a cluster environment, you need to publish your public key in multiple places. The first approximation may be writing a for script with the mentioned ssh-copy-id, but this faces an awkward problem: Either you have to type multiple times the same key, or you have to pass it insecurely, for example:

for host in host1 host2 host3; do

yes ‘MyPassword’ | ssh-copy-id $host

done

Using this way, your password is exposed to all users (just by issuing a ps command), so it is not a Good Practice.

PhD. Casiano Rodriguez Leon, exposed this problem to me during one of my PhD Courses, and suggested doing a Perl script to make this publishing key issue faster and more secure.

After some work, We’ve come up with a solution called pssh-copy-id, which is a perl script / library, published on google code [4]. We hope to refine and clean the code, so it would be accepted on CPAN and freely available to all the community.

pssh-copy-id, currently work-in-progress, enables to use a syntax similar to ssh-copy-id to publish the key, for example:

$ pssh-copy-id  host1 host2 host3

Will ask four your password (assuming is the same for all of the hosts) , and publish the default key on all the machines listed. The password won’t be exposed in any way*. In addition,pssh-copy-id will check if the key has been already published, in which case it won’t be repeated. Also, pssh-copy-id supports host without password, in example, a host with another key published.

Currently, pssh-copy-id supports also the host definition syntax of net-parscp[5], which allows us to use regular expression to define hosts, the same command as before could be written like this:

$ pssh-copy-id host1..3

Future versions of pssh-copy-id will make the process of key publishing parallel, by spawning one process by host, so the process of publishing the key to several host will be faster.

This utility could be a quite useful tool for system administrators, that will enable them to publish and distribute keys faster, or integrate on bigger a script (like we’re doing on the SAII) to simplify the user key distribution problem.

Notes:

* except maybe under a process memory dump, which has not been tested

References:

[1] http://linux.die.net/man/1/ssh-copy-id

[2] http://oreilly.com/catalog/sshtdg/chapter/ch08.htm

[3]http://blog.ganneff.de/blog/2007/12/29/ssh-triggers.html

[4] http://code.google.com/p/pssh-copy-id/

[5] http://code.google.com/p/net-parscp/


Uncategorized

Comments (0)

Permalink

Some notes about Django

WARNING!: This post has been written in English, because I want to practice. If you find some mistake (orthographic, grammatical, whatever), please, don’t laugh and tell me where is it. Thanks for your collaboration!

In the SAII[1], we are currently developing applications using Django Framework[2]. Django is an open source application framework, written in Python. It follows the model-view-controller design pattern (MVC[3]). We chose Django because it’s a powerful environment that allow us to quickly pass from the UML class diagram to the model structure, and after that, it’s only a matter of creating the admin interface with two or three simple calls. This offers you a quickly starting point, and, if you are writing a small application, you’ll only need to customize a few aspects of the admin interface.

Django Logo

Django Logo

Recently, Django has reached the 1.0 version. This version is a huge milestone for the Django team, who started three years ago with only some code lines. Now Django have more than 4000 code commits, 40.000 lines of documentation and a really active comunity supporting the proyect.

However, perhaps you’ll need to use some features that are not in the 1.0 version. If that is your case, you’ll need to use the Django subversion[4], which is the easiest way to get the last version of the proyect. This version is usually  stable, and you can use it without too much trouble. But be careful: Sometimes the trunk version will have some api changes, that could break your application, or third party applications. So, if you want to develop and application, and don’t need the cutting-edge version of the subversion, I would recommend you using the stable release, 1.0, or the next 1.0.1, which contains some bugfixes.

In the SAII, we are in a dangerous position right now, because we need some third party applications (django_xmlrpc and tagging) that need features of the subversion version. This has lead us to some problems, which we need to fix manually, “diving” into the Django code with the debugger. All of the cases were solved by updating the django trunk or the third party application package. Our plan at this moment is to pick the current trunk revision, and use that as our “stable” revision, freezing the state of the framework until we’ll need some extra feature.

In conclusion, Django is a really good framework for web applications. Don’t hesitate to use it in any size projects. One of the applications we developed was used by 250 users simultaneusly during a short time period, and it worked flawlessly. I’ll try to run some benchmarks with the new application, which will have many more users, to measure the charge on the system.

[1] www.saii.ull.es

[2] www.django.com

[3] http://en.wikipedia.org/wiki/Model-view-controller

Uncategorized

Comments (0)

Permalink

Factorías de clases en Python

Hay veces que necesitas crear en tiempo de ejecución clases nuevas (Ojo, no nuevas instancias de una clase, sino clases en si mismas). Es útil cuando las clases se tienen que generar en función del contenido, o cuando hay que generar muchas clases parecidas y no queremos estar escribiendo.

Un ejemplo es el framework para aplicaciones web Django. En este framework, se pueden generar fomularios HTML automágicamente, por ejemplo, para crear un formulario html que permita introducir los datos del modelo Tutu, simplemente hay que hacer una clase del tipo:

>>> class TutuForm(ModelForm):
...     class Meta:
...         model = Tutu

El problema surge cuando tenemos muchos modelos y tenemos que generar autoformularios para todos. Si tenemos que hacer esta clase para cada uno, se nos hace el código muy grande, y tenemos que trabajar con un esquema fijo de urls por ejemplo.

En este caso, una mejor aproximación es utilizar el concepto de Factoría de Clases, es decir, una función (o clase incluso) que genera nuevas clases en tiempo de ejecución. Es posible hacerlo en varios lenguajes, por ejemplo Perl, pero la belleza de la sintáxis de Python lo hace realmente sencillo y claro:

def formClassFactory(modelName):
   """ Función que genera clases autoformulario en base al nombre del modelo del que queremos el formulario """
   # Buscamos la clase que corresponde al modelo
   modelClass = getModel(modelName)
   # Si no la encuentra, no devolvemos ninguna
   if modelClass == None:
      print "No existe un modelo para esa clase"
      return None
   else:
      print "Model Class" + str(modelClass)
   # creamos la clase fantasma (sólo tiene ámbito local)
   class _innerFormClassTemplate(ModelForm):
      class Meta:
	 # Le injertamos el atributo modelo con la clase
         model = modelClass
         exclude = ('grupo','id', 'user')
   # Devolvemos la clase injertada, con la que podemos definir el formulario modelo del método que queramos
   return _innerFormClassTemplate

El código es muy pythónico y claro, pero aún así lo cuento un poco. Como se dice en la docstring, la función genera clases de formulario automáticamente en función del nombre del modelo que queramos. Por ejemplo, si tenemos un modelo que se llama Tutu, esta función devolverá una clase que genere un formulario, y que excluya tres campos que no queremos que aparezcan.

Para ello, primero obtiene la referencia a la clase cuyo nombre tenemos en una cadena. Se podría hacer con un getattr directamente, pero utilizando la función getModel se realizan ciertas comprobaciones de seguridad que no vienen al caso. Luego comprobamos que la clase devuelta no sea nula, porque en ese caso no existiría el modelo del que queremos generar el formulario.

Aquí es donde aparece El Truco. Creamos una clase, con un nombre cualquiera, con la forma que queremos utilizar. Ésta clase tiene ámbito local a la función, así que sólo existe (a priori) en la función local. Aprovechando que tenemos la variable modelClass, fijamos el valor del atributo model de la clase Meta a modelClass, para que la clase nos genere un formulario modelo de la clase. Lo que hacemos finalmente es que la función nos devuelva una referencia a la clase que hemos creado. Como existe esa referencia, la clase sigue existiendo (recordemos que al ser un lenguaje interpretado, las variables existen mientras hayan referencias hacia ellas), y la podemos utilizar como una nueva clase desde el lugar donde hayamos invocado a la función.

En el momento de invocar a la función y obtener la clase, podemos crear una instancia de la misma, como por ejemplo:

  form = formClassFactory(_type)(instance = grp)

Como hemos visto, una factoría de clases es una forma muy cómoda de gestionar la creación de muchas clases similares, ahorrándo código y tiempo, sin poner en peligro la legibilidad.

Algunos enlaces para ampliar:

[1] http://www.ibm.com/developerworks/linux/library/l-pymeta.html?S_TACT=105AGX03&S_CMP=ART

[2] http://rgruet.free.fr/PQR25/PQR2.5.html

Uncategorized

Comments (1)

Permalink

Thunderbird, Lightning y Google Calendar

Recientemente he estado utilizando Thunderbird y Google Calendar para gestionar el correo con el primero, y las citas con el segundo. A veces, la interfaz de Google Calendar se me hace pesada, no sólo porque hay que cargar el navegador, sino porque ciertas cosas no puedes hacerlas, como por caejemplo, copiar una cita de un día a otro (tienes que crearla de nuevo).

El otro día conocí la extensión Lightning de Thunderbird, que permite integrar la funcionalidad de Sunbird (gestor de calendarios de mozilla). Está muy interesante, y funciona bastante bien. Tiene todas las características habituales: Eventos, tareas, vistas de calendario, etc.

Pero claro, tengo todo en google calendar, que tiene la ventaja de poder acceder a él desde cualquier sitio, así que no me interesaba pasarme por completo a Lightning.

Aunque Google Calendar permite exportar en formato ical o xml, Lightning por defecto sólo permite leer los calendarios en sólo lectura. El problema es que para escribir en el calendario, tienes que autentificarte como usuario de google (¡y no es una característica estándar precisamente!)

Para permitir importar los calendarios en modo de escritura, existe una extensión de Lighting (y Sunbird) llamada muy originalmente Provider for Google Calendar. Con sólo poner la URL privada del calendario de google en lugar de la pública, y proporcionar el usuario y contraseña cuando se nos solicite, podremos acceder tranquilamente a los calendarios, y modificarlos sin problema.

Cuidado con las versiones. Provider for Google Calendar sólo es operativa con las versiones más recientes de Lightning y de Thunderbird. La versión que se encuentra en el repositorio de Ubuntu es basura, así que es mejor si la instalan a mano.

Para terminar, aquí hay un tutorial muy sencillo de cómo utilizar el plugin. Que lo disfruten si les interesa ;)

Uncategorized

Comments (0)

Permalink

Y ahora, en dreamhost

En el primer post que puse (hace algún tiempo) en este blog, mostraba las fotos de como tenía mi cuartucho en el garage, con la supuesta infraestructura de servidor y demás.

El servidor que estaba encima del armario, hacía de servidor web, de correo, de ssh, de DNS, de Lineage 2 , y de algunas cosas más que ya no recuerdo. Estaba configurado con un Gentoo Hardened, que (supuestamente) era bastante seguro.

Sin embargo, cada vez me llevaba más tiempo mantenerlo, con las actualizaciones de seguridad que fallaban, con discos duros que se estropeaban, etc. Pensé en cambiarlo por otro servidor, pero eso me llevaría bastante tiempo, así que recordé las palabras de mi maestro Jake hace tiempo, en las que me recomendaba que usara dreamhost y me dejara de problemas.

Así que lo hice, contraté 3 años de hosting, y ahora, poco a poco, estoy migrando las cosas aquí. Primero los blogs, luego los repositorios de subversion, y finalmente las backups de las prácticas. Espero que esté todo para finales de febrero, para empezar con buen pié el segundo cuatrimestre.

Ahora en casa no tengo servidor. La configuración de red (firewall, dhcp, etc) la gestionan ahora dos routers, el Linksys ADSL2 Gateway AG241 y el Linksys WRT54G que tengo con el firmware de HyperWRT.

El primero se encarga de la conexión al ADSL y de la red del cuartucho. Tiene el cortafuegos principal y es el que tiene el dhcp. A éste router está conectado el otro, a través del cable más largo de mi casa, que llega hasta el cuarto de la tele. El WRT se encarga de la red Wifi y la red pequeña para los windows, donde se engancha mi familia sin riesgo de sufrir el acoso de los hackers. Aquí también está enchufada la Playstation 3, pero en una DMZ, para no tener problemas con el juego online.

En la imagen aparece un esquema sencillo de como está la red ahora.

Esquema de la red de casa

Ya describiré las máquinas que hay en detalle, sobre todo la PlayStation y Endymion, que son las que estoy “tocando” últimamente. Venturis e Hyperion son las máquinas viejas, que no tengo conectadas, pero que usaré para cosas más adelante, cuando tenga tiempo.

Espero tener menos problemas con esta configuración, y así poder dedicar mi tiempo a cosas más molonas que se puedan contar aquí ;)

Uncategorized

Comments (0)

Permalink

Macro DEBUG

Un comentario sobre la Depuracion en C

Cuando se programa, normalmente uno no se da cuenta de lo grande que es un código, o de o complejo que es un programa, hasta que se cuelga, y hay que depurarlo. La técnica habitual consiste en ir poniendo printf en sitios estratégicos para ver que está haciendo nuestra criatura, pero el problema es que pecamos de inconsistentes. Un mensaje puede decir “Leyendo puntero” y otro decir “Esto no debería de salir nunca”, y si no sabemos exactamente donde está esa cadena, nos quedamos donde estábamos.
Llevaba tiempo queriendo homogeneizar las cadenas que uso para depurar los programas, sobre todo los muy grandes. Había visto en algunos códigos de GNU unas macros que encapsulaban un printf, de forma que tu ponías algo como DEBUG(“Tutu vale %d“, tutu), y se transformaba en algo como “Depuración, línea 55, archivo titi.c: Tutu vale 3“.

Incluso en otras que he visto, se puede especificar un nivel de depuración (si estás en depuración 1 sólo muestras las llamadas a funciones, pero si estás en 500 muestras todas las asignaciones, y cosas así). Sin embargo, hay un problema, ¿como pasas un número de parámetros variable a una macro?

Un recordatorio sobre las Macros en C
Recordemos que una macro es una cadena que interpreta el preprocesador, haciendo una sustitución sencilla de esa cadena por la equivalencia que hayamos definido. Si la macro permite parámetros, simplemente se sustituye el parámetro por el valor en la aparición de la cadena. Por ejemplo, si tenemos la macro

#define SUMAR(A,B) a + b

y nos encontramos con:

int z,x,y;
z = SUMAR(x,y);

El preprocesador cambiará la línea anterior por:

int z,x,y;
z = x + y;

En ese sentido, el printf nos presenta un problema, porque los argumentos que se le pasan, son variables. Podemos hacer printf(“tutu %d tete %f titi %s\n”, tutu, tete, titi) o también podemos hacer simplemente printf(“wisconsin\n”), por lo tanto, no podemos definir una macro concreta para un printf, porque no sabríamos los parámetros que habría que pasarle.
¿Por qué se llama entonces este post Macro Debug?
Porque sí se puede… pero sólo desde que salió el estándar C99. Acorde, entre otras pocas, con la wikipedia, en el estándar de C99 se implementaron por primera vez las macros con argumentos variables, justamente para poder hacer macros que encapsulen a un printf y similares, sin tener que hacer funciones específicas.

Hacerlo es bastante sencillo:

#define DEBUG(FILENAME,STRING,...) printf("DEBUG: " FILENAME " " STRING, __VA_ARGS)

Cuando usemos esa macro, por ejemplo, haciendo

DEBUG(__FILE__,"Tutu %d tete %c", tutu, tete)

el preprocesador nos generará la línea:

printf("DEBUG: main.c Tutu %d tete %c", tutu, tete);

Como podemos ver, el preprocesador extiende automáticamente las comillas para ocupar todos los parámetros consecutivos. Usando esta función (con los parámetros que se quieran poner), se puede tener una salida homogénea para la depuración del código. Incluso, si no queremos generar código de depuración pero no queremos borrar todas las líneas de debug porque pueden hacernos falta en un futuro, podemos hacer:

#ifdef I_WANT_DEBUG
#define DEBUG(FILENAME,STRING,...)
printf("DEBUG: " FILENAME " " STRING, __VA_ARGS)
#else
#define DEBUG(FILENAME,STRING,...) ;
#endif

Usando el código anterior, si está definida la macro I_WANT_DEBUG, generaremos el código de printf, de lo contrario, generaremos una sentencia vacía.

Buena suerte a todos.

Uncategorized

Comments (1)

Permalink

Folding en vim (Pliegues)

Los Folds (Pliegues) son herramientas muy útiles para cuando se programa. Permiten agrupar trozos de códigos de forma que el editor las oculte o muestre según las necesitemos o no, acortando bastante el tiempo que se pierde buscando algo por el código. En muchos editores visuales se hace casi automáticamente, mostrando un “+” a un lado. En vim, es algo más complicado.
Antes utilizaba las funciones de los plugins de sintáxis, para que el folding se aplicara automáticamente en el código, pero a veces no funciona. Mientras que con python va sin problemas, curiosamente con C no me funciona bien, supongo que será por no usar el estándar de codificación de GNU y seguir el que nos han enseñado en la ETSII.

Si queremos usar el sistema automático basado en la sintáxis:
set fdm=syntax

Si usamos uno basado en la indentación del código (si usamos tabulaciones va bien, pero puede ser excesivo)
set fdm=indent

Si usamos el basado en marcas (código de vim insertado en el fuente)
set fdm=marker

Una marca se pone con {{{ y se termina con }}}. Podemos seguir las marcas con un número de nivel, {{{1 sería el primero y {{{2 estaría dentro del anterior, y así sucesivamente. Estas marcas no interfieren con el código, se pueden poner, por ejemplo, dentro de los comentarios de C:

/* esto es un comentario {{{1 */
int funcion(int parametro) {
printf("Hola pliegues!!");
} /* funcion }}} */

Para cualquier tipo de pliegue, si dentro del rango del plegado (p. ej. en el printf) tecleamos el comando zc, se cerrará el pliegue actual. Con el comando zo lo abriremos de nuevo. Si la segunda letra es mayúscula, se aplica a todos los pliegues. Más información en la documentación de vim sobre folding

Suerte

Uncategorized

Comments (1)

Permalink

Memoria Compartida y Librerías

Mucho cuidado al incluir las librerías de memoria compartida en los programas.

Es importante usar:


#include <sys/ipc.h>
#include <sys/shm.h>

Si no se usan los includes correctos, seguirá compilando pero tendrá comportamientos anómalos (páginas de memoria en las que no se puede escribir y similares). No sé exactamente que librerías coje si no especificas concretamente el shm.h, pero lo que es seguro es que no funciona bien.

Suerte.

Uncategorized

Comments (0)

Permalink

Script autoextraíble

Intentando enviar un archivo zip con ejecutables dentro por gmail, se me ocurrió un sistema para hacer un script autoextraíble. He visto algunos por ahí pero el código que meten es bastante feo y grande, y yo quería algo sencillo para un sólo uso.
La idea es colocar el archivo a extraer a continuación del “exit” del script, y hacer que el script lo saque a otro archivo. Para sacarlo, utiliza dd, el origen es el propio archivo y el destino es el archivo incrustado. Se saltan tantos bytes como ocupe la parte “ejecutable” del script a la hora de sacar la información.
El código del script es sencillo:

#!/bin/bash
dd if=$0 of=nombreIncrustado bs=1 skip=$(( `grep -a -b -x exit $0 | cut -f1 -d:` + 5 )) 2> /dev/null
exit

Lo más complicado sería tal vez el grep: La opción a evita que salga lo de “Coincidencia en archivo binario”, la -b hace que el valor devuelto sea el offset en bytes hasta el principio del match y la x hace que sólo casen líneas completas. De lo que nos devuelve el grep nos quedamos con la primera columna, que es el offset y le sumamos 5 (4 bytes de longitud del exit y 1 más para el final de línea).
Luego simplemente nos saltamos esa cantidad de bloques al hacer la copia y así sacamos todo lo que está después del exit a otro archivo.
Para incrustar el binario dentro del script, simplemente hacemos

#> cat script.sh binario > script.run

Con darle permisos de ejecución ya tenemos un script autoextraíble, que, por cierto, el gmail y demás correos onlines no detecta como archivo peligroso ;)
Saludos y suerte

Uncategorized

Comments (0)

Permalink