twitter

Salvense ustedes. Para mi ya es tarde.

Discussion (5) Loading... Vote up! Vote down!

reto-api

Terminó el reto de El Tiempo para el desarrollo de programas que usen el nuevo API que todavía está en pruebas.

En este hilo se anuncia el ganador.

Me sorprende que lograran escribir código en un entorno como el de la Campus Party en el que es difícil concentrase para hacer algo debido a que pasan muchas cosas al mismo tiempo.

El programa ganador probablemente no fue el que requirió más esfuerzo, pero es una buena idea que se ve bien. Es muy normal que Julian Amaya se encontrara sorprendido al ganar, ya que otros programas se veían más trabajados.

El programa de Santiago Villegas me recuerda a tumbolia:

Aca está el listado completo de programas:

Camilo Andres Galeano Prieto
http://www.evoled.com/wii/eltiempo/
Manuel Ignacio Rodriguez Fernandez
http://rapitors.net46.net/Prueba
Manuel Ignacio Rodriguez Fernandez
http://rapitors.net46.net/ZonaUsuario/index.xhtml
Andrés Sepúlveda
http://www.andressepulveda.com
Santiago Ramirez
http://72.47.252.70/eltiempo/index.php
John Jaiver Acosta Fernandez
http://www.expresionmedia.com/maquina/
Santiago Villegas
http://www.bioral.com.co
Julian Amaya
http://tiempoloverader.appspot.com/static/TiempoFeed.html
David Bello
http://pujaplicaciones.javeriana.edu.co/ElTiempo/
Fabian Andres Sabogal Ocampo
http://fvioz.eviled.org/
Aldemar Bernal
http://smart-feed.vertigoproject.net/
Alejandro Gonzalez
http://www.zerofractal.com/lab/eltiempo-api/noticias-petit.html

Discussion Loading... Vote up! Vote down!

ubuntu-and-debian-redbull

Logos de Debian y Ubuntu en la Campus Party de Colombia usando latas de redbull.

Ah?

En este video despiertan y entrevistan a quien se tomó el trabajo de hacerlos.

Discussion (1) Loading... Vote up! Vote down!

Pesadilla a lo Monterroso

Cuando despertó, Uribe todavía estaba allí y se quería quedar.

Discussion (1) Loading... Vote up! Vote down!

envosconfio

Nota:Esto es un borrador público, en evolución.

Por diversas circunstancias, he pensado que sería muy util un mecanismo para crear una red relaciones de confianza, que no sirva para firmar ni para encriptar. Un sistema que sea fácil de usar por personas no expertas en temas técnicos.

La idea sería que uno vea si los amigos de uno confían o no en personas, y así recursivamente. El mejor resumen sería:

Tener un grafo similar al que se crea en las redes sociales (grafos que permiten ir de un usuario a otro). En las redes sociales usualmente se busca el menor camino o la distancia promedio. En este caso lo importante sería ver si por intermedio de calificaciones hechas por amigos uno puede o no confiar en una persona.

Por eso, propongo crear el sistema (o la iniciativa) envosconfio.

Mi archivo sería uno como:

No es necesario listar a todos los conocidos. Vivimos en un mundo bastante conectado, y seguramente existirán diferentes caminos en la red que se forma para establecer relaciones de confianza con más personas.

Esto funcionaría bien en aplicaciones cerradas. Un ejemplo, es Orkut existe calificación de confianza. Hay tres caritas felices, y ahi las personas que confían en uno marcan el grado de confianza que tienen en uno. La idea central sería hacer algo similar, pero que no sea una red social, sino un estándar.

Es sólo una idea. Este asunto es muy complicado y no sabría en el momento como implementarlo. Nada más complejo que las relaciones humanas.

No sé si sea viable. Es sólo una idea, que vale la pena considerar.

Lo más difícil del asunto es hacer las calificaciones públicas.

Discussion (4) Loading... Vote up! Vote down!

utf8

Demoré mucho tiempo para usar UTF8 como localización por defecto.

utf8

Por fin.

Discussion (5) Loading... Vote up! Vote down!

songwrite2: El cantor de Fonseca (Carlos Huertas)

Actualización:

Terminé la canción completa ( versión lenta | versión rápida ).

He tratado de usar varios programas para hacer MIDIs a partir de partituras, pero no me ha ido bien con los que he probado. En todo caso es algo que quiero hacer y supongo que algún día aprenderé a usar uno bueno.

Por el momento encontré uno que es más bien sencillo, y gracias a eso pude ingresar parte de la canción El Cantor de Fonseca, de Carlos Huertas. (Aclaro que tengo la partitura en papel, no es de oido, los bajos si los puse).

El programa songwrite2 tiene sus errores pero funciona bien y no se bloquea. Es algo engorroso editar pensando en cuerdas y trastes y no transcribir una partitura directamente.

En todo caso, el que el método de entrada sea simple tiene sus ventajas: funciona y es predecible.

Programa songwrite2

Por esta vez, documentaré el proceso de conversión a MP3 para que no se me olvide (y tal vez sea útil para alguien más).

Primero, se usa el propio programa y se exporta un MIDI. Luego se usa TiMidity++ para convertir de MIDI a WAV.

 timidity -Ow -s 44100 -o output.wav cantor-de-fonseca.mid

Luego se usa un encoder (LAME) para convertir a MP3.

 lame -S -h -V2 -b32 -mj -q1 output.wav  cantor-de-fonseca.mp3

Copié los archivos a un servidor (temporalmente):

El archivo fuente de songwriter2 está acá.

Esta canción me gusta.

Discussion Loading... Vote up! Vote down!

robot-party

Yesterday I went to my first Robot Party hosted by Luis Felipe.

We started with a task: Build a simple self-balancing robot with two wheels.

We had available:

I was on a team with Diego. We advanced our design and we finished the basic structure. We also got the AVR working in a protoboard, but at 9PM Diego had to leave and we decided it was better if I joined Luis Felipe who had a working prototype with a simple ON-OFF control (he is very fast). This is what our structure looked like:

El que había iniciado con diego

When Diego left I helped Luis with ideas and with debugging and he ended up with a working proof of concept that could stay balanced using a PID controller.

Otra vista
Desde arriba

Unfortunately, we didn't have better sensors and since we used photo-resistors we had issues with light. This is the best video we could take ( Time to get an infrared camera :-) ).

I had a lot of fun but I felt a little frustrated because I didn't finish my own implementation. I know we would have finished it but finishing the real thing would have made me happier :-)

Perhaps next time we should not do a contest and instead work in a big team. The problem with this approach is that you always have ideas to try and having at least two teams allows everyone to try different ideas faster.

Discussion (3) Loading... Vote up! Vote down!

temblor

Hubo un temblor muy fuerte en Bogotá (de 5.5). Todavía estoy asustado. Estoy con Diego y con Luis Felipe en un 5to piso en una "Robot Party", armando dos robots de juguete.

Las comunicaciones están difíciles.

Discussion Loading... Vote up! Vote down!

Queues in Python

I hadn't needed a queue in python before. Yesterday I needed one and I wanted to check the standard library for the implementation of a queue. I ran into a nice webpage: FIFO as single linked lists.

Python offer the pop(0) method of standard list to implement fifo. Unfortunately lists pop(0) operation need to perform a copy of the whole content of the list, this is quite inefficient if you need to store a large set of data.

Thus you should not implement a queue doing pop(0) to a list (unless you have just a few elements). This implementation has N^2 running time!:

#!/usr/bin/python

LIMIT = 10000000

f = list()
for i in xrange(LIMIT):
  f.append(i)
while len(f):
  f.pop(0)

The right way to do it nowadays is:

#!/usr/bin/python

from collections import deque

LIMIT = 10000000

q = deque()
for i in xrange(LIMIT):
  q.appendleft(i)
while len(q):
  q.pop()

In the webpage FIFO as single linked lists I found a very nice implementation and it runs almost as fast as the previous implementation reversing and copying only once, later I will show an example where the performance is much worse. Amortized algorithms are really pretty. What I liked of this example is that I hadn't seen a class inheriting from list before. This example also shows how you can implement a queue by using a single linked list (or a stack).

#!/usr/bin/python

# Code written by Jeremy Fincher

class ListSubclassFifo(list):
    __slots__ = ('back',)
    def __init__(self):
        self.back = []
    def enqueue(self, elt):
        self.back.append(elt)
    def dequeue(self):
        if self:
            return self.pop()
        else:
            self.back.reverse()
            self[:] = self.back
            self.back = []
            return self.pop()

LIMIT = 10000000

f = ListSubclassFifo()
for i in xrange(LIMIT):
  f.enqueue(i)
while len(f):
  f.dequeue()

If you change the test, then deque is much faster than ListSubclassFifo. A hint:

f = ListSubclassFifo()
for i in xrange(LIMIT/5):
  for j in xrange(5):
    f.enqueue(i)
  for j in xrange(5):
    f.dequeue()

Conclusion: use deque.

Discussion (3) Loading... Vote up! Vote down!

interview-cuda-cpu-gpus

I'm very curious about processing with GPUs. CUDA seems to be a very nice implementation available from Nvidia. This is a rather new technology.

I found a nice interview and here are some parts of it:

... GPUs and CPUs are very different. If you built a hybrid of the two, it would do both kinds of tasks poorly instead of doing both well

our next products will support double precision

The bigger picture is going to be that when CUDA tools arrive that allow you to write regular CUDA code that runs on the CPU as well as the GPU. Then it does run everywhere and we can start adding GPUs or CPU cores to increase performance

What Intel does well is not just building good CPUs, it's the fact that they're a vertically integrated manufacturing company - Intel's in the business of turning sand into money

I think that if we were to compete with Intel, we would need to become a vertically integrated company and have our own fabs

We have to keep an eye on Intel's Ct for multi-cores, too.

I'd like to do something with CUDA next year.

Discussion Loading... Vote up! Vote down!

Debugging STL code with GDB

I wanted to debug a small C++ program that uses the STL. I didn't know how to look into STL vectors and I really wanted to do it. I tried with Eclipse and I didn't like to use a GUI. Not just because I stay away from GUIs but because it was not helpful for inspecting STL objects. It seems there is an extension for that. If you know about it please let me know.

Eclipse + C++, no thanks.

Almost every time I try a GUI to debug a program I end up using vim and GDB again. I guess I'll use a GUI when I need it, but today is not that day.

I wanted to know how to debug using GDB so I searched the WEB for tips and I found two of them to be interesting.

First, there is a nice collection of GDB scripts updated for GCC 3.3 and GCC 3.4. I couldn't get them to work and I would get this error:

me@host:~/gdb_stl_utils$ gdb
GNU gdb 6.8-debian
(cut...)
This GDB was configured as "i486-linux-gnu".
/home/me/.gdbinit:1: Error in sourced command file:
/home/me/.gdb/gdb_stl_utils:21: Error in sourced command file:
The address where /home/me/.gdb/StlStdContainers.o has been loaded is missing.

So, I didn't use them today. Anyway, I am starting to discover how powerful GDB is. I guess I will need to use the scripting facilities of GDB someday.

Fortunately, this message saved my day. It is nice to be able to call functions from GDB. The idea is to code a custom function that allows you to print what you want to inspect.

So, I just used the following functions.

void
dump (const vector <string> &v)
{
  int c = 0;
  for(vector<string>::const_iterator i(v.begin()); i != v.end(); ++i)
    cerr << '[' << (c++) << ']' << " => \"" << *i << "\"" << endl;
}

void
dump (const string &s)
{
  cerr << "\"" << s << "\"" << endl;
}

And this is a sample session:

   me@host:~work$ gdb ./a.out
   GNU gdb 6.8-debian
   Copyright (C) 2008 Free Software Foundation, Inc.
   License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
   This is free software: you are free to change and redistribute it.
   There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
   and "show warranty" for details.
   This GDB was configured as "i486-linux-gnu"...
   (gdb) list 118
   113       {
   114         cerr << "space:" << i << " ";
   115         loop(j,space[i].size())
   116           cerr << " " << space[i][j];
   117         cerr << endl;
   118       }
   119
   120       int m = 51;
   121
   122       loop(i, space[0].size())
   (gdb) break 120
   Breakpoint 1 at 0x80492ff: file MatchString.cpp, line 120.
   (gdb) run
   Starting program: ~/work/a.out
   0 => TIK
   1 => PPPO
   2 => OP
   space:0  0
   space:1  3
   space:2  1

Now comes the interesting part:

   Breakpoint 1, MatchString::placeWords (this=0xbfe49633, matchString=@0xbfe495f0,
       matchWords=@0xbfe495e4) at MatchString.cpp:120
   120       int m = 51;
   (gdb) call dump(MatchString)
   A syntax error in expression, near `)'.
   (gdb) call dump(matchString)
   "TOP"
   (gdb) call dump(matchWords)
   [0] => "TIK"
   [1] => "PPPO"
   [2] => "OP"
   (gdb)

I liked this simple method. I think I will use it for simple programs. It is nice to know that you can modify the dump function and have it print data structures using ranges. It also works with nested structures.

I'd like to ask the following question:

Discussion Loading... Vote up! Vote down!

knuth-interview

This is a nice interview with Don Knuth:

http://www.informit.com/articles/article.aspx?p=1193856

I know that important applications for parallelism exist–rendering graphics, breaking codes, scanning images, simulating physical and biological processes, etc. But all these applications require dedicated code and special-purpose techniques, which will need to be changed substantially every few years.

When reading it remember that he only cares about fundamental stuff, not about trends.

I currently use Ubuntu Linux, on a standalone laptop–it has no Internet connection. I occasionally carry flash memory drives between this machine and the Macs that I use for network surfing and graphics; but I trust my family jewels only to Linux.

No Internet in his computer. I really understand how this works. I really love how this guy does things in batch. Reading articles of the same subject in batch is a very good thing to do.

On the other hand, I willingly put myself in God's hands with respect to how much more I'll be able to do before cancer or heart disease or senility or whatever strikes.

He has accomplished a lot and he still wants to accomplish more. I've noticed that a lot of people I know start thinking they are too old for anything when they are 30!

Almost every biography of every person whom you would like to emulate will say that he or she did many things against the "conventional wisdom" of the day.

This interview is a very good thing to read.

Discussion (2) Loading... Vote up! Vote down!

compressed-swap

Today I noticed this project: compcache:Compressed Caching for Linux.

It allows you to specify an amount of RAM that will be used as a swap device, with compressed pages.

This is a trend that we will start seeing, at least while fast cheap persistent storage becomes common.

If I test this soon in a small device I'll post the results.

Discussion (1) Loading... Vote up! Vote down!

caffeine

I've been working a lot lately. I am quite happy because I managed to cut down caffeine intake (almost to zero). I sleep well most of the time (I need 8/9 hours to feel OK).

Now when I drink some coffee I feel it tastes very good but there is a downside: When I drink caffeine (even if it is just a little) I cannot fall asleep easily. when I was used to it I could even drink a Coke before going to sleep. Sometimes you read that a little caffeine is good for your health but I guess that now that I don't drink it I will not be able to drink any.

Discussion (2) Loading... Vote up! Vote down!

growing-a-language

This is a good thing to watch:

Video
http://video.google.com/videoplay?docid=-8860158196198824415
Talk
http://www.cs.virginia.edu/~evans/cs655/readings/steele.pdf

This guy is quite a geek. In his talk he speaks with short words. I wish I could do that here.


I tried to write very short words in this post but it is very hard. There are many English words that have just one syllable. In Spanish most simple words have more than one.

Discussion Loading... Vote up! Vote down!

gcc4.3

Estuve leyendo los cambios en GCC 4.3 y hay varias cosas interesantes.

macro __COUNTER__
para generar identificadores únicos.
Integración con la librería MPFR
Lo que hace innecesario definir constantes como COSENO_30 para evitar el llamado a la función cos.
-Warray-bounds
opción para chequear algunos desbordamientos de buffers (no es posible chequearlos todos).
Constantes binarias
Como 0b1100, las había querido usar antes. Creo hace muchos años las usaba en Borland C++.
Soporte experimental para el modo paralelo
Esto se ve interesante para probar.

Nota personal:

Discussion Loading... Vote up! Vote down!

No Country for Old Men

I think watching the movie No Country for Old Men was a good experience. Destiny, Luck, Free will, etc are always good topics for a movie.

Links:

Discussion Loading... Vote up! Vote down!

Sweeney Todd: The Demon Barber of Fleet Street

I really liked the movie Sweeney Todd: The Demon Barber of Fleet Street. I'll will never visit a barber! :-)

I'll give it 10/10.

Links:

Discussion (2) Loading... Vote up! Vote down!

verbose-diffs

I find this command useful:

 svn diff --diff-cmd=diff -x -U10 

Sometimes having more lines of unified context is very useful. For instance, when you're trying to merge some -and not all- the code by hand from a branch. I am somehow used to reading patches in diff format. Note that this is not subversion specific, the important command is diff.

This is an example of the results:

Using svn diff, you get:

Index: sendsend.c
===================================================================
--- sendsend.c	(revision 602)
+++ sendsend.c	(working copy)
@@ -8,6 +8,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <sched.h>
 
 /* netcat -u is dying when the remote UDP port is not listening */
 
@@ -23,7 +24,14 @@
     struct timeval tv;
     int retval;
     char buf[LEN];
+    struct sched_param param;
 
+    param.sched_priority = 30;
+    if(sched_setscheduler(0, SCHED_FIFO, &param)==-1){
+      perror("sched_setscheduler failed");
+    }
+
+
     if (argc != 3) {
         fprintf(stderr,"options:  hostname port\n");
         exit(1);
@@ -50,7 +58,7 @@
       FD_SET(0, &rfds);
 
       tv.tv_sec = 0;
-      tv.tv_usec = 100000; /* 100 ms */
+      tv.tv_usec = 500000; /* 1/2 sec */
 
       retval = select(1, &rfds, NULL, NULL, &tv);

Using svn diff --diff-cmd=diff -x -U10, you get:

Index: sendsend.c
===================================================================
--- sendsend.c	(revision 602)
+++ sendsend.c	(working copy)
@@ -1,35 +1,43 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <sched.h>
 
 /* netcat -u is dying when the remote UDP port is not listening */
 
 #define LEN 512
 
 int main(int argc, char *argv[])
 {
     int sockfd;
     struct sockaddr_in their_addr;
     struct hostent *he;
     int numbytes;
     fd_set rfds;
     struct timeval tv;
     int retval;
     char buf[LEN];
+    struct sched_param param;
+
+    param.sched_priority = 30;
+    if(sched_setscheduler(0, SCHED_FIFO, &param)==-1){
+      perror("sched_setscheduler failed");
+    }
+
 
     if (argc != 3) {
         fprintf(stderr,"options:  hostname port\n");
         exit(1);
     }
 
     if ((he=gethostbyname(argv[1])) == NULL) {
         perror("gethostbyname");
         exit(1);
     }
@@ -43,21 +51,21 @@
     their_addr.sin_port = htons(atoi(argv[2]));
     their_addr.sin_addr = *((struct in_addr *)he->h_addr);
     memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
 
     while (1)
     {
       FD_ZERO(&rfds);
       FD_SET(0, &rfds);
 
       tv.tv_sec = 0;
-      tv.tv_usec = 100000; /* 100 ms */
+      tv.tv_usec = 500000; /* 1/2 sec */
 
       retval = select(1, &rfds, NULL, NULL, &tv);
 
       if (retval == -1)
       {
         if (errno != EINTR)
         {
           perror("select");
           exit(1);
         }

You might find this a little exaggerated but I found this useful while integrating some changes by hand from a branched source.

Links:

Discussion Loading... Vote up! Vote down!

Loading... Vote up! Vote down!

Last update: 2007-06-28 (Rev 11825)

svnwiki $Rev: 12966 $