Latest Entries »

Sabias palabras (en inglés):
The Master, The Expert, The Programmer

Un sticky footer decente

El problema del sticky footer es famoso y apmplio. La idea es lograr que el footer de una página web se ubique al fondo de la ventana del navegador si el contenido no es el suficiente para llenar la ventana, pero que se ubique justo debajo el contenido, en caso de que este supere el tamaño de la ventana.

La verdad es esta: Nunca encontré una solucion que funcionara en serio. El problema principal es que los estandares HTML actuales no nos dejan usar tablas para organizar una página (lo que me parece perfecto). Y no nos quedan muchas herramientas para lograr nuestro objetivo. Todo lo que es organizacion vertical de los elementos dentro de un HTML normalmente es un dolor de cabeza.

Después de recorrer muchos foros y blogs, y hacer muchos experimentos llegué a la conclusión de que la única solución es usar javascript.

La idea básica es crear dentro del body tres divs, id Header, Content y Footer. Header y Footer van a tener un alto fijo definido en sus estilos.

Y al final de la página vamos a ejecutar un pequeño javascript que setee el minheight del div Content en base al tamaño de la ventana y ademas vamos ejecutar este script cada vez que la ventana cambie de tamaño.

Este sería el código javascript a usar:

var headerDiv = document.getElementById("Header");
var contentDiv = document.getElementById("Content");
var footerDiv = document.getElementById("Footer");
Resize();
window.onresize = function () { Resize() }
function Resize() {
    var windowHeight = 0;
    if (typeof (window.innerHeight) == 'number')
        windowHeight = window.innerHeight;
    else if (document.documentElement && document.documentElement.clientHeight)
        windowHeight = document.documentElement.clientHeight;
    else if (document.body && document.body.clientHeight)
        windowHeight = document.body.clientHeight;
    var contentHeight = windowHeight - headerDiv.clientHeight - footerDiv.clientHeight - 30;
    contentDiv.style.minHeight = contentHeight + "px";
}

La función resize usa varios métodos distintos para averiguar el alto de la ventana. Esto es porque los distintos navegadores reportan de distintas maneras la altura de la misma.

Fijense tambien que en la anteultima linea a la altura de la ventana le estoy restando la altura del header, luego la del footer y luego un numero constante. Este numero puede variar, en base a los margenes de los divs y otras cosas por el estilo. Les dejo a ustedes la tarea de encontrar el numero adecuado para sus paginas. Mientras tanto pueden ver un ejemplo funcional y su código en este link.

Un saludo y espero que les sirva.

Buenas Prácticas

Sobre como el concepto de buenas prácticas se desmorona sobre sí mismo (en inglés)
 

La historia de Mel

Es viejo y seguro que muchos de ustedes ya lo conocen, pero no puedo hacer menos que dejarles un link con la historia de uno de los verdaderos cowboys del codigo fuente:
 
The story of Mel (en inglés)

Wolfram Alpha

Este proyecto es, sin duda, uno de los más grandes de los últimos tiempos.
Es algo así como una gigantesca base de datos de conocimiento. Pero con un toque interesante, es conocimiento computable. ¿Y a que me refiero con esto? A que el buscador dentro de la pagina es capaz de interpretar nuestros requerimientos y con eso buscar en la base, cruzando referencias y generando datos en tiempo real.
Esto nos permite desde graficar funciones matemáticas hasta comparar la cotizacion de dos monedas con graficos historicos. Pasando por estudios del clima en ubicaciones especiífica y generacion de fractales a medida.
 
les dejo el link para que lo revisen: Wolfram Alpha

Druid

En este post les quiero comentar sobre una programa con el que me tope de casualidad. Se llama Druid. Es una herramienta para diseñar bases de datos. Y la verdad es que es una auténtica poesía ejecutable.
Esta hecho en java y es open source. Este es el link  http://druid.sourceforge.net/
Me maravilló la simplicidad con que puedo definir tablar y relacionarlas, simplemente definiendo como tipo de datos de la columna, a una columna de otra tabla. Además de eso permite generar diagramas, insertar comentarios y definir triggers. Esta oprientado a ansi sql, por lo que funciona con casi cualquier motor serio.
Una vez que tenemos todo nuestro diseño hecho, nos genera una documentacion muy bonita en PDF, los scripts para generar las tablas y hasta los xml para mapear a entidades de hibernate.
Les recomiendo seriamente que lo prueben. Vale la pena.
 

¿ABM o ABCC?

La sigla ABM viene de los términos Alta, Baja y Modificación. Y se refiere a las acciones que podemos hacer sobre una lista de objetos. Es decir, Imaginemos que tenemos un programa en el cual podemos ver un catálogo de productos. Sobre este catálogo normalmente podemos Agregar, Borrar o Modificar un elemento.

Hasta acá todo parece bastante simple. Pero me gustaría centrarme un poco en la parte de la modificación. Una modificación es un término ambiguo. ¿Qué implicaría modificar uno de estos artículos? Bueno. Quiere decir dos cosas distintas. Y ningún usuario les va a pedir esto de forma suficientemente explícita.

Sigamos con el ejemplo y asumamos que un usuario quiere cambiar el precio. Una pregunta que la mayoría no hace es si lo quiere cambiar porque se equivocó al cargarlo o porque la inflación requiere que nuestros productos cuesten más a partir de este momento. Y lo que implica esta diferencia es abismal.

Mirando el producto no vamos a notar la diferencia, pero si miramos también todas las facturas generadas hasta el momento se empieza a ver la brecha. En un caso los cambios son retroactivos. En el otro no.

Tal vez las facturas no sean el mejor ejemplo, porque seguramente en las mismas se guarda también una copia del precio y el monto, junto con cotizaciones y otros valores que afectan el total. Así que por las dudas veamos otro ejemplo. Uno con el que yo sufrí en persona.

  1. Tenemos una lista de personas. Uno de los atributos de esta persona es su categoría (Empleado de planta, Administrativo, Gerente, Invitado, Asesor externo, etc.)
  2. Y tenemos también una lista de entradas y salidas a la empresa.
  3. Me piden que una persona debía ser modificable, es decir que, entre otras cosas, su categoría podía cambiar.
  4. Luego de varios meses de usar el programa un asesor externo se modificó para ser un administrativo.
  5. Un par de días después recursos humanos estaba verificando un reporte de entradas y salidas y noto que esta persona figuraba como si siempre hubiera sido un administrativo.
  6. Yo tuve que rediseñar mi programa para que los cambios se aplicaran de ahora en más y no fuera una simple modificación del registro de la tabla.
  7. Un tiempo después Recursos humanos corrige el número de documento de otra persona que estaba mal. Pero verificando los listados nota que el cambio solo se aplica desde el momento en que se corrigió y no desde el principio…
  8. Pienso en como corregir esto y llego a la conclusión de que implicaría deshacer el último cambio que hice.
  9. Agarro la escopeta doble caño y me dirijo a RRHH. (No, mentira. Pero ganas no me faltaron)
  10. Finalmente entendí que estábamos hablando de dos conceptos diferentes.

Estos dos conceptos di en llamarlos Corregir y Cambiar.

Esto es a lo que quería llegar ABCC es Alta, Baja, Corrección y Cambio.

La mayoría de las veces se van a encontrar con este dilema y se les va a escapar por debajo de las narices hasta que sea muy tarde.

Recuerden. No existe tal cosa como la modificación. Existe más de un concepto bajo la misma palabra. Traten de averiguar a cual se están enfrentando.

¿Web o Escritorio?

Este tema me da vueltas en la cabeza hace mucho tiempo. Desde que estoy metido en esta industria, veo cada vez más aplicaciones empresariales desarrolladas sobre plataformas web. ASP, PHP, etc. Y la verdad es que nunca logré entender por qué. En general suelo escuchar dos argumentos a favor:

  • Es la correcta implentación de las tres capas (del lado del cliente solo existe la interfase gráfica, dejando en el server la capa de necgocios y la de datos)
  • Facilidad de implementación (lo instalas en un servidor web y listo. Todo el mundo lo accesa desde ahí)

Bueno. Voy a pasar a refutar esos argumentos.

Una implementación de tres capas se puede hacer perfectamente bien en una aplicación de escritorio. No hay nada que lo evite. Se puede mantener del lado del cliente la interfase de usuario y llamar a métodos de servidor. Para la lógica de negocios. Incluso haciendo uso de web services esto es más que simple.

Este error de concepto del que las aplicaciones escritorios no implementan 3 capas viene de la época en que nadie lo hacía. todas las aplicaciones accesaban directamente a la base de datos desde el cliente y toda la lógica de negocios se ejecutaba en el cliente mismo. Pero el hecho de que durante años se hayan hecho mal las cosas no implica que no se puedan hacer bien. De hecho, hoy se siguen haciendo mal a pesar de estar implementadas sobre web, o sino no conoceríamos terminos como "SQL injection".

En cuanto a la facilidad de implementación, bueno, si es cierto. Es mucho más facil para el implementador instalar la aplicación en el servidor, configurar un par de cosas y olvidarse de todo. Pero en definitiva… ¿Para quién es la aplicación? ¿Para el implementador? ¡No! ¡Es para el usuario! En el usuario es en el hay que pensar. ¿Y qué le molesta al usuario de usar una aplicación web?… Veamos.

La aplicaciones web son LENTAS. Aún cuando usemos tecnologías nuevas como AJAX, no hay forma en que una aplicación web se aproxime al rendimiento de una aplicacion de escritorio. Simplemente porque TODA la interfase de usuario esta viajando continuamente por la red. Y si ven a un data-entry tratando de cargar 200 recibos, van a notar que molesto se pone al tener que esperar un segundo o dos mientras la página se refresca.

Las paginas web no tienen estado. Lo que implica que que siempre que hay que mandar datos al servidor, hay que mandar un montón de información sobre el estado de todos los objetos del lado del cliente. Esto llena la red de información que de otra forma se resolvería mucho más eficientemente. Y como si esto fuera poco la información de autenticación tiene que viajar todas y cada una de las veces en forma de cookies, para que el servidor se acuerde de quienes somos.

Las paginas web son todas distintas. No hay una norma que diga "un botón de cerrar luce así" o "cuando veo esta flecha significa que puedo desplegar un menú". Este es el menor de los problemas. Una persona puede aprender a usar un aplicación, y en muy poco tiempo interpreta la interfase sin siquiera pensarlo. Pero aún así es mucho menos intuitivo que una aplicación de escritorio.

Las páginas web fueron pensadas para otros usos. Toda la tecnología que usamos hoy en las aplicaciones web es un agregado. Desde los viejos días de los HTML las cosas han cambiado mucho. DHTML, Javascript, CSS, AJAX, etc. Todos ellos son tecnologías inventadas para cubrir los huecos de un protocolo que originalmente fue pensado para un objetivo completamente distinto.

Las páginas web no se actualizan. El protocolo HTTP funciona de la siguiente forma: Yo pregunto el server responde. Punto. Esto carece de algo fundamental. Las notificaciones de cambios. Si yo estoy consultando un artículo y alguien en otra terminal modifica su precio, el servidor no es capaz de informarme esto y mi página web no se actualiza hasta que yo no decida volver a cargarla. Este ejemplo es bastante simple pero complicaciones como estas las hay por todos lados. Yo recientemente tuve que crear un programa de chat dentro de una página web. Finalmente decidí hacer una rutina en javascript que pregunte una vez cada 3 segundos al servidor para ver si hay mensajes nuevos. Esto es casi un record de ineficiencia. Pocas cosas me pueden hacer doler las tripas más que verme obligado a hacer algo así.

Las páginas web tienen poco acceso a la PC. Los navegadores actuales se encargan de eso. Y está bien que lo hagan. Porque sino yo podría entrar a una página web y esta borrarme todos los archivos del disco. Pero esto también trae problemas cuando necesitamos que ese acceso. Hace puco tuve que hacer que una página web grabara la voz del usuario desde el micrófono y enviara esos datos a un server. Más allá del hecho de que tuve que construir un control ActiveX que manejara toda esta lógica del lado del cliente. También tuve que luchar mucho con los permisos de estos controles y solamente conseguí un éxito parcial. Para que la aplicación funcione es necesario otorgarle permisos especiales dentro del administrador del .NET framework que le dan acceso al hardware, para así poder leer el micrófono.

En conclusión. ¿Por qué usaríamos un martillo para atornillar un tornillo? Si hay tan lindas herramientas….

Si alguien tiene algún argumento en contra de lo que dije, por favor lo invito a poner un comentario. Quiero saber más de esta tendencia inexplicable para mí. Y sé que puedo estar muy equivocado. Así que cualquier opinión es bienvenida.

¿Compacto o explícito?

Ese es el gran dilema. Cuando escribimos un programa deberíamos tratar de ser claros para beneficio otros programadores o compactos para beneficio del programa. Muchas veces me encontré con algo así:

If a = True Then 
   b = True 
Else 
   b = False
End If

En este caso se me ocurren muchas optimizaciones que podemos llevar a cabo. Por empezar por el hecho de que comparar una variable a True o False no tiene sentido. Por qué decir If x = True cuando podemos decir If x.
Pero en definitiva este bloque se puede resumir en algo así

b = a

El gran problema es que un código tan simple como ese, la mayoría de las veces viene tan disfrazado que nos cuesta reconocerlo. Miren esto:

IF Objeto.Propiedad = False Then
  Lista.Items.Add(new Item("Alguna Descripcion", True))
Else
  Lista.Items.Add(new Item("Alguna Descripcion", False))
End If

Cuántos de Ustedes se darían cuenta de que esto es un:

Lista.Items.Add(new Item("Alguna Descripcion", Not Objeto.Propiedad))

Esta es otra forma clásica del mismo problema:

If a = b Then
  return True
Else
  Return False
End If

Cuando esto podría escribirse tan fácil como:

Return (a = b)

Para terminar me gustaría hacer referencia al operador ternario. Esta instrucción que existe en casi todos los lenguajes de programación nos hace la vida más compacta a los programadores (aunque también tiene sus detractores). Último Ejemplo:

If a = b
  Return "Hola"
Else
  Return "Chau"
End If

Si bien puede parecer que no hay forma de comprimir este algoritmo, la hay. Con el operador ternario lo podríamos expresar así:

Return IIF(a = b, "Hola", "Chau")

Esta función toma tres parámetros. Evalúa el primero. Si el resultado es verdadero devuelve el segundo parámetro, en caso contrario devuelve el tercero.

Todos estos cambios no tienen como único objetivo hacer más corto el código. También sirven para acelerarlo. Recuerden que ahorrarse un par de ciclos de procesador no es la gran cosa, pero… ¿Qué pasa si un algoritmo así se usase para calcular el color de un pixel en alguna aplicación gráfica? Esto implica que este algoritmo se ejecutaría al menos 1.000.000 de veces por cada imagen llevada a la pantalla. Imagínense eso unas 20 veces por segundo. Cambios tan simples como estos pueden ser la diferencia entre el éxito o fracaso de una aplicación. Pero bueno. Si la claridad del código es tan importante…

Frases

Esta una lista de frases clásicas del mundo informático. Es muy probable que conozcan la mayoría, pero aún así me voy a dedicar a compilarlas y postearlas. A medida que vaya encontrando nuevas, las voy a ir agregando a este post.

Ah! Puede haber alguna que otra en ingles. Que le vamos a hacer. Si no se puede traducir bien, no se traduce.

  • Los verdaderos programadores no documentan. Si fue difícil de escribir, debería ser difícil de leer.
  • No hay lugar como 127.0.0.1
  • Hay 10 clases de personas en el mundo… Las que saben números binarios y las que no.
  • Nueve personas no pueden tener un bebe en un mes. – Fred Brooks
  • 1f u c4n r34d th1s u r34lly n33d t0 g37 l41d
  • Think Globally. Act within local variable scope.
  • ¿Porqué nunca hay tiempo para hacerlo bien, pero siempre hay tiempo para hacerlo de nuevo?
  • Debuggear es dos veces más difícil que programar. Así que si programás tan inteligentemente como sea posible, por definición no sos capaz de debuggear.  – Brian W. Kernighan
  • Recuerda que no hay código más rápido que la falta de código.
  • Si la primera vez fallas… Llamalo versión 1.0
  • Siempre programá como si quien fuera a mantener tu código fuera un psicópata violento que sabe donde vivís.
  • Roses are #FF0000, Violets are #0000FF. All my base Are belong to you.
  • I’m not anti-social; I’m just not user friendly
  • Me encantaría cambiar el mundo, pero no tengo el código fuente.
  • I spent a minute looking at my own code by accident. I was thinking “What the hell is this guy doing?”.
  • La inteligencia artificial no es rival para la estupidez natural.
  • ¡Compila! Entregen.
  • Lo bueno de los estándares es que hay tantos para elegir…