2014/12/01

Gource para verte mejor



Gource es una herramienta de google para visualizar como video la evolución de un repositorio.

Lo he probado en una Mac, instalado previamente gource y ffmpeg via Homebrew.

brew install gource
brew install ffmpeg

Colocarse en el directorio del repo y ejecutar:

gource -1280x720 -o - | ffmpeg -y -r 60 -f image2pipe -vcodec ppm -i - -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -crf 1 -threads 0 -bf 0 gource.mp4

Para más información: https://code.google.com/p/gource/wiki/Videos

2014/11/20

Luces de espera con CSS3

Algunos ejemplos de luces de espera usando animaciones CSS (hacer click en Result):

Light Waiting

Ring Light Waiting

Iris Lights Waiting

Iris Lights Waiting (Infinite shape)

2014/11/09

iPod Touch Jailbreak

Dispositivo iOS

iPod Touch 4

Procedimiento

  1. Descarga de p0sixspwn (1.0.8 Mac) desde http://p0sixspwn.com/
  2. Ejecución de p0sixspwn, según http://www.iphonehacks.com/2014/06/jailbreak-ios-6-1-6-using-p0sixspwn.html.
    La aplicación identifica al dispositivo conectado y va mostrando el status.
    Luego de varios minutos termina el proceso y aparece el icono de Cydia agregado a la lista de apps del dispositivo.
  3. Ejecución inicial de Cydia.
    Demora unos minutos.

2014/11/02

Resolviendo Mac actualizada a Yosemite: Dialogo muy grande


Usando Yosemite (que recientemente instalé, desde Mavericks), encontré que, a veces, al presentarse el diálogo de archivo, los botones aparecían debajo del docker. Para alcanzarlos tenía que ocultar el docker o moverlo a un lado.

Investigando, parece que el problema se presenta cuando uno está en Chrome (donde paso la mayor parte del tiempo ^^). Parece que se trata de un bug del navegador.

Mientras el bug se resuelve, hay un workaround o rodeo: Usar el pequeño botón verde de la esquina superior izquierda de la ventana para maximizarla. Entonces, el diálogo se muestra completo.

Resolviendo Mac actualizada a Yosemite: Inicio estancado

De Mavericks a Yosemite

Recientemente actualicé el sistema de la Mac, de Mavericks a Yosemite.

Fue un proceso largo. Más largo de lo que esperaba. Lo inicié en el trabajo e incluso reinicié la computadora un par de veces a mitad de un proceso porque parecía que no había progreso. Un amigo fue quien me aclaró que era un proceso largo, que tuviera paciencia.

El proceso terminó varias horas después en mi casa.

Primeras impresiones

Yosemite se ve bien, con su efecto de pavonado transparente. Lo iconos del docker, algo más planos, pero con matices. Es un look que me parece más cercano a Ubuntu Linux que al Metro de Microsoft. Antes Mac daba la pauta y los demás la imitaban, ahora, como que no necesariamente.

Problema

Bueno, resulta que un día, la Mac se iba poniendo cada vez más lenta. A pesar de que el monitor de recursos indicara que había memoria. Reinicié y seguí trabajando pero luego de un rato se repitió la situación. Volví a reiniciar y esta vez fue diferente: la barra de progreso que aparece debajo de la manzanita no pasaba de la mitad. Luego de esperar un rato decidí reiniciarla. Hice varios reinicios sin lograr pasar de ese punto.

Investigando en la otra computadora (Windows 7), encontré que los problemas con Yosemite no eran escasos, principalmente para los que habían llegado actualizando desde Mavericks.

Encontré que presionando Command+R luego del sonido que indica el inicio del sistema, se entra en modo de recuperación. Allí, hay un juego de utilidades para restaurar un backup, reinstalar el sistema, buscar ayuda, verificar los discos, etc. También hay un terminal.

Primero, opté por verificar el disco. Se hallaron algunas inconsistencias (habrá sido por mis interrupciones en la actualización?) que luego indiqué corregir. Después, reinicié, pero igual seguía estancado el inicio.

Reinstalando

Volví al modo de recuperación y decidí indicar que reinstalara el sistema. Parecía que la computadora intentaba conectarse a algún lugar y no lo lograba. Insistí, sin resultado. Seguí entonces el consejo de una página, que tenía que ver con la conexión a red. Entré al terminal y ejecuté el par de comandos:

# launchctl unload -w /System/Library/LaunchDaemons/com.apple.discoveryd.plist
# launchctl load -w /System/Library/LaunchDaemons/com.apple.discoveryd.plist

Luego de eso, indiqué reinstalar el sistema y esta vez si conectó y se realizó el proceso. Demoró toda la noche.

La mañana del día siguiente, entré al renovado Yosemite y me fue bien durante todo el día.

Pero hoy, al retomar la computadora, de pronto parecía que los procesos dejaban de responder, incluso el terminal y el monitor de recursos, como antes de la reinstalación. Reinicié la computadora y llegué otra vez al inicio estancado.

Volví al modo de recuperación, pero esta vez fui al terminal y ejecuté el par de comandos:

# launchctl unload -w /System/Library/LaunchDaemons/com.apple.discoveryd.plist
# launchctl load -w /System/Library/LaunchDaemons/com.apple.discoveryd.plist

Luego, al reiniciar, el inicio se realizó normalmente.

Así que, aparentemente, hay un problema con el manejo de los recursos de red. Si tienes un problema similar, ojalá que estos comandos también te ayuden.

Para más información, esta es la página que encontré:

http://osxdaily.com/2014/10/25/fix-wi-fi-problems-os-x-yosemite/

2014/08/15

2014/06/07

Git: Un Cuento de Tres árboles

Hoy vi una presentación muy iluminadora sobre git, Un Cuento de Tres árboles, por Scott Chacon:

ARCHIVOS: Es el árbol donde hacemos nuestros cambios
STAGE: Es el árbol intermedio, nuestro futuro commit
HEAD: Es el árbol del commit más reciente

Hacer

vim file.txt
  creo file.txt en ARCHIVOS

git add file.txt
  agrega file.txt al STAGE

git commit
  crea un nuevo commit con lo que esté en STAGE y lo hace HEAD

Deshacer

git reset --soft HEAD~
  deshace el último movimiento del HEAD

git reset HEAD~
  deshace el último movimiento del HEAD y copia el commit apuntado al STAGE

git reset --hard HEAD~
  deshace el último movimiento del HEAD, copia el commit apuntado al STAGE y también a ARCHIVOS

Diferencias

git diff
  muestra las diferencias de ARCHIVOS con STAGE

git diff HEAD
  muestra las diferencias de ARCHIVOS con HEAD

git diff --cached
  muestra las diferencias de STAGE con HEAD

Ver

cat file.txt
  muestra el contenido del archivo en ARCHIVOS

git show :0:file.txt
  muestra el contenido del archivo en STAGE

git show HEAD:file.txt
  muestra el contenido del archivo en HEAD

Fuente original: http://akcaprendiendo.blogspot.com/2014/06/git-un-cuento-de-tres-arboles.html

2014/05/05

El 80-20 en programación

Esta la observación de que el 80% de los problemas se debe a un 20% de las causas. Sin embargo, ocurre que con frecuencia la gente usa casi todo su tiempo en atender ese 20% que, en el mejor de los casos, dejará el 80% de los problemas sin resolver.

Lo hacemos. Y hasta nos sentimos orgullosos por el esfuerzo.... pero estamos apuntando al porcentaje equivocado.

Quizás lo hacemos por la misma razón que el hombre que busca su anillo bajo la luz del farol en lugar de en la esquina donde se le perdió... dice que porque aquí hay más luz.

Es muy difundido en la comunidad de programadores el hábito de procurar escribir código con el menor número de líneas, realizar el algoritmo más eficiente o la solución más elegante. Largas discusiones se arman en la búsqueda del mejor framework o incluso el mejor lenguaje de programación.

Y disfrutamos de los placeres que nos da lograr esas cosas.

Pero que nos de placer o nos haga sentir poderosos no significa necesariamente que estemos resolviendo algo.

En realidad, no importa si el código no es el más eficiente, ni si tu lenguaje de programación no es el más elegante. Lo que importa al final es los problemas que llegas a resolver con él.

Los programadores puristas sufren viendo como prosperan lenguajes feos como PHP y Javascript. Niegan con la cabeza. O se burlan. O los odian.

Quizás tengan que ver más allá y tratar de comprender la razón por la cual prosperan. No es una cuestión de lenguaje, sino de utilidad.

De modo parecido a como el valor de un bien no es cuánto te cuesta hacerlo, sino lo que el comprador está dispuesto a pagar por él (la razón de la oferta y la demanda), el valor de un programa no esta determinado por cuán pequeño has logrado tu código o que tan eficiente es tu solución... incluso en los casos que parece que así es, el verdadero valor es lo que le permite hacer al usuario.

Por ejemplo, PHP y Javascript empezaron como lenguajes de juguete. Algo que permitiera llenar fácilmente el vacío de un lenguaje de programación en un servidor web, o en un navegador. A pesar de todas las críticas técnicas que se les puedan hacer, el hecho es que ambos son de lo más útil. Democratizaron el desarrollo web y lo siguen haciendo.

El anillo que los programadores buscamos no está bajo el farol del código mínimo o más eficiente, o el purismo académico. Está en la desconocida esquina del uso que la gente le da, ahora.

Quizás debamos invertir más nuestro tiempo en apuntar a ese 80%.

2014/04/24

Un background con inline css es contenido funcional

Se prefiere que en el HTML esté el contenido y en el CSS la presentación.

De ese modo, viven independientes. Es posible cambiar el .css por otro y dar un aspecto totalmente nuevo a la página.

Una imagen en background se considera presentación. No le corresponde un tag ni un nodo de texto. Pero quizás se pueda hablar de contenido funcional.

Una imagen que es contenido:

index.html
<div class="foto"> <img src="imagen.jpeg" /> </div>

Si ahora pusiera la imagen como background definido en CSS:

style.css
.foto {
 background: url('imagen.jpg') no-repeat;
}

index.html
<div class="foto"> </div>

Al hacer eso, imagen.jpg deja de ser contenido y pasa a ser presentación.

Pero, si el css no estuviera en un archivo aparte, sino inline:

index.html
<div class="foto" style="background: url('imagen.jpg') no-repeat;"> </div>

Entonces, imagen.jpg se podría considerar como contenido.

Cierto que está definido usando CSS, pero es inline, está pegado al HTML y en el flujo de trabajo se puede tratar de modo similar a un img. Es como si fuera contenido.

Estas serían formas de definir contenido de manera no tradicional:
  • Usando background en inline css
  • Usando un inline script
    <div class="texto"><script>document.write('Hola Mundo!');</script></div>



2014/01/23

Kanbiando con Kanban


Hace unos días, en mi trabajo, hicimos una actividad interesante.

Se propuso a los miembros del equipo un problema de programación no muy complejo. Se eligió un lenguaje de programación y una sola computadora, cuya pantalla se reflejaba en un televisor para todos, donde cada uno trataba de avanzar lo que pudiera durante 5 minutos.

Excepto el jefe, que debía mantenerse al margen haciendo intervenciones ocasionales, nadie más que quien estaba en su turno podía hablar, contando a los demás que iba haciendo y por qué lo hacía.

Además podía buscar en Google, y modificar o borrar el código previo.

Se sucedieron varias rondas y paso un par de horas sin que lográramos escribir una solución funcional.

Entendíamos la solución a la que queríamos llegar, y probablemente todos hubieran podido escribirla trabajando solos durante quince minutos o media hora. Pero, por alguna razón, no la lográbamos alcanzar.

Cuando terminó la jornada, me retire, pero el problema continuaba en manos que quienes podían quedarse.

Me sentía frustrado, pero, conforme pasaba el tiempo me iba sintiendo además instruido. Un problema simple y solucionable se había vuelto prácticamente irresoluble debido a las condiciones de trabajo impuestas.

Estas condiciones fueron tales que prácticamente anulaban la comunicación. Eso inhabilitaba el trabajo en equipo. Al menos, él trabajo en equipo usual.

Reflexionando, me di cuenta que, al inicio, nadie asumió el reto como un trabajo en equipo. Cada uno quería, de ser posible, terminar el problema en su turno.

Luego, cuando las primeras rondas iban mostrando que no sería tan fácil, apareció gente que prefirió hacer explícita una estrategia en lugar de programar. Entonces, el trabajo de todos empezó a encauzarse y parecía que se resolvería pronto. Nos estábamos adaptando.

Es allí donde el jefe cambió de pronto las reglas. Dijo que estaba clara la solución y que el reto sería ahora tratar de escribirla una sola persona, desde cero, en 5 minutos.

Además de transformar el problema en una competencia de tipeo, de entrada, eso destruía la comunicación incipiente que había surgido espontáneamente. Fue entonces cuando me retiré.

Camino a casa iba pensando que pasaría si esa prueba se repitiera cada semana. Creo que iniciaríamos sacrificando tiempo de programación para establecer mejor primero un marco de trabajo y luego la estrategia para resolver el problema. Y luego recién empezaríamos a codear.

Me pregunte luego cuántos proyectos habrá así en la vida real. Con gente competente y sin embargo sin avances significativos. Y todo por una organización contraproducente.

Deming, el padre de la mejora continua de la calidad, decía que el 95% del resultado éxito o fracaso se debía a la organización y solo 5% a la gente.

Pero no es obvio. Mucha gente tiende a culpar a la gente y lanzarse a tomar medidas correctivas en ese sentido. Llamadas de atención, recorte de privilegios, castigos, en el peor de los casos. Capacitaciones y coaching en el mejor de los casos.

Pero, si la causa es la organización, no se solucionará nada. A menos que se empondere a la gente para que la pueda mejorar.


Un par de días después, asistimos a un seminario sobre Kanban (la metodología de visualización de flujo de trabajo inspirada en las prácticas de Toyota).

Resulta que es una herramienta muy simple y poderosa para visualizar el estado del flujo de trabajo en una organización. Y para hacer evidentes sus virtudes y defectos.

Siendo evidentes los defectos, es más fácil proponer cambios de políticas e ir gradualmente cambiando la organización.

Yo pensaba que venía utilizando Kanban, al menos en mis proyectos personales. Descubrí que lo estaba haciendo de modo incompleto. Para que Kanban haga su magia, es necesario hacer hacer explícitos los límites de trabajo en progreso (WIP, por sus siglas en inglés) y las políticas de aceptación de tareas.

Ahora estoy leyendo y aprendiendo más al respecto. Un libro que me parece sumamente útil y fácil de leer es "Scrum y Kanban: Usando lo mejor de ambos", de Henrik Knigerg y Mattias Skarin.

Estoy viendo que podría usarlo también para mejorar mi forma de estudiar... y hasta para procesar con más eficacia las montones de cosas que quiero hacer en la vida (Personal Kanban)

Una gran virtud de Kanban es que te permite iniciar como eres ahora, con lo que tienes ahora.

Viva Kanban \(^_^)/

2014/01/13

En equipo

Es muy diferente escribir código solo que en equipo.

Cuando eres solo una persona, tienes más libertad para elegir lo que te gusta o desechar lo que no te gusta. Para elegir usar patrones que solo tu conoces, para inventar tu propio framework, para usar los hackings que te gustan...

Cuando eres solo una persona, escribes código para solucionar un problema. Y punto.

Pero cuando estás en un equipo, escribes código para solucionar el problema de modo que otros puedan entender la solución y mantenerla.

Eso puede ser un poco más complicado. Porque la mayoría de tu equipo puede tener otras preferencias de formato, usar mejor otros frameworks, y cosas como los hackings (que te hacen googlear media hora para entenderlos), no son recomendados.

Pierdes la sensación de control total que puedes sentir cuando dominas tu código. En su lugar, va apareciendo el sentimiento de que todo es caos.

Y, sin embargo, del caos surge un orden, y soluciones valiosas, si las sabes ver. Es cuestión de abrir la mente para estar dispuesto a aprender... que nunca se acaba de aprender. Y que hay soluciones que no son tuyas ni mías, sino de ambos.

Cuando aparece la sinergia, donde uno más uno es más que dos, es como magia que jamás conocerías si no fuera porque trabajas en equipo. Y entonces, lo valoras.

2014/01/06

Justo a Tiempo

Just In Time (Justo a Tiempo), JIT, es una filosofía de producción.

Sus principios se basan en los que empleaba Toyota en los 1970, pero adecuados a occidente.

En el libro "Justo a Tiempo", de Edward J. Hay, mencionan que algo principal en JIT es la eliminación de desperdicio.

Los japoneses definen desperdicio como "todo lo que sea distinto de la cantidad mínima de equipo, materiales, piezas y tiempo laboral absolutamente esenciales para la producción".

A Hay le parece que determinar lo que es absolutamente esencial es subjetivo y redefine el desperdicio como "todo lo que sea distinto de los recursos mínimos absolutos de materiales, máquinas y mano de obra necesarios para agregar valor al producto".

Estoy leyendo sobre JIT y otros temas de metodologías ágiles porque estoy interesado en hallar mejores formas de desarrollar software en equipo.

En mi caso, la definición original de desperdicio, como aquello que no es el mínimo esencial para producir algo sí tiene mucho sentido.

En TDD, se va escalando sobre mínimos necesarios para producir algo. Cada escalón debe ser trivial respecto al anterior. Nada de considerar posibles mejoras por adelantado. Nada de generalizaciones antes de tiempo. Nada de de optimizaciones prematuras. Primero, lo mínimo necesario para que funcione. Las optimizaciones llegan a través de reflexión y refactorizaciones.

La definición japonesa de desperdicio la entiendo muy bien en ese contexto.

En cambio, la definición de Hay, como aquello que no agrega valor al producto, me parece contraproducente. Y realmente subjetivo, al menos desde el punto de vista de TDD.

Porque no faltarán clientes, jefes de producto o jefes de equipo que insistan en incluir por adelantado una funcionalidad X porque opinan que eso agrega valor al producto (y no están pensando en el producto actual sino el que está dos ciclos adelante, o incluso el final, o más allá...).

En cambio con la definición original uno está a salvo: ¿es absolutamente necesario para que funcione ahora? No. Entonces lo anotamos en la lista de deseos, pero la implementaremos cuando sea su momento, no antes.

Bueno, eso esta es una nota en el camino... continuaré leyendo el libro...  :-)




2014/01/02

Sobre autores

DRM (Digital Rights Management) es una clase de tecnologías usadas para controlar la copia de contenido digital después de la venta.

¿Por qué?
Las nuevas tecnologías facilitan la copia de contenido.

El copyright es un concepto legal para asegurar la exclusividad en el derecho de copiar contenido.

¿Por qué?
El contenido puede ser considerado como un producto.

El derecho de autor es un concepto legal para atribuir a un autor el copyright del contenido que produzca.

¿Por qué?
Para que el copyright pueda ser considerado como un producto.

¿Por qué?
Si algo es valioso, quien más gana es el intermediario, el encargado de la distribución.
Es una gran ventaja asegurar la exclusividad en la distribución.
Cuando alguien produce contenido, si su valor de distribución es alto, el intermediario tenderá a asegurar la exclusividad de su servicio.
El derecho de autor es un producto que el distribuidor le compra al autor para asegurar esa exclusividad.
El distribuidor defiende el derecho de autor para asegurar que ese producto siga existiendo.

El concepto de derecho de autor no ha existido siempre. Cuando aparecieron impresores que reclamaban a perpetuidad la exclusividad en la copia de los libros que habían adquirido de los autores, los gobiernos establecieron leyes con plazos menores (en el siglo XVIII). Desde entonces se ha jugado de esa manera.

¿Cuál es el problema?
El contenido, a pesar de que le han dado ese nombre, es contenedor de conocimiento. Las limitaciones comerciales para la distribución de productos, cuando son aplicadas a contenedores de conocimiento, limitan la distribución de conocimiento.

Antes, el conocimiento se difundía lentamente, principalmente de manera oral. Cuando apareció la imprenta, el conocimiento se pudo difundir principalmente por vía escrita. Eso facilitó que se empezara a considerar al contenedor de conocimiento como un producto comercial.

¿Es el conocimiento un producto comercial?
En un mundo ideal, las obras contendrían como referencia los nombres del autor o los autores que contribuyeron a su creación. Porque eso es útil para contactarlos, documentar su desarrollo, mejorar el conocimiento.

Actualmente, si la preocupación por los autores fuera sincera, se defenderían más bien derechos de atribución, para asegurar que la contribución de cada autor figure en la obra y sus derivados.

Pero lo que se defienden son cosas que permitan exclusividad comercial del contenedor, aún a pesar de que eso limite el libre desarrollo de lo que contienen, que es el conocimiento.

Lo saben los autores de libros y música, que realmente reciben bajas comisiones de parte de las distribuidoras. La mayor parte va siempre para el intermediario. Por eso, algunos autores están optando por auto publicarse o usar canales de distribución menos onerosos. Incluso, el propio autor debe pedirles permiso para citarse a si mismo.

Hubo un tiempo, reciente, en que la distribución comercial fue aliada de la distribución de conocimiento. Porque no estaba al alcance de la mayoría imprimir un libro o editar un disco. Pero la tecnología ha avanzado y ahora tenemos el poder de hacerlo. Ahora podemos contribuir a la distribución de conocimiento.

Eso significa el final de una era para los distribuidores. Tendrán que descubrir o inventarse nuevos roles. Sin embargo, lo que hacen muchos es usar sus recursos para tratar de salvar su antigua forma de vida lo más que puedan.

La opción extrema, es renunciar al copyright y usar el copyleft. Es decir, salvaguardar el derecho de atribución, pero permitir la libre distribución y modificación de la obra, con la condición que cada copia y sus derivados tenga también el mismo copyleft.

Así es como el software libre ha podido hacer tantos ciclos de desarrollo y lograr avances notables comparados con las alternativas con copyright. Así es también como Wikipedia dejó fuera a MS Encarta e incluso a la Enciclopedia Británica. Así es como el conocimiento se abre paso.

El conocimiento merece que veamos más allá de su aspecto comercial, que ha sido como el bote que ha permitido llegar a esta playa. Porque es la búsqueda del conocimiento la razón de todo lo que nos trae hasta aquí. Deberíamos honrarlo, respetarlo, cultivarlo. Dejar que sea libre y nos lleve a donde seamos capaces de ir.

Más artículos