Cumpleaños feliz!

— [ edit | raw ] migrated from node/1027
Bueno, pues ha pasado otro año. La web de CRySoL (tal como la conocemos hoy) cumple 3 años ya. Se inauguró el 20 de octubre de 2005. Aunque como muchos sabéis había algo parecido a una web cutre desde unos años atrás.

Programación de Tareas

— [ edit | raw ] migrated from node/1026
A veces puede resultar útil poder programar el sistema para que realice tareas a una hora determinada. En esta receta veremos dos maneras de hacerlo.

at

La utilidad at nos permite ejecutar tareas a una determinada hora. Si no la tenéis en el sistema, basta con instalar el paquete at de la manera estándar. Por ejemplo, vamos a programar que aparezca el eye-of-gnome a las 12:05. Para ello, ejecutamos en un terminal el comando at, indicando a continuación la hora a la que debe comenzar la tarea. Como veréis, aparece un prompt en el que indicaremos las tareas que queremos que se ejecuten, una por línea. Para salir del prompt, hay que pulsar Ctrl+D. Aparecerá un mensaje confirmando la hora y el número de la tarea (job).
$ at 12:05
warning: commands will be executed using /bin/sh
at> eog
at> <EOT>
job 2 at Fri Oct 17 12:05:00 2008
A menudo, lo que queremos es ejecutar varias tareas, pero en un orden secuencial, no todas a la vez (vamos, lo que viene siendo un script). Suponiendo que queramos ejecutar mistareas.sh, haremos lo siguiente:
 $ at -f miscript.sh 13:45
warning: commands will be executed using /bin/sh
job 4 at Fri Oct 17 13:45:00 2008
También se podría poner miscript.sh como una tarea en el modo interactivo del prompt, siempre y cuando tenga los permisos adecuados de ejecución. Cabe destacar que con at, las tareas quedan programadas para una sola vez, y se borran después de ejecutarse. Es decir, al día siguiente no volverán a ejecutarse. Si queremos borrar una tarea que tenemos programada, debemos conocer primero su número (el que sale al programarla). Para borrarla, utilizamos atrm. Si no conocemos el número de la tarea o lo hemos olvidado, podemos consultar las tareas programadas con la opción -l:
$ at -l
4	Fri Oct 17 13:45:00 2008 a nacho
$ atrm 4
$ at -l
$

cron

Cron es una herramienta que permite la ejecución de tareas periódicamente en varios intervalos: horario, diario, semanal y mensual. Su utilización es más sencilla que la de at: Basta con guardar el script que queramos ejecutar (éste no tiene modo interactivo) en el directorio correspondiente a cuándo queremos que se ejecute.:
  • Cada hora: /etc/cron.hourly/
  • Cada día: /etc/cron.daily/
  • Cada semana: /etc/cron.weekly/
  • Cada mes: /etc/cron.monthly/
Esta simplificación de uso es específica de Debian (y derivados quizá). Aunque la funcionalidad es posible conseguirla en otras distribuciones, no es tan sencillo (y puede que los directorios mencionados no existan). Para saber exactamente cuándo se van a ejecutar las tareas, echamos un vistazo al fichero /etc/crontab. Éste es el mío:
# m h dom mon dow user  command
 17 *  *   *   *  root    cd / && run-parts --report /etc/cron.hourly
 25 6  *   *   *  root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
 47 6  *   *   7  root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
 52 6  1   *   *  root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

Las columnas indican lo siguiente:
  • m = minute (minuto)
  • h = hour (hora)
  • dom = day of month (día del mes)
  • mon = month (mes)
  • dow = day of week (día de la semana)
Por lo tanto, mi crontab indica que: - Las tareas "horarias" se ejecutarán en el minuto 17 de cada hora. - Las tareas diarias se ejecutarán a las 6:25 - Las tareas semanales se ejecutarán el séptimo día de la semana, a las 6:47 (0 y 7 indican Domingo, 1 es Lunes, etc...) - Las tareas mensuales se ejecutarán el día 1 de cada mes, a las 6:52

udev: Configurando el acceso al USB sin ser root

— [ edit | raw ] migrated from node/1024
Cómo escribir reglas para udev permitiendo a dispositivos USB ser usados sin necesidad de ser root

Introducción

A veces sucede que quieres utilizar un dispositivo USB un poco "exótico" y resulta que no puedes utilizarlo sin ser root. Un ejemplo de ello puede ser dfu-programmer o pk2, que son aplicaciones no muy estándard y por lo tanto no se les ha dado el soporte necesario, haciendo que haya que invocarlas como root si queremos utilizarlas. La solución para ésto pasa por crear unas reglas para udev que permitan que éstas aplicaciones accedan al puerto USB de nuestro PC en modo normal.

Un ejemplo: dfu-programmer

Ilustraré el proceso con una aplicación de ejemplo: dfu-programmer. Se trata de un cliente para el bootloader USB instalado en los micros con soporte para dicho interfaz de Atmel. Para añadir las reglas, abrimos (mas bien creamos) el archivo que contedrá dichas reglas:
javieralso@rigoberto:~$ sudo emacs /etc/udev/rules.d/99-dfu-programmer.rules
En este archivo, deberemos escribir algo tal que así:
SUBSYSTEM=="usb", ACTION=="add", SYSFS{idVendor}=="03eb", SYSFS{idProduct}=="2ffb", MODE="660", GROUP="plugdev", SYMLINK+="at90usb-%k"
BUS=="usb", ACTION=="add", SYSFS{idVendor}=="03eb", SYSFS{idProduct}=="2ffb", MODE="660", GROUP="plugdev"
Básicamente lo que se hace es indicar a udev que dfu-programmer usa el sistema USB, dando información detallada acerca del vendorID y el productID del dispositivo que se va a conectar al puerto. También indica con qué permisos se debe acceder al puerto y especifica el grupo cuyos permisos hereda la aplicación.

Referencias

Contenedores y downcasting en C++

— [ edit | raw ] migrated from node/1025
En esta receta se explica cómo hacer downcasting de los elementos de un contenedor a una clase más derivada.

Introducción

Supongamos que tenemos la siguiente jerarquía (nos servirá a lo largo de toda la receta):
class A {
public:
    virtual ~A() {}
};

class B : public A {
public:
    string getB() {
        return "Soy de tipo B";
    }
};

class C : public A {
public:
    string getC() {
        return "Soy de tipo C";
    }
};

El vector de B's y C's

En muchas ocasiones, utilizamos los contenedores de C++ (como vector, stack...) para almacenar distintos tipos de datos. Por ejemplo, imagina que queremos tener un 'vector' que contenga tanto instancias de 'B' como de 'C'. En C++ es necesario crear un vector de la clase padre de ambas, o sea, un 'vector' de A's. Un pensamiento ingenuo (como el mío), implementaría esto mismo así:
B b;
C c;
....
vector<A> v;
v.push_back(b);
v.push_back(c);
....
/*
   Aquí el downcasting. Pero habrá una sorpresa...
*/
¡Y compila!. Lo que está ocurriendo es legal, pero realmente no es lo que queremos ya que el compilador "trunca" el objeto para añadirlo al contenedor y satisfacer el tipo del vector. Este proceso se denomina "Object Slicing". De esta forma, NO estas incluyendo en el vector objetos de tipo 'B' o 'C', sino que todos son de tipo 'A' y, por lo tanto, cuando quieras recuperarlos te encontrarás con que no es posible hacer el molde a tipos más derivados (esa es la sorpresa de la que habla el comentario del texto :-)).

Solución

Antes de dar la solución, vamos a pensar qué queremos realmente. Queremos tener un contenedor que tenga varios tipos de objetos. Hemos visto que el compilador hace slicing de los objetos si estos son instancias. Pero si lo que introducimos en el contenedor son referencias a los objetos, el Object Slicing no ocurre, por lo que tendremos los objetos completos para luego hacer el downcasting. De esta forma, el código correcto sería el siguiente:
// El upcasting se hace sin problemas (Polimorfismo)
A* b = new B();
A* c = new C();

....

vector<A*> v;
v.push_back(b);
v.push_back(c);

....

// Downcasting
B* be = dynamic_cast<B*>(v[0]);
C* ce = dynamic_cast<C*>(v[1]);

cout << be->getB() << endl;
cout << ce->getC() << endl;
Como puedes ver, para hacer el downcasting C++ ofrece el operador dynamic_cast. Es necesario que las clases que intervienen en el casting dinámico estén "en una jerarquía polimórfica real", es decir, la clase padre tiene que tener, al menos, un método virtual.

Referencias

Mini tutorial de OO con Python

— [ edit | raw ] migrated from node/1023

Esta receta es una pequeña introducción al soporte de Python para diseño orientado a objetos. Para programadores noveles, se aconseja primero la lectura de nuestra ya veterana receta Mini tutorial de Python.

GTK UIManager

— [ edit | raw ] migrated from node/1022

Una breve referencia sobre gtk.UIManager y gtk.Action

Mailman and Exim4

— [ edit | raw ] migrated from node/1021
Una buena recetilla sobre el tema: http://www.debian-administration.org/articles/617

Encuentra una idea y participa en el Concurso Universitario de Software Libre de C-LM

— [ edit | raw ] migrated from node/1020
El próximo 17 de Octubre finaliza el periodo de inscripción al II Concurso Universitario de Software Libre de Castilla-La Mancha y ¡¡Queremos Animarte a Participar en esta Nueva Edición!!

El inesperado valor docente del absentismo

— [ edit | raw ] migrated from node/1019

Los nuevos tiempos del ECTS y el espacio europeo traen nuevos “aires” a la vida universitaria. Esta nueva metodología docente aboga por la evaluación continua y el control del progreso del alumno a lo largo del curso. Eso ya se estilaba en mi cole cuando hice la EGB, tampoco es que sea nada innovador.

Probando OS

— [ edit | raw ]
migrated from node/1015
Aquí tenéis un artículo muy interesante sobre la oferta de sistemas operativos disponibles. Si queréis ser originales de verdad, dejarsen de Güindor, de Linus y de macoesequis, y probad alguno de estos: