05.17.13

Trick of the day: rendering graphics in your terminal

“Those who cannot remember the past are condemned to repeat it”

– Jorge Agustín Nicolás Ruiz de Santayana y Borrás

limecat

Over the past few years, a number of “graphic terminal” emulator software have emerged. Some examples:

This is nothing new, in fact it was possible back in the 70′s, and you can try it using XTerm, the default terminal emulator bundled with X installations since forever!

The process is very simple, you simply have to run:

$ xterm -t -tn tek4014

Which will start an xterm emulating a TEK4014 terminal (instead of the default VTxxx plain-text terminal).

Tektronix_4014

TEK4010 terminal

Now we’ll download some images we want to display. These 40 year old terminals don’t support JPEG though (it didn’t exist back then), nor any popular modern image format, so we’ll have to provide images in a format they understand. Plotutils includes a couple of these vectorial images, so we will run:

# apt-get install plotutils

And finally it’s simply a matter of feeding the Tek4014 terminal with an image, for example:

$ zcat /usr/share/doc/plotutils/tek2plot/dmerc.tek.gz

The terminal will  be fed with an appropriate escape character sequence, along with the actual image contents, it’ll interpret it as an image (just like other escape sequences are interpreted as colored or underlined text), and the awesome result will be this:

 

xterm

How cool is that? :-)

 

You can even resize the terminal window, and the graphics will be re-rendered with the correct size (remember it’s a vectorial image, so wen can zoom in indefinitely).

 

01.31.13

Helpful VIM highlighting

Here’s a quick snippet that you can add to your .vimrc in order to get:

  • MS Visual Studio-like ‘current word‘ highlighting.
  • Trailing space highlighting.

The result looks like this:

vim_hl

And the code is:

1
2
3
4
5
6
7
8
9
10
11
12
function Matches()
    highlight curword ctermbg=white ctermfg=black cterm=bold gui=bold guibg=darkgrey
    try
        call matchdelete(w:lastmatch)
        unlet w:lastmatch
    catch
    endtry
    silent! let w:lastmatch=matchadd ('curword', printf('\V\<%s\>', escape(expand(''), '/\')), -1)
    highlight eolspace ctermbg=red guibg=red
    2match eolspace /\s\+$/
endfunction
au CursorMoved * exe 'call Matches()'

Yes, one day I might convert it to a vim plugin, meanwhile just copy-paste to your .vimrc.

Enjoy!

12.3.12

HTML5 + Box2D = Quick’N'Dirty Dakar Rally Sim

I very rarely mess with web development these days, but the power of current JavaScript engines and latest HTML5 features were just too juicy to pass on.

So sometime around early 2011, I took two afternoons and played with these technologies. Just now I remembered the project I had in hands, and decided I could give it a name and publish it on the net for your personal amusement.

Consider it pre-alpha, and expect bugs! :-)

qnd_dakar_rally_sim

Features:

  • Infinite landscape, using procedural generation (how else could I squeeze infinity into a few KBs?), and adaptive terrain features based on play style (namely, how fast you like to drive).
  • Somewhat realistic physics (based on Box2dJS library).
  • Incredibly detailed graphics engine based on WebGL. Nah just kidding, it’s the default HTML5 canvas-based rendering provided by Box2D itself…
  • Physically-modelled rolling stones on the driving surface. Framerate suffers too much so they’re disabled by default. To re-enable, dive in the source code and hack away.
  • Tested on major PC browsers, and on Dolphin Browser Mini on Android.

Controls:

  • right-arrow -> gas
  • left-arrow <- brake

Right now I’m in the middle of a physical home migration so the code is not githubbed yet, but you can access it by clicking the following link:

Quick’N'Dirty Darkar Rally Sim 2011

There’s no purpose as of yet, but you can try to race against the terrain and see how far you last before ending up on your roof or suffering a physics explosion.

License is GPLv3.

11.27.12

Tramitar baja de ADSL YaCom

Interrumpimos temporalmente la emisión de posts en este blog para meter un offtopicazo, porque no me cuesta nada, y si con esto consigo ayudar a algún alma perdida de dios que quiera dar de baja su linea ADSL de yacom (ahora orange), pues algo bueno habré aportado…

 

Procedimiento a seguir (comprobado el día 27-11-2012):

  1. Obtener el número de referencia de la baja:
    1. Usar el teléfono 900 900 282 (número  gratuito, aunque no aparezca a día de hoy en nomasnumeros900). Insistir varias veces si nadie coge, a la tercera va la vencida.
    2. Tras una breve charla (de verdad, es breve) sobre el motivo de la baja, se te facilitarán unas instrucciones (que proveo a continuación), así como un número de baja (de 9 cifras en mi caso concreto).
    3. Dar las gracias si la persona que te ha atendido ha hecho un buen trabajo y si te apetece (porque ir de pitufo gruñón por la vida no lleva a nada).
  2. Enviar la carta:
    • Remitente: tú mismo…
    • Destinatario: YACOM – Apartado de Correos 35809 – CP 28080 – Madrid
    • Contenido:
      • Carta escrita con:
        • Nombre y apellidos del titular de la cuenta.
        • Tu número de teléfono fijo contratado con YACOM.
        • El número de contrato
        • El motivo de la baja, por ejemplo “Cambio de domicilio”, “Defunción por suicidio tras intentar dar de baja la línea durante varios días”, o cualquier otro motivo igualmente creíble.
        • El número de baja que te han facilitado antes por teléfono.
        • Firma del titular de la cuenta.
      • Fotocopia del DNI por ambas caras.
    • Las gentes de internet recomiendan no enviar una carta tradicional, sino un burofax, aunque vale con una carta certificada. El tema es que no pongan excusas tontas para seguir cobrándote durante meses.
  3. La baja se comenzará a tramitar al de 7-10 días de recibir la carta/burofax (aunque legalmente disponen de hasta 15 días, no solamente 7 ó 10). En ese momento dejarán de facturar.
  4. Después, esperar a que cobren la última factura. Desde su adquisición por parte de Orange, los cobros de YACOM se realizan después (y no antes) de cada período de facturación (que es del día 16 del mes anterior, al 15 del actual), por lo que tras recibirse la carta/burofax, quedará por llegar la última factura. Ésta debería estar prorrateada para reflejar los días reales que se ha utilizado la línea, y no necesariamente el período completo de facturación. La factura llegara a finales de mes.).
  5. Por su seguridad, y con el justificante de envío de la carta/burofax en mano, mandar orden al banco de rechazar recibos de YACOM.
  6. Alea jacta est!

 

Por último, no hace falta que leais este párrafo a partir de este punto, porque esgrimiendo mis increíbles habilidades de ese-e-o, escribiré algunas palabras clave para que la gente que quiera dar de baja, cancelar, eliminar o dejar de pagar su línea de conexión de acceso a Internet de banda ancha de ADSL con teléfono fijo del proveedor de Internet y telefonía fija YACOM, a veces también llamado ya.com, y comprado recientemente por Orange, pueda encontrar este post mediante busquedas tan típicas como “Quiero dar de baja mi linea de YACOM”, o “Cómo cancelo mi conexión de internet con ya.com 10 megas”, o tal vez “Hoygan no consigo dar de baja mi adsl de yacom, ¿cómo hago?”, o incluso “Me gusta el olor a ISP quemado por la mañana”, en su buscador preferido.

 

Muchas gracias por su atención, y tengan un buen día.

 

10.24.12

Liberación de recursos en python

Pongámonos en contexto: estamos usando Python, un lenguaje no mucho más viejo que Java, y donde una de las primeras lecciones que se aprenden es que la memoria es gestionada automáticamente.

Hurrah! Ya no hay que hacer mallocs, ni deletes, ni tener destructores, ni hostias en vinagre,  porque python lo hace todo!

 

¿Entonces, por qué nos topamos a menudo con código como éste?:
f = open("foo.txt", "r")
text = f.readlines()
f.close()        # WAT.
O bien esto?:
with open("foo.txt", "r") as f: # WAT.
    text = f.readlines()

Y no hablo solo de ficheros, sino cualquier tipo de recurso: conexiones de red, puertos hardware, primitivas de sincronización, memoría RAM, etc.

(nota: el texto a continuación es básicamente un copiapega de un mail  enviado a una lista de correo privada. lo digo por si algo no encajara…)

Vamos a meternos en detalles (al menos hasta donde yo conozco; y no dudeis en corregirme si veis algún fallo, así aprendemos todos):

No es necesario hacer un close:

Es cierto, no es estrictamente necesario hacer un close, porque por defecto el lenguaje python se encarga de esas tareas mundanas por nosotros. El problema es que lo hace automáticamente, y a su manera, y puede que no sea la que nos interese.

De ahí que se suela hacer un close() explícito (ya sea con una llamada directa, o mediante el “with” que he comentado antes).

¿Por qué podría no interesarnos lo que hace python por defecto?
Puede ser por muchos motivos:

La vida de las variables en python es un detalle de implementación:

Por ejemplo, el intérprete que solemos usar (CPython) mantiene los objetos en memoria como mínimo hasta que salen de ámbito, y como máximo hasta cuando el GC de CPython lo determina en alguna de sus pasadas (cuando existen ciclos de referencias, y según el perfil de uso de memoria de nuestro programa).

En cristiano: que una variable que se sale de ámbito, podría eliminarse al momento, o podría tardar media hora en ser eliminada por el GC. Imaginad que las conexiones a una misma cámara IP solo se cierran cada diez minutos (porque hemos delegado todo al GC), y que esa cámara acepta como máximo 4 conexiones simultáneas…

(otras implementaciones como PyPy, Jython, IronPython, etc. pueden comportarse distinto)

En .NET ocurre lo mismo, como bien dice David (de ahí viene el jaleo de usar iDisposables incluso para recursos managed…), y en Java más de lo mismo.

Bugs de terceras partes:

Alguna vez hemos sufrido bugs de conteo de referencias, por alguna librería de python escrita en C que no actualizaba correctamente los conteos y provocaba leaks de nuestros propios objetos.

Si esos objetos tenian recursos abiertos, hay que cerrarlos a mano, o sino seguirán abiertos hasta que muera nuestro proceso de python.

Bugs propios:

Incluso asumiendo una gestión de memoria perfecta e instantánea por parte de CPython (que no es el caso necesariamente, como he explicado), existen casos en que nuestro código puede estar manteniendo variables en memoria (y con recursos abiertos) sin que nos demos cuenta.

Algunos casos típicos:

Variables de instancia:

def __init__(self):
    self.my_file = open(...)
    print self.my_file.readline()
    # el recurso permanecerá abierto al menos
    # hasta que el objeto self sea eliminado

Variables dentro de una función de larga duración:

my_file = open(...);
print my_file.readline()
while True:
    # bucle principal del programa
    # my_file sigue con el recurso abierto al
    # menos hasta el fin de la función

Variables que por su naturaleza son compartidas:

El ejemplo más claro, un mutex. También semáforos, bufferes de memoria compartidos por varios hilos, etc.

Variables referenciadas por closures:

Aunque salgamos de una función, los closures alargan la vida de las variables que cogen prestadas de su función padre:
def my_function():
    my_file = open("foobar")
    def internal_function():
        return my_file.readline()
    return internal_function
my_closure = my_function()
# my_file sigue existiendo y con el archivo
# abierto, hasta que se destruya my_closure

Ámbito de función, no de bloque:

Es algo básico de python, pero no está mal repasarlo: en python no vale definir una variable dentro de un bloque (por ej. dentro de un for), porque su ámbito es siempre de función:
for path in ["/a.txt", "b.txt"]:
    my_file = fopen(path...)
    print my_file.readline()
print path    # va a imprimir "b.txt", aunque
              # estemos fuera del bucle.
print my_file # lo mismo pasa con my_file, aunque
              # pueda ser anti-intuitivo
del my_file   # si queremos que se elimine esta
              # referencia a la variable, y el GC
              # pueda hacer su trabajo en algún
              # momento indeterminado
while True:
    #bucle principal de duración infinita
Bueno, creo que así queda una explicación más completa (y espero que también sea técnicamente correcta!) :-)

06.18.12

Software steadicam – Or how to fix bad cameramen

So you’ve just come back from vacations (wohoo), having filled 10 gigs of photos and video, only to discover you’re a (let’s be honest here) shitty cameraman without your tripod?

 

Fret not, for this article will show you the secret to solve your problems!

 

In an ideal world, your hands are as steady as a rock, and you get Hollywood quality takes. In the real world, however, your clumsy hands could use a hand (hah!).

So here’s your two main options:

 

Hardware solution (for use while filming)

This is the proper solution: a system that will compensate for the vibration of your shaky hands and the movement of your body while walking – not unlike the springs on your car allow for a pretty comfortable ride through all sorts of bumps.

Ideally, it will compensate for all the 6 axis (3D traslation + 3D rotation), but in practice you may be limited to less than that. Unfortunately (for most), this depends on how deep your pockets are (buying a ready-to-use steadicam, ranging from 100 bucks to several thousand), or on how handy you are with your toolbox (building a home-built equivalent).

The result could (in theory) be similar to this:

(ah, yeah… a segway, minor detail)

Software solution (for use after filming):

If you can’t spare a segway + a steadycam backpack, there are affordable alternatives. And if you already have many shaking, blurry videos lying on your hard disk, then this is your only option!

We’ll rely on PC software to fix those videos. This, you can do for free at home. There are some payware software packages that may produce slightly better results: but what I’m going to show you is freeware, very quick to use, and good enough quality for most purposes.

The software method may not be that good when compared to an actual steadicam, but hey, it’s better than nothing!

 

The steps:

I’m not going to go much into details, so here’s the basics.

  1. Download VirtualDUB, an open source and free video editing software.
    (Make sure you can open your videos. E.g. you may need to install the ffdshow-tryout codecs and set them up, or whatever; Google is your friend! :-) )
  2. Once you can open your videos, you have to download the magic piece of the puzzle: Deshaker.
    (This free tool – though unfortunately not open source – will do all the important work)
  3. Now open your video, add the Deshaker video filter, choosing “Pass 1“.
    (If you have a rolling shutter camera (most likely), and know its speed (unlikely), you can also correct it by entering the necessary values in there)
  4. Click OK, and play the video through.
    (This will gather information about motion vectors and similar stuff, in order to find out how to correct the shaking, if present)
  5. Now edit the Deshaker video filter settings again, and choose “Pass 2“. Tweak settings at will, and click OK.
    (A progress window will be visible for just a few moments)
  6. Finally, export the resulting video, and you’re good to go!

For a more detailed guide (including rolling shutter values for some cameras), just read the official Deshaker page, or browse Youtube; there’re some tutorials there too.

The settings basically tune the detection of camera movement, as well as what method will deal with the parts of the image that are left empty after deshaking.

The results:

The video below is an example I’ve cooked for you. Each of the 3 processed videos uses a different combination of settings, and was created in no more than 20 minutes each.

I sticked them all together for your viewing pleasure. The improvement can be easily appreciated!

 

That’s it. Happy filming! 8)

 

Bonus track

If you insist on using hardware solutions (good!), here’s a neat little trick that’ll allow some smooth panning (provided you’re not walking):

01.29.12

Zonas horarias, DST, Desplazamientos y otras zarandajas

Ir a la parte 1 de 2: "Sobre la Hora Universal y los relojes atómicos (o qué tienen en común el TomTom y unos trigales)" ]

Continuamos desentrañando el misterio de las horas, orientando la explicación principalmente a programadores.

Hemos establecido qué sistemas de medición de la hora existen. También hemos visto que el estandard de facto es UTC, y por buenas razones.

Y ahora vamos a ver como se pueden representar esas horas en una aplicación.

A efectos prácticos, en este artículo voy a llamar “hora” al conjunto de “fecha+hora“.

 

Conceptos básicos

Repaso de UTC

Quedabamos en que UTC es una hora universal, que trata de indicar la hora del planeta Tierra en general. No está ligado a ningún país en concreto, ni a ningún continente, sino al planeta entero: España no tiene horas UTC. Argentina no tiene horas UTC. El planeta Tierra sí que tiene horas UTC.

Si en una hora UTC particular es pleno día en España, entonces en esa misma hora UTC será noche cerrada en sus antípodas; y será el amanecer o el anochecer si nos quedamos a medio camino entre ambos puntos.

UTC no sufre saltos [*], sino que avanza siempre a una velocidad constante. Porque el planeta Tierra tampoco sufre saltos ni rotaciones bruscas en ningún momento (menos mal :-D ).
[*] Técnicamente sí (tiene saltos por debajo del segundo), pero se puede ignorar perfectamente para este artículo.

 

Hora Local (Local Time)

Los habitantes de este planeta estamos acostumbrados a hablar en términos locales. Yo, como habitante de Madrid, puedo decir “Me levanto a trabajar a las 07:00″. Un japonés, a su vez, puede decir “Yo también me levanto a trabajar a las 07:00″. Pero obviamente no hablamos de la misma hora UTC, sino de una hora “local”.

Trabajar con horas locales puede ser complicado, por ejemplo cuando el locutor se desplaza de sitio. Si despegas de Madrid a las 10:00 (hora local madrileña), vuelas 10 horas, y aterrizas en Miami, la hora local de Miami no serán las 20:00, sino otra, que hay que calcular en base a unos cuantos factores.

En cambio, si despegas a las 10:00 UTC, que aterrizas a las 20:00 UTC.

Desplazamiento (Offset)

El offset es, literalmente, la siguiente resta matemática: hora localhora UTC.

Por ejemplo: La hora local actual en Madrid es finales de Enero a las 20:00. La hora UTC actual en el planeta es finales de Enero a las 19:00 UTC. Por tanto, 20:00 – 19:00 = 01:00 de offset.

Inciso sobre el Horario de Verano:

El Horario de Verano, como sabeis, tiene como objetivo reducir el consumo eléctrico, tener más luz durante las horas laborales, etc (al margen de que se consigan o no dichos propósitos :-P ).

Consiste en mover las manecillas de los relojes locales de un país, para atrasar o adelantar la hora local durante unos meses determinados, cada año.

  • Lo típico es atrasar o adelantarlo 1h, pero en algunos paises es 30 minutos.
  • Cada país lo puede aplicar durante unos meses diferentes: de marzo a octubre, de abril a septiembre… Los días exactos también pueden variar.
  • En muchos países ni siquiera se aplica el Horario de Verano.

En cualquier caso, el offset ya lleva incluído el horario de verano cuando se usa, puesto que el offset se obtiene restando la hora local (que ya lleva aplicado el cambio horario) y la hora UTC.

Otro ejemplo: En Agosto de este año se habrá aplicado el horario de verano en Madrid, por lo que el offset no será 01:00h sino 02:00h.

El offset de una localización geográfica puede variar tanto a lo largo de un mismo año, como hemos visto, pero también a lo largo de varios años. Por ejemplo:

  • Antes del 1901, cada provincia española tenía su propia hora local, en base a su meridiano concreto. Ahora ya no.
  • En el 1918, en España se decide empezar a aplicar el horario de verano, que nunca antes se había utilizado. El offset ya no es el mismo todo el año, sino que aumenta 1h en verano (como en el presente).
  • El 16 de Marzo de 1940, España decide incrementar todos sus relojes en una hora: el offset pasa de 0h a 1h en invierno, y de 1h a 2h en verano. (se ha cambiado la zona horaria, que explico más abajo)
  • Si varios paises con diferentes horas locales eliminan sus fronteras políticas para unirse en un solo país, seguramente modifiquen sus horas locales para coincidir en todo el territorio (variando por tanto el offset).

Por tanto, es perfectamente posible que dos países tengan el mismo offset durante algunos meses del año, pero difieran durante otros.

Dicho de otra forma: a partir de un offset, no se puede deducir en qué localización te encuentras, ni por tanto qué otros offsets existirán en otros momentos del año.

Por ejemplo: Si no sabes si tu +01:00h actual es de Madrid o del Congo, no puedes saber si en Agosto será un +02:00h (caso de Madrid), o se mantendrá en +01:00h (caso de Congo, sin horario de verano).

 

Zona horaria (Time Zone, o TZ)

Se dice que varias poblaciones están en una misma Zona Horaria, cuando desde el año 1970 han compartido siempre la misma hora local. La nomenclatura es “Area/Localización”.

Mapa de todos los TimeZones

No hay que confundir con los husos horarios, meridianos ni offsets. Son conceptos diferentes: “UTC+02:00″ no es realmente una Zona Horaria, es un Offset respecto de UTC.

Por ejemplo: En España, desde el 1970 hasta ahora, han existido tres regiones que no siempre han compartido completamente las horas locales en todo momento. Las tres zonas horarias (o TZs) son:

  • Europe/Madrid: para la península y baleares principalmente.
  • Atlantic/Canary: para el archipiélago canario.
  • Africa/Ceuta: para Ceuta y Melilla.

Actualmente, esas 3 timezones usan horario de verano, por lo que actualmente sus offsets respectivos de invierno son 1h, 0h y 1h; y los de verano 2h, 1h y 2h.

Cada TZ ha tenido un pasado diferente: algunos aplicaron el horario de verano durante 20 años, otros no lo aplicaron; unos tenian un offset de 5h, otros de 10h, etc.

Toda esa información se almacena en lo que se llama tz database (en castellano, base de datos de zonas horarias).

La tz database debe ser actualizada constantemente, reflejando los cambios horarios que se pueden producir a lo largo de los años.

 

Empieza el meollo de la cuestión


Una vez que conocemos los conceptos básicos, podemos pasar a la acción:

¿En qué me influye todo eso a la hora de diseñar mi software?

¿Cómo gestiono las horas correctamente?
¿Y si mi usuario vuela de España a la India y cambia el reloj de su portatil?
¿Y si mi usuario quiere introducir la hora local de despegue y la hora local de aterrizaje en mi software de calendario?
¿Y si mi software tiene varios usuarios simultáneos en diferentes zonas del mundo?

Una política habitual en el mundo de la programación es:

Almacena y procesa globlamente, muestra localmente“.

Dicho de otra forma: elige un formato neutro para almacenar y operar sobre los datos, y preocúpate de las particularidades culturales cuando debas mostrar o recoger los datos de un usuario final.

Recordemos que en este post se usa la palabra “hora” como abreviación de “fecha+hora“.

 

“Almacena y procesa globalmente”

Empecemos con un ejemplo sencillote:

Tenemos una variable tipo entero, cuyo valor es 7 millones.
  • El ordenador almacena y opera globalmente. Concretamente, usa el binario: 00000000011010101100111111000000.
  • En cambio al mostrarlo en una hoja de cálculo, nos puede mostrar ”7.000.000“, o bien “7,000,000“, o tal vez “7e6“, o incluso “######“, según el contexto local (dónde vivimos, tamaño de la celda, formato del número…).
De igual forma, la práctica apropiada suele ser almacenar y operar en Hora UTC, y mostrar en Hora Local.
Y no es porque sea conveniente, sino que muchas veces además es necesario. Por ejemplo:

Tenemos una Hora Local, las 15:00 de un día de Enero. Se le quiere sumar casi medio año (24h*180días=4320h) a esa hora. ¿Cuál será la Hora Local resultante?:

  1. Las 15:00 hora local, como en la hora de partida.
  2. Las 16:00 hora local, porque hay que aplicar el Horario de Verano.
  3. Ninguna de las 2 anteriores.
  4. Cualquiera de las 3 anteriores.

Y la solución es 4) Cualquiera de las tres anteriores, puesto que depende de la zona horaria:

  • En el Moscú actual o el Madrid del año 1910, no hay horario de verano, luego sería 1) Las 15:00.
  • En el Madrid actual hay horario de verano, luego sería 2) Las 16:00.
  • En la Isla de Lord Howe hay horario de verano de 30m, en vez de la hora típica, luego sería 3) Las 15:30.

Queda claro entonces que la única forma de operar correctamente con horas es pasarlas a UTC, operar sobre ellas y finalmente (si hace falta), convertirlas a la Hora Local de nuestra elección para mostrárselo al usuario final.

 

“Muestra localmente”

Hemos establecido que, para la interfaz con el usuario final, necesitamos conversiones de UTC a Hora Local (al renderizar en pantalla) y viceversa (al aceptar datos del usuario)

Si habéis entendido perfectamente todo lo explicado hasta hora, se pueden deducir cuáles son las posibles conversiones inequívocas que podemos hacer:

Para conseguir esto...:...puedes usar esto:
Hora LocalUTC con TZ del usuario
Hora LocalUTC con Offset del usuario en esa hora y lugar
UTCHora Local con Offset del usuario en esa hora/lugar
UTCHora Local con TZ del usuario -- Imposible
Dos aspectos a destacar son:

a) Almacenar el offset no vale para mucho

Un offset solamente es válido para una hora concreta del año, en un lugar concreto del planeta.
Tal y como se explicó antes, en la sección de Offset: si solamente conocemos el Offset para una Hora Local, no podemos averiguar mágicamente a qué lugar (TimeZone) pertenece esa Hora Local.
Y por tanto, tampoco podemos calcular automágicamente el offset que habrá en otros momentos del año (o lo que es lo mismo, la Hora Local en otros momentos del año). Para ello necesitamos el TZ; no queda otra opción posible.
Así que en vez de almacenar, Hora Local + Offset, bien podríamos almacenar únicamente el UTC a secas.

b) El usuario debería poder especificar el offset al introducir una hora

Como veis en la tabla, la unica forma inequívoca de que el usuario introduzca una hora, es indicar también el offset de alguna forma.
Por ejemplo: si el usuario introduce la Hora Local “02:30″, necesitamos saber a cuál de las dos posibles “02:30″ existentes se refiere (en caso de existir horario de verano en ese lugar).
Existen muchas formas de hacerlo:
  • Un checkbox con el que marcar si la fecha va con DST o no.
  • Una dropdown con 25 o 23 elementos (horas), en vez de los 24 habituales.
  • Una mensaje de pregunta que únicamente saltará cuando se dé el caso de una hora ambigua.
  • Etc.
Por ejemplo, esta es una forma que aconseja Microsoft si se utiliza su framework de .NET:  MSDN – How to let users resolve ambiguous times

 

Si no se da esa opción al usuario, el sistema informático deberá resolver la ambigüedad de forma arbitraria. Que en función del caso concreto, puede ser algo perfectamente aceptable (aunque siempre mejorable).

Ultílogo

Con esto terminamos la segunda y última parte del temario.
Espero que hayais conseguido leer y entender hasta este punto, y no estéis aquí unicamente porque os haya llamado la atención eso de “ultílogo;-) .
Con suerte el artículo ha sido de ayuda y os evitará bugs y quebraderos de cabeza en un futuro.

 

Happy coding!

Ir a la parte 1 de 2: "Sobre la Hora Universal y los relojes atómicos (o qué tienen en común el TomTom y unos trigales)" ]

01.25.12

Sobre la Hora Universal y los relojes atómicos (o qué tienen en común el TomTom y unos trigales)

Ir a la parte 2 de 2: "Zonas horarias, DST, Desplazamientos y otras zarandajas" ]

Con este ladrillazo de artículo intento esclarecer unos cuantos detalles sobre esos grandes desconocidos que son UTC, GMT y demás acrónimos indescifrables.

 

Obligatory disclaimer: Intento dar una explicación inteligible, no algo 100% tećnicamente correcto. En parte porque… bueno, tampoco soy aquí un experto en la materia ;-) . Tanto mis fuentes como mi interpretación pueden ser erróneas. Así que si algo canta, os ruego dejéis un comentario para corregirlo.

 

TAI

TAI es una medición del tiempo, independiente del planeta Tierra, del sistema solar, y de cualquier astro en general. Está basada en relojes atómicos.
Empezó a medirse en el 1972, y es completamente independiente de cualquier otro sistema de medición.

Si el día de mañana cae un meteorito que ralentiza el giro del planeta, haciendo que los días duren 3 minutos extra desde ese momento, al TAI se la trae floja. :-D

Actualmente el TAI lleva un desfase acumulado de más de medio minuto (porque la Tierra ha ido ralentizándose desde 1972).

 

UT

No, no aceptamos la hora de un Casio como UT.

UT es una medición del tiempo, conforme al planeta Tierra. Por tanto, UT varía si el comportamiento de la Tierra varía.

Ejemplos: movimientos de placas tectónicas, terremotos, el susodicho meteorito de los dinosaurios, mareas por la Luna, o por si al Sol, Saturno y Jupiter les toca alinearse, etc.

El UT puede medirse de muchas formas diferentes. Ninguna de ellas se puede dar como Verdadera ™ realmente, porque la Tierra ni siquiera es una esfera, y esto de “la hora del día” es una invención humana al fin y al cabo.

Existen unos cuantos de esos métodos de medición: UT0, UT1, UT1R, UT2, UT2R, y UTC (para más info: UT Versions).

 

UTC

DUT1

Evolucion del DUT1 a lo largo de los años

  • UTC, en concreto, usa una especie de media entre varios relojes atómicos situados en diferentes puntos del planeta (por efectos relativistas que no vienen al caso)
  • UT1, por su parte, usa fuentes “externas” (como cuásares, posiciones de satélites, etc) para intentar medir el UT. Se suele considerar como la mejor técnica de las existentes. Aunque es algo subjetivo, claro está, y dependerá de la aplicación.
  • Al offset que acumula UTC respecto a UT1, se le denomina DUT1.

 

Por definición, UTC debe mantener el DUT1 por debajo de 1 segundo.

 

Este año 2012, el DUT1 anda muy cerca del segundo, por lo que en Junio el UTC sufrirá un salto para corregir ese DUT1 excesivo. A eso se le llama leap-second.

Los ordenadores se suelen sincronizar via NTP con un proveeder de UT basado en relojes atómicos (UTC), de ahí que se use tanto el término UTC en computación.

Si quitas todos los leap-seconds que ha habido, UTC se convierte efectivamente en TAI.

Esto es un cuasar, por si te lo estabas preguntando.

GMT

GMT es lo que se usaba antes de establecerse los UTs actuales para medir el tiempo del planeta Tierra. En el 1972, se decidió pasar a llamarlo “UT”, sin más, así en general. A veces GMT se refiere a UTC, a veces a UT1, y a veces a lo que usaban antes del 1972 (observaciones únicamente desde el meridiano de Greenwhich).

Además, GMT es una zona horaria usada como referencia para otras. Por ejemplo, GMT (ó GMT+0), es usada en ciertas épocas del año por UK.

No solo eso, sino que el viejo GMT tuvo varias definiciones: inicialmente se ponía la “hora cero” al mediodía (muy usada por astrónomos, y ahora llamada GMAT), y más tarde, a la noche. El cambio se produjo al pasar del año 1924 al 1925. Ese año Diciembre no tuvo 31 días, sino 31.5 días.

Resumiendo, tenemos unas cuantas acepciones de GMT:

  1. Sistema previo al 1924 (basado en mediodía, también llamado GMAT)
  2. Sistema entre 1924 y 1972 (basado en medianoche)
  3. Sistema posterior al 1972 (UT1).
  4. Sistema posterior al 1972 (UT1+DUT1, es decir, UTC).
  5. Zona horaria de algunos países.
  6. Otras posibles acepciones (cualquier otro UT) en fechas posteriores a 1972.

Efectivamente: al explicarlas, las siglas GMT suelen ir acompañadas de las siglas WTF.

Por todo ello, GMT se puede usar en entornos informales (peliculeros, noticiarios, o lo que sea). Pero en entornos computacionales, militares, médicos, aeronáuticos, y cualquier otro que sea crítico, lo mentalmente saludable es usar siempre algo como UTC.

 

TomTom y los trigales

"En la próxima rotonda, tome la tercera salida hacia el primer trigal que vea"

En realidad esto de los trigales lo había puesto por atraer un poco la atención (¿¿ha funcionado??), pero ya que estamos, habrá que explicarlo…

El GPS como sabéis, utiliza satélites. Concretamente, utilizan muchísimo las mediciones de tiempo para poder estimar la posición y altitud. Es imperioso que todos los GPS funcionen en un marco horario común, o sino los delicados cálculos de vuestro TomTom no valdrían para nada.

Usar UTC no es muy serio, por el tema de los leap-seconds. UT1 tampoco es especialmente útil, porque cambia continuamente, según cambia el planeta Tierra.

Así que los GPS usan su propio sistema, el GPS-Time. GPS-Time es idéntico al TAI mencionado al principio del post, pero tiene un offset constante de unos 19 segundos. Esto se debe a que el GPS-Time coincidía con UTC en el momento de su creación (en 1980), pero no avanza a la velocidad de UTC, sino a la del TAI.

Si el GPS-Time tuviera una velocidad variable como cualquier UT, entonces sería facil que el navegador del coche acabara situándote 100 metros más allá de donde realmente estás, plantándote en medio de una pradera, o en el fondo de un lago.

Así que, por suerte para los conductores, el TomTom y los trigales tienen pocos puntos en común.

 

Zonas horarias, DST

¿Creíais que empezabais a entender el tema?

Pues olvidaos, porque aún falta todo el tema de zonas horarias y DST, que es la verdadera miga del asunto en lo que a programación se refiere.

Y eso que no se han tocao apenas temas tangenciales, como pueden ser los meridianos de referencia, las horas métricas, las horas decimales como la Internet Time de Swatch, el protocolo NTP con sus stratums…

 

Pero lo dejo ahi, porque bastante gordo ha quedado ya el post!

 

Ir a la parte 2 de 2: "Zonas horarias, DST, Desplazamientos y otras zarandajas" ]

01.21.12

AwesomeMounter: join plug’n'play drives into a single large directory

Have you ever run out of space, and decided to offload some of the bigger files to a second (or third…) disk? Sometimes even an external drive?
Are you tired of having to look around all disks in order to find that specific file?

Well, you’re in luck!
Because AwesomeMounter is an awesome program that will get you rid of all that mess, without ever needing to know what LVM, RAID, or even filesystem means.

(…probably!)

AwesomeMounter is free and GPLv3. Based on inotify and mhddfs [en], it’s actually a pretty simple bash script (so if you’re interested, you can easily tinker with it).

 

What can AwesomeMounter do?

Here’s an example. You’ve got 3 places where you store music: your Linux home (50 gigs), a Windows partition (100gigs), and an 8 gigs USB pendrive:

  1. /home/foo/music/ (has reggae and jazz subdirectories)
  2. /mnt/windows/data/mp3/ (has pop and jazz subdirectories)
  3. /media/pendrive/songs/ (has hiphop and electro subdirectories)

And you want all the music in a single place. Namely:

  • /music/ (will contain all the aforementioned music)

 

With AwesomeMounter, you can access music through the 3 original paths, or through /music/, like this:

  • /music/ (total size: 50+100+8 = 158 gigs!)
    • /reggae
    • /pop
    • /jazz
    • /hiphop
    • /electro

How cool is that?

 

Plug-n-Play!

With AwesomeMounter, you gain the ability to disconnect (or umount) any drive at any time.
Reciprocally, whenever a previously set-up drive is connected or mounted again to your system, the data will automatically reappear where the AwesomeMounter config files tells it to.

This makes it perfect in combination with external drives, such as pendrives, USB hard disks, cellphones, memory cards…

 

Continuing the example: the USB pendrive at /media/pendrive/, can be removed as you normally would (e.g. right click -> unmount drive), and /music/hiphop and /music/electro will automatically disappear from /music.

 

Storage balancing!

(a.k.a. what happens when I write stuff in there?)

(c) Peter Riedel/Rex Features
Any new file you try to write, will automatically be put in the drive with the most free space.

E.g.: If your pendrive is full, data will be stored somewhere else.

 

If you need to write stuff to a specific drive, you can bypass this awesome automatic storage balancing. by simply using the corresponding original path at /media/pendrive/*, instead of the joined path that AwesomeMounter made available to you at /music/.

 

How do I use it?

First, copy the script anywhere on your disk, and give it execution permissions.

Then, create a configuration file at ~/.awesomemounter/config. Example file:

##########################
# some configured dirs:
/music /home/foo/music,/media/pendrive/songs
/movies /home/foo/videos,/media/bigHDD
/downloads /home/foo/incoming,/mnt/windows/p2p
# you can nest mounts w/out problems
/video /movies,/downloads/series,/home/foo/docus
##########################

Then simply run awesomemounter from command line (you may be prompted for root access):

$ ./awesomemounter.sh

That’s it!

 

Where do I get it?

AwesomeMounter is available at GitHUB:

https://github.com/stenyak/AwesomeMounter

Don’t forget to create the config file!

 

DISCLAIMER: Use at your own risk. If your house burns down because of it, don’t blame me. Instead, call the firefighters and only then don’t blame me.

11.17.11

Puenting en Azkoitia

Vamos a dar un poco de vidilla al blog, paradójicamente tirándome de un puente ;-)

Aterrizamos en el lugar (inmediaciones de Azkoitia) al mediodia, recibiéndonos una grandiosa vista, de esas que tanto echo de menos ahora que he dejado la capital del mundo (Bilbao) para irme a la capital del país (Madrid):

Muy bonito, sí, pero cambiando un poco la perspectiva se aprecia el cuadro completo…

Shit happens

El salto fue posible fruto de un sorteo que hizo GNG. Fui con un par de colegas, el señor Kazbayadum y su compañero de trabajo Luis.

La altura oficial desde donde saltabamos eran 30 metros, aunque existia otro salto (doble puenting, o pupuenting) de 60 metros, que no pudimos probar.

Vertical del puente

Y sin más dilación, el momento del Salto de Fe:

Un servidor

La próxima de espaldas, que se rumorea que da más sensación; o de paracaídas que dura más :-D

Si a alguien le apetece, los que organizan el tema son Experiencias Radicales Tremendas y Zumbonas.