jueves, julio 05, 2018

Web Assembly en julio de 2018

Hay multitud de información sobre Web Assembly y sobre Emscripten en la red pero, por hacer referencia a diferentes versiones, a varios años de tiempo y demás, pueden acabar despistando. En este artítulo intento recopilar información sobre desarrollo práctico con Emscripten para WebAssembly a fecha de julio de 2018.

 Lo primero de todo un repaso de conceptos. WebAssembly surgió como evolución de los experimentos que hubo de pasar código C a Javascript simplificado (asm.js). Con esto tan sencillo ya se lograron algunos éxitos de rendimiento. Se evolucionó el concepto, hacia algo casi "código máquina para la web, multiplataforma). Por fin, en 2017 hubo versiones en todos los navegadores más populares que soportaban este nuevo formato de ejecución.

WebAssembly
WebAssembly

Siempre hubo discusiones respecto a si WebAsembly venía a sustituir Javascript o no. En mi opinión, esta muy bien para labores que supongan mucha CPU o para los que quieran ofuscar su código, pero para intregración con navegador, sus APIs y demás, es mejor seguir con Javascript u otros lenguajes soportados directamente por el navegador de turno (opinión a julio de 2018).

Y aquí aparece Emscripten. Este paquete / framework / producto fue el más famoso que pasaba código de C/C++ a asm.js, y luego ha evolucionado hasta ser el rey en pasar código a WebAssembly.

Emscripten
Emscripten

Y como es un producto que ha estado siempre entre experimental y producción, introduciendo nueva funcionalidad, dependencias,... su documentación y formas de uso han ido cambiando, de ahí uno de los problemas que he visto, que al buscar ayuda por Internet sobre algún error, las soluciones pueden variar mucho, dependiendo de la época del producto que mencionen.

Fase 1 - Instalación de entorno


En su estado, a día de hoy basta con ejecutar los siguientes comandos para tener una instalación de Emscripten totalmente funcional, y activarla:

git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest

En el entorno de Windows tuve problemas para que funcionara correctamente, por lo que al final me generé una imagen Docker:

FROM ubuntu:bionic
MAINTAINER Marcos Perez <alguien@aqui.es>
RUN apt-get update && apt-get install -y git wget python2.7 nodejs cmake default-jre
RUN apt-get install -y python g++
RUN cd opt && git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install latest && ./emsdk activate latest

Fase 2 - Generación de WebAssembly

Originalmente se indicaba en la documentación que, para compilar un proyecto normal C/C++ nativo a el sistema de Emscripten, el procedimiento sería algo como:

cd emsdk
./emsdk activate latest
cd proyecto
./emconfigure ./configure
./emmake make

Sin embargo, hoy en día, en un proyecto normal se podría user directamente "configure" y make, en lugar de los específicos emconfigure y emmake.

Como resultado podríamos tener un fichero .wasm para usar.

Fase 3 - Usar en navegador

Una vez que tenemos el fichero WASM, su uso en un navegador moderno debería ser sencillo.
Un código como este es muy habitual ver en las webs:
fetch('simple.wasm').then(response =>
  response.arrayBuffer()
).then(bytes =>
  WebAssembly.instantiate(bytes, importObject)
).then(results => {
  results.instance.exports.exported_func();
});

Y, de hecho, el concepto es sencillo: cargar el fichero WASM, pasarlo a binario, compilar, instanciar y usar las funciones que vinieran dentro.
Sin embargo, en cuanto no es muy óbvio, esto no es tan sencillo, principalmente por la memoria. Hace falta declarar la memoria que podrá hacer uso el wasm, y luego la que podría ser compartida con Javascript. En el fondo, son multitud de detalles, que podrían depender de implementaciones internas.
Por ello, mi recomendación sería dar un paso atrás (volver a Fase 2), y crear un comando que nos genere el objeto final.

emcc -lmibiblioteca micodigo.c -Os \
-s WASM=1 -s ALLOW_MEMORY_GROWTH=1 \
-s MODULARIZE=1 -s EXPORT_NAME='MIMODULO' \
-s EXPORTED_FUNCTIONS="['_mifuncion1', '_mifuncion2']" -o misalida.js

En este caso, hemos supuesto que tenemos creada una biblioteca de algún otro producto, y luego hemos hecho la interfaz de comunicaciones ad hoc micodigo.c.
Todas las opciones especiales de emscripten va con "-s":
  • WASM=1 para que genere WebAssembly
  • ALLOW_MEMORY_GROWTH=1 para que pueda reservar más memoria según la vaya necesitando
  • MODULARIZE=1 para que se puedan juntar varios módulos, y meter todas sus funciones en su espacio de nombres
  • EXPORT_NAME sería para dar nombre el módulo que generar
  • EXPORTED_FUNCTIONS indica las funciones que se podrán llamar desde Javascript. Importante recalcar que sus nombres serán con la convención de C, y de ahí que añada un "_" al principio del nombre de la función
  • Finalmente el -o misalida.js . De este modo nos generará un misalida.wasm y un misalida.js que se encargará 
Y con esta compilación, su carga y uso en Javascript podrían ser:
importScripts("misalida.js");
console.log("Cargado");
console.log(MIMODULO);

// Modulo WASM
var mimodulo=null;
MIMODULO().then(function(Module) {
    mimodulo=Module;
    mimodulo._mifuncion1();
    console.log("Inicializado");
});

De esta manera, la preparación de la memoria y demás correría a cargo del código javascript que ha preparado antes Emscripten.
Como dicho webassembly hay que compilar, antes hay que esperar a que se prepare todo, y de ahí la importancia de MIMODULO().then(), para así realizar las tareas cuando esté disponible, NO ANTES.

Fase 4 - Comunicación

Llamar a las funciones con parámetros básicos como números o texto es directo, por ejemplo:

var resultado = mimodulo._mifuncion2(4, "mi texto");

Sin embargo, la cosa se complica cuando hay "punteros" de por medio, y es que en este caso el sistema no hace una conversión automática de los parámetros.
Por ejemplo, para acceder a la memoria de wasm, se puede hacer mediante las vistas:
  • HEAP8 memoria compartimentada como 8 bits con signo
  • HEAP32 memoria compartimentada como 32 bits con signo
  • HEAPU32 memoria compartimentada como 32 bits sin signo
  • HEAPF32 memoria compartimentada como punto flotante de 32 bits
Con el método "set" podemos copiar de un Array con tipo en Javascript a una zona de estas vistas de la memoria.
Y para traer datos de WASM a Javascript, sería con métodos "from" y un subarray. Por ejemplo:

var vector = Float32Array.from(
    MiModulo.HEAPF32.subarray(desde>>2, (desde + salida*4) >>2)
);


Importante señalar que, a la hora de indicar los comienzos / fin, hay que modificarlos por los tamaños de lo apuntado. En este caso, lo dividimos entre 4, por ser Punto flotante de 32 bits.

Para ejecutar código Javascript desde dentro del C / C++:

EM_ASM(
    console.log("Pintar salida");
  );

martes, junio 23, 2015

Registros con datos validados de otras bases

Las aplicaciones cada vez están más relacionadas, tienen mas interdependencias, y se requiere cada vez más que nos permitan relacionar información entre sistemas, tanto a nivel de datos como a nivel funcional. Nos vamos a centrar en uno de los casos más sencillos y habituales: datos de nuestra base de datos que estén validados o relacionados con datos cuya gestión depende de otros.

Por ejemplo, en las bases documentales es muy habitual manejar el dato "proveedor" o "cliente", como un simple dato asociado a nuestra documentación, pero que queremos que este bien asociado al mismo proveedor o cliente que lleva el resto de la empresa. Por ejemplo, no se podría dar de alta un contrato, sin haberse dado de alta la empresa como proveedor. Pero dicha creación, ¿cuando se verá en el sistema de los contratos? ¿al momento, al rato, al día siguiente, a la semana siguiente?

Cuando me mudé de casa tuve que dar mis nuevos datos a proveedores, bancos,... y en todos ellos, al final la dirección se introduce en una aplicación. Algo sencillo e inmediato, a priori, se convirtió en toda una lotería, ya que hacia poco que habían asignado el código postal a mi nuevo barrio, con lo que muchos sistemas daban por erróneo el código correcto. Años después sigue pasando.
Código postal de la dirección
Código postal de la dirección

Hoy en día uno puede pensar que, nada mas matricular un coche, ya tiene todos los derechos y deberes por tener dicho vehículo, pero resulta que, dependiendo del tramite, ventanilla, impuesto, privilegio,... puede ser instantáneo, tardar un día o  una semana su regularización. ¿Que pasa si no podemos aparcar en nuestro barrio en la zona de aparcamiento restringido (SER, ORA,...) o porque el sistema no reconoce nuestra matricula para saber lo que nos tiene que cobrar?
Matrícula del coche
Matrícula del coche

Pero este problema no es solo del mundo digital. Se ha agrabado por la confianza y automatización cada vez mayor de las empresas, pero también puede pasar con el papel. Hace varios años, cuando tuve que hacer una transferencia al extranjero, quedé sorprendido al ver que de poco valían los datos que daba en la sucursal. Tuvieron que echar mano de un libro aun mas gordo que el de Petete, para localizar un código SWIFT de la sucursal destino en cuestión. ¿Que pasa con todas las sucursales que se crearan entre actualizaciones de dicho libro?

En el fondo es siempre el mismo problema, queremos tener los datos bien, para lo cual muchos campos los definimos como paramétricos o contra tablas, pero algunos de dichos  datos son cambiables y gestionados por otra aplicación. ¿Como aseguramos una base limpia, y bien relacionada con otros sistemas?
En el fondo, dependiendo del caso, hay 2 soluciones:
 1. En linea: siempre que se introduzca un dato, se lanza una validación contra el sistema gestor original
 2. réplica: se mantiene una copia actualizada de los valores válidos, respecto del sistema gestor original

Diferentes soluciones arquitectónicas
Diferentes soluciones arquitectónicas

Dependiendo del caso de uso o arquitectura, la solución mas adecuada puede ser una u otra.

Bases enlazadas
Un caso muy común es que ambos sistemas de datos estén bien comunicados, ya sea por estar en la misma máquina, mismo CPD, mismas instalaciones o compartir algún otro tipo de infraestructura. En tal caso, si la confianza entre ambos sistemas es alta, así como la relación de negocio es también alta, y se emplea el mismo sistema gestor de base de datos, se puede optar por emplear tablas enlazadas a nivel de Base de Datos.

En Oracle este concepto esta bastante evolucionado, permitiendo, desde un motor de base de datos tratar una tabla que se encuentra en otro motor como si fuera interna. Este DBLink se configura y se accede como si fuera otro espacio de tablas mas. Permitiendo numerosas configuraciones y optimizaciones. El mismo concepto existe para MS SQL Server, DB2, o PostgreSQL.

En MySQL, habría que optar por un concepto algo más general, las tablas federadas. En ese caso, el motor de la base de datos no almacenaría información, sino que haría de mero proxy y TODAS las tablas que mostrara estarían gestionadas por otros motores.

Además, si los motores de base de datos no son iguales, pero hay confianza, todavía se podrían enlazar las tablas a nivel de motor de base de datos. Por ejemplo, para ver desde MS SQL Server tablas de un motor Oracle o DB2 habría que instalar un proveedor de OLEDB de dichas tablas. Desde Oracle se pueden enlazar tablas accesibles mediante ODBC,... y así otras múltiples opciones.

En 2003, se definió una extensión al estándar SQL, SQL/MED, para la gestión de datos externos desde nuestro motor de base de datos. Ya ha sido implementado por varios motores, tanto relacionales como no relacionales.

Pero, aunque se haya decido por esta opción, no esta todo cerrado. Puede que la comunicación o que la tasa de actualizaciones sea muy alta / baja y en tal caso, en lugar de un enlace vivo que continuamente muestra o copia datos, sea mejor realizar una copia de los datos. En este caso, si obviamos las opciones automáticas de caché de los motores, se puede hacer uso de disparadores que, ante cualquier cambio en una tabla enlazada, traerían / enviarían información para actualizar la copia local, la cual sería la accedida por las aplicaciones de esta base.
En este caso, podría ser:
  • push, la iniciativa de copiar un dato es del gestor de la tabla original. Sólo cuando cambie un dato de la tabla, conectará con el / los otros sistemas y les enviará el cambio realizado. Esta opción es muy buena para cuando la tasa de cambios es muy baja y no merece la pena ir preguntando continuamente por las novedades.
  • pull, cada uno de los sistemas que quiere copiar la tabla se conectará al sistema y comprobará si ha habido cambios. Esta opción sólo es apta si la tasa de cambios es alta, con lo que no hay tanto desperdicio en las conexiones. También permite que no haga falta registrarse como usuario de un dato, con lo que es más rápido el despliegue, pero por el contrario, por vagos puede que esta laxitud haga que nuestra base de datos de dependencias de los sistemas en el departamento de informática no esté actualizada.
Consulta periódica
Consulta periódica

Pero no todo es perfecto. Esta solución trae consigo un ALTO ACOPLAMIENTO, ya que cambios en el modelo de datos de un sistema pueden implicar cambios en el otro, el cual puede tener otro ciclo de desarrollo. Se pueden minimizar mediante vistas. También puede complicar los mantenimientos de ambos sistemas.

Disminuyendo acoplamiento
Si la conectividad entre ambos sistemas no es buena por lenta, por seguridad, por fiabilidad,... en dicho caso, la única solución es la RÉPLICA. Sería un caso más general que una tabla enlazada a nivel de motor de base de datos. En este caso, ya sea por un evento o periódicamente, se copiarían total o parcialmente los datos.
Habría que hacer un análisis de, tanto la importancia de una sincronización total como de la frecuencia de cambios en los datos origen. Si los datos cambian mucho, o el total de la tabla es pequeña, se podrían realizar copias limpias completas cada vez. Pero si es muy importante que no se cuele ningún caso en nuestro negocio en el que el dato ya no sea válido, o que no se bloquee una operativa importante porque le falta llegar un dato, la sincronización debería ser inmediata.
Para los demás casos, una sincronización diaria, semanal,... dependiendo del volumen y la importancia de los datos. Que podrá ser diferencial o completa.
Dado que los sistemas no son perfectos, y puede haber labores nocturnas de mantenimiento, imprevistos,... :
  • es aún más importante de lo normal mantener un registro e histórico de los últimos intercambios de valores, ya que entre actualizaciones puede detectarse algún caso de falta / error de valores, y se achaque a la propia sincronización.
  • También resulta muy útil permitir que el sistema sea "repetible", esto es, que se pueda volver a cargar el mismo fichero de sincronización tantas veces como haga falta, obteniendo el mismo resultado, si todo fuera bien. De este modo, en caso de algún error temporal se puede volver a lanzar la operación entera en el Gestor de operaciones repetitivas batch, y también nos sirve para, en caso de que se necesite una sincronización intermedia, que se pueda realizar, y luego que se puedan ejecutar los procesos programados.
Estas réplicas implican a los 2 equipos de mantenimiento de ambos sistemas. Uno para generar los datos de exportación a partir de su sistema origen, y otro para cargar y actualizar los datos de su sistema destino.

Dado que los sistemas cada vez colaboran más entre sí, y hay más campos o funcionalidad relacionada, es lógico que en un departamento de informática se hayan disparado el número de procesos de réplica. Por ello se recomienda, tanto una sencilla, precisa y actualizada gestión de dependencias, como que los procesos sean todos gestionados por un mismo sistema. Hoy en día hay multitud de "programadores" de tareas que podrían realizar esta función.

Nada de copias
Pero puede darse el caso de que los datos cambien mucho, o sean de un gran volumen en origen, pero que no todos acaben afectando a nuestro sistema, y no se puedan discernir a priori. En tal caso, mucho mejor es no copiar ni actualizar nada, sino emplear búsquedas y validaciones.
Consulta y validación en el momento
Por ejemplo, a la hora de editar un documento que tenga un campo validado contra tabla, se permitirá al usuario buscar en la tabla, que la aplicación traducirá en llamadas al sistema "remoto". Una vez introducido el valor, este se debería guardar tanto como "índice" interno (el índice único que permite enlazarlo con el sistema remoto), como el literal que ve el usuario. De este modo, si luego cambiara el literal en el lugar de origen, se seguiría manteniendo la integridad.

Otras consideraciones
Como consideración lateral, hay que tener en cuenta un detalle: ¿Qué hacer si en el sistema origen eliminan un valor que antes era válido?
Si todas las tablas formaran parte de nuestro sistema, para cada posible tipo de valor a borrar, habría una posible gestión, la que más se adecue a nosotros, evitando dejar claves sin enlazar,... Pero resulta que ahora hemos enlazado con datos que gestionan otros sistemas, independientes.
Tratamiento general:
  • Copia de tabla. Es el caso en el que más nos hemos centrado. Este es el caso mejor para cuando se van a reutilizar varias veces los mismos datos. Este tabla pasaría a ser una copia de la original salvo por los borrados que, en nuestra tabla sólo se borrarían si no tuvieran dependencias. Tiene el defecto que podría crecer mucho, y convertirse en un histórico de la tabla original
  • Copia literal de los datos. Si no se van a reutilizar muchos datos, o no se quiere gestionar altas / bajas,... se copia directamente el dato que nos interesa, sin dejar enlazado con datos de otros sistemas.
Hay un caso mas: la posible conversión de datos. Por ejemplo,  cuando se crean nuevos códigos postales, es posible que sean un desglose de alguno anterior. Pudiera hacer falta una conversión de valores antiguos a nuevos. Cada posible caso es un mundo y suele hacer falta involucrar a alguien del equipo externo.


Conclusión
Como hemos podido ver, siendo este un caso sencillo de integración de aplicaciones, el tema debe dar para todo un análisis de las necesidades y relaciones de nuestros usuarios y sistemas. Una mala decisión puede llevar a problemas inesperados, tanto técnicos como de negocio.

martes, junio 09, 2015

ITIL de pasillo o Corridor ITIL

ITIL define una serie de funciones, procedimientos, conceptos, objetivos,... y luego los departamentos de informática y telecomunicaciones lo aplican a su manera, que a su vez cada integrante del equipo lleva a cabo de su muy personal forma.
Ahora que esta tan de moda el ITIL, y a raíz de un conversación del tipo "y si...", descubrimos una modalidad poco documentada: el ITIL de pasillo o Corridor ITIL.
Pasillo amplio
En lugar de emplear las aplicaciones, infraestructura, procedimientos definidos,... se trabaja a base de encontrar a gente por el pasillo, improvisar breves reuniones informales, muy de ir al grano, acordándose fechas de pases a producción, informando de nuevas direcciones y otros datos importantes de forma oral.
Existe una variante, algo más formal, que implica el desplazamiento de uno o varios miembros de un departamento a las dependencias de otro departamento y, allí, a salto de mata, se discute, acuerda, comparte, demuestra,... lo necesario del momento.
En ambos casos, como mucho una de las 2 partes de la reunión es consciente de los temas a tratar en ella, lleva los deberes hechos, y conoce toda la información relevante.
Pero dado que hay que crear las recetas que nos permiten seguir estandarizando nuestros departamentos, aquí van algunas buenas prácticas o sugerencias.
  • empapelar las paredes de los pasillos y cuartos de baño con papel tipo pizarra blanca, y dejar siempre bien visibles y accesibles unos rotuladores de colores. De esta forma, cualquier información relevante y concreta se podrá apuntar en el momento, corregir y volver a ella en cualquier momento. Como beneficio secundario, se deja la información para que fluya entre diferentes departamentos.
  • Salteados por los pasillos, se pueden poner unos corchos con chinchetas y tacos de papeles de colores. De este modo, pedazos de información pueden viajar con nosotros, reproducirse en los tableros de corcho, moverse indicando algún significado,... Aquí aparecería el Kanban Corridor ITIL.
  • Cada cierto tiempo, normalmente entre 1 mes y 1 año, hay que recorrer los pasillos con una videocámara grabando las paredes. Posteriormente se publica dicho vídeo en los sistema de compartición de información del departamento, junto con la fecha. Posteriormente, SE BORRA TODO-TODO. De esta forma, nos aseguramos de ir actualizando la información. Y además, disponemos de un histórico para ver y analizar los cambios.
  • Opcionalmente, los departamentos cuyos pasillos dispongan de cámaras, pueden señalizar dichas cámaras de tal forma que las reuniones de pasillo se realicen cerca de ellas. Al final de cada reunión, se podrá usar como acta de dicha reunión la grabación, que habrá que solicitar al departamento adecuado, y luego publicar en el sistema de compartición de información del departamento.
  • Unos cestos pequeños, con caramelos, ayudarán a evitar problemas de sequedad en la garganta, en especial para aquellos se continuamente estén de reuniones
  • Una webcam colocada en cada lugar estratégico, destino de los paseos, como la impresora, entrada a los baños, entrada a los despachos de jefes,... de tal forma que se pueda ver quien pasa por allí y así salir a la reu-pasillo a tiro hecho.
  • Automatizar que, cuando alguien envía una tarea a imprimir, se indique en una pantalla como posible receptor de reu-pasillo.
Como vemos, con estas sencillas prácticas, se puede seguir haciendo reuniones de pasillo y mejorar las técnicas de comunicación, disminuir los tiempos de reunión, mejorar la comunicación e información entre departamentos,... y todo con un toque muy latino.

miércoles, febrero 11, 2015

Tipos de datos compuestos en Python



Python es un gran lenguaje de programación, que probablemente haya alcanzado la madurez (se dice que en 2015 es el lenguaje más popular), y a todos nos gusta hablar de las últimas novedades, de sus características más maravillosas, implementaciones alternativas,... pero de vez en cuando hay que retomar sus orígenes.


En este caso he recopilado unos videos, a modo de repaso, sobre las características y usos más comunes de los tipos de datos compuestos en Python, esto es, aquellos empleados para agrupar uno o más elementos. Serian:
  • Listas, el equivalente a vectores, array,... O sea, 0 o más elementos ordenados.
  • Tuplas. Sería algo muy similar a listas, pero "inmutables". Esto quiere decir que, una vez creada una tupla, esta no se puede modificar. Muy interesantes a nivel de concurrencia
  • Diccionarios, tablas hash, tablas asociativas,... Tablas cuyo índice es una función a partir de un objeto, y el contenido será otro objeto.













Como habréis podido ver, es sencillo manejar datos agrupados en Python. Espero que esto os sirva a algunos de acicate para introduciros más profundamente en el lenguaje.



viernes, enero 16, 2015

Gestión de fecha y hora en Python

Uno de los puntos débiles en la programación es la gestión de las fechas y las horas. En general, tendemos a creer que, "como nuestra aplicación sólo se va a ejecutar en un mismo ordenador, no habrá problemas por la fecha-hora". Sin embargo, incluso en ese caso más básico, multitud de problemas pueden surgir el día del cambio de hora (por el cambio de / hacia hora de verano).
Además de contolar el calendario Gregoriano, otros conceptos hay que manejar:
  • Las zonas horarias, sus nombres y como afectan a la hora
  • UTC Zona horaria de referencia. Se correspondería con la zona GMT de Reino unido, o de Greenwich
  • DST u hora de verano, que sería la hora modificada en periodo veraniego para que haya más luz a la hora de trabajar. En España se corresponde con adelantar la hora en marzo y volverla a atrasar en octubre.
Biblioteca estándar
La biblioteca estándar de Python viene con diferentes módulos para gestionar fechas y horas aunque, luego veremos, no es tan completa como uno pudiera esperar en algunos aspectos.
La funcionalidad principal esta en los módulos time y datetime.
El módulo time permite manejar la hora "estilo unix", esto es, como un número de segundos desde el 1 de enero de 1970. A partir de ahí, se puede obtener la hora actual, se puede imprimir de forma textual la fecha,...
La hora que maneja es como un número, que puede tener decimales, o la que llama struct_time, que es una tupla de 9 elementos: año, mes (1-12), día, hora, minutos, segundos, día de la semana (0-6 lunes - domingo), día del año, es DST (0 o 1 para indicar no / si, y -1 para indicar modo automático).
Para obtener la hora actual:
  • localtime() --> struct_time
  • time() --> milisegundos desde 1970
Por otro lado, un módulo más usable es datetime. Compuesto por las clases:
  • time para almacenar una hora del día
  • date para manejar fechas
  • datetime maneja el par fecha-hora junto
  • timedelta para indicar una diferencia de tiempo
  • tzinfo es una clase abstracta para manejar zonas horarias, pero que con la biblioteca básica sólo disponemos de la clase correspondiente a horas UTC.
Para obtener la hora local actual, se llama al método estático datetime.now(). Si queremos la hora en UTC, sería con datetime.utcnow(). En ambos casos va sin información de zona horaria. A partir del datetime podemos obtener el objeto time, que solo lleva la hora.
La fecha actual se obtiene como el método estático date.today()

Conversiones

Según la funcionalidad que deseemos conseguir en cada caso, será más interesante usar un tipo u otro, por lo que tendremos que poder convertir formatos de uno a otro.
  • datetime.timetuple() --> struct_time . Para obtener la tupla de 9 dígitos a partir de un objeto datetime
  • estático datetime.fromtimestamp(número) --> datetime . Para obtener un objeto datetime a partir de un número
  • time.mktime(struct_time) --> número . Para pasar de tupla a número
  • static datetime.combine(date, time) --> datetime . Junta la información de una fecha y una hora, para tener un datetime completo
  • datetime.date() --> Obtener sólo la fecha
  • datetime.time() --> Obtener sólo la hora
Conversión a texto
Al final de las manipulaciones de fechas y horas, en muchos casos hay que recibir / mostrar la fecha al usuario, a través de una cadena de texto. Para ello existen las funciones / métodos strftime y strptime. Ambas manejas una cadena de texto que indica el formato en que se espera la fecha-hora.

import datetime
import locale

formato_local = "%x %X"
formato_elaborado = "%Y %B %d %A %I:%M"
ahora = datetime.datetime.now()
#Italiano en Windows. 
locale.setlocale(locale.LC_ALL, "ita")
#Salida: '17/12/2014 13.20.35'
print(ahora.strftime(formato_local))
#Salida: '2014 dicembre 17 mercoledì 01:20'
print(ahora.strftime(formato_elaborado))
#Español en Windows
locale.setlocale(locale.LC_ALL, "esp")
#Español en Linux
locale.setlocale(locale.LC_ALL, "es_ES.UTF-8")
#Salida: '17/12/2014 13:20:35'
print(ahora.strftime(formato_local))
#Salida: '2014 diciembre 17 miércoles 01:20'
print(ahora.strftime(formato_elaborado))

Mediante strftime, tanto del módulo time, como del módulo datatime, se convierte de fecha-hora a texto.
Con strptime se interpreta una cadena de texto que representa una fecha, para obtener la fecha en formato interno, manejable.
Los campos que se pueden interpretar son:
%a Día de la semana abreviado usando localización 
%A Día de la semana usando localización
%b Nombre del mes abreviado, usando localización 
%B Nombre del mes, usando localización 
%c Fecha y hora en la representación que indica la localización
%d Día del mes [01,31].  
%f Microsegundos como número decimal [0,999999], relleno de ceros por la izquierda para mantener longitud constante
%H Hora en formato 24 horas [00,23].  
%I Hora en formato 12 horas [01,12].  
%j Día del año [001,366].  
%m Mes del año [01,12].  
%M Minutos [00,59].  
%p AM / PM en formato localizado
%S Segundos dentro del minuto [00,61].
%U Número de semana del año [00, 53] (suponiendo que el domingo sea el primer día de la semana).
%w Día de la semana como número [0 (Domingo),6].  
%W Número de semana del año [00, 53] (suponiendo que el lunes sea el primer día de la semana).
%x Fecha en formato localizado 
%X Hora en formato localizado
%y Año como 2 cifras (decenas y unidades) [00,99].  
%Y Año con todas sus cifras 
%z Diferencia horaria con UTC en formato +HHMM o -HHMM
%Z Nombre de la zona horaria 
%% Para incluir el carácter '%' literalmente.
Como vemos, hay campos para todo, en formato numérico y textual localizado.
Los formatos textuales localizados emplean utilidades del sistema operativo o de módulo locale correctamente configurado, para manejar la información como se ha configurado para un idioma - lugar.
Por ejemplo, para el formato empleado en el ejemplo anterior,"%Y %B %d %A %I:%M":
  • %Y Año con todas sus cifras. Ej: 2015
  • %B Nombre del mes como texto. Por ejemplo, en España podría ser Enero, en Reino Unido podría ser January
  • %d Día del mes
  • %A Día de la semana, como texto. Por ejemplo, podría ser Domingo o Lunes, y en Reino Unido sería Sunday, Monday.
  • %I:%M  Horas en formato 12 horas y minutos. Luego mostraría cosas como 08:34 , pero no mostraría 15:43, ya que eso sería 24 horas.
Información de zona horaria en Python 2
A partir del módulo time, se puede acceder tanto al nombre de la zona horaria normal, como de la zona horaria durante el horario de verano, así como las diferencias horarias en ambos casos:
import time

#Tupla con el nombre de la zona horaria normal, y en DST
zonas_horarias_locales = time.tzname
print(zonas_horarias_locales)
# 0 / 1 si esta definida zona para DST
hay_zona_DST = time.daylight
print(hay_zona_DST)
#Diferencia horaria con UTC en segundos
dif_UTC = time.timezone
print(dif_UTC)
#Diferencia horaria con UTC en segundos durante DST
dif_UTC_en_DST = time.altzone
print(dif_UTC_en_DST)

Información de zona horaria en Python 3
Igualmente, a partir del módulo time se puede acceder a la información de la zona horaria, pero de forma ligeramente distinta:
import time

#Hora local
hora_local = time.localtime()
print(hora_local)
#Abreviatura de la Zona horaria
zona_horaria = hora_local.tm_zone # Ej: 'CET'
print(zona_horaria)
#Diferencia con hora UTC
dif_horaria = hora_local.tm_gmtoff # Ej: 3600
print(dif_horaria)
if time.daylight!=0:#Esta definido DST
    print(time.altzone)


Aritmética de fechas
En ocasiones hay que sumar un día a una fecha, o sumar unas cuantas horas,... y no es plan llenar nuestro código de sentencias "if" encadenadas. Para ayudarnos podemos usar la clase timedelta que, junto con las operaciones definidas para las clases de datetime, nos permite lograr lo que queremos:

from __future__ import print_function
import datetime

ahora = datetime.date.today()
#Ahora: 2015-01-04
print("Ahora: ", ahora)
delta = datetime.timedelta(days=1)
#delta =  1 day, 0:00:00
print("delta = ", delta)
ahora_mas_1_dia = ahora + delta
#Ahora + delta =  2015-01-05
print("Ahora + delta = ", ahora_mas_1_dia)

En el ejemplo superior, vemos que se puede crear un objeto timedelta con la diferencia de tiempo que queramos emplear (se pueden pasar como parámetros con nombre cosas como días, horas,... ), y luego basta con realizar la suma / resta necesaria, y así tendrá en cuenta cosas como años bisiestos, meses con más o menos días,...

Biblioteca pytz y tzlocal
Zonas horarias
Zonas horarias


Hasta ahora hemos visto como gestionar las fecha-hora con la biblioteca estándar, pero hay 2 bibliotecas extras que nos pueden ayudar mucho para el caso de tener que lidiar con diferentes zonas horarias, pytz y tzlocal:
  • pytz tiene una base de datos con las zonas horarias conocidas. Tanto su nombre, como su comportamiento. Se puede instalar con un simple: pip install pytz
  • tzlocal permite conocer la zona horaria que tiene configurada el sistema local donde se ejecuta la aplicación. Se puede instalar con un: pip install tzlocal
Por un lado, tenemos la zona horaria de referencia, pytz.utc, que nos da un objeto tzinfo, y por otro, a partir de pytz.timezone("nombre estandar zona horaria") se puede obtener un objeto tzinfo sobre la zona horaria indicada.

import pytz
import datetime

zona_UTC = pytz.utc
madrid = pytz.timezone("Europe/Madrid")
eastern = pytz.timezone("US/Eastern")

ahora = datetime.datetime.now()
#Nos da un datetime con tzinfo la zona de Madrid
ahora_madrid = madrid.localize(ahora)
print(ahora_madrid)
#Pero la hora en USA, costa Este
costa_este = ahora_madrid.astimezone(eastern) 
print(costa_este)

#Conocer las zonas horarias para un pais
print(repr(pytz.country_timezones("ES"))) 
#[u'Europe/Madrid', u'Africa/Ceuta', u'Atlantic/Canary']
#Para obtener listado de todas las zonas horarias
print(repr(pytz.all_timezones)) 
#Lista con ['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa' ...


Sin embargo, la gran mejora viene cuando tenemos una hora en un zona horaria, y queremos conocer su equivalente en otra zona horaria.
Si quisiéramos listar todas las zonas horarias, ya sea para que elija el usuario, o para ver las posibilidades, se encuentran en la lista pytz.all_timezones. Pero esta lista es muy grande y dificil de manejar. Para conocer las zonas de un país, se podría preguntar a partir de la función country_timezones. Por ejemplo, para España, daría 3 zonas horarias: Europe/Madrid, Africa/Ceuta, Atlantic/Canary.

Para obtener la zona horaria en que se encuentra el sistema donde se ejecuta la aplicación hay que emplear el módulo tzlocal, con tzlocal.get_localzone().
import pytz
import tzlocal
import datetime

#Para obtener el nombre bueno de la zona local del ordenador
zona_local = tzlocal.get_localzone()
ahora = datetime.datetime.now()
ahora_local = zona_local.localize(ahora)
print(ahora_local)
#Pasar a hora UTC
ahora_UTC = ahora_local.astimezone(pytz.utc)
print(ahora_UTC)

Como hemos visto, no hay razón para no gestionar correctamente las fechas y horas en nuestras aplicaciones usando Python. Es verdad que al principio parece que lo hacen todo más largo y engorroso, pero acompañado de una auto-documentación mínima, puede evitar grandes errores y despistes en el mantenimiento y evolución del software.

domingo, octubre 26, 2014

Informática en el Festival de Sitges 2014


Ha terminado el Festival de cine fantástico de Sitges 2014, y toca analizar lo vivido. Normalmente me centraría en las películas de corte ciencia ficción o similar pero, lamentablemente, todo queda eclipsado por el desastre ocurrido a la hora de la compra de las entradas.



Otros años, la compra de entradas para las películas se realizaba a través de servicios que se dedicaban a ello durante todo el año, incluyendo grandes eventos. Por ejemplo, el año pasado por el de Caixa Cataluña, teleentradas. Tenía sus formas peculiares de localizar los eventos, y de mostrarlos, pero el resultado era aceptable, y los usuarios se podían acostumbrar a ello, incluso a la complicación de recuperar el PDF de las entradas...

Sin embargo, este año han optado por un servicio personalizado, o eso parece:
  1. Cuando quieres entrar, primero te pone en cola, te muestra tiempo estimado para entrar y,... a esperar.
  2. Luego introduces tus credenciales, o las reutiliza si las tiene de anteriores sesiones / fracasos
  3. Entonces, te avisa del tiempo máximo que se te concede para realizar la compra (10 -12 minutos). Y dicho tiempo comienza a bajar inmediatamente
  4. Por más que sigas añadiendo entradas a la cesta, el tiempo sigue bajando inexorablemente. Da igual si cada vez que realizar una operación tarda 3 o hasta 5 minutos en cargar la siguiente página
  5. Cuando queda poco tiempo ( 5 minutos), decides ir a pagar lo que llevas elegido y, para sorpresa, el tiempo sigue bajando. Algo debe ser especialmente doloroso en este paso, que tarda aún más en cargar la página
  6. Volver a la página de espera en cola (paso 1)
Con lo que al final, nos encontramos con un montón de gente que ha estado consumiendo recursos, seleccionando compras, ilusionándose,... para luego que no haya valido para nada, ni para el cliente ni para el vendedor.
Hubo quejas por Twitter, también gente que estaba contenta porque lo habían logrado, y gente de la organización diciendo que estaban hablando con los de la web de ventas.
Por un lado, demuestran que sabían que había riesgo de avalancha el primer día de puesta a la venta de las entradas, pero por otro lado toman unas decisiones cuando menos, discutibles.
Lo de la espera para entrar no sería problema si luego te garantizara un comportamiento aceptable y la seguridad de que podrías completar la operación
En otras web de compras, el contador de tiempo se pone al máximo cada vez que añades un nuevo item al carro.
Y, desde luego, como vendedor, una vez que alguien dice "pagar", debería tener máxima prioridad, ¿o no?

Por si todo este "problema" no fuera suficiente, también la usabilidad fue manifiestamente mejorable. Tanto en esta edición como en anteriores, desde la sección de "entradas" se podía ver información referente a las entradas, precio, tipos,... y un enlace para poderlas comprar. En años anteriores, dicho enlace abría la web de venta de entradas. Sin embargo, este año llevaba a la misma página de Festival, y ¡ya esta! Por más que se mirara, no había forma "obvia" de comprar las entradas.

Resulta que, para comprar las entradas, había que bajar en la página (no se veía a la primera) y, en un cajetín "tipo publicidad" se tenía acceso a la compra y gestión de las entradas.
Si tu negocio depende de acabar vendiendo abonos o entradas, el acceso a dicha sección debería merecerse una página propia y, fácil de llegar a ella desde cualquier lugar.

Otro problema que me encontré fue el manejo de las entradas a la entrada, valga la redundancia, del cine. En teoría sólo valía impreso en PDF, algo arcaico teniendo en cuenta que van con un código único de un único uso, pero había gente que llevaba algo en el móvil y también pasaba, no sin que costara horrores a los que atendían a la entrada que el aparato lo leyera correctamente.
Y algún problema debían de tener dichos lectores de códigos, puesto que no señalaban lo suficientemente bien que una entrada no era válida para la sesión en curso. Casos vi de gente que pasó enseñando entradas para otra sesión por error.

Cine
Volviendo a lo que más nos interesa, el cine, de entre las películas que había en cartel, destacan por su tratamiento futurista Young ones, Automata, Space Station 76 y The last days on Mars.

Young ones destaca por ser un tipo de historia "del oeste", en un futuro relativamente cercano, donde la tecnología es sencilla y esta muy incorporada en el día a día de los ciudadanos.
Los protagonistas, dedicados a llevar mercancías a lugares mal comunicados, emplean para ello un burro.Cuando dicho animal muere, es sustituido por un robot de carga. No habla, no se queja, sin interacción con los humanos, pero va a donde se le indica, y lleva la carga por terrenos complicados.

Young ones - Llevando carga en burro
Young ones - Llevando carga en burro

Young ones - Llevando carga en un robot
Young ones - Llevando carga en un robot

Parece todo muy obvio y natural, pero dicho tipo de máquina es todo un logro. Ya no hablamos de moverse por terrenos asfaltados, ni por escaleras de dimensiones conocidas, sino de moverse por terrenos complicados, donde un humano también lo pasaría mal, mantener el equilibrio, seguir cumpliendo su labor llevando cantidades de peso muy diferentes,...
En la propia película se mencionan sus sensores de distancia con el entorno que lo rodea, pero es que también recibe golpes laterales, empujones, disparos,... y llegado un momento, es capaz de atravesar de motu propio un basto terreno hasta llegar a un punto predeterminado, ante ciertas circunstancias. ¡todo un logro de relación con el ambiente que lo rodea!

Pero aparecen otros avances muy interesantes, como un móvil con una pantalla desplegable, no pareciendo holográfica.
Young ones - móvil con pantalla abanico
Young ones - móvil con pantalla abanico
Ya hay pantallas flexibles como las que han mostrado LG o Samsung pero este modelo mostrado, ¿podría ser una pantalla enrollable? Eso sí que sería flexibilidad y muy delgado. Lo podríamos poner en un posible futuro cercano ;-) y resolvería el problema actual de tener el móvil con la pantalla quebrada y, aún así, en uso.
Otro elemento que aparece, casi sin importanciam es un sistema de motores, sin llegar a ser exoesqueleto, que ayuda a una mujer a moverse, a veces, por un hospital.
Young ones - sistema de soporte al movimiento
Young ones - sistema de soporte al movimiento
Este tipo de sistemas es complejo. ¿Cómo se le indica que se quiere uno mover y nos tiene que ayudar? ¿y cuanto? Sin embargo, se esta avanzando mucho en este terreno, a pesar del fiasco visto en la inauguración del mundial de futbol de Brasil.

Otro elemento que aparece, y que ya es casi una realidad, es un "drone" que lleva carga. Tenemos ejemplos de Amazon o Google.
Young ones - drone de carga autónomo
Young ones - drone de carga autónomo


Space Station 76 sería un ejemplo donde se quiere mostrar tecnología con la falsa apariencia de estilo años 1970. Una mano biónica con aspecto a control de Nintendo, unas pantalla de ordenador con gráficos muy simplificados, robots muy modernos por dentro pero de apariencia de película de serie B años 1950.
Por ejemplo, la pared con los controles de la estación espacial, el ordenador,... parecía la típica zona llena de lucecitas y bips de hace muchos años.

Space station 76 - paneles de control
Space station 76 - paneles de control

Space station 76 - pantalla de ordenador
Space station 76 - pantalla de ordenador
La pantalla de ordenador también recuerda el estilo vectorial de Star Trek la serie original, o de Tron, incluso. Muy sencilla, tanto en composición como en color. Aunque, lo cierto, es que no necesitaría más para ser útil. Muchas veces nos esforzamos los desarrolladores y diseñadores de interfaces en poner más y más componentes en pantalla, más y más llamativos, cuando algo sencillo puede ser tanto o más efectivo.
Otro elemento que aparece mucho en la película son los robots. Se parecen mucho a los de cine de los años 50, pero en tamaño reducido.
Space station 76 - Robot doméstico
Space station 76 - Robot doméstico

Space station 76 - Robót psicólogo
Space station 76 - Robot psicólogo

Unos son robots domésticos para moverse por la "casa", y realizar tareas cotidianas de ésta, llevando cosas, colocando, avisando,... Los otros son una especie de psicólogos, que intentan ayudar a los ciudadanos de la estación con sus problemas psicológicos, aunque en la película las conversaciones son de lo menos útil.
Automata es una película en la que había muchas esperanzas. Presupuesto razonable, elementos de Bladerunner y de Yo robot, un protagonista conocido, un argumento atractivo,... Pero no acaba de cuajar.
Primero, en vez de las 3 reglas de Isaac Asimov, pasan a 2 protocolos, para controlar a los robots:

1er protocolo: un robot no puede herir ninguna forma de vida
1er protocolo: un robot no puede herir ninguna forma de vida

2o protocolo: un robot no puede alterarse a si mismo o a otros
2o protocolo: un robot no puede alterarse a si mismo o a otros
 Y la clave está en este 2º protocolo, ya que significa que ningún robot puede auto-repararse, ni reparar a otro (algo que podría aligerar el trabajo humano), aunque tampoco nadie puede arreglar un robot si no es la fábrica que lo creó.
Enseguida vemos a algún robot que se puede reparar a sí mismo.
Robot auto reparándose
Robot auto reparándose
El leit motif de la película esta en que aparecen robots que se puede reparar a si mismos, lo cual es inadmisible y da auténtico terror a los "expertos" en robots.

En cualquier conversación donde aparecen robots autónomos, o los nuevos coches autónomos, se mencionan las 3 reglas de Isaac Asimov, en experimentos recientes se ponen en duda dichas reglas como: "si 2 personas van a morir si no hacemos nada, ¿a quién salvar? ". Pero esta nueva regla, la de la "no reparación" parece rara. 

Por último, aparece un toque retro. En lugar de comunicarse mediante mensajería instantánea, teléfono, correo electrónico,... varios personajes se comunican entre ellos con algo que parece un fax y, no contentos con ello, el aparato monta un escándalo típico de las impresoras matriciales.

Correo electrónico en papel
Correo electrónico en papel

En resumen, aunque no había muchas películas de ciencia ficción, o futuristas (la ganadora, I origins, ¿entra en esta categoría?), si que había alguna, con un cierto interés. Diferentes formas de integrar la tecnología pero, lo más importante, ya no vista como un elemento principal, sino que se integra suavemente en la forma de vida de los personajes.
Se atisba una tendencia a películas de ciencia ficción de bajo presupuesto, sobre futuros cercanos y con los desafíos personales que puedan surgir de la relación hombre - tecnología. La convivencia con nosotros y que, al aumentar su importancia e interacción, puedan ser responsables / culpables / salvadores de nuestras vidas ;-)

miércoles, agosto 20, 2014

Almacenamiento en casa

Casi sin darnos cuenta, cada vez tenemos más datos importantes, dependiendo cada vez más de ellos. Ya sea música, películas, libros, documentos, fotos... vamos incrementando el número de objetos digitales. Si fueran platos, irían a la cocina, si fueran libro, irían a la estantería, pero, ¿y si es algo digital?

Diferentes tipos de almacenamiento externo (HDD 3.5, HDD 2.5, Flash, SD)
Diferentes tipos de almacenamiento externo (HDD 3.5, HDD 2.5, Flash, SD)

En varias ocasiones he encontrado padres que van a todas partes con un disco duro portátil, donde acumulan las películas o series para entretener a sus hijos. Hay "Informáticos" con una unidad USB Flash siempre encima, ya sea con utilidades "por-si", sistemas operativos de rescate, o para actuar anónimamente en Internet... ¿Cuantas veces me han enseñado fotos en un móvil o tableta? Pero se quejan de lo difícil que es llevarlas a otro dispositivo, si no es a través de la red, la nube, o algún otro tipo de intermediario.
Diferentes tamaños de discos duros
Diferentes tamaños de discos duros
Asimismo, casi sin darnos cuenta, las disqueteras han desaparecido de nuestros ordenadores y cada vez se ven menos lectoras y grabadoras de CD, DVD o similar. Además, muchos de nosotros hemos desarrollado una suerte de síndrome de Diógenes que hace que vayamos almacenando información sin parar, con la excusa de que puede que algún día nos pudiera servir.




     
  
Televisor con puerto USB para reproducir contenidos multimedia
Televisor con puerto USB para reproducir contenidos multimedia

Por lo tanto, cada vez somos más digitales, y nuestra dependencia es mayor. Lo que ha disparado varios órdenes de magnitud el problema ha sido la acumulación de fotos y vídeos propios o ajenos. Como alternativa, algunos mencionarían la tantas veces referenciada "nube", donde se pueden guardar algunos o todos nuestros recursos, de forma única o como copia de respaldo. Sin embargo la mayoría de servicios de almacenamiento no serian muy fiables, ya antes de las revelaciones de "Mártir Snowden". Dropbox se sabe que esta completamente comprometido. Quizás Spiderbox pudiera ser considerado todavía seguro. Y es que no solo hay vídeos o recetas que guardar, ¿donde almacenaríamos con seguridad nuestro certificado SERES para la declaración de la renta? ¿y alguna carta personal y comprometida? ¿y alguna foto personal?
Otro argumento extra a favor de la nube es el tener disponibles y sincronizados nuestros datos en nuestro cada vez mayor número de dispositivos digitales, ordenador, portátil , tableta, móvil, ordenador del trabajo, reproductor multimedia,...
Pero, ¿siempre dispondremos de conexión? ¿nos cabrán los datos que necesitamos para una ocasión en nuestro dispositivo? Para estas eventualidades prefiero la sincronización al acceso online de los datos, y así tener siempre disponibles mis contenidos, así como poder controlar la cantidad de disco / memoria interna que necesitaré.

Como alternativa a los discos USB se encuentran los discos en red. Ya sea por wi-fi o por red, permiten acceder a nuestros datos desde cualquier dispositivo conectado en casa. Una posibilidad más evolucionada sería disponer de una solución de almacenamiento NAS que, además de darnos almacenamiento en red, nos da posibilidades de gestión y computación, controlando así diferentes niveles de acceso, con diferentes protocolos y valor añadido con aplicaciones instalables como gestor de feeds propios (fuentes de noticias), descargas largas en diferido, e incluso una nube propia disponible con productos como Bittorrent sync.
NAS grande, para oficinas
NAS grande, para oficinas


Para la importancia que han ido adquiriendo los objetos o assets digitales en nuestra vida, parece como si les fuéramos dando solución temporal o a mata-caballo. Habría que pensar más globalmente para dar una verdadera respuesta a nuestros diferentes problemas.

Mi sugerencia sería pensar un poco a más largo plazo las necesidades de almacenamiento y disponibilidad para evitar acabar teniendo decenas de unidades USB, o que no nos quepa un mínimo de ¿fotos?, ¿vídeos?, ¿música? en nuestro móvil, por lo que yo veo imprescindible que disponga de ranura para tarjetas de memoria, por mucho que a google le fastidie.

martes, abril 01, 2014

Consumidores de contenidos digitales

Con el paso del tiempo, casi sin darnos cuenta, hemos pasado de tener cintas, discos, libros, DVDs,... a tener libros en el lector de libros electrónicos, a escuchar música digital en reproductores minúsculos o en el móvil, a ver películas desde un reproductor multimedia,... Pero, eso que hemos comprado, ¿es tan nuestro como cuando era en papel, plástico o metálico?

La respuesta es "NO", pero, ¿nos importa? ¿es relevante? ¿y el precio esta justificado? ¿somos conscientes de ello? ¿Hay alternativa?

Serie en Versión Original con subtítulos de fans - Nodame Cantabile
Serie en Versión Original con subtítulos de fans - Nodame Cantabile

Partiendo de la base de que todo el mundo tiene derecho a una remuneración por su trabajo, y de que si alguien quiere hacer uso del trabajo de otro al menos debería preguntar lo que quiere a cambio, se esta llegando a un sistema perverso, donde cada vez el autor obtiene menor recompensa por su esfuerzo, y el usuario o cliente tiene menos derechos sobre lo que ha comprado.

Ya desde hace muchos años las distribuidoras intentaron incluir algún sistema para evitar copias ilegales de sus contenidos. Desde el ridículo anacronismo de limitar por zonas los DVDs hasta la instalación de rootkits en ordenadores para evitar el acceso fraudulento a los contenidos de un CD, hemos pasado a sistemas cada vez más perversos.

Una vez lanzado el Kindle por parte de Amazon, y con la tienda de libros digitales totalmente funcionando, en 2009 se dio la paradoja de que Amazon perdió los derechos del libro 1984. En lugar de sólo dejar de venderlo, fue capaz de lanzar la orden de eliminar dicho libro de los kindles que ya lo tenían comprado y descargado. ¿No tenían los usuarios comprado el libro? ¿hubiera podido pasar lo mismo si fueran libros de papel?
A mediados de 2013 una web, JManga, que vendía tebeos en formato digital, avisó que cerraría. Como los tebeos tienen algún tipo de control de derechos, indicaron que la gente se quedaba sin poder seguir disfrutando de sus comics. ¿Pero no eran comprados?
Reproductor abierto, de formatos conocidos, y contenido abierto
Reproductor abierto, de formatos conocidos, y contenido abierto

Volviendo a Amazon (son de los mayores vendedores de contenidos digitales en la tierra, por lo que sus sucesos son muy conocidos), justo antes de las navidades  de 2013 dejaron de vender el acceso por streaming a algunas películas de Disney. El motivo fue que Disney quería poder vender dichos contenidos a través de sus canales durante las navidades, por lo que decidió revocar parcialmente el contrato que tenía con Amazon (cosa que parece ser que sí podía, según su contrato). El problema es que también dejaron sin poder ver dichas películas a gente que ya las tenía compradas de antes. De nuevo intereses corporativos se imponen sobre derechos y deberes de las partes.

Ya en 2014 nos encontramos con el anuncio de Adobe, de que cambiarían a mediados de año el sistema de DRM suyo, y que obligaban a todos los que usaban el sistema actual a cambiar de versión, dejando inusables multitud de dispositivos, y muchos contenidos comprados legalmente. ¿pero no eran comprados? ¿y eso no significa para siempre? Por suerte, parece que, al menos temporalmente, Adobe ha dado marcha atrás.
Audio editable
Audio editable
Y así podríamos seguir con multitud de casos que se han ido dando.
En el mundo del vídeo bajo demanda, el rey ha sido, en general, Flash, ya que permitía algún tipo de control sobre el reproductor, y así controlar toda la cadena involucrada en la reproducción del vídeo. En 2013 se generó una enorme controversia ya que la W3C aprobaba la especificación EME, una API que permitiría conectar un objeto binario, no multiplataforma, con unos contenidos recogidos a través de HTML. El propio Tim Berners-Lee salió a dar su opinión. En el mejor de los casos se considera el menos de los males.
No todo son malas noticias. Recientemente Steam ha anunciado la posibilidad de prestar un juego, temporalmente, a otra persona.
Las restricciones en cuanto a zonas o países están a la orden del día, ocurriendo que un mismo proveedor no ofrezca los mismos contenidos en EE.UU. que en España. Se persiguen webs que almacenan subtítulos de series o películas, pero luego no les duelen prendas en emplear dichos subtítulos como propios (¿verdad que si HBO?).
En cualquier caso, lo que vemos es que nos quieren seguir cobrando lo mismo o más por menos derechos sobre los contenidos.
Pero cada surgen lugares donde los contenidos van sin DRM. Un ejemplo es iTunes, de Apple, que originalmente incluía DRM en sus canciones, para luego retirarlo. También hace poco ha surgido la noticia de una nueva tienda de libros digitales en España, que no tendrá DRM, Lektu. Y no cualquier libro, sino que incluirían la saga de Juego de Tronos, por ejemplo.

¿Cual podría ser mi modelo?
Para empezar un "único" repositorio central con TODOS los contenidos que pudiera haber disponibles en todos los territorios por igual. Y sobre ello, diferentes comercializadoras, que venderían unos paquetes de acceso a dichos contenidos. Los aficionados tendrían derecho a hacer y poner disponibles, en dicha plataforma o por otros medios, cualquier obra derivada que facilite el acceso, disfrute y comprensión de dichos contenidos. Por ultimo, TODOS los contenidos irían sin DRM de ningún tipo. Hoy en día hay tecnologías que permiten añadir marcas de agua "invisibles", ligadas a la persona que este viendo / oyendo / leyendo de tal forma que, si se encontrara algún contenido, siempre se pudiera saber de donde salió (algo así ya se usó en los Oscar de 2013).
Arquitectura de proveedor de contenidos digitales abierta
Arquitectura de proveedor de contenidos digitales abierta

De esta forma, el acceso a los contenidos se trataría como un servicio y no como una venta. Ya la gente no graba en DVD sus películas, sino que las tiene en un disco duro, o en la "nube".
De este modo todo el mundo tendría claro lo que podría hacer con lo que "tiene", y los proveedores podrían y tendrían que competir en un mercado global. Por supuesto, minimizando las ventanas de exclusividad de contenidos.

De todas formas, no hay que perder de vista el otro extremo de la cadena, los autores, intérpretes o creadores en general. En España y muchos otros países están representados a nivel general por las sociedades de autores, para poder entrar en negociaciones de mayor nivel, o generales. La más famosa en España es la SGAE. Se han probado varios modelos, pero no parece que hayan contentado a nadie. Desde el famoso canon a CDs, DVDs y demás soportes, hasta intentos de tasar las conexiones a internet e, incluso, dar un dinero procedente de todos los españoles. Lamentablemente todos estos sistemas tienen el problema de ningunear a otras asociaciones y a los autores pequeños, por lo que siguen sin ser válidos.

Para concluir hay que resaltar que yendo a modelos tipo servicio, ¿estamos renunciando a la propiedad? ¿y al disfrute de contenidos sin conectividad? No debería ser así, gracias a la confianza, concienciación, precios razonables,... Siempre tiene que haber algún medio que permita la posesión para "siempre" y sin necesidad de estar conectado de un contenido, y además, que no haga faltatenerlo en soporte físico. ¿quizás algo de firma digital?
Supongo que a esta y otras cuestiones el tiempo y la ingeniería darán solución, pero que quede claro, que este tipo de problemas solo acaban de empezar y que ya se han dado en cosas físicas como la tinta de las impresoras o las capsulas de las cafeteras monodosis pero, ¿qué pasara con los diseños para impresoras 3D?