(Zzzzz...)

Que lento que viene Enero, parece que los redactores del blog se fueron todos de vacaciones, jeje.

La verdad, es que estuve a full en otras cosas, algunas de las cuales merecerán otros posts.

Por un lado, estuvimos viendo muchas pelis con Moni (al fin estoy retomando el ritmo, más de esto, justamente, en otro post), e incluso vimos toda una miniserie: Kingdom Hospital (eran quince capítulos de 45 minutos, pero nos la devoramos), con libro de Stephen King. Muy bizarra, muy buena.

Por otro lado, me estuve dedicando al software. No solo estuve siguiendo un poquito el desarrollo mostrado acá, sino que me estoy metiendo en XPN.

XPN es un lector de noticias, con una interfaz gráfica, hecho en Python. Lo estoy empezando a usar, pero le hace falta algunas cosas que yo quiero. Entonces decidí meterme y participar en el desarrollo del mismo. De paso, empiezo a conocer un poquitito de PyGTK, a ver si prende en mi espíritu o no.

También terminé los cambios que tenía planeado para mi blog. El último fue la incorporación de un plugin que hizo Mariano, que muestra lo que escribí hace un año (fíjense en la barrita vertical de la derecha, casi arriba de todo). Está muy bueno porque te da un flashback del tipo "Uh, que loco, me acuerdo de eso... ¿ya pasó un año?", :)

Lo otro que cerré esta semana a nivel de software fue mi participación en el Google CodeJam, pero esto también es para otro post.

La semana que viene me voy de vacaciones, así que quizás escriba un poquito más, o no, pero seguro habrán fotos, :)

Comentarios Imprimir

Asado "movistaroso"

Ayer me junté, en casa de Diegote, con algunos ex-compañeros de Movistar: Diegote, Kike, Ramón, Germany, el Pollo, Marcelo, Gustavo, Javier, Gabriel...).

Arrancamos con una picadita, y después Diego y Javier se mandaron un lindo asado, todo correspondientemente regado con cerveza, vino, fernet, gancia. Comimos bien, tomamos demasiado. La lluvia nos hizo un par de amagues, pero nos dejó tranquilos.

Foto foto foto!

Al final de la velada se armó un truco. No salí sorteado en la primera vuelta, así que entré en la segunda a jugar contra los ganadores anteriores. Javier y el Pollo eran mis dos coequipers. Ganamos dos partidos de forma divertida. No fácil, porque fueron ambos muy ajustados hasta el final, pero sí divertidos.

En el segundo partido, nos recontragastaban porque nos iban ganando 14 a 11 en las buenas... y les hicimos cuatro puntos en una sola mano. Nos reimos mucho, :)

Comentarios Imprimir

¿Cuánto falta?

Uno de los típicos problemas con los que uno se encuentra cuando hace algún programa es el de estimar cuanto falta para terminar una tarea (E.T.A. por sus siglas en inglés).

Analicemos esa oración con detalle.

Sí es típico, es que sucede muchas veces, no sólo a un programador, sino a muchos. Pero que uno se presente con el problema, y se siga presentando siempre con el problema, significa que todavía no está resuelto. O al menos no de forma genérica y satisfactoria.

Que queramos estimar, y no calcular exactamente cuánto, implica que es suficiente con dar una idea de cuanto falta. Consideremos que esta indicación es para el usuario impaciente que está mirando la barrita de progreso, o que abre cada tanto la aplicación y estima si la película que está bajando va a terminar para después de la cena o mejor busca algo en la tele. No hace falta decirle que calculamos terminar a las 19:33, pero es importante saber si esperamos que finalice a las 19, a las 20, o mañana...

Barrita ejemplo 1

Entonces... ¿por qué no está resuelto todavía de forma genérica y satisfactoria? Porque no es tan simple como parece. Veamos por qué. Por un lado, la velocidad con la cual estamos completando la tarea puede variar, y por el otro, le tenemos que dar una indicación a un humano. Y ambos son dos quilombos totalmente distintos... y complicados.

La velocidad con la cual vamos completando la tarea es todo un tema, porque si estamos descargando un archivo, podemos tener el problema de que la conexión se corte, por ejemplo, o que pongamos a bajar algo y la velocidad caiga a la mitad. Venía pareja, de repente baja a la mitad, y luego queda en ese nivel por el resto de la descarga. Como un escalón. O podemos estar reordenando una estructura, y sabemos cuantas partes nos falta reordenar, pero no tenemos ni idea cuanto va a tardar reordenar cada una de esas partes.

Y como decía antes, la indicación es para un humano. Si le muestro siempre el mismo número, no le sirve. Si le cambio el valor de 1 a 34 y después a 2 y a 38, y a 0, y a 50, cambiando cinco veces por segundo, tampoco le sirve. Y agreguémosle componentes sicológicos, como no mostrarle que la velocidad cae si sólo cayó por un momento porque es feo que vaya más lento (aunque sea verdad).

De algunos de estos inconvenientes estuvimos hablando la vez pasada en una conversación de PyAr. A mi me quedó colgado el tema en alguna esquinita del cerebro, y estoy finalmente escribiendo esto.

Requisitos

En general, podríamos definir las necesidades de nuestro algoritmo como las siguientes:

  • Tiene que ser fácilmente legible por el humano. Debería cambiar, máximo, dos veces por segundo si uno tiene buena vista. Si hay que prestarle atención al nro, una vez por segundo está bien.

  • Debe estimar lo mejor posible el tiempo faltante para terminar, pero nos tomamos la libertad de mentirle al usuario algunas veces si es para mejorar la calidad del indicador.

  • No tiene que depender de la aplicación: deberíamos encontrar un algoritmo que se desempeñe como corresponde más allá de qué estemos midiendo.

En función de eso, vamos con algunas consideraciones que he estado elaborando, leyendo en la lista de correo, en otros lados, o que ya tenía en mi cabeza desde antes. Pero para que nos entendamos mejor, vale una aclaración.

Barra ejemplo 2

Todo el trabajo, donde la magia reside, es en calcular la velocidad estimada con la cual vamos a estar desde ahora hasta el final de la tarea. De esa manera, en función de lo que falta para terminar (en KB descargados, partes del archivo a procesar, o lo que sea), podemos estimar cuanto falta en tiempo, y consecuentemente le podremos mostrar al usuario cuando terminaremos.

Esa velocidad estimada con la cual vamos a estar desde ahora hasta el final de la tarea la llamaremos, como corresponde, de alguna manera más corta. Como esa velocidad es calculada en función de la experiencia obtenida en lo que va de la tarea, normalmente se llama Velocidad Promedio, pero no crean cuando lean ese nombre que es, justamente, la velocidad promedio, sino que es la velocidad calculada con el algoritmo que estamos tratando de encontrar, con un nombre corto, :).

Simulando

Antes de comenzar a discutir cómo calcular nuestra ya famosa Velocidad Promedio, tenemos que encontrar alguna forma de simular el estímulo.

Es decir, deberíamos hacer un programita que nos vaya dando valores simulados para probar las formas de cálculo de la Velocidad Promedio (de otra manera, tendríamos que incorporar esas distintas maneras a sistemas reales, lo que dificultaría muchísimo probar y ver qué nos gusta más y qué nos gusta menos).

Entonces me armé un generador de valores, que será la fuente de nuestros ejemplos. Las reglas del generador son sencillas, porque no quería perder más tiempo armando el simulador que jugando con lo otro. Así y todo, aunque a veces tira escenarios raros, la mayoría de las veces funciona como esperamos.

Comienza generando en cero, y permanece tres valores en cero, como si fuera tiempo de conexión, una especie de inactividad inicial. Luego pega un salto de 50, o sea que se conectó de golpe y comienza a tener "vida". De aquí en más, siempre con limitado al rango de 0 a 99 (inclusives), los valores van variando al azar, con el siguiente comportamiento:

  • El 1% de las veces se desconecta, tira 10 valores en cero y luego trata de volver (lo logra el 10% de las veces, y vuelve al valor que tenía antes)

  • El 4% de las veces genera picos de 2 valores de ancho, de +/- 40 (luego de los dos vuelve al valor que tenía antes)

  • El 70% de las veces varía al azar sumando alguno de [-2,-1,0,1,2] (obvio, si suma -2, es que baja dos puntos)

  • El 15% de las veces varía al azar sumando alguno de [-5, -4, ..., 4, 5]

  • El 10% de las veces varía al azar sumando alguno de [-10, ..., 10]

¿Entonces? ¿Cuánto falta?

Un concepto que usé desde entrada (concepto bastante básico) es el de tomar no todos los valores para calcular la Velocidad Promedio, sino sólo algunos últimos (analogía eléctrica: es como si estuviésemos pasando la señal por un filtro pasabajos). Esto tiene el efecto de calmar el indicador que mostramos, siendo no tan nervioso sino que variará más tranquilamente.

El truco es cuantos valores tomar para este promedio. Y como no podemos ver el futuro y saber de entrada la mejor cantidad para este cálculo, la mejor manera que se me ocurrió es tratar de ir adaptándose.

El primer modelo que armé agranda o achica la cantidad de valores a tomar en función de cuan nervioso esté el indicador. Si se pone nervioso (es decir, varía mucho de valor a valor), agrandamos en uno la cantidad de valores. Y si se tranquiliza, achicamos en uno la cantidad.

El segundo modelo también agranda o achica la cantidad de valores. Pero ahora, cuando está nervioso, en lugar de incrementar en uno y seguir, vamos incrementando hasta que lo notamos lo suficientemente tranquilo. Y si luego se estabiliza, achicamos (como antes), la cantidad de puntos en uno.

El tercer modelo trata de tranquilizar el indicador de otro modo. Tomamos siempre la misma cantidad de valores, pero nos fijamos en cual fué la variación mayor en ese grupo, y cual es la variación entre el último y el nuevo valor. Si esta última variación es mayor a la que veníamos teniendo, tomamos eso como símbolo de nerviosismo y no usamos el último valor para el promedio, sino uno recortado.

El siguiente es un ejemplo de los tres modelos para el mismo conjunto de valores simulados (primero a tercer de arriba para abajo). Tienen más ejemplos aquí y aquí, y el código que genera todo aquí.

Comparando comportamientos

Como ven, el tercero es el que más tranquilo parece, y así y todo luce responsivo a los cambios de largo o mediano plazo. A mí es el que más me gusta. Pero tiene una falla segura: la cantidad de puntos a tomar en el promedio permanece constante (en este caso, está prefijada a 20).

Cambio de punto de vista

Me puse a pensar entonces en como podía tener este tercer modelo más adaptativo (o sea, que la cantidad de valores en el promedio no esté fija en 20 sino que vaya subiendo y bajando en función de algo más).

Y me di cuenta de que las reglas que determiné arriba quizás estén incompletas, que se les podría agregar la siguiente:

  • Debe tener en cuenta, en lo posible, en qué parte del proceso de completamiento estamos.

O sea, que el sistema quizás se comporte distinto, estimando diferente, si estamos en la primer parte de, digamos, la descarga, en la mitad, o cerca del final. Por ejemplo, si estamos a un 40% de la descarga, está bien que tomemos valores tranquilos, porque falta un montón y tenemos que estimar lo que viene. Pero si nos falta un 5%, ¿tiene sentido que tomemos el otro 95% como indicador? Porque cualquier variación, faltando tan poco, tiene una alta incidencia en el tiempo que nos falta para terminar.

Entonces desarrollé otro simulador, pero ahora con una lógica distinta, ya que en este calculamos lo que nos falta para terminar. Fíjense en las siguientes dos curvas, que tenemos en gris las velocidades reales, en negro la Velocidad Promedio, y en azul lo que le diríamos al usuario que falta.

En la curva de arriba pueden ver el comportamiento del modelo C de la etapa anterior, y en la inferior, el mismo modelo, solo que ajustamos la cantidad de valores para realizar el cálculo en función de por donde estamos de la descargar (lo que hacemos es tomar todos los valores hasta que llegamos a la mitad, y luego de la mitad la cantidad de lo que faltaría para terminar). Más allá de si nos gusta más o menos, este nuevo modelo tiene la complejidad de saber cuantas unidades falta para terminar (podemos saberlo si estamos descargando un archivo del que conocemos el largo total, pero no de otra manera, por ejemplo).

Nuevo modelo

Fíjense que en este nuevo modelo no estamos generando la misma cantidad de puntos siempre para la simulación, sino que arrancamos con una determinada cantidad para descargar, y seguimos hasta que se descargue todo (por eso el ancho de los ejemplos es variable). Noten también que recorté en un máximo la indicación del usuario, para que el detalle inferior se vea mejor.

Tienen dos ejemplos más acá y acá, pueden generar más con este programa.

Conclusiones

Luego de cotejar ideas, gráficos, probar mil y una veces, no llegué a encontrar el modelo que yo diga "¡Este!". Pero el que creo que más se acerca a como a mi me gustaría que se comporte, es este último (lo cual no es mucha casualidad, ya que es el último porque lo fui trabajando, esto fue una evolución).

Así y todo, no tengo manera de demostrar que este es el mejor, y eso se debe en gran parte porque las pautas iniciales eran claras, pero vagas. Quizás si alguien apareciese con una mejor explicación de cómo se debería comportar el sistema, fuese más fácil lograrlo.

Pero creo que el 90% de la complejidad de esto es, justamente, que no tenemos muy en claro cómo se debe comportar.

Así y todo, creo que este análisis sirve, aunque sea porque para demostrar que estoy equivocado vas a lograr un mejor resultado, :D

Ah! Y un resultado secundario, es que me divertí mucho tirando curvas con PIL, la biblioteca para imágenes en Python.

Comentarios Imprimir

2007, un nuevo año

¡Que semanas moviditas! Aunque esté de acuerdo con Mariano en este post, es siempre difícil evitar que la segunda mitad de Diciembre sea aceleradísima.

Para cerrarlo, el último finde estuvimos de aquí para allá. Algunos flash de esos días...

El sábado a la noche, que pintaba tranquilo en casa, recibí un SMS de mi primo contándome que tocaba La Percanta en el Bar de Luisa. Era una oferta que no podía rechazar (miento, ya había recibido ofertas similares en los últimos meses y no había podido ir), así que pasada la medianoche estábamos con Mónica cerca de Lugano, en el barrio Sarmiento.

Como siempre (aunque no pude quedarme hasta que terminen porque era tardísimo), La Percanta es un buen espectáculo

La Percanta

El 31 a la noche nos quedamos en casa. Vino la familia de Mónica, y Kike y Fabi (más las nenas, obvio). Estuvo muy bien, nos super divertimos toda la noche, que incluyó mucha comida, mucha bebida, pool, ping pong, rocanrol, y hasta la rara costumbre de brindar arriba de las sillas en el momento de cambio de año:

Brindando

El primero de enero, como siempre, en casa de Papá. Hice el asado, y se pueden imaginar lo que transpiré, al lado de la parrilla, al sol, con 40 grados de sensación térmica. Mi viejo y Gustavo me ayudaron, y el asado salió riquísimo.

A la tarde se armó el Clásico de Año Nuevo, el partido de tute cabrero de la familia. Perdí tan mal, tan mal, que todos estaban sorprendidos, :(

El clásico

Año nuevo, vida nueva un carajo: la misma vida que el año anterior, que viene muy bien, muy bien.

Comentarios Imprimir

Disfrazados

Ayer tuvimos un cumple. Un doble cumpleaños. Dos personas cumplían 50 años, Inés (hermana de Marcelo Halm), y Silvia (directora de Moni en uno de los jardines). Al cumple lo hicieron en conjunto en una quinta por Tortuguitas.

Al punto del post: había que ir disfrazados, vestidos como la década del '70.

Moni y Facu disfrazados de 70s

El cumple, muy bien, muy emotivo (encima este es el último año de Silvia como directora). Silvia tiene como 1000 primos, algunos bastante histriónicos, e hicieron una teatralización y todo (¡muy divertido!). Había unas pizzas riquísimas, y cerveza tirada (tomar nota: cerveza tirada es una muy buena opción para una fiesta, y no creo que salga más caro). Tocó una banda en vivo, cantaron los mismos invitados, muy lindo.

La pasamos muy bien.

Comentarios Imprimir