Planet

[Boost en español I] Las bibliotecas en el TR1 (1ª part, Array y Hash)

Este es el primero de una serie de posts sobre Boost en español, en el que haremos un repaso por un subconjunto de estas bibliotecas.
Descargando, compilando y usando Boost
Además de su utilidad, las bibliotecas Boost brillan en su facilidad de uso, ya que la inmensa mayoría de las mismas están totalmente definidas en ficheros de cabecera que simplemente incluiremos en nuestro proyecto, evitando tener que compilarlas y enlazarlas de forma independiente. Hay una serie de bibliotecas que, por su complejidad, necesitan ser compiladas y enlazadas, pero son casos en los que la compilación es indispensable y merece la pena por la funcionalidad que ofrecen.
Hoy en día la mayoría de las distribuciones de GNU/Linux alojan en sus repositorios paquetes con las bibliotecas Boost. Por regla general, se distribuye un paquete con la mayoría de las bibliotecas de cabecera, y por separado un paquete por cada biblioteca que necesita enlazado. En esta serie de artículos se indicará convenientemente cuándo es necesario realizar alguna clase de operación especial al compilar y enlazar.
C++ Technical Report 1
Como comenté en el post anterior, vamos a empezar comentando por encima las bibliotecas de Boost que aparecen en el C++ Technical Report 1. Pero primero, ¿qué es ese documento?
Tal y como explica la wikipedia, se trata de un documento que propone una serie de adiciones a la biblioteca estándar de C++. No es un estándar en sí mismo, sino una propuesta borrador, aunque con toda probabilidad gran parte o la totalidad del mismo formará parte de la siguiente versión de C++. Por lo tanto, es interesante echarle un vistazo para familiarizarse con lo que está por llegar.
En cuanto a Boost, 12 de sus bibliotecas han sido incluídas en el TR1, aquí las veremos todas por encima y algunas con más profundidad.
Nota Dado que las primeras librerías que vamos a ver está en el TR1, es posible usar directamente las implementaciones de los compiladores.
Por ejemplo, para boost.array, en lugar de usar la cabecera boost/array.hpp podemos usar tr1/array (sin extensión, típico de la std), y cambiar el namespace boost por el tr1. Sin modificar nada más, el código compilará usando la implementación de array de GCC.
Boost.Array
Documentación: http://www.boost.org/doc/libs/1_43_0/doc/html/array.html
Cabecera: boost/array.hpp
Se trata de un wrapper que adapta las arrays de tamaño fijo, típicas de C, para su uso como contenedor estándar, añadiendo una serie de métodos y tipos de datos tales como size y at, iteradores, etcétera. Las ventajas sobre los arrays clásicos son claras: métodos útiles para conocer el tamaño, métodos de acceso con control de límites, etcétera.
Hay muchas ocasiones en las que utilizamos std::vector incluso sabiendo que el tamaño no va a variar, simplemente por evitar utilizar arrays a pelo. En esos casos, boost::array es ideal, ya que comparte la mayoría de métodos de vector y, al no tener que lidiar con ampliaciones y reducciones dinámicas de memoria, es mucho más eficiente.
Por último, otra de las grandes ventajas de esta biblioteca es la posibilidad de inicializarse en línea como un agregado, lo que nos evita andar inicializando los elementos uno a uno.
#include <boost/array.hpp>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
/*
Ejemplo 1: Inicialización básica de un boost::array
*/
boost::array<string, 3> primos = { {"Shurmano", "Shurprimo", "Shurperro"} };
cout << primos[0] << endl
<< primos[1] << endl
<< primos[2] << endl;
/*
Ejemplo 2: Métodos típicos de los contenedores
*/
// Tamaño
cout << "Tamaño: " << primos.size() << endl;
// Bound checking (comprobación de límites)
try{
cout << primos.at(4) << endl;
}catch(std::out_of_range&){
cout << "Fuera de rango" << endl;
}
// Iteradores
cout << *primos.begin() << endl
<< *(primos.end()-1) << endl;
// Operadores
boost::array<int, 4> yo = { {0, 1, 2, 3} };
boost::array<int, 4> another = { {0, 1, 2, 5} };
cout << ((yo == another)?"Iguales":"Diferentes") << endl;
return 0;
}
En este enlace se explican las motivaciones y detalles detrás de boost.array.
Boost.Hash
Documentación.
Cabecera: boost/functional/hash.hpp
Un hash es una forma de identificar de forma unívoca a cualquier elemento. Se utiliza una función hash que, a partir de las propiedades de un objeto, genera un código único. Los hashes se suelen utilizar en contextos en los que es necesario identificar e indexar elementos, como en los contenedores. La ventaja que ofrece el indexar por hash en lugar de por otro tipo de clave es que la comparación de hashes es muy eficiente, por lo que los accesos se hacen más rápido.
Boost.Hash nos permite generar hashes para enteros, flotantes, punteros y cadenas de forma nativa, y además, provee soporte para la generación de hashes de tipos de datos definidos por el usuario y hashes combinados. La utilización de esta biblioteca es muy sencilla: simplemente creamos una instancia de la clase paramétrica boost::hash, que recibe como parámetro el tipo de dato a hashear. Seguidamente, cuando queramos generar un hash, utilizaremos el operador () del objeto creado.
boost::hash<std::string> string_hash;
cout << "Hash de cadena: "
<< string_hash("Don't hash me, bro!") << endl;
Si tenemos un tipo de datos propio, por ejemplo una clase, y queremos calcular su hash, previamente tendremos que sobrecargar la función size_t hash_value(const T & t), siendo T nuestro tipo de datos. Dentro de esa función tendremos que implementar el algoritmo de hash para nuestra clase concreta.
Por regla general, a la hora de implementar el hash de un tipo propio, tenemos que fijarnos en qué propiedades tiene cada instancia de esa clase que la hace única. Si, por ejemplo, tenemos una clase código de barras con un atributo número que la identifica, el hash de la clase será el hash del código.
class codigoBarras{
int numero;
public:
// ...
friend std::size_t hash_value(const codigoBarras & C){
boost::hash<int> hasher;
return hasher(C.numero);
}
};
Otro ejemplo: si tenemos una clase alumno con dos atributos nombre y apellido, el hash de esa clase será una combinación del hash del nombre y el hash del apellido.
class alumno{
string nombre, apellido;
public:
// ...
friend std::size_t hash_value(const alumno & a){
std::size_t valor = 0;
boost::hash_combine(valor, a.nombre);
boost::hash_combine(valor, b.nombre);
return valor;
}
};
Boost.hash se utiliza en la biblioteca Boost.unordered, que proporciona alternativas no ordenadas a los conjuntos (set) y mapas (map) de la STL, mejorando la eficacia en órdenes de magnitud.
Hasta aquí la primera entrega de estos artículos.

Memoria del PFC [Vídeo]

¡No hemos abandonado el proyecto! Ni muchísimo menos, de hecho hemos estado trabajando mucho en él, pero en la memoria. Este  último mes hemos estado escribiendo la memoria del proyecto en LaTeX. Siguiendo con la filosofía del software libre también liberamos los fuentes de la memoria, los podéis encontrar en Gitorious. Ayer entregamos la memoria, [...]

Taller de Boost – Ahora en posts

Esta semana se han celebrado en la OSLUCA los Cursos de Verano, en los que yo me estrenaba como ponente con un taller de Boost. Al final no tuvo mucha asistencia, pero creo que se puede aprovechar para otra ocasión. Además, he hecho bastantes materiales, que están a disposición del público en el svn http://osl.uca.es/svn/taller-boost.
La cosa es que he decidido trasladar el taller al blog mediante una serie de posts en los que intentaré explicar las bibliotecas más importantes utilizando ejemplos y de la forma más sencilla posible. Inicialmente haré un repaso sobre las bibliotecas de boost que forman parte del C++ Technical Report 1, y luego de una selección de bibliotecas que me parecen útiles o importantes haré una explicación más extendida. Espero que salga la cosa adelante, ya que al fin y al cabo solo se trata de adaptar las transparencias al blog y poco más.

Servicio de negociación

Durante el desarrollo de Argos, poco a poco, me he ido dando cuenta que ciertas partes del código se repetían en los diferentes elementos que conforman el sistema. En concreto, todo el algoritmo denegociación de AVStreams se repetía en cada elemento fuente o sumidero, lo cual implicaba la re-escritura del código en diferentes lenguajes y, además, tener duplicado dicho algoritmo en diferentes ubicaciones.A raíz de este "descubrimiento" empecé a pensar en simplificarlo: si la negociación siempre se hace de la misma forma, dando los mismos pasos, ¿por qué no hacer un servicio que se encargara de ella? Empecé así a escribir un servicio que permitiera a cualquier sumidero ser anunciado/publicado en el sistema y realizar la negociación escribir una sola línea de AVStreams en el mismo, delegando todo ello en ese servicio.Tras realizarlo, observé que la idea era fácilmente adaptable para acoger no solo a los elementos que quisieran actuar como sumideros, si no también a aquellas fuentes que así lo quisieran.De esta idea, surgió poco a poco el servicio que por ahora llamo MMDeviceCreator (se admiten sugerencias en el nombre :D). Este servicio proporciona a sus clientes la posibilidad de delegarle totalmente la negociación de la conexión AVStream. El programador de un elemento solamente tendrá que preocuparse de escribir como proporcionar el flujo multimedia (o como consumirlo, en el caso de los sumideros) y "decirle" al servicio que capacidades tiene (de la misma forma que AVStreams hace para negociarentre dos extremos de conexión). Con ello, y solamente definiendo un nuevo fichero de interfaz slice, se desacoplaba la negociación del flujo propiamente dicho, y de paso, se permite que la implementación final esté realizada en el lenguaje que queramos (siempre que sea compatible con Ice, por supuesto).El servicio ya está "terminado", aunque en fase de pruebas. Ya he realizado la puesta en marcha de algunos casos de uso y he implementado un sumidero y una fuente que utilizan el servicio, pero estos serán material para próximas entradas.

Sigo vivo!

Es curioso no ver posts en 15 días, pero es lo que tiene estar en la fase final de exámenes, para terminar la carrera de una vez. Debido a esto, los últimos 15 días el proyecto ha estado totalmente parado, eso no implica que a partir de la semana que viene se ponga otra vez en marcha, para intentar tener una versión estable y funcional antes de septiembre.
A partir de entonces el proyecto se desdoblará en corrección de fallos para la versión actual y desarrollo de la versión nueva.
Además de la finalización de la aplicación en sí, también tengo que acabar la documentación y los manuales de usuario, por lo que es tiempo que debo tener en cuenta. Por ello espero que tengáis paciencia y comprensión.
Un saludo!

Noticias de nuevo

Después de mucho tiempo sin tocar el blog y en general el desarrollo de GEXAL volvemos a la carga.
Hemos rediseñado un poco el blog cambiandole el estilo y mejorando un poco las distintas páginas que teniamos ya creadas y creando una nueva la de premios y articulos de prensa donde prodreis ver los premios que hemos recibido y alguno que otro medio de comunicación en los que hemos salido.
Sobre el desarrollo hace dos días que volvimos a el pero viene pegando fuerte como un pequeño adelante deciros que se esta empezando a adaptar un sistema de templates usando para ello Smarty y empezar ya a darle un poco de alegría y colorido a la aplicación.
Estamos también mejorando la usabilidad a nivel de la interfaz del profesor añadiendo pequeños detalles con jQuery para que sea todo bastante más facil e intuitivo.
Ya por ultimo deciros que hemos habilitado una dirección de correo electronico a traves de la cual podreis contactar con nosotros aquellos que os interese el proyecto bien para proponer mejoras o bien para contribuir directamente al codigo.

Traduciendo a mi manera

Yo, en vez de intentar terminar las cosas que tengo empezadas, prefiero añadir nuevas funcionalidades al proyecto que a su vez se suman a las cosas que se quedan a medias. Así soy yo xD
Bueno, esta vez he conseguido empezarla y terminarla, más o menos. Aquí ando intentando internacionalizar el proyecto. He estado leyendo un rato sobre gettext pero la verdad es que el tema de los locale y demás me parece un coñazo, así que he decidido montarme mi mini sistema cogiendo algunas ideas de allí y de aquí.
Se me ocurrió hacerlo porque el comando xgettext no me estaba cogiendo las cadenas del código, y mejor que darle más vueltas, pues hacerlo uno mismo. Primero he hecho un script en Python (del que no sé apenas nada, pero es muy fácil y en un rato tienes lo que sea andando) que me saque del código fuente las cadenas indicadas para ser traducidas (el script está aquí), que son de la forma _("cadena"). Este script genera un archivo en formato JSON con un par “cadena original : cadena traducida” con todas las cadenas leídas, para que el traductor pueda coger y traducirlas al idioma que sea.
Luego en C++ he implementado la función _() usando boost::property_tree, que trae un parser para JSON. Se parsea el fichero de traducciones y se devuelve la cadena traducida según el idioma indicado al inicio de la aplicación.
Para más detalles, visite el svn (el de googlecode, no el de rediris).

Hedgewars

Hoy no vengo a contar ningún rollo ni nada acerca de WikiUNIX… Hoy toca hablar de videojuegos que nunca he hablado en este blog de ello. Creo que es un juego del que merece la pena hablar, porque además de ser muy bueno, es software libre… Qué más se puede pedir.
El videojuego del que quiero hablaros se llama Hedgewars y es una versión libre del clásico Worms, donde los bichitos que se revientan unos a otros son erizos en lugar de gusanos.
No es exactamente un clon en el sentido estricto de la palabra, puesto que incorpora además de las armas clásicas (aunque parodiadas: por ejemplo en lugar de la Bomba Plátano hay una Bomba Sandía, en lugar del Holy Hand está la granada infernal, etc) otras armas como el portal (creo que saldrá en la siguiente versión) y las dichosas bolitas. Digamos que intentan ampliar el juego original.
Además el juego es completamente libre y multiplataforma (han generado paquetes para un montón de distribuciones Linux y también los instalables para Windows y Mac OS X, que podéis descargaros desde aquí), por lo tanto amplía mucho la cantidad de gente que podría jugar. En Ubuntu, simplemente tenéis que escribir en la terminal:
sudo apt-get install hedgewars
Como dato adicional, solo comentar que está desarrollado por 4 rusos (3 programadores y un diseñador)  utilizando Pascal para el motor del juego, C++ con SDL y Qt4 para la interfaz gráfica y haskell para el servidor. Personalmente me parece que tiene mucho mérito, puesto que no es el primer clon que se intenta desarrollar de Worms (véase Wormux), pero no se han obtenido los mismos resultados ni de lejos.
He aquí el vídeo de promoción de la versión 0.9.13, que me parece simplemente genial:

Y el de  la anterior 0.9.12:

Os dejo un último video que me gusta mucho, porque se ve a los ericitos en su máximo esplendor y de fondo suena una gran canción…

Sin más, os espero en los servidores de Hedgewars
Un saludo a todos, unixeros
PD: Lo que se pretende con este post es que llegue al mayor número de personas posibles, para ampliar el número de viciados al susodicho juego, así que si alguien quiere copiar esta entrada/crear una entrada derivada en su propio blog, que lo haga. Bienvenido sea.
Archivado bajo:Videojuegos Tagged: erizos, hedgewars, videojuego

Tutorial Instalación de Artoolkit (y ejecución) en Ubuntu

Bueno hace unos días tuve que instalar de nuevo artoolkit en otra máquina con Ubuntu 10.04 y hacía tanto tiempo de la primera vez, que no me acordaba muy bien, así que para que no me pase más he escrito un pequeño manual de instrucciones / tutorial con los pasos para la instalación y la ejecución de las aplicaciones de ejemplo en Ubuntu (probado en Ubuntu 10.04).
Y como la mayoría de visitas que recibe este blog es por este motivo, pues aquí lo dejo:
Instalación Artoolkit
Paso1. Instalar los siguientes paquetes o la versión actual más parecida desde Synaptic aceptando también la instalación de todas las dependencias que nos proponga
freeglut3-dev
libgstreamer0.10-dev
libgstreamer-plugins-base0.10-dev  (quizas este no es necesario)
libxi-dev
libxmu-headers
libxmu-dev
libjpeg62-dev
libglib2.0-dev
libgtk2.0-dev

Paso2.  Descargar artoolkit, la última versión libre es esta:
ARToolKit-2.72.1.tgz
para otros sistemas operativos:
http://sourceforge.net/projects/artoolkit/files/
Paso3. Descomprimir desde un terminal en la ubicación deseada con el comando:
tar zxvf ARToolKit-2.72.1.tgz


Paso4. Ir dentro de la carpeta de artoolkit y configurar desde un terminal con el comando
./Configure
elegir opción 5 Gstreamer Media Framework y responder sí (yes) a las siguientes preguntas (no he probado con las otras opciones la verdad).
Paso5. En la misma carpeta ejecutar desde el terminal el comando make
make
(cruzar los dedos para que todo se compile bien, y ya está terminada la instalación, los ejecutables de los ejemplos estarán en la carpeta bin)
Ejecución Artoolkit
Para la opción de instalación seleccionada supongo que lo que la mayoría desconoce es que hay que darle valor a la variable de entorno ARTOOLKIT_CONFIG
Ejecución de Ejemplos con webcam
Para ejecutar ejemplos de artoolkit con video proveniente de una webcam ejecutar antes el siguiente comando en un terminal para darle valor a la variable de entorno:
export ARTOOLKIT_CONFIG=”v4l2src device=/dev/video0 use-fixed-fps=false ! ffmpegcolorspace ! capsfilter caps=video/x-raw-rgb,bpp=24 ! identity name=artoolkit ! fakesink”
donde pone video0 puede que sea otro número video1 por ejemplo, depende de donde instale la webcam o cuando.
Ejecución de ejemplos con archivos de vídeo en disco
Hay que ejecutar primero el siguiente comando desde un terminal cambiando la ruta de location=/…   por nuestra.
export ARTOOLKIT_CONFIG=”filesrc location=/home/alberto/Escritorio/proyectos/prueba.MOV ! decodebin ! ffmpegcolorspace ! capsfilter caps=video/x-raw-rgb,bpp=24 ! identity name=artoolkit ! fakesink”
Nos fijamos que el valor que se le da a location es la ruta del vídeo que queremos usar como entrada de vídeo, el resto mejor dejarlo como está.
Ejemplo con otra ruta:
export ARTOOLKIT_CONFIG=”filesrc location=/home/nosotros/Escritorio/prueba.MOV ! decodebin ! ffmpegcolorspace ! capsfilter caps=video/x-raw-rgb,bpp=24 ! identity name=artoolkit ! fakesink”
Y listo, ahora podemos ir a la carpeta bin, o donde tengamos el ejecutable y llamarlo desde línea de comandos, siempre con ./ delante.
ejemplo:
./simpleTest

How to use the lastest development version of Tivion

All your bug are belong to me(English version)Tivion is growing. I have many bugs on Launchpad of Tivion 0.0.4 (Lepiron) and I need more testing. So, if you wanna test or simply use the bleeding edge version of tivion you should try this for Ubuntu versions:1 – For test, you need bazaar:?Ver código SHELL1 sudo apt-get install bazaar2 – And then copy the lastest development files with:?Ver código SHELL1 bzr branch lp:tivionIt creates a folder called tivion with all code.3 – Then run with:?Ver código SHELL1 python src/tivion.pyThis version maybe unstable on certains moments, and may cause that tivion dont start or some feature don’t working, but it contains all the new code, features and mostly new channels. I try to fix it as soon I can for the critical bugs, but I am human with limited time.So stay tuned!PS: I start to write some post in English (mostly of tivion), because now tivion is more international. Usually, I don’t use translators and my english is basic-medium, so some patient with me (Versión en Español)Como usar la última versión en desarrollo de tivionTivion está creciendo. Tengo muchos bugs en Lauchpad de Tivion 0.0.4 (Lepiron) y necesito más testeo. Asi que, si quieres probar o simplemente usar la última versión en desarrollo de tivion deberías probar esto para versiones de Ubuntu:1 – Para testear, necesitas instalar bazaar:?Ver código SHELL1 sudo apt-get install bazaar2 – Y entonces copiar los últimos archivos de desarrollo:?Ver código SHELL1 bzr branch lp:tivionEllo creara un directorio llamado tivion con todo el código.3 – Entonces ejecutalo con:?Ver código SHELL1 python src/tivion.pyEsta versión puede ser  inestable en ciertos momentos, y puedo causar que tiempo no inicie o alguna característica no funcione, pero contiene todo el nuevo código, características y mayormente nuevos canales. Intento arreglarlos tan pronto como puedo para bugs críticos, pero soy un humano con tiempo limitado.¡Así que estate pendiente!PD: Voy a empezar a escribir algunos artículos en Inglés (mayormente de tivion), porque tivion ahora es más internacional. Normalmente no uso traductores y mi inglés es básico-medio, así que algo de paciencia conmigo Rating: 0.0/10 (0 votes cast)Comparte, descargalo en pdf, imprimelo o enviaselo a un amigo!

Entradas relacionadas:

  1. Como mostrar la versión de GTK y PyGTK en Python
  2. Tivion 0.0.4 “Lepiron”
  3. Tivion aceptado en el Concurso Universitario de Software Libre (CUSL)
Distribuir contenido