miércoles, 27 de octubre de 2010

Programas interesantes: alternativas a la consola de comandos cmd de Windows

En esta ocasión vamos a analizar un par de aplicaciones que añaden nuevas e interesantes características a la consola de comandos de Windows.

Console
Sencilla consola que incorpora algunas características adicionales a la consola de Windows: varias sesiones (una en cada pestaña), configurabilidad (fuente, transparencia, colores), etc. El autocompletado que viene es el mismo que el de Windows, es decir, que con el tabulador se completa el nombre del directorio o del archivo.

Enlace: http://sourceforge.net/projects/console


PowerCmd
Sencillamente espectacular. Permite tener varias sesiones abiertas en la misma ventana, las cuales se pueden organizar. También es posible tenerlas en una mismo marco en diferentes pestañas. Una característica muy interesante y útil es la del autocompletado de comandos, ofreciendo sugerencias de comandos o incluso de directorios y archivos. También permite realizar búsquedas de texto en los comandos y resultados mostrados con antelación. También permite poner bookmarks o marcadores en las líneas vistas previamente, para navegar rápidamente entre ellos. Posee también muchas opciones de configuración, tales como el aspecto (transparencia, colores, fuentes...), opciones de autocompletado, logs, atajos para lanzamiento de comandos o aplicaciones, etc.

Enlace: http://www.powercmd.com

lunes, 25 de octubre de 2010

Aplicaciones Web sencillas con Python

Este artículo está dedicado a aquellas personas que quieran dar sus primeros pasos en el desarrollo de aplicaciones web, y para aquellos que desarrollan aplicaciones sencillas, sin demasiadas complicaciones. Antes de redactar este artículo he estado probando y evaluando diversos frameworks para crear sitios web, tales como Bobo, Web2Py, CherryPy, Django, etc., pero al final me he decantado por WebPy, por su extrema sencillez para empezar, y por la similitud que tiene con otros frameworks de otros lenguajes, con lo que la curva de aprendizaje es óptima.

Más adelante, si los proyectos web se vuelven muy complejos y se requiere de elementos prefabricados y avanzados (como objetos persistentes a bases de datos, encriptación, modelo vista controlador, etc.), recomiendo utilizar los otros frameworks citados anteriormente (hay muchos más, pero éstos son más populares y potentes).

Se asume que el lector tiene conocimientos básicos de Python y que previamente tiene instalado el intérprete de Python en su máquina:


Configuración del servidor Web

WebPy, a diferencia de otros frameworks, no posee un servidor de aplicaciones potente propio, y por ello, es mejor apoyarse en uno que ya esté funcionando. Entre los posibles candidatos se encuentran Apache, Lighttpd y nginx. Para este artículo he optado por Apache, dada su gran popularidad.

Una vez instalado Apache en nuestra máquina, es necesario agregar el módulo mod_wsgi, que permite hacer uso de Apache como servidor para aplicaciones escritas en Python. Este proyecto está alojado en: http://code.google.com/p/modwsgi

Una vez descargado, si estamos usando Windows, renombrar el archivo a mod_wsgi.so y copiarlo al directorio modules de Apache. En el caso de Linux, compilar el módulo mod_wsgi (consultar: http://code.google.com/p/modwsgi/wiki/QuickInstallationGuide)

Una vez instalado el módulo, hay que configurar Apache para que reconozca dicho módulo. Para ello, editar el archivo httpd.conf (en el directorio conf de Apache), y agregar la siguiente línea en la misma parte en que Apache utiliza otras cargas LoadModule:

LoadModule wsgi_module modules/mod_wsgi.so

Al arrancar Apache desde la terminal debería dar un mensaje similar a éste:

Apache/2.2.2 (Unix) mod_wsgi/1.0 Python/2.3 configured

Si se lanzó desde Windows, el Apache Service Monitor, debería dar el mensaje en la parte inferior:


Instalación de WebPy

Hay varias maneras de instalar WebPy (consultar http://webpy.org/download).

Se puede descargar directamente la última versión desde la siguiente URL (consultar http://webpy.org/download para conocer cuál es la última versión):

http://webpy.org/static/web.py-0.34.tar.gz

También se puede descargar desde el repositorio en github:

http://github.com/webpy/webpy

Una vez descargado, descomprimir el archivo tar.gz, y ejecutar la siguiente sentencia para instalarlo como librería en Python:

python setup.py install


Primera aplicación Web

Para ilustrar la sencillez de desarrollo de una página Web con WebPy, vamos a crear la típica aplicación “Hola, Mundo”.

import web

urls = (
  '/', 'index'
)

app = web.application(urls, globals())

class index:
  def GET(self):
    return "Hola, Mundo"

if __name__ == "__main__":
  app.run()


La variable urls es una tupla que contiene pares de direccionamientos URL y nombres de clase. En este ejemplo, el direccionamiento “/” (root), estará asociado a la clase index. Se pueden definir tantos pares como sean necesarios para la aplicación Web.

El objeto app contendrá la definición de la aplicación Web. En este ejemplo se asocian las URL’s de la aplicación a namespace global.

La clase index contiene un método GET, el cual se lanzará cuando se invoque a la página, pudiendo recibir parámetros. En su interior, retornará el literal “Hola, Mundo”, el cual se imprimirá en el navegador. Existe también un método POST, que funciona como GET, pero ofuscando los parámetros. Estos dos métodos son los medios habituales de invocar a una página Web pasando (o no) parámetros.

Por último, las dos últimas líneas indican a WebPy que comience a servir páginas web con la configuración indicada.

Una vez se ejecuta este programa, el intérprete de Python se queda en modo de espera. El servicio Web está en marcha, esperando peticiones. Para probarlo, abrimos un navegador web e introducimos la URL:

http://localhost:8080

Debería aparecer nuestro bien conocido mensaje “Hola, Mundo”.


Parámetros y HTML

En una aplicación Web introduciremos elementos HTML para formatear el aspecto de las páginas. Además, añadiremos dinamismo permitiendo que las páginas muestren datos parametrizados (por ejemplo, recogidos de un formulario, o capturados de una base de datos).

Vamos a añadir más funcionalidad a nuestra aplicación anterior:

import web

urls = (
  '/hola', 'Saludo'
)

app = web.application(urls, globals())

class Saludo:
  def GET(self):
    data = web.input()
    return """
    <html>
    <head></head>
    <body background='#AAAAFF'>
    <h1>Hola, %s %s %s</h1>
    </body>
    </html>""" % (data.nombre, data.apellido1, data.apellido2)

if __name__ == "__main__":
  app.run()


El primer cambio lo hemos realizado en la sección de urls, donde ahora, el mapeo a la página Web será el siguiente:

http://localhost:8080/hola

Cuando se apunta a /hola, se invocará a la clase Saludo, concretamente a su método GET, en donde hemos agregado varios cambios. El primero de ellos ha sido definir una variable data, la cual recogerá los parámetros que se pasen por URL, lo que se consigue mediante la función input() del módulo web. Estos parámetros se recogerán en formato de diccionario, y son pares de parámetro y valor.

A la hora de retornar la salida, se retornará HTML, en donde hemos añadido un mensaje con formato de título (<h1>), un saludo con nombre y apellidos (extraídos de los parámetros pasados), los cuales se formatean mediante %s, e indicando después qué parámetros extraer.

Para invocar a la nueva página se pasan los parámetros en la misma URL, tal y como haría una llamada desde un formulario:

http://localhost:8080/hola?nombre=Carmen&apellido1=Martinez&apellido2=Salguero

El resultado es el siguiente:


Plantillas

En el último ejemplo comenzamos a utilizar HTML, que, al fin y al cabo, es el medio por el cual presentaremos la información en el navegador. El problema que tenemos es que se mezcla el código de Python y de HTML, y a la hora de depurar o realizar modificaciones, se vuelve enfarragoso y complejo. La forma ideal de trabajar sería separando la presentación (HTML) del código de negocio (el que procesa la información (Python)). Por un lado estarían las etiquetas HTML que ponen la información, y por otro el código Python que accede a la base de datos y la prepara en estructuras de datos (por ejemplo).

WebPy posee la característica de utilizar plantillas, que son directivas especiales embebidas en un código HTML, y que permiten conmutar valores que se pasan desde la capa de negocio o interactuar directamente con código Python.

Para estructurar nuestro código, vamos a crear un directorio donde se van a guardar las plantillas que vamos a necesitar. En nuestro caso la llamaremos plantillas. Dentro de este directorio crearemos un fichero llamado (por ejemplo) plantilla.html, y cuyo contenido será el siguiente:

$def with (nombre, apellido)
<HTML>
  <HEAD></HEAD>
  <BODY>
  $if (nombre!='' and apellido!=''):
    <H1>Hola, $nombre $apellido</H1>
  $else:
    <b>ERROR:</b> No ha facilitado el nombre y el apellido
  </BODY>
</HTML>

La primera línea

$def with (nombre, apellido)

debe ser la primera de la plantilla, y se encarga de recoger los parámetros enviados desde el código de negocio, los cuales serán presentados en la página HTML.

A continuación se crea el código HTML. Cuando es necesario presentar la información, hemos creado una estructura de control if para comprobar los datos pasados. En nuestro caso comprobamos si nombre y apellido contienen datos, en cuyo caso imprimirá en un título el mensaje “Hola, “ seguido del nombre y del apellido. Si uno de los dos datos no se ha facilitado, entonces (else) se mostrará un mensaje de error.

Ha de notarse que anteponiendo el símbolo $ (dólar) a una línea en Python, esta se procesará como código Python. Asimismo, este símbolo también se utiliza dentro del HTML para sustituir una variable por su valor.

Esta plantilla, por sí misma no hace nada. Debe ser asociada a la capa de negocio. Para ello crearemos el código en un fichero situado fuera del directorio plantillas, justo en el nivel anterior. El código será el siguiente:


import web

urls = (
  '/hola', 'Saludo'
)

render = web.template.render('plantillas')

app = web.application(urls, globals())

class Saludo:
  def GET(self):
    data = web.input()
    nombre = data.nombre if 'nombre' in data else ''
    apellido = data.apellido if 'apellido' in data else ''
    return render.plantilla(nombre, apellido)

if __name__ == "__main__":
  app.run()


El objeto render apuntará al directorio donde se encuentran nuestras plantillas, creando internamente un objeto por cada plantilla encontrada.

En el método GET de la clase Saludo, hemos reforzado el código (a prueba de errores) en cuanto a los parámetros. Si se pasa el parámetro especificado, recogerá su valor. Si no se pasa, le asignará una cadena vacía. Los parámetros pasados están en formato diccionario, por lo que es posible averiguar si el parámetro (clave) está dentro del mismo (‘clave’ in diccionario).

Por último, se retorna lo generado por la plantilla. Para ello se invoca a la plantilla:

render.plantilla(nombre, apellido)

Como se comentó anteriormente, internamente, WebPy toma las plantillas dentro del directorio al que apuntaba, y generará un objeto accesible por cada una de ellas. A la plantilla le facilitará los parámetros nombre y apellido, que serán recogidos por la primera línea de éste ($def with).


Un ejemplo más complejo

Los ejemplos anteriores han sido muy básicos. Vamos a ver un poco más a fondo cómo podemos aprovechar todo lo anterior. Imaginemos que queremos hacer una consulta a un catálogo de productos. Esta consulta puede ser general (muestra todos los productos), o bien específica (muestra un producto determinado). La solución pasaría por implementar un acceso a base de datos. Pero para no extender demasiado este artículo, vamos a tenerlo completamente en memoria (para más información sobre cómo acceder a bases de datos desde Python, recomiendo ver mi anterior artículo: http://rafinguer.blogspot.com/2010/10/conceptos-basicos-de-python-y-sqlite.html.

El código de negocio quedaría como sigue:

import web

urls = (
  '/ejemplo', 'Consulta'
)

render = web.template.render('plantillas')

app = web.application(urls, globals())

class Consulta:
  def GET(self):
    criterio = web.input()

    # Tuplas de diccionaris con datos de consulta.
    # Puede ser una carga de datos de una bbdd
    datos = (
      {'producto':'Tornillo', 'precio':0.45, 'marca':'Acme'},
      {'producto':'Tuerca', 'precio':0.55, 'marca':'Solme'},
      {'producto':'Clavo', 'precio':0.30, 'marca':'Calme'},
      {'producto':'Remache', 'precio':0.60, 'marca':'Acme'},
      {'producto':'Clavija', 'precio':0.95, 'marca':'Acme'},
      {'producto':'Grapa', 'precio':0.25, 'marca':'Tecme'}
      )

    registro=''

    if criterio:
      for i in range(0,len(datos)):
        if datos[i]['producto'] == criterio.producto:
          registro = datos[i]
          break

    if registro =='':
      registro = datos

    return render.productos(registro)

if __name__ == "__main__":
  app.run()


La llamada a la página puede hacerse sin parámetros (mostraría todos los productos), o bien pasando el parámetro producto, especificando cuál queremos consultar.

En ambos casos, a la hora de invocar a la plantilla, se pasaría la lista de productos o un único producto, que se almacena en la variable registro.

El código de la plantilla (productos.html) sería el siguiente:

$def with (registro)
<HTML>
  <HEAD></HEAD>
  <BODY>
  <TABLE BORDER='1'><TR BGCOLOR='#AAAAFF'>
  <TD><B>PRODUCTO<B></TD>
  <TD><B>PRECIO<B></TD>
  <TD><B>MARCA<B></TD></TR>

  $if 'producto' in registro:
    <TR>
    $for i in range(0,len(registro)):  
      <TD> $registro.values()[i] </TD>

    </TR>
     
  $else:
    $for i in registro:
      <TR>
      <TD> $i['producto'] </TD>
      <TD> $i['precio'] </TD>
      <TD> $i['marca'] </TD>
      </TR>

  </TABLE>
  </BODY>
</HTML>


En el caso de que se pase un único registro (la consulta se hizo por un único producto), éste será en sí un diccionario, por lo que al consultar si tiene una clave llamada producto, retornará el valor True. En tal caso, la función len() retorna el número de pares clave/valor del diccionario. Conociendo este valor, se recorre cada campo del diccionario en el bucle for y se extrae su valor, visualizándolo en una columna.

En el caso de pasar el catálogo completo, la función len() retornaría el número de filas (diccionarios) que contiene la lista. El acceso a la lista debe realizarse mediante un iterador (i), el cual recoge, una a una, cada fila (diccionario). El valor se extrae invocando el nombre de su clave.

El resultado final sería el siguiente:

Conclusiones

Este breve tutorial cubre los aspectos más básicos, pero, a la vez, más potentes y flexibles, para comenzar a desarrollar aplicaciones Web mediante Python. A partir de las nociones vistas anteriormente, podremos empezar a desarrollar complejas web dinámicas de una forma sencilla y eficaz.


Referencias

Lenguaje Python: http://www.python.org
mod_wsgi: http://code.google.com/p/modwsgi
WebPy: http://webpy.org
Apache: http://httpd.apache.org


Safe Creative #1010257670146

sábado, 23 de octubre de 2010

Cambio de tecnología

Cuando viene una nueva tecnología llamada a convertirse en estándar, surgen fricciones ante el cambio. Eso mismo le ocurrieron a los monjes copistas cuando pasaron del pergmino al libro. ¿Ocurrirá lo mismo ahora entre el libro y el eBook?

miércoles, 20 de octubre de 2010

El lado oscuro de la tecnología

Interesantísimo documental en el que se destripa el origen y el destino de la tecnología que consumimos a diario, y por qué está tan barata, y los pocos escrúpulos de las multinacionales en usar mano de obra barata de forma precaria, exponiendo su salud a la muerte. Las imágenes y los testimonios (subtitulados) no tienen ningún desperdicio. Recomiendo hacer click sobre el icono de la pantalla para verlo a pantalla completa y leer bien los subtítulos:

Después de ver este vídeo, uno se piensa bien el comprar un aparato y contribuir así a la pobreza de millones de parias a favor de la riqueza de unos pocos, así como también llevar la enfermedad y la muerte. ¿Seremos, indirectamente, unos asesinos? Da qué pensar.

martes, 19 de octubre de 2010

Conceptos básicos de Python y SQLite

En el presente post vamos a aprender los conceptos básicos para desarrollar código en Python utilizando la base de datos SQLite. Se presupone que el lector conoce los conceptos básicos de Python y de SQL, y que ya tiene instalado en su máquina tanto el intérprete de Python como SQLite.

Librería pysqlite

Lo primero que debemos hacer es descargar e instalar la librería pysqlite desde su página web: http://code.google.com/p/pysqlite

En el caso de tener Windows, descargamos un archivo ejecutable (.exe) y lo ejecutamos, instalándolo como cualquier aplicación Windows.

En el caso de tener Linux, descargamos el archivo comprimido (.tar.gz), y lo descomprimimos. Una vez descomprimido, instalamos la librería mediante el siguiente comando:

$ python setup.py build
$ python setup.py install


Conexión a la base de datos

Para realizar una conexión a una base de datos SQLite, ésta debe estar arrancada:

$ sqlite3 mibasedatos.bbdd

Para realizar una conexión a una base de datos, importar la librería:

from pysqlite2 import dbapi2 as sqlite

A continuación se establece la conexión indicando el archivo de base de datos:

con = sqlite.connect('mibasedatos.bbdd')


Consultas de datos

Para todas las operaciones con la base de datos, hay que crear un cursor a partir de la conexión:

cur = con.cursor()

A partir del cursor, se pueden ejecutar las operaciones que se requieran, como la consulta de datos:

cur.execute('select campo from tabla')

Al ejecutar la consulta, el cursor apunta antes del primer registro o fila. Los siguientes comandos avanzan hasta el siguiente registro:

cur.next() # Avance
cur.fetchone() # Avance y recupera registro

Para obtener de una vez todos los registros del cursor:

cur = con.cursor()
cur.execute('select * from tabla')
result = cur.fetchall()

En la variable result se almacenará una lista o secuencia de tuplas, cada una de las cuales corresponde a un registro, y el valor de cada uno de los campos se encuentra separado por comas:

print result
[(0, u'valor1', 87), (1, u'valor2', 32), (2, u'valor3', 38)]

En este ejemplo, el resultado da 3 registros con tres columnas o campos, de los cuales, el primero y el último son numéricos, y el segundo es alfanumérico.

print result[1] # registro 2
(1, u'valor2', 32)
print result[2][1] # campo 2 del registro 3
valor3

Recorrer el resultado resulta muy sencillo, utilizando un iterador sobre la secuencia:

cursor = con.cursor()
cursor.execute('SELECT id, nombre, nick, password, rol FROM usuarios')
for fila in cursor:
   print 'id:', fila[0]
   print 'Nombre:', fila[1]
   print 'Nick:', fila[2]
   print 'Password:', fila[3]
   print 'Rol:', fila[4]
   print '*'*30


Actualizaciones

Por actualización se entiende toda aquella operación que realiza algún cambio, lo que implica algún tipo de escritura. Existen varios tipos de escritura o modificaciones en la base de datos. El primero afectaría únicamente a los datos de las tablas, lo que se consigue mediante las sentencias UPDATE, INSERT y DELETE de SQL. Otro afectaría a la estructura de la base de datos, pudiendo crear, modificar o eliminar tablas o índices.


Actualización de datos en tablas

Para todas ellas, se utilizará un cursor y la función execute(), tal y como vimos anteriormente:

from pysqlite2 import dbapi2 as sqlite
con = sqlite.connect("ticube.bbdd")
cur = con.cursor()
cur.execute("insert into tbconfig (parametro, valor, descripcion) values ('PARAM1', '10', 'Parametro 1')")
cur.lastrowid

En este ejemplo se inserta un registro en una tabla. La última línea retorna el número de la última fila afectada en el cursor. Si sólo se realizó esta operación de escritura, pero no afecta a ningún registro, no retornará nada. Si todo fue bien, retornará (en este caso) 1.

El cursor acumulará operaciones de escritura, a medida que se vayan ejecutando. Pero estas operaciones no se hacen efectivas físicamente en la base de datos. Ello se debe a que se encuentran en una transacción.

Una transacción resulta muy útil cuando hay un encadenamiento de operaciones de escritura que tienen dependencias unas de otras. Cuando se completan todas las operaciones de escritura, si no se ha producido ningún tipo de error, se puede procesar toda la transacción indicando a la conexión de la base de datos que perpetre definitivamente la transacción con todas las operaciones realizadas:

con.commit()

Si se produjera algún error durante la transacción, podrían abortarse todas las operaciones de escritura indicadas en el cursor para evitar inconsistencias de datos. Para ello, una vez se detecte algún error o inconsistencia, se indicaría a la conexión de la base de datos que dé marcha atrás, cancelando todas las operaciones realizadas:

con.rollback()



Actualización de la estructura de la BBDD

También es posible acceder y modificar la estructura de la base de datos, pudiendo crear nuevas tablas, añadir campos a las tablas existentes, crear o borrar índices, etc.

El proceder es idéntico a como hemos visto antes, a través del cursor. El siguiente ejemplo crea una sencilla tabla en nuestra base de datos:

cursor.execute("CREATE TABLE configuracion (parametro VARCHAR(30) NOT NULL, valor VARCHAR(30))")

A diferencia de la actualización de datos en las tablas, este tipo de actualizaciones se realiza directamente, y no requiere de transacciones.


Consultas parametrizadas

Imaginemos que se pretende hacer una carga masiva de datos de una tabla. En lugar de tantas sentencias INSERT como conjuntos de valores (cosa inviable si los datos son dinámicos), se pueden recoger éstos de otra consulta o de un fichero, y asignar dichos valores a unas variables y utilizar el valor de éstas en una única sentencia INSERT:

from pysqlite2 import dbapi2 as sqlite
con = sqlite.connect("ticube.bbdd")
cursor = con.cursor()
parametros=['UNO','DOS',’TRES’]
valores=['1','2','3']
max=len(parámetros)
for i in range(0,max):
   cursor.execute("INSERT INTO configuracion (parametro, valor) VALUES (?, ?)", (parametros[i], valores[i]))
con.commit()

En este ejemplo se insertarán 3 registros en la tabla configuracion, obtenidos de dos secuencias (parametros y valores). El símbolo ? (interrogación), reserva el valor que va a tomar de la lista de parámetros que se especifican a continuación, en el mismo orden en que se enumeran.

Esta capacidad se puede aplicar también a otras consultas de actualización (como UPDATE o DELETE) o a consultas de datos (SELECT).



Cerrar siempre

SQLite es una base de datos muy versátil, ligera y práctica. Ello se consigue sacrificando una parte esencial en entornos distribuídos: la concurrencia. Así es: SQLite no es concurrente. Por ello, para evitar problemas e inconsistencias por la concurrencia, deberemos siempre cerrar todos los cursores y conexiones una vez han sido utilizados y no los utilicemos en cada módulo. Ello libera la conexión para nuevas operaciones.

El método close() se encarga de esta operación:

cursor.close()
con.close()

El orden de apertura y cierre es importante:

1) Abrir conexión
2) Abrir cursor
3) Operaciones
4) …
5) Cerrar cursor
6) Cerrar conexión

Safe Creative #1010197608377

lunes, 18 de octubre de 2010

Steve Ballmer y el Doctor maligno

Programas interesantes: Macbuntu

Ha pasado por mis manos una interesante aplicación que me ha sorprendido gratamente. Se trata de Macbuntu, el cual transforma por completo tu Ubuntu en un flamante MacOS X. En otras ocasiones he hablado de aplicaciones similares para Windows, pero Macbuntu me ha sorprendido por lo casi casi casi exacto que es, incluyendo los efectos, el menú Apple, fuentes, cierre del equipo, etc.

La instalación es sencilla, aunque hay que seguir los pasos aquí indicados. Antes de nada, indicar que aquí se expone cómo hacerlo para Ubuntu v10.04 y Ubuntu v10.10. Para otras versiones de ubuntu, habrá que consultar la página de Macbuntu.

Para ello se abre una terminal o consola de comandos y escribir los siguientes comandos:

Ubuntu v10.04
$ wget https://downloads.sourceforge.net/project/macbuntu/macbuntu-10.04/v2.2/Macbuntu-10.04.tar.gz -O /tmp/Macbuntu-10.04.tar.gz
$ tar xzvf /tmp/Macbuntu-10.04.tar.gz -C /tmp
$ cd /tmp/Macbuntu-10.04/
$ ./install.sh


Ubuntu v10.10
$ wget https://downloads.sourceforge.net/project/macbuntu/macbuntu-10.10/v2.3/Macbuntu-10.10.tar.gz -O /tmp/Macbuntu-10.10.tar.gz
$ tar xzvf /tmp/Macbuntu-10.10.tar.gz -C /tmp
$ cd /tmp/Macbuntu-10.10/
$ ./install.sh


Nota: $ se refiere al prompt de la consola

El aspecto final se puede apreciar en los siguientes pantallazos:

¿Es hora de colgar los hábitos?

He consagrado mi vida, mi profesión y mi futuro a la informática, concretamente al desarrollo. Recuerdo con añoranza el año 1985, cuando comencé a colaborar con una extinta compañía de videojuegos para el Spectrum, en Madrid. No había legislación de sueldos, categorías ni convenios. Se cobraba algo simbólico, y más siendo aprendiz. No importaba. Me apasionaba poder descubrir cada día nuevos algoritmos, dar vida a personajes, explotar las capacidades de la máquina, exprimir los bytes y hacer que una rutina en código máquina se ejecutara rápidamente y sin errores.

Después aposté todo a la carrera informática en la universidad. Era una carrera muy reciente, comenzando con lo tradicional. En aquella época yo ya desarrollaba en Clipper, C++ y Visual Basic, pero en la facultad íbamos por Cobol, RPG, Fortran y muchas teorías que empezaban a ser obsoletas. Mientras hice la carrera, también hice la mili, enseñaba informática en academias y colaboraba con empresas de videojuegos y editoriales versadas en el tema de la informática.

Acabé la carrera y debía dar un vuelco a mi carrera. No sólo por el dinero, si no también por la profesionalidad. Comencé en una pequeña consultora, donde puede comenzar como analista programador, y donde las ilusiones y el buen rollo eran su principal virtud. Después de tres años, y debido a que no podía seguir creciendo ni ganar más dinero, y a que empezaba una nueva vida que iba a requerir más recursos (me casaba), tuve que cambiar, a mi pesar, a otra empresa mayor. A partir de ahí, fui viviendo una vorágine de acontecimientos hasta el día de hoy: proyectos y servicios impuestos por comerciales, consultoras que sólo ven números y no empleados, cortinas de humo, asignación de proyectos y equipos que no se ajustan a las necesidades, habilidades y expectativas del mismo ni de sus integrantes, etc.

Durante más de veinte años he visto una degradación progresiva de esta profesión y de las empresas que participan en este juego. Al principio, los clientes no tenían el conocimiento y delegaban en las consultoras. Después han incorporado con mejor o peor acierto a gestores con un mínimo de conocimientos para su control. En la actualidad, se han llegado a prácticas humillantes, de mercadillo, subastando proyectos y servicios al menor postor (al que lo haga por menor precio).

Al principio, un programador era un ingeniero con unos conocimientos importantes, y su talento en aplicar esos conocimientos para resolver los problemas de la empresa eran muy estimados. Después aparecieron consultoras tipo langosta (el insecto, no el crustáceo), para devorar el mercado de un lugar sin generar nada a cambio. Reducían sus tarifas ofreciendo servicios "profesionales", y colocando (muchas veces) a becarios sin experiencia, personal no cualificado o reciclando profesionales de otras áreas. La calidad, obviamente, era (y sigue siendo) de dudosa confianza, y muchos proyectos han generado cuantiosas pérdidas. Pero la mayor pérdida de todas, ha sido la de la confianza en nuestra profesión, y ser informático ahora es un sinónimo de desconfianza, de chapuza, de estafador, etc.

No sé si os ha ocurrido como a mi, que en las consultoras somos carne al peso, y tanto si eres jamón pata negra, como si eres ternera de primera, como pollo de granja alimentado con pienso, o una simple rata callejera, te venden como una hamburguesa, a veces por debajo de costes, y todo por la estrategia de quitar a la competencia. Da igual si tienes conocimiento o experiencia en la tecnología o en la arquitectura del proyecto donde te venden. Si no venden tu carne (o tu alma), hay más carne en la despensa, incluso con mayor margen de beneficio.

La vorágine del negocio no tiene rasero, ni ética ni escrúpulos. Los comerciales tienen que vender para seguir en nómina, tener su comisión y su cuenta de resultados. Es un currito más, y debe hacer cosas que no le gustaría, pero debe conseguirlo de ese modo, porque hay otros comerciales de otras consultoras, con estómagos más acostumbrados a lo podrido. Si no venden, se cierra el negocio, y con ello todo lo demás. Así son las reglas de este juego.

Una vez (mal) vendido un proyecto o un servicio (mejor dicho, una vez nos hemos metido), hay que crear un equipo con lo que haya, o si no traer gente de fuera con el supuesto conocimiento o la supuesta experiencia. Volvemos al bucle de traer gente de fuera en lugar de promocionar, o de enseñar y reciclar, a gente de dentro, que no tienen ni la sinergia, ni la fidelidad ni la filosofía de la empresa. Esto, a su vez, genera discordia dentro, la desconfianza de que no se cuenta con ellos, que a su vez también se ve que la empresa pone techos de cristal, donde ves nuevos zapatos de nuevos compañeros con categoría superior a la tuya, y que te has tirado trabajado años y años en lo mismo y sin posibilidad de que tus zapatos estén en ese techo de cristal. Por eso se ve tanto movimiento de profesionales, donde ven en el cambio de empresa el único medio para crecer profesionalmente, de subir de categoría y de sueldo. De esta manera, terminamos convertidos en mercenarios con los mismos escrúpulos que los que pagan nuestras nóminas.

Cuando nos paramos a mirar nuestra profesión hoy en día, ¿qué vemos?. Una tierra baldía y desoladora. Chavales que desestiman o tienen miedo de hacer una carrera que no les asegura el trabajo, y que éste está poco remunerado y apestado. Una trabajo al que le dedicas horas "by the face", ni pagadas ni agradecidas. Una profesión al que le dedicas pasión, investigación, sacrificio y adquisición constante de nuevos conocimientos para no quedarte obsoleto, para luego tener un sueldo menor al de otras profesiones que no requieren conocimientos especiales ni tanta dedicación. Una profesión en la que hoy estás aquí, mañana allí, y nunca conservas compañeros durante muchos años. Una profesión donde en cualquier momento te pueden echar, especialmente cuando te quedas sin proyecto, cosa que ocurre no sólo por término del mismo, si no también por cancelación por falta o reajuste de presupuestos por parte del cliente. Una profesión en la que se valora más la imagen que la productividad, donde no se valora el trabajo del equipo productivo, donde esos "picateclas" siempre tienen la culpa de que los proyectos fracasen (es una ironía), y por eso deben cobrar menos y saborear más el látigo. Una profesión que da más quebraderos de cabeza y desilusiones que satisfacciones. Una profesión maldita que no respeta la personalidad del empleado, un ser con sentimientos, con dudas, temores, motivaciones, talento... Una profesión que llega a anular o a condicionar el estilo de vida de nuestros profesionales, dentro y fuera de la empresa. Una profesión odiada por clientes y por nosotros mismos, y de la cual no paramos de hablar tanto dentro como fuera de nuestras horas de trabajo, en cualquier lugar, con cualquier persona y a cualquier hora.

Todo se traduce a negocio. Si no hay negocio, no trabajas. Los clientes ahora son tiburones que obtienen el mejor (el más barato) precio de proyectos innovadores. Se aprovechan del clima generado por la crisis, aumentando más ese clima para su beneficio. Es muy fácil tener un mendrugo de pan y rifarlo a una horda de harapientos mendigos a cambio de obtener lo máximo aprovechándose de él. Si no tienes mucha hambre, debes luchar también por ese mendrugo de pan, porque al próximo mendrugo quizá ni cuenten contigo. Y el resto de hambrientos tienen hambre y tienen el ingenio agudizado. El esfuerzo de los comerciales aquí es tremendo, estresante e insatisfactorio. Y una vez que te llevas el mendrugo, hay que acatar el elevado precio que has pagado, y verás que una vez empezado el proyecto, el cliente te pedirá más de lo que te pedía al principio, con el miedo de perderlo la próxima vez si no cumples.

Ha habido muchos debates al respecto, sobre si la culpa la tienen los comerciales, o por el proyecto Bolonia que va a dar al traste nuestras titulaciones, o el intrusismo, o las consultoras mega-picadoras-de-carne que meten a no profesionales, o la falta de regulación por un Colegio Oficial, la ávida avaricia de las empresas, etc. Todos estos debate, aunque interesantes, tienen razón y no la tienen, según desde el cristal por el que se mire. Yo creo que en la situación actual la culpa la tenemos todos, desde el primero hasta el último. Yo me incluyo, porque en este país nos quejamos de todo, pero no hacemos nada al respecto, aunque nos den oportunidades para ello. No hemos dado ningún puñetazo en la mesa para decir: "basta", "estos son mis derechos y voy a luchar por ellos". Sólo nos preocupamos de seguir conservando la nómina, despotricar con la boca pequeña mientras nos tomamos un café con los compañeros, y marcharnos a la seguridad de nuestra casa agradeciendo haber tenido otro día duro de trabajo.

He pintado un cuadro gris-oscuro bastante feo. ¿Cómo arreglarlo y darle pinceladas de color?. La verdad, honestamente, no lo sé. La reciente creación de un Colegio Oficial de Ingenieros Técnicos de Informática en Madrid, o la creación de cualquier Colegio Oficial, ya sea territorial o estatal, no creo que sea una solución, ni que asegure una calidad óptima en los proyectos. Los clientes no van a querer pagar más cuando antes pagaban menos. Un colegiado estará obligado a implantar metodologías que lastrarán (como siempre) los proyectos. La metodología no asegura la calidad, si no que es una trinchera desde la cual lidiar pleitos y juicios, que hacen perder el tiempo en la productividad y que va en detrimento de la ecología, al desarrollar muchos documentos innecesarios y consumir más energía para producirlos. Estas metodologías incrementarán también el tiempo y el coste de los proyectos.

Por otra parte, estar colegiado tampoco te acredita como profesional. He conocido (y conozco) a muchos ingenieros superiores en informática o en telecomunicaciones, que tras la carrera su aptitud y su actitud han ido dirigidas a despachos y titulitis, pero no aportadas a los proyectos. Sin embargo he conocido "intrusos" (personas sin carrera (conocimientos acedémicos) o personas provenientes de otras carreras), cuya actitud y cuya aptitud han sobresalido sobre la de aquellos con aires de grandeza.

He llegado a ser gerente y director. Desde hace casi cuatro años soy director de proyectos. El título me da igual, pues a veces he de picar código, en otras a definir portfolios, estrategias de negocio, análisis, preventas, planificaciones, etc. Me da igual analizar una tecnología que instalar y configurar un nuevo sistema, hacer pruebas o entrar a una reunión de crisis con un cliente y conciliar conflictos. Suelo tomar café y comer con "la tropa", con compañeros que tienen vidas, sueños, sentimientos y mucho qué decir sobre nuestra profesión en primera línea de combate. Los comentarios son desgarradores, y reflejan una realidad que está lejos de muchos dirigentes que sólo ven su vergel y su BMW.

A mi edad no puedo volver hacia atrás. La salida sería estudiar un Master en Dirección de Empresas o similar. Hace dos años estuve buscando uno "baratito" y sin prestigio. Al final di con uno de 3000 euros, y pedí a la empresa que me subvencionaran parte del máster a cambio de aplicar dichos conocimientos y prácticas para la empresa, con lo que ambas partes saldríamos ganando. La respuesta la podéis suponer. Si no puedo ir hacia atrás ni hacia delante, y si además veo el mercado laboral en el que piden jefes de proyecto de menos de 30 años, y directores de proyecto de menos de 35 años, mi futuro no lo veo muy halagüeño. Mi sueldo es mayor que el de uno similar de un treintañero con ganas de comerse el mundo, sin limitaciones (yo tengo hipoteca y familia) y sin pegas. Toda mi experiencia y todos mis conocimientos no pueden competir contra eso.

Otra salida sería montar mi propia empresa. Llevo dos años en ello, pero no me queda mucho tiempo después del trabajo para consagrarme a mi faceta emprendedora. Tan sólo puedo abordar pequeños proyectos para poder garantizar una entrega a corto plazo. Los costes y los esfuerzos, de momento, no compensan ni dan rentabilidad. Tampoco quiero abordar de repente un gran proyecto, pues no lo puedo garantizar, y tampoco quiero socios (ya he tenido dos amargas experiencias). A día de hoy, sigo invirtiendo parte de mi poco tiempo libre en buscar alguna fórmula en este sentido.

Otra salida sería cambiar de profesión, pero... ¿adónde voy? En esta profesión tengo más de 25 años a mis espaldas, y a mi edad me pedirán experiencia en cualquier otra profesión, que no tengo. Puede que en algún trabajo en una cadena de producción o como comercial sin experiencia tenga una oportunidad, pero, ¿en qué condiciones (salariales)?.

¿Qué futuro nos espera a los informáticos? El presente es muy jodido (perdonadme esta expresión), y la experiencia me ha demostrado que siempre va en detrimento, pues los escrúpulos en los negocios no existen, y no se valoran ni se miman las herramientas de trabajo, y si se pueden cambiar 1000 empleados por una máquina de churros, pues mejor. En este sentido, no me dejará de asombrar las ingeniosas fórmulas para reducir cada vez más las tarifas, exprimir más la fuerza productiva y extraer más zumo. En su día, España fue interesante para invertir, por ser una mano de obra barata y de calidad. Ahora tenemos una calidad dudosa, y otros países, como los países del Este y China, vienen detrás arrebatándonos ese lugar.

Es posible que decida - como otros muchos ya lo han hecho - emigrar de este querido pero absurdo país, de nuestra cultura mezquina del pelotazo y de leyes absurdas y cargantes para los emprendedores. He trabajado en UK y en Francia, de donde deberíamos aprender muchas cosas en lo referente a negocios y a valorar en su justa medida a los que realmente producen y crean el producto, el servicio y el proyecto. También hay que aprender mucho sobre su cultura emprendedora y de negocios. Un negocio no es ganar pasta rápido, a toda costa y donde sólo ganas tú. Un negocio es crear lazos duraderos, de confianza, de amistad, donde ganamos todos satisfaciendo las necesidades mutuas.

¿Es hora de colgar los hábitos? Lo estoy reflexionando.

miércoles, 13 de octubre de 2010

¿Dónde se justifica la diferencia de precio en un ordenador Apple?

He realizado un sencillo ejercicio para ver la diferencia de precios de ordenadores entre Apple y otras marcas de primer orden. Para ello, no he escatimado en un equipo normal, si no en uno de alta gama. En este post solamente hablo de la máquina, no del sistema operativo Mac (que da también para otro post).

La lista comparativa es la siguiente:

Apple MacBook Pro
CPU: Core i7 2,63GHz
Memoria: 4GB DDR3 1,066GHz
Disco duro: 500GB
Unidad HD: DVD/CD
Pantalla: 17 pulgadas
Precio: 2419,99 euros

Lenovo ThinkPad T410i
CPU: Core i7 2,63GHz
Memoria: 4GB DDR3 1,066GHz
Disco duro: 500GB
Unidad HD: DVD/CD
Pantalla: 17 pulgadas
Precio: 2323,2 euros

HP EliteBook 8740w
CPU: Core i7 2,63GHz
Memoria: 4GB DDR3 1,333GHz
Disco duro: 500GB
Unidad HD: DVD/CD
Pantalla: 17 pulgadas
Precio: 1802 euros

Sony Vaio VPC-EC3X5E
CPU: Core i7 2,80GHz
Memoria: 6GB DDR3 1,066GHz
Disco duro: 640GB
Unidad HD: BlueRay/DVD/CD
Pantalla: 17,3 pulgadas
Precio: 1339 euros

Mountain Performance 17
CPU: Core i7 2,66GHz
Memoria: 4GB DDR3 1,333GHz
Disco duro: 500GB
Unidad HD: DVD/CD
Pantalla: 17,3 pulgadas
Precio: 1074 euros

Toshiba Satellite A660-13T
CPU: Core i5 2,26GHz
Memoria: 4GB DDR3 1,066GHz
Disco duro: 640GB
Unidad HD: DVD/CD
Pantalla: 16 pulgadas
Precio: 899 euros

Vista la lista, la mejor opción sería el Sony Vaio, pues presenta más potencia de CPU, más memoria, más disco duro y el BlueRay, por una diferencia de precio de 1081 euros (casi la mitad). Si el Vaio se configura con 4GB de RAM, 500GB HDD y DVD, el precio sería de 1108,99 euros (menos de la mitad). Resulta cuanto menos curioso que también el Mountain Performance tenga las mismas características que el MacBook Pro y cueste menos de la mitad.

Me pregunto, ¿cómo justificar la diferencia de precio?. Componentes de alta calidad ya lo encontramos en todas estas marcas, y todas están preparadas para aguantar condiciones extremas de trabajo. Quizá la tarjeta gráfica (Mac utiliza una nVidia), pero alguno de estos ordenadores (como el HP) también usa la misma, y el precio es muy inferior. El Lenovo puede justificar su elevado precio gracias a que está diseñado muy ergonómicamente y a que está construído con materiales muy resistentes a caídas y golpes, así como también contra el polvo. ¿La carcasa de aluminio? No creo que justifique tanta diferencia, y ya hay varios ordenadores en el mercado con una carcasa así y ni se acercan a esos precios. ¿El sistema operativo? Visitando la página de El Corte Inglés, el Windows 7 Professional (el más alto y caro), cuesta 354 euros. En la página de Apple, el Mac OS X Server con licencia ilimitada son algo menos de 500 euros. El sistema operativo instalado no es de servidor, y debería costar bastante menos. La actualización a la versión 10.6 (que creo que tiene el sistema completo), cuesta tan sólo 30 euros. Y estamos hablando de un sistema operativo basado en Unix, que comparte su corazón y sus aplicaciones, y al que se le ha puesto una interfaz de usuario bastante usable, y en el que se ha automatizado mucho las operaciones más duras y técnicas. Aún así, no justifica tanta diferencia.

A un Apple lo veo como un ordenador tuneado: mucho diseño, muy bonito, con lucecitas y chorraditas varias, pero no aporta valor añadido ni práctico a lo que realmente es: un PC. Imaginemos un coche con motor, distribución, cambio, frenos, dirección y chasis de alta gama. Sobre esta arquitectura varios fabricantes añaden el resto al coche: carrocería, cuadro de mandos, volante, asientos... Desde luego, un fabricante que exhibe el mejor diseño llamará más la atención, y si encima plantea el mejor marketing, el éxito estará asegurado. Pero el coche no correrá más ni hará más cosas. Incluso el diseño perjudicaría otros aspectos importantes (por ejemplo, recortar los amortiguadores para mayor deportividad, fastidiaría los bajos en baches, rampas, bordillos, etc.; o unas ruedas más anchas y de perfil más bajo, son más deportivas, pero se consumen mucho más rápidamente y son contraproducentes en caminos cuando llueve). Puede ser un ordenador bello, pero no es más eficiente, ni más rápido, ni resuelve operaciones especiales... Es el mismo ordenador pero con un aspecto más bello y agradable. A mi me gusta. Pero no así la diferencia, la cual veo injustificada.

lunes, 11 de octubre de 2010

Reflexiones sobre los lenguajes de programación

Desde los albores de la informática, ha sido necesario algún nexo de comunicación entre las máquinas y los humanos. En un principio se codificaban instrucciones lógicas, matemáticas, asignación, flujo... asociadas a códigos binarios. Para hacerlo un poco más legible, aparecieron los mnemotécnicos del ensamblador o código máquina. Más tarde, la productividad exigía lenguajes más sencillos para ganar rapidez, eficacia y reducir la cantidad de errores. Aparecieron el Fortran, el Cobol, el RPG, el ADA, el LISP, el Basic, el Logo, el Pascal, el C, el C++, el Java, el .NET, el Python, el Ruby, etc.

Hoy día tenemos una riqueza enorme de lenguajes de programación (ver lista de lenguajes de programación en http://people.ku.edu/~nkinners/LangList/Extras/langlist.htm). Algunos lenguajes se han inventado para tratar algunas tareas específicas. Otros lenguajes, sin embargo, son utilizados para propósitos generales. Algunos lenguajes son de muy bajo nivel, con lo que su rendimiento es altísimo. Otros lenguajes son de muy alto nivel, ganando así en productividad y en reducción de errores. Algunos lenguajes son muy sencillos de aprender y de utilizar, mientras que otros son místicos o esotéricos, reservados sólo para los elegidos que se adentran en sus arcanos conocimientos (consultar http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_esot%C3%A9rico. Hay lenguajes compilados, semicompilados, interpretados o de script. Hay lenguajes textuales y lenguajes gráficos. Hay lenguajes que comprenden uno o varios paradigmas, como el imperativo, el declarativo, el estructurado, el orientado a objetos, el funcional, el lógico, etc.

A lo largo de la historia de la programación ha habido una evolución constante, tanto de los lenguajes como del entorno del negocio de la programación. En su día, un programador era una eminencia por la que se pagaba un sueldo envidiable. Hoy día, la programación está al alcance de cualquiera, y los sueldos han bajado hasta igualarse a los de otros oficios. Hoy se valora más la gestión de equipos de programadores y la optimización de la productividad, que los conocimientos individuales de un programador.

Antiguamente se elaboraban más algoritmos, por lo que era habitual repetir el código de ciertas funcionalidades (ordenación, índices, accesos a discos, etc.), especialmente porque el código no se compartía y había mucha patente. Hoy en día hay librerías para todo, y frameworks avanzados que facilitan mucho la labor de la programación, haciéndola más productiva y estandarizada.

Un paso importante fue incluir rutinas de bajo nivel en un chip, como la ROM, la cual era (y sigue siendo) accesible por cualquier programa (especialmente por uno que acceda a bajo nivel, como C/C++). A esto le siguió incluir también rutinas estándar en el sistema operativo (nuestro adorado DOS ya las incluía). Hoy día, casi cualquier dispositivo tiene una librería de bajo nivel con los servicios estándar para su gestión. Desde hace algún tiempo también se está experimentando incluir un sistema operativo en un chip (éste era uno de los proyectos de Linus Torvalds), o incluso complejos programas completos. Tener software implementado a nivel de chip incrementaría enormemente la velocidad, aunque los chips deberían ser de acceso aleatorio y sobreescribibles, con el fin de poder actualizar bugs, firmwares, funcionalidades, etc. Asimismo, los chips deberían ser también estándares, con el fin de poder integrarlos en otros dispositivos o máquinas con sólo conectarlos.

El contenido y el contenedor de los programas también ha cambiado, aunque la esencia es la misma. Antiguamente se codificaba el código (en lenguaje máquina) en tarjetas perforadas, las cuales eran leídas y pasadas a la memoria del ordenador, que procesaba el programa. Más adelante, los lenguajes de programación se compilaban (traducían y guardaban) a código (de la propia máquina o de la propia plataforma), y las tarjetas perforadas se sustituyeron por soportes de almacenamiento magnético (y/u óptico). Los lenguajes actuales permiten crear programas independientes de la plataforma, gracias a que están en crudo y son interpretados por un intérprete (como JavaScript), o bien están semicompilados a nivel de bytecode (como Java o .NET). En ambos casos no es la máquina o el sistema operativo el que ejecuta el programa, si no otro programa (intérprete o máquina virtual). Otro punto en que se ha evolucionado el contenido y el contenedor, es que los programas solían estar en la misma máquina, y ahora ese no es un requisito indispensable, pues se pueden ejecutar servicios de programas en remoto. Con la programación en nube, los programas se sirven como un servicio, y no es necesario hacer instalaciones ni tener sistemas de almacenamiento, si no tan sólo una conexión a internet y un navegador.

Otro punto especialmente relevante ha sido la filosofía del software libre (y por ende, todo lo relacionado, como el código abierto y todo tipo de licencias no propietarias), que ha supuesto la liberación de la programación como un fenómeno profesional, cultural y social. Esto permite ya no sólo tener las libertades, si no también la igualdad para todos de poder crear productos y tener las mismas oportunidades para compartirlo, promocionarlo y explotarlo.

¿Y cuál será el futuro de los lenguajes de programación? ¿Qué más pueden evolucionar? ¿Qué más pueden aportar a nuestra sociedad de la información?

La tecnología sigue avanzando y evolucionando. Esto genera nuevas necesidades y problemas que marcarán el qué y el cómo, así como también las tendencias en los lenguajes de programación, los cuales seguirán estando con nosotros, ya que necesitamos máquinas, y las máquinas nos necesitan a nosotros, y para que ambos nos entendamos es necesario un lenguaje.

Recuerdo cuando programaba en Clipper que mi jefe me decía que los programadores iban a desaparecer, ya que apareció la primera versión de Visual Basic, y todo se hacía automáticamente con tan sólo el ratón. Pero nada más lejos de la verdad, pues ello generó muchas más necesidades, problemas y soluciones de lo que antes habíamos imaginado. Y bajo ese prisma, creo que todo avance ampliará mucho más los horizontes que ya tenemos.

Lo mismo que ocurre con los idiomas humanos, los lenguajes de programación minoritarios se extinguirán poco a poco incrementando el uso de los más consagrados, debido a la carencia de su necesidad en la industria (otra cosa que sean objeto de estudio, como el latín o el griego). Los lenguajes de alto nivel ganarán cada vez más cotas de uso, y seguirán necesitando de lenguajes de bajo nivel para equilibrar sencillez frente rendimiento y velocidad. Se abstraerá aún más la semántica del lenguaje a fin de realizar muchas más cosas con menos, con la posibilidad de entrar en detalles. Habrá lenguajes de programación en nube, como servicio, así como también infraestructuras de desarrollo y despliegue en nube. Si bien las aplicaciones Web y en nube van a ver aumentada su cuota, las aplicaciones de escritorio seguirán presentes para ciertas necesidades, y especialmente por privacidad, por gustos, para problemas específicos (especialmente ligados al hardware donde corren), etc. Las RIA's serán un referente muy importante, pues los usuarios agradecerán aplicaciones intuitivas y productivas, capaces de hacer mucho con pocas acciones, fáciles de utilizar, potentes en el tratamiento de los datos y su presentación, y en la productividad que generan, además del tiempo que se gana. No olvidemos también la capacidad multiplataforma: se hará indispensable que el código de un lenguaje de programación se pueda ejecutar en cualquier sistema operativo. El escritorio y el navegador terminarán fusionándose e integrándose como uno sólo, y sus aplicaciones tendrán lo mejor de los dos mundos.

Otra baza decisiva para el éxito de un lenguaje de programación es su apertura y la libertad de uso, sin limitaciones. Poder desarrollar aplicaciones con total libertad, sin limitaciones por licencia o imposiciones, será (y es) un factor decisivo, por costes, por libertades, por promoción de herramientas y aplicaciones igualmente libres, por cultura, por igualdad y por derecho. Una empresa con intereses comerciales y monopolistas, detrás de un lenguaje de programación (o cualquier producto software), aún a pesar de sus largos tentáculos y negocios, verá cómo los programadores que no estén bajo su nómina le darán la espalda, y cómo los clientes adoptarán cada vez más soluciones libres.

La computación en nube tendrá éxito, aunque no creo que tan rápido ni en toda su extensión. Habrá ciertos servicios o aplicaciones en los que el cliente manda por encima de toda la potencia tecnológica, todas las funcionalidades y las capacidades que pueda ofrecer la nube. La privacidad será decisiva, así como tener el control de los datos y de los dispositivos de almacenamiento, amén del coste del servicio versus software tradicional.

Habrá frameworks más sofisticados capaces de desarrollar y desplegar aplicaciones con unos pocos parámetros. Actualmente podemos verlo en Ruby on Rails o en Django, pero esto sólo es el principio. Habrá interfaces (de código y de usuario) que ayuden a los frameworks en estas tareas, y después para ajustes toquemos el mínimo código que sea necesario. Y no sólo para la Web. También veremos frameworks en nube, capaces de integrarse con nuestras aplicaciones locales, remotas o en nube.

También aparecerán entornos de desarrollo (IDE) online o en nube. Serán capaces de generar aplicaciones multipropósito: escritorio, web, nube, para dispositivos móviles, para ordenadores, etc. También permitirán agregar componentes online o en nube. ¿Imagináis crear un programa sin instalar nada en el ordenador, y que las aplicaciones desarrolladas sean accesibles desde cualquier ordenador o dispositivo sin necesidad de compilarlas, ni instalarlas, ni parametrizarlas... todo de forma transparente y natural? ¿Imagináis realizar aplicaciones sin centrase tanto en lo interno, si no más bien en lo externo, como obtener información de un servicio web o de otro programa en nube (en lugar de currarte tú mismo tu sistema de base de datos y mantenerlo)?

Quizá aparezca un nuevo paradigma de programación, basado precisamente en los recursos y servicios en red, o quizá en requisitos y resultados. Quizá aparezcan también lenguajes capaces de autoaprender según la experiencia de los programadores, o analizando los problemas de los aplicativos. O entornos de desarrollo que automáticamente ponderen la forma más eficiente de desarrollar una aplicación, eliminando u optimizando el código, y corrigiendo automáticamente todo tipo de errores. Quizá los lenguajes de programación atiendan las funcionalidades como parámetros de entrada y desarrollen automáticamente el diseño y el código libre de errores más cercano posible (paradigma basado en requisitos y resultados). Quizá los lenguajes de programación aseguren la calidad de las aplicaciones en un porcentaje cercano al 100%, minimizando el tiempo de pruebas y ahorrando tiempos de desarrollo. Quizá la semántica de las aplicaciones y de la Web condicionen también que los lenguajes de programación sean más semánticos o contemplen la semántica.

La evolución de los lenguajes de programación conllevará también una evolución en las metodologías de trabajo, en marcos o en sistemas de trabajo. El dinamismo de la tecnología y de los productos reclaman agilidad, aunque los clientes demandan metodologías predictivas para un mayor control y como arma legal. Las metodologías predictivas y la agilidad son filosofías antónimas, aunque también poseen puntos en los que se puede extraer lo más importante y positivo de cada una, ver dónde se aplican, integran y formen sinergias fortalecidas. Los clientes, las empresas de servicios, consultoras, etc., deben tener la misma visión y entenderla para no cometer los mismos errores una y otra vez. Esta dependencia condicionará también la evolución de la tecnología, de los lenguajes de programación y de los productos y servicios. Posiblemente dejemos de ver los proyectos como lo vemos actualmente, con un tiempo, un coste, una tecnología y un sistema predeterminado desde el principio. Quizá veamos los proyectos como servicios de desarrollo incrementales y dinámicos, con contratos por objetivos, sin dependencias ni fricciones entre cliente y proveedor.

A lo largo de estas reflexiones he ido anotando puntos que ya he empezado a ver, y algunas ideas que se me han ocurrido. No pretendo afirmar nada, pues el futuro llega antes de lo que uno se piensa, y de distinta manera a como uno lo ha imaginado. Ideas se tienen, y no todos por igual. Hay ideas que prosperan y otras que fenecen, al igual que las semillas. Todo depende del escenario y de las circunstancias.