2010/07/28

Programando una mejor sociedad

Hoy, en Perú, como cada año, el Presidente da un mensaje a la nación.

Mientras lo escucho, reflexiono sobre el significado de las cosas que se hacen. Y el por qué se hacen de ese modo.

Yo no sigo con mucho detalle los acontecimientos políticos ni las noticias. Quizás podría decir que contemplo el panorama, y trato de entender.

Nacemos siendo habitantes del país de nuestros padres. Aprendemos a ser gobernados por reglas que alguien más creó. Pero luego vamos notando que podemos hacer algo al respecto.

Nuestro destino está influido por una sociedad que sigue reglas acordadas por ella misma. Es como si la sociedad se programara a sí misma.

En los detalles, tal vez la mayoría de la gente encuentre que la política y la programación son dos cosas muy diferentes, pero pienso que tienen algunas similitudes que podrían ayudarnos en la búsqueda de una sociedad mejor.

Qué tan buena es una sociedad. Cómo debería construirse. Qué tan bueno es un programa. Cómo debe construirse.

En el mundo de la programación tenemos experiencias y propuestas que quizás podrían aplicarse a la construcción de las reglas que guían nuestra sociedad. Principalmente las provenientes del movimiento de software libre, que han mostrado como cosas que antes parecían imposibles en realidad son muy posibles y prácticas. Se decía, por ejemplo, que, como cada vez que se agregaba un programador a un equipo se observaba un retraso en el avance y un aumento en la complejidad del proyecto, había un tamaño que jamás podría superarse. Los proyectos open source, como Linux, con miles de colaboradores alrededor del mundo, mostraron que el límite está determinado por la forma de organizarse. Una forma diferente de organizar el trabajo permitió coordinar el trabajo de muchísima más gente.

En nuestros proyectos locales, podemos tener la oportunidad de ver como nuestras decisiones afectan el trabajo que hacemos. Podemos ser como el soberano del proyecto de programación que implementamos. Ser el presidente de nuestro código. Y desempeñar también roles equivalentes al del legislador, magistrado, policía, etc. (quizás, cualquier sistema, alcanzado cierto nivel de complejidad, pueda generar roles como esos)

Algunas veces tenemos las mejores intenciones, y planteamos resolver las cosas de un modo que nos parece bueno, pero luego nos estrellamos con muros que nosotros mismos construimos.

Después de mucha prueba y error, los programadores han reunido un conjunto de buenas prácticas que sirven como pautas en nuestro trabajo. La experiencia de los miles de programadores en proyectos extensos también ha sido util para los programadores de proyectos más pequeños. Aquí menciono algunas:

El principio KISS (Keep It Simple as poSible*). Si hay dos maneras de hacer algo, es mejor usar la más simple. ¿Por qué? Cuando algo puede fallar, falla; así que es mejor minimizar el número de cosas que pueden fallar para facilitar el inevitable proceso de mantenimiento y mejora. Además, hay cierto grado de complejidad que los humanos podemos manejar con comodidad. Cuanto más simple, hay más capacidad mental disponible para la creatividad.

Reutilizar las cosas tanto como sea posible. Si algo funciona bien, no hay que estar repitiendo una y otra vez el mismo trabajo. Sin embargo, tener al mismo tiempo la libertad de reinventar la rueda y proponer alternativas, porque así es como se encuentran mejores opciones que puedan reemplazar a la anterior.

Minimizar el acoplamiento. Es decir procurar que el cambio que se hace en un componente no requiera hacer cambios coordinados en los demás. Esto facilita su mantenimiento y evolución.

Me pregunto por los montones de procedimientos que hay en nuestra sociedad. Por las duplicidades y los acoplamientos en las funciones municipales y ministeriales, en la policía y en el serenazgo. Por los pequeños feudos administrativos en los que se convierten las universidades, e incluso las facultades dentro de la misma universidad aunque sea pública. Por las absurdas reglas que se plantean y no se evalúan. Por el sistema de justicia que obliga a pelear una y otra vez las mismas batallas (¿por qué, si la justicia debiera ser igual para todos?). Por las reglas que no se siguen y las coordinaciones que no se hacen porque el protocolo resulta más complejo que el problema que se quiere resolver.

Las leyes y reglas mál dadas se observan en la práctica, al tratar de ejecutarlas. Igual que los frameworks en programación. Por más buenas intenciones que se hayan tenido al momento de darlas, por más que hayan funcionado en otros casos, para otras personas y otras circunstancias, cuando vemos que no funcionan en nuestro caso particular, debemos aceptar los hechos y tratar de hacer algo constructivo al respecto.

Es importante que las reglas sean simples, claras en sus intenciones, transparentes en su funcionamiento, y corregibles en su evolución. ¿Son así las leyes que tratan de aplicar en nuestra sociedad?.

Me parece también importante reconocer que telarañas de complejidad se pueden tejer cuando se trata de aplicar una regla que no se puede cumplir. Imaginemos el ejemplo absurdo de alguien que pusiera la regla de no respirar más de 30 veces por minuto. De pronto, todo el comportamiento de la gente cambiaría radicalmente. La gente no podría correr o hacer mucho esfuerzo porque la conduciría a un acto ilegal. Para verificar el cumplimiento de la norma se necesitaría policías que eligieran individuos sospechos (quizás demasiado chaposos) y les hicieran una auditoría. Seguramente habría excepciones para esos policías (que a veces tendrían que perseguir a los criminales) y los militares y agentes secretos. Aumentaría el trabajo de los jueces y abogados. Líderes sociales reclamarían ampliar el número a 31. Fuerzas conservadoras presionarían para disminuirlo a 29. Aparecerían libros y películas contando anécdotas y actos heroicos al respecto. Con el tiempo, tendríamos demasiada gente cuyo bienestar depende de la existencia de tal regla que, si alguien se preguntara por ella, nos tildarían primero de soñadores, luego de locos, y después de subversivos. Nos amedentrarían hasta que ellos mismos tuvieran una razón para hacerse la misma cuestión. He visto reglas así surgir incluso familias y en pequeños grupos de amigos. ¿Cuántas reglas como esa habrán en nuestra sociedad? Incluso las podrá reconocer en algunos dogmas religiosos.

Como programadores, podemos experimientar con reglas en las sociedades que representamos en un proyecto de desarrollo de software y aceptar con humildad que funciona y qué no funciona. Podemos tomar nota de ello, ganar experiencia, y desarrollar una intuición que puede servirnos para hacer una mejor tarea cuando tengamos la oportunidad de contribuir por una sociedad mejor.

* KISS, Keep It Simple, Stupid, era la versión original. Creo que el tono tenía la intención de llamar la atención entre amigos. Aquí uso una versión más cordial.


Crédito de la imágen: canada.com

2010/07/26

Fondo de página redimensionable

PROBLEMA

Cómo lograr que el fondo de una página sea redimensionable.

SOLUCION

La técnica consiste en colocar un img con un width=100%:

<img src="friends-and-moon.jpg" width="100%"/>

Sin embargo, a menos que se trate de un popup, aparecerán barras de scroll para permitir ver el resto de la imagen que no esté en pantalla.

Para evitar eso, se coloca el img dentro de un div con estilos adecuados:

body {
  margin:0;
}
#bg {
  width: 100%; height: 100%; left: 0px; top: 0px; position: fixed;
}
#container {
  position: absolute; top: 0; left: 0; width: 100%;
}
<!-- ... -->
<div id="bg"><img src="friends-and-moon.jpg" width="100%"/></div>
<div id="container">
<!-- content -->
</div>
Como se observa, luego el contenido de la página se puede colocar en un div posicionado absolutamente sobre la imagen. De ese modo se simula un fondo de página redimensionable.

El problema de la presentación del scroll se soluciona de este modo en los navegadores estandar, pero persiste en IE6.

Puede ver un demo aquí.

REFERENCIAS

2010/07/23

Personalizando bullets

Normalmente, una lista tipo ul luce así:
  • Item 1
  • Item 2
  • Item 3
Se puede usar CSS para cambiar el tipo del bullet (que por default es disc):
list-style:disc
  • Item 1
  • Item 2
  • Item 3
list-style:circle
  • Item 1
  • Item 2
  • Item 3
list-style:square
  • Item 1
  • Item 2
  • Item 3
list-style:none
  • Item 1
  • Item 2
  • Item 3
list-style:url(flecha_roja.gif)
  • Item 1
  • Item 2
  • Item 3
Para controlar la posición del bullet, se puede usar la técnica de poner la imagen como fondo del item.
En este ejemplo aplico los estilos en línea, para ilustrar la idea. Sin embargo, en un caso real, lo usual es que use clases y bloques u hojas de estilo para indicar lo mismo.

<ul style="list-style:none;">
<li 
  style="background:url(flecha_roja.gif) 1px 2px
  no-repeat; padding-left:10px;">
  Item 1: Bullet más cerca y centrado</li>
<li
  style="background:url(flecha_roja.gif) right 2px
  no-repeat; width: 250px;">
  Item 2: Bullet a la derecha</li>
</ul>

  • Item 1: Bullet más cerca y centrado
  • Item 2: Bullet a la derecha

Puede ver un demo en aquí

Crédito de la imagen: http://www.robbinssports.com

2010/07/09

Cómo centrar un bloque en una página

Centrar un bloque tanto horizontal como verticalmente es algo que se requiere a veces. Lo ideal es que el centrado se acomode automáticamente cuando la ventana del navegador se redimensiona. La solución podría ser más fácil, pero la familia IE, dificulta un poco el problema.

Nota
Estas soluciones funcionan en la mayoría de navegadores, incluso en IE6, pero recientemente encontré que no es así en Safari. Puede encontrar un método alternativo, que funciona en todos los navegadores, en el artículo Cómo centrar un bloque en una página 2.
    Soluciones
    • En los navegadores estandar (principalmente no-IE6), para lograr que un bloque, por ejemplo #content, de 400px por 100px, quede centrado en la página, se le puede aplicar los siguientes estilos:

          #content {
            width: 400px;
            height: 100px;
            position: absolute;
            top: 0; right: 0; bottom: 0; left: 0;
            margin: auto;
            overflow: auto;
        }

      El truco aquí es que el margin: auto también sirve para el centrado vertical si se especifica height, position: absolute, y además top: 0; right: 0; bottom: 0; left: 0;
      Una limitacion de esta solución es que la altura es fija. El overflow: auto es para que, cuando el contenido haga que #content sobrepase la altura especificada, aparezca un scroll.
    • En IE6, lo anterior no funciona. Es necesario colocar #content dentro de un #container, y usar los siguientes estilos:

          #container {
            position: absolute;
            top: 50%;
        }
        #content {
            width: 400px;
            height: 100px;
            position: relative;
            margin: 0 auto;
            top: -50%;
            overflow: none;
        }

      Aqui se usa la técnica de mover el top del #container hacia abajo el 50% de la altura de su contenedor, body, y luego el top del #content 50% hacia arriba de la altura del mismo #content (debería ser de su contenedor, #container, pero este es un bug de IE6, paradójicamente util para resolver este problema mejor que en el caso estándar, pues permite que la altura vaya más allá del inicial de 100px mientras el bloque se acomoda automáticamente siempre en el centro).
    • En IE7, lo anterior no funciona (así que hay cosas que funcionan diferente en IE6, IE7 y IE8). Es necesario agregar un #container2, y usar los siguientes estilos:

        #container {
          position: absolute;
          height: 50%;
          width: 100%;
        }
        #container2 {
          width: 100%;
          position: absolute;
          bottom: 0;      
        }
        #content {
          background-color: gold;
          width: 400px;
          height: 100px;
          overflow: auto;
          position: relative;
          margin: 0 auto;
          top: 50%;
        }

    • Para combinar estas soluciones en un paquete que funcione para ambos casos, se puede usar la técnica del hack underscore.
      La idea de la técnica es simple e ingeniosa: Normalmente, una propiedad css que comienza con un _, #, un punto, o un número es ignorada por los navegadores estándar (de hecho, anteponer un número al nombre de la propiedad es un truco util para desactivarla), pero IE6 filtra la cadena quitándole ese primer caracter, si es _ o #, para usárla normalmente. De ese modo, sólo para IE6, _position, o #position, se vuelven position, por ejemplo. Del mismo modo, IE7 filtra el punto y .position se vuelve position.
      Asi, luego de tener las cosas listas para los navegadores estándar, se puede intentar agregar o sobrescribir lo que necesitemos para IE6 e IE7, como se muestra a continuación:

        #container {
          _position: absolute;
          _top: 50%;
          .position: absolute;
          .height: 50%;
          .width: 100%;
        }
        #container2 {
          .width: 100%;
          .position: absolute;
          .bottom: 0;      
        }
        #content {
          background-color: gold;
          width: 400px;
          height: 100px;
          position: absolute;
          top: 0; right: 0; bottom: 0; left: 0;
          margin: auto;
          overflow: auto;
          _position: relative;
          _margin: 0 auto;
          _top: -50%;
          _overflow: none;
          .position: relative;
          .margin: 0 auto;
          .top: 50%;
        }

    Referencias

    2010/07/04