Los Jedi no existen, que no te engañen

Los Jedi no existen, que no te engañen es el mensaje que publicita un autobús que estos días va recorriendo las calles de varias ciudades, explicando a los ciudadanos que eso de los Jedi, la Fuerza, etc., es producto de la imaginación de un productor de cine, materializado en unas pocas películas, series y videojuegos, aunque con una capacidad de marketing impresionante.

¿Y por qué este despliegue informativo? Porque se está comenzando a imponer la obligación de enseñar a los niños, esas mentes frágiles y cual esponjas, que los Jedi son reales y que la Fuerza es una poderosa aliada. Porque, seguramente con el afán de proteger del odio a una minoría, se está obligando mediante leyes a que todos crean que los midiclorianos nos dan la vida y otra serie de ideas asociadas.

¿Hay algún problema con que alguien crea en la Fuerza? ¡Ninguno! ¿Son malos o hay que odiar a quienes lo creen y se visten de Jedi por las calles? ¡De ningún modo! Todo lo contrario, hay que respetar e incluso amar a todos (como nos enseñó Nuestro Señor Jesucristo), independientemente de sus ideas. Están en su derecho a creerlo, pero este derecho no está por encima del derecho de otros a no creerlo, y menos aún de que se imponga, pasando por encima del derecho de los padres a educar a sus hijos como mejor les parezca, imponiendo ese particular punto de vista cual dictadura mediante sanciones económicas o penales.

Esto ha llegado a tal punto de imposición que incluso hay ciudades que pueden quitar la patria potestad si, al menor movimiento de mano de su hijo de 3 años, los padres no lo llevan corriendo al centro de formación Jedi más cercano y lo consagran de por vida al duro entrenamiento que ahí se imparte, sin importar las consecuencias a largo plazo. Cualquier imposición de creencia o de opinión es, por definición, un atropello contra la libertad, incluso si esas creencias son las que uno comparte y vive.

La libertad de expresión consiste en poder decir lo que se piensa, sin ofender pero sin miedo a ser ofendido. Cuando uno se encoleriza y tacha de intolerante y radical, simplemente porque alguien piensa de forma diferente, es porque el intolerante y el radical es uno, no el otro.

En este mismo sentido, estar en contra de estas ideas no es ser Jedifóbico, ni es odiar a los seguidores de la Fuerza, son cosas muy distintas. Se puede discrepar sin que ello implique violencia, persecución u odio. Detalle que, por cierto, parece ser que a unos cuantos Jedi no les han enseñado en Coruscant, ya que atacan con todo su arsenal a cualquiera que discrepe de ellos, ¡incluso a un autobús!.

See you on the 7th… ¿qué esperar realmente hoy de Apple?

Hoy a las 19:00 hora peninsular (España) tendrá lugar una nueva keynote de Apple (verla en directo). Más allá de los metros de scrollbars que han corrido sobre lo que se presentará, me gustaría compartir con todos la verdadera lista de cosas que se esperan para hoy (por dar un toque de realidad humorística):

  • Tim Cook comenzará diciendo “Good morning! Good morning! Thank you very much for coming.”
  • Algún ejecutivo de Apple dirá “I’m really excited to be here today to talk about…”
  • Phil Schiller dirá “This is the most powerful iPhone ever”.
  • (Sir) Jony Ive hablará en un vídeo sobre el diseño del nuevo iPhone vistiendo una camiseta gris clara.
  • Tim Cook llevará puesto el último modelo de Apple Watch (con correa blanca ¡por supuesto!).
  • Craig Federighi repetirá todo lo dicho en la WWDC 2016 y será el mejor presentador de la noche.
  • Eddy Cue se callará en por lo menos dos ocasiones esperando los aplausos que tardarán 1 segundo en llegar.
  • Estará el empleado de Apple encargado de aullar “uh uh” en algún momento de la presentación.

Esto por ir a lo seguro, ¡aunque realmente pueden pasar muchas cosas más! ¡Feliz keynote day!

Lo estás haciendo mal

Todos recordarán el antennagate, cuando el diseño de antena exterior del iPhone 4 mostró un pequeño fallo: el usuario era capaz de puentear las antenas con su mano al agarrarlo, degradando la recepción hasta el punto de no tener señal en algunas ocasiones. El problema era gordo, aunque también es cierto que tampoco era para empezar la tercera guerra mundial como muchos quisieron hacer. Yo mismo he tenido el iPhone 4 y el fallo se convertía en problema básicamente en zonas de baja recepción; no quito peso al fallo, pero si a la publicidad que se le hizo.

Pero vayamos a lo que interesa, lo que dijo Steve Jobs al respecto: “Lo estás agarrando mal”. El meollo del asunto no fue que hubiera un error en el diseño, sino la gestión que se hizo del problema desde la empresa: ga-rra-fal.

Hace unos meses se hizo viral un vídeo (así como sus clones) titulado “10 cosas que estabas haciendo mal”. El vídeo en cuestión pertenece a un canal de hackings (trucos caseros), la gran mayoría muy útiles, por cierto.

Puse el ejemplo del iPhone 4 antes porque uno de esos “trucos” básicamente dice lo mismo: estás agarrando mal el brick. A todos nos ha pasado que salpicamos todo cuando se vierte la leche o el zumo desde un brick. Esto se debe a la turbulencia creada cuando el aire que entra en el envase se encuentra de frente con el líquido que sale. A continuación se puede ver el truco propuesto para evitar ese problema.

En resumen, se propone girar el envase de forma que el agujero de salida quede arriba en lugar de abajo (donde todo el mundo lo usa), permitiendo que el aire entre libremente sin crear turbulencia.

El problema está que esto no es un fallo de uso de parte del consumidor, que lógicamente pone la boca del envase lo más cerca posible del recipiente para maximizar la puntería (con la boca puesta como en el truco se hace más difícil acertar). El problema está en el diseño del envase que prioriza otros factores como volumen óptimo y almacenamiento frente a su uso, dejando como única salida el poner la boquilla en un lugar tan poco apto.

No es que “lo estés agarrando mal”, es que está mal diseñado. No es culpa del consumidor sino del fabricante. Y el vídeo no hace sino acentuar esa percepción de “inutilidad” del usuario al llamarlo algo que “estabas haciendo mal” en lugar de llamarlo un simple truco para compensar el fallo de diseño.

Esto ocurre en muchos otros ámbitos, incluido el mío profesional (programación). Creemos que es el usuario el que lo hace mal (aunque no faltan ejemplos) cuando nuestro trabajo, en su clímax, ¡es lograr que el usuario lo haga bien sin tener que explicárselo! Ya lo dice Jony Ive (CDO de Apple): “Pienso que nuestra meta es que tengas la sensación de que no hay diseño”, de que las cosas funcionan y ya, de que son intuitivas, de que tenían que ser así.

En este sentido me gustaría mostrar dos envases de los que compramos en casa. El de la derecha es el típico brick tetraédrico con la boquilla en una esquina (y su consiguiente turbulencia y derrame). El de la izquierda es de otra marca donde han querido evitar ese problema con un diseño mejorado: la forma en pico de la parte superior hace que la boquilla quede por encima del líquido durante el vertido, facilitando la entrada del aire y eliminando la turbulencia. Para evitar que la pérdida de resistencia colapse el envase al apilarlos, se agregó un tabique de cartón en el medio de los empaques de 6 unidades para absorber parte del peso. En términos de coste no sé cómo afectará, pero no es el producto más caro de su género y creo que han llegado a una solución más que buena.

¡Volando! tic() … toc()

En estos días he descubierto un gran lugar donde aprender y practicar nuevas técnicas de programación y mejorar nuestra habilidades: hackerrank.com. De ahí he podido, además, sacar una comparativa de rendimiento de lenguajes de programación basada en el entorno de compilación / ejecución que se le asignan a cada lenguaje en las máquinas virtuales (ver entorno).

Se puede ver que los lenguajes a los que se les da menos tiempo de ejecución (por ende los más rápidos) son: C, C++ (de esperar), Objective-C (esperable), Pascal (curioso, pero no de extrañar)… y… ¡tarán! ¡Swift!. Además, todos ellos están en el mínimo de memoria (512MB), aunque en este caso sí es de notar que muchos otros lenguajes se suman al carro (salvo Go con 1GB, y en los problemas más exigentes, Java 7 y Python con 1GB, ¡Java 8 con 2GB!).

Y si queréis leer un poco más de Swift, podéis entrar en la página oficial del lenguaje.

OS X: crear DMG (servicio)

Como regalo de Navidad os dejo un servicio de OS X que he creado para crear un disco DMG a partir del contenido de un directorio (o si hay varios directorios seleccionados, creará un fichero por cada uno).

Para instalarlo basta con descomprimirlo y copiarlo al directorio ~/Library/Services (en Finder, abrir el menú Go (Ir) mientras se presiona la tecla de Opción (alt), y elegir Library (Biblioteca). Como veis, tengo mis sistemas en inglés, dejo el servicio con el nombre en ambos idiomas.

Descargar (español)

Descargar (inglés)

Si tenéis algún problema, dejad un comentario y procuraré resolverlo.

Optimización 90-10

Ya dicen que el 90% del tiempo de ejecución está en el 10% del código, y en situaciones como la que menciono hoy es muy patente.

En un código para leer un determinado tipo de fichero tenía la siguiente secuencia (la función completa es unas 7 veces más larga):

for (ii = 0; ii < 3; ++ii) {
 if (tokens[ii].empty()) {
 break;
 }
 elem.clear();
 boost::split(elem, tokens[ii], boost::is_any_of("/"));

 if (elem.empty()) {
 break;
 }
 a[ii] = stoi(elem[0]) - 1;
}

Este fragmento se repite unas 80000 veces en el fichero de pruebas (los ficheros más grandes pueden requerir más de 2 millones de iteraciones). La función contenedora ya estaba optimizada en términos de uso de memoria, creación de objetos temporales, rutas más probables, etc.

Aunque en la versión de despliegue la función es suficientemente rápida (0,45 segundos de media), en modo depuración se vuelve insoportablemente lenta, en torno a los 60 segundos.

Analizando el problema se ve que lo único importante es el primer elemento del vector, es decir, lo que va desde el comienzo de tokens[ii] hasta el primer carácter “/”, por lo que la función puede re-escribirse como sigue:

for (ii = 0; ii < 3; ++ii) {
 if (tokens[ii].empty()) {
 break;
 }

 int p = tokens[ii].find('/');
 a[ii] = stoi(tokens[ii].substr(0, p)) - 1;
}

En modo depuración ahora tarda 28 segundos: ¡50% menos!. En modo final la optimización es menos notable para ficheros pequeños, ya que la función de Boost en cuestión es mucho más eficiente en este modo. De todas formas, los tiempos han mejorado y ahora tardo menos en abrir mis ficheros para corregir errores.

Cambiando el mundo: primeros pasos

Quejarse, deporte nacional. Bien sabido por muchos y practicado profesionalmente por otro tanto. Y si es quejarse de las autoridades, ya estamos hablando del derbi.

¡Qué no hay donde aparcar en el polígono industrial! (por ejemplo, y sin guardar relación con lo que me pasó esta mañana). Pero, ¿y nuestro granito de arena? Se nos suele olvidar y mientras repetimos la queja como un mantra dejamos 80cm de distancia con el coche de enfrente o en diagonal sin pensar que ese acto lo primero que hace es restar un puesto más a la zona.

La frase es muy sabida y repetida pero poco practicada: para cambiar el mundo primero debemos cambiar nosotros.

Daemon-start-stop

Hoy estuve creando un servicio en Debian para iniciar automáticamente un pequeño servidor (el demoniodaemon en inglés) en la empresa. El proceso en sí es bastante sencillo, basta con copiar el fichero /etc/init.d/skeleton a /etc/init.d/<nuestro_daemon>, darle permisos de ejecución y modificar los valores correspondientes a nuestro demonio.

Detallo los puntos de “ensayo y error” en los que trabajé y que me parecen más interesantes. Al final del post dejo, para los curiosos, el servicio de arranque finalizado (he cambiado el nombre por motivos internos).

  • Si se pasan argumentos al ejecutable, lo más sencillo es invocar al mismo con la ruta absoluta.
  • Los argumentos deben ser lo último en la línea de comandos del daemon-start-stop, y no justo después del –exec (como pensaría uno de primeras). Ejemplo: daemon-start-stop –start –quier –exec $DAEMON_EXEC –test — $DAEMON_ARGS
  • Muchas veces queremos ejecutar el demonio como un usuario diferente (permisos, seguridad). En ese caso, se usa el parámatro –chuid [<user>][:<group>], siendo opcionales cualquier de ellos (y siempre los argumentos de ejecución del demonio al final, recordad esto).
  • El parámetro –background ejecuta el programa en segundo plano y no tenemos que preocuparnos nosotros de hacer el fork de nuestro proceso. Importante cuando el demonio se lanza durante el arranque, para no frenarlo.
  • Si nuestro programa no crear su pidfile podemos pedirle al sistema que lo haga por nosotros con la opción –make-pidfile. El pidfile es un fichero especial del tipo /var/run/<nombreproceso>.pid que únicamente tiene dentro el identificador de proceso, y que se utiliza para localizar procesos de forma rápida.

Más información sobre el daemon-start-stop.

Continue reading