VISITAS:

miércoles, 28 de julio de 2021

Flutter: autenticarse en Google

Requisitos

  • Flutter instalado
  • Android Studio con plugin para Flutter
  • Tener una cuenta de Google

Pasos

  1. Crear proyecto Firebase
  2. Crear aplicación Flutter
  3. Añadir aplicación Android a proyecto Firebase
  4. Añadir aplicación iOS a proyecto Firebase
  5. Añadir las dependencias al proyecto Flutter
  6. Habilitar autenticación de Google en Firebase 
  7. Integrar la autenticación en la aplicación Flutter

Crear proyecto Firebase

Entrar en la consola de Firebase (es necesaria una cuenta de Google):

Pulsar en Agregar proyecto:



En el nombre del proyecto poner, por ejemplo: "FlutterDemo" y después, pulsar en continuar



En el siguiente paso podemos habilitar o desabilitar Google Analytics (no es importante para este ejemplo). Pulsar en Continuar:


Seleccionar la cuenta por defecto para Google Analytics y pulsar en Crear proyecto


Tras unos segundos se crea el proyecto Firebase:



Pulsar en Continuar:


Aparecerá la pantalla principal del proyecto Firebase:


El siguiente paso es crear el proyecto Flutter.

Crear aplicación Flutter

Abrir Android Studio y crear un proyecto Fltutter:


O bien, si ya tenemos abierto Android Studio:




Elegir Flutter App y pulsar Next (comprobar que el directorio del SDK de Flutter es correcto):



Rellenar el nombre del proyecto, directorio, organización y pulsar Finish:



Tras unos segundos, se crea el proyecto Flutter y se abre en Android Studio.



Opcionalmente, podemos ejecutar el proyecto qe hemos creado en el simulador para comprobar que todo está bien:



Ahora tenemos que añadir las aplicaciones Android e iOS al proyecto Firebase. El proceso es diferente para cada sistema operativo.

Añadir aplicación Android al proyecto Firebase

En Android Studio, abrir el fichero <project>/android/app/build.gradle y buscar la cadena "applicationId":


El identificador de la aplicación, com.joseanquiles.google_signin, identifica unívocamente a la aplicación.
En la consola de Firebase, registrar una aplicación Android:


Poner el id de la aplicación, un sobrenombre cualquiera, opcional y pulsar en "Registrar app":


Descargar el fichero google-services.json pulsando el botón:


Copiar el fichero google-services.json al directorio <project>/android/app

En Android Studio abrir el fichero <project>/android/app/build.gradle y buscar la cadena "apply plugin". Añadir la siguiente línea:

apply plugin: 'com.google.gms.google-services'


En Android Studio abrir el fichero <project>/android/build.gradle (NOTA: es distinto del fichero anterior). Añadir la siguiente línea en la sección de dependencias:

classpath 'com.google.gms:google-services:4.3.8'

NOTA: Buscar la versión exacta actualmente en: https://developers.google.com/android/guides/google-services-plugin



Pulsar "Siguiente", de nuevo "Siguiente" y por último, pulsar en "Ir a la consola"

Y con esto, ya tenemos configurada la aplicación Android en el proyecto Firebase.

A continuación haremos el proceso similar para iOS.

Añadir aplicación iOS al proyecto Firebase

Abrir XCode y abrir el proyecto de nuestra aplicación:


Navegar hasta la carpeta ios de nuestro proyecto, seleccionar el fichero Runner.xcodeproj y pulsar Open:


Seleccionar Runner (raíz del árbol de la izquierda), pestaña General y copiar el "Bundle Identifier":


En la consola de Firebase registrar una aplicación iOS.
Pulsar en "Agregar app":


Seleccionar iOS:


Rellenar el id de la aplicación que hemos copiado en XCode, un sobrenombre opcional y pulsar en "Registrar app":


Descargar el fichero GoogleService-Info.plist:


Copiar el fichero descargado a <project>/ios/Runner

Pulsar "Siguiente", "Siguiente", "Siguiente" y "Ir a la consola".


Añadir las dependencias al proyecto Flutter


En Android Studio abrir el fichero <project>/pubspec.yaml y añadir las siguientes dependencias:

firebase_core: ^1.4.0
firebase_auth: ^3.0.1
cloud_firestore: ^2.4.0

NOTA: Buscar la versión exacta actualmente en: https://firebase.flutter.dev/

 

Pulsar en "Pub get" para descargar las dependencias:



Habilitar autenticación de Google en el proyecto Firebase

Ir a la consola de Firebase y entrar en Autenticación:



Pestaña Sign in method:


Pulsar en Google y habilitar. Introducir el correo electrónico de mantenimiento:



Pulsar en Guardar y luego en Listo:


La autenticación por Google aprecerá ahora habilitada:


La aplicación de Android necesita una huella SHA-1 que hemos dejado vacía anteriormente. Abrimos un terminal, vamos al directorio del proyecto Flutter y ejecutamos los siguientes comandos:

cd google_signin
cd android
./gradlew signingReport


La primera vez instala algunas cosas y puede tardar. Nos interesa el resultado final SHA-1:


Copiamos esta cadena tal cual y nos vamos a la consola del proyecto Firebase.




Buscamos la aplicación Android y pulsamos "Agregar huella digital":


Pegamos la huella digital y pulsamos "Guardar":


En la misma pantalla, descargamos el fichero google-services.json y lo copiamos al directorio <project>y /android/app sobreescribiendo el anterior:








martes, 29 de junio de 2021

El Input Manager de Unity

El Input Manager es el sistema que tenía Unity hasta ahora gestionar la entrada desde diversos dispositivos: teclado, touch, ratón, joystick...

En 2021 Unity ha introducido un nuevo sistema: el Input System, más versátil, soporta nuevos dispositivos, soporta entrada multi-usuario y es más configurable. Sin embargo, el nuevo Input System es más complejo de usar debido fundamentalmente a su versatilidad, y por eso, el Input Manager se sigue y se seguirá usando mucho tiempo como gestor de dispositovs de entrada en Unity.

En este post revisaremos el antiguo Input Manager de Unity, porque creo que en una gran parte de juegos no es necesaria la versatilidad del nuevo Input System.

Cómo maneja Unity la entrada

La pregunta es ¿necesitamos realmente un sistema para gestionar la entrada en Unity? Al fin y al cabo, es posible escuchar y detectar eventos de entrada directamente utilizando la clase Input:

void Update() {
    if (Input.GetKeyDown(KeyCode.Space)) {
         // spacebar pressed
    }
    if (Input.GetMouseButtonDown(0)) {
        // left mouse button pressed
    }
}

Este método funciona correctamente.
El problema es que si queremos cambiar la tecla espacio por otra tecla o bien por un botón del joystick, entonces tendríamos que cambiar todos los scripts donde se utilice esta entrada.
La solución es utilizar un sistema de entrada modular: la entrada que dispara una acción se separa del script que la procesa. De esta forma, se definen acciones, las cuales se asocian a diversas entradas (teclado, ratón, joystick...), y los scripts utilizan estas acciones para manejar el juego. Así, el script, en lugar de mirar una tecla concreta, mira una acción (en otro sitio, la acción se asocia a una o más entradas). Las acciones son algo como: "Fire", "Horizontal", etc
De esta forma, es fácil cambiar o añadir los mecanismos de entrada sin tocar los scripts, ya que basta con cambiar las asociaciones que tiene una acción.



El Input Manager de Unity

El Input Manager es un sistema de gestión de entradas modular. Consta de dos partes:
  • Input Manager
  • Input Class
La clase Input es la que utilizan los scripts para recoger la entrada: Input
El Input Manager es la ventana de settings de Unity (Edit -> Project settings) donde se asignan botones, teclas y movimientos (los dispositivos reales) a las entradas virtuales (acciones que utilizan los scripts)

Cómo recibir entradas en un script

Los scripts pueden "escuchar" las acciones utilizando los métodos de la clase Input.
Imaginemos un script que permite "disparar" cuando el jugados pulsa la tecla espacio. La forma directa de implementarlo (sin Input Manager) es:

void Update() {
    if (Input.GetKeyDown(KeyCode.Space)) {
        // disparar
    }
}

Esto funciona, pero como hemos visto, tiene algunos inconvenientes.

Con el Input Manager podemos utilizar una acción ya existente, por ejemplo "Fire1" (también podemos crear nuevas acciones), y la asociamos a la tecla de espacio. En el script escucharemos la acción "Fire1".

  1. Abrimos Project settings > Input Manager: Aquí tenemos todas las acciones predefinidas: "Horizontal", "Vertical", "Fire1", etc. Podemos añadir nuevas acciones cambiando el Size.
  2. Abrimos la acción "Fire1"
  3. Cambiamos el Input Type: Key or Mouse Button
  4. Cambiamos Positive button a space. Para ver otras posibilidades: Documentación del Input Manager




Ahora, después de configurar el Input Manager, ya podemos escribr un script que escuche eventos de tipo "Fire1" con la clase Input:

void Update() {
    if (Input.GetButtonDown("Fire1")) {
        // disparar
    }
}

NOTA: Usamos GetButtonDown que retorna true en el primer frame que se haya pulsado la tecla espacio (pero no en los demás frames). Sin embargo, GetButton devuelve true en todos los frames que se mantiene la tecla pulsada.

Usando el Input Manager es fácil cambiar la entrada física asociada a una acción sin tener que tocar los scripts que usan esta entrada. Además, también se pueden añadir otras entradas físicas asociadas a la misma acción, soportando así múltiples controles para la misma acción (y sin tener que tocar los scripts).

Múltiples entradas asociadas a la misma acción

Como hemos dicho, se pueden asociar varios dispositivos de entrada a una misma acción del Input Manager. Por ejemplo, "Fire1" tiene asociada la tecla espacio, pero podemos hacer que se dispare "Fire1" por ejemplo al pulsar el botón izquierdo del ratón.
Tenemos que crear una nueva acción. Para esto, cambiamos el Size sumando uno más al Size actual. Abajo aparecerá una acción nueva que tenemos que rellenar. El campo más importante que hay que rellenar es Name, donde pondremos "Fire1", o sea, el mismo nombre que tiene la acción que estamos tratando. Los demás datos son los que definen la entrada física. De esta forma, tenemos una acción "Fire1" asociada a dos entradas físicas distintas.

NOTA: Hay otra posibilidad para que una acción esté asociada a dos entradas físicas distintas: Alt Positive Button. En este campo podemos poner otra entrada distinta que se asociará la acción. Utilizar este campo Alt no es muy correcto y Unity recomienda utilizar estos campos para botones secundarios de un mismo dispositivo.

Uso de Axis en el Input Manager

Hasta ahora hemos visto dispositivos de entrada de tipo On/Off, o sea, que están activados o no. Pero el Input Manager también maneja dispositivos tipo Axis, los cuales nos dan un valor entre -1 y +1. El valor de reposo es 0.
Los dispositivos de tipo Axis se tratan igual que los de tipo On/Off en un script, excepto que el valor retornado está en [-1 .. +1]

void Update() {
    arriba = Input.GetAxis("Vertical")
    giro = Input.GetAxis("Horizontal")
}

En realidad, los dispositivos tipo On/Off retornan también un valor entre 0 y +1, igual que los Axis, pero en este caso normalmente sólo nos interesa chequear si está en reposo (valor 0) o no (valor mayor que 0).



domingo, 18 de octubre de 2020

CONDA: entorno para trabajar con Python y machine learning

Python es el lenguaje más usado para machine learning y también para deep learning. Hay algunas iniciativas para promocionar el lenguaje Go (golang) para machine learning. Mi opinión es que a día de hoy, las librerías más avanzadas para “x learning” están en python, y aunque creo que el futuro puede derivar a Go, actualmente es python el lenguaje dominante.

Sin embargo, la instalación típica de Python tiene un problema cuando se quiere trabajar con librerías para machine learning, ya que el comando pip para instalar librerías no maneja correctamente algunas dependencias que están escritas en C o en Fortran. Librerías como numpy, scikit-learn, Tensorflow o Keras pueden dar problemas.

La solución está en CONDA, una distribución de Python preparada específicamente para trabajar con data science y machine learning. CONDA se puede instalar de dos formas:

- Anaconda: es una distribución que incluye un gran número de librerías preinstaladas y que permite trabajar directamente sin necesidad de instalar nada más. Ocupa unos cuantos gigas.

- Miniconda: es una distribución básica que permite instalar fácilmente cualquier librería python (incluidas las que están en C o Fortran). Ocupa mucho menos que Anaconda y es igual de funcional, aunque tendremos que instalar manualmente las librerías que necesitemos.

Instalación de miniconda

Mi elección es miniconda, que incluye el intérprete python, unas cuantas librerías básicas y un gestor de paquetes. Miniconda se descarga de:

http://conda.pydata.org/miniconda.html

Dispone de instaladores para Windows, OSX y Linux.

Después de la instalación, tendremos un directorio miniconda3 en nuestro directorio HOME. Es conveniente añadir a la variable PATH el directorio bin de miniconda, para utilizar más fácilmente los comandos.

Para comprobar que conda se ha instalado correctamente:

$ conda  --version

Para actualizar a la última versión de conda:

$ conda update conda

Entornos conda

En entorno en conda es muy similar a los virtual environments de python. En pocas palabras se trata de crear una instalación con una versión concreta de python y con unas librerías instaladas. De esta forma, ejecutando nuestro programa python en ese entorno, podemos asegurar que la versión de python es la adecuada y que disponemos de las librerías necesarias.
Crear un entorno:

$ conda create -n <env_name> python=3.7

Este entorno se crea en el directorio:

$HOME/miniconda3/envs/env_name

Activar y desactivar un entorno:

$ conda activate <env_name>
$ conda deactivate <env_name>

Mostrar todos los entornos disponibles:

$ conda info --envs

Mostrar todos los packages (librerías) instalados en un entorno:

$ conda list -n <env_name>

Instalar packages en un entorno (junto con sus dependencias):

$ conda install [-n <env_name>] numpy

Actualizar packages:

$ conda update [-n <env_name>] numpy

Eliminar packages de un entorno:

$ conda remove [-n <env_name>] numpy

Eliminar completamente un entorno:

$ conda remove -n <env_name> --all

Replicar entornos

Una utilidad de los entornos es poder replicarlos, por ejemplo cuando se incorpora un nuevo desarrollador a un equipo, queremos que utilice la misma versión de python y las mismas versiones de las librerías que se utilizan en un proyecto. Y por supuesto, también es muy importante al desplegar en los distintos entornos: integración, certificación y producción. Siempre nos va a interesar mantener las mismas versiones con las que se ha desarrollado un programa python.

Para exportar un entorno:

$ conda activate <source_env>
$ conda list -e > requirements.txt

Para crear un entorno a partir de otro:

$ conda create -n <target_env> --file requirements.txt

También se puede hacer utilizando yaml:

$ conda env export -n <source_env> > environment.yml
$ conda env create --file environment.yml









jueves, 21 de febrero de 2019

React (1)

Después de mucho tiempo intentándolo, voy a empezar a publicar una serie de artículos sobre React.
¿Qué es React? Como dicen en su propia web: React es una librería Javascript para construir interfaces de usuario. Es una librería javascript y se utiliza para escribir código de cliente, no de servidor. Sirve para implementar la interfaz de usuario y está orientada a componentes. Los componentes son "piezas" de código auto-contenidas, parametrizables y reutilizables.
Sus principales características son:
  • Lenguaje declarativo (no programático) para construir la UI
  • Basado en componentes (reutilizables)
  • Independiente de la plataforma (web, mobile...)
Así a priori, parecen unas características muy prometedoras para nosotros, los desarrolladores. Y efectivamente, así es, aunque la realidad es un poco más gris que lo prometido.
En estos artículos voy a intentar mostrar React desde un punto de vista absolutamente práctico y para desarrolladores. No quiero contar lo mismo que hacen cientos de tutoriales y manuales sobre React. Me gustaría contar las cosas de forma que un desarrollador con cierta experiencia en web pueda aprender React lo más rápidamente posible.
Por otro lado, quiero aclarar que aunque React no está "atado" a ninguna plataforma, en estos artículos me voy a centrar en la web. Existen librerías como React native, basadas en React que permiten desarrollar para plataformas móviles.
Empezamos con el clásico Hello world para ir abriendo boca...

Hello world of React!

En principio, para empezar a desarrollar y aprender con React, no es necesario instalar nada. Aunque más adelante veremos que es conveniente instalar algunas sencillas herramientas, sobre todo para el despliegue de la aplicación.
Vamos a hacer una pequeña página HTML con React.
En primer lugar nos descargamos tres ficheros javascript que incluiremos en nuestra página HTML:
  • react.js : librería react
  • react-dom.js : librería react para acceso a DOM
  • babel.js : transforma JSX (que ya veremos más adelante) en javascript que entiende el navegador
NOTA: Estos enlaces nos muestran el contenido del fichero javascript, por tanto habrá que seleccionar todo el código y hacer copy/paste a un fichero react.js, react-dom.js o babel.js

En segundo lugar, copiamos estos tres ficheros en el directorio donde vayamos a poner nuestra página HTML.
Y por último vamos con nuestro ejemplo.

HTML

Creamos una página html con el siguiente contenido:

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 <title>Hello world of React!</title>
</head>
<body>
 <div id="app"></div>
 <script type="text/javascript" src="react.js"></script>
 <script type="text/javascript" src="react-dom.js"></script>
 <script type="text/javascript" src="babel.js"></script>
 <script type="text/babel" src="./app.js">
 </script>
</body>
</html>

Javascript

Y ahora creamos un fichero javascript denominado app.js en el mismo directorio de la página html y con el siguiente contenido:


var template = <div><h1>Hello world of React!</h1><p>This is JSX</p></div>
var appElement = document.getElementById('app');
ReactDOM.render(template, appElement);

Ejecutamos

Es importante abrir el fichero html con Firefox, no con Chrome. Y no porque Chrome no sea compatible con React (no entremos en modo pánico tan al principio), sino porque al abrir un fichero en local, no descargado de un servidor http, Chrome da algunos errores de seguridad con los ficheros js que hemos descargado. Ya digo que esto no es un problema, porque en un caso real la aplicación React vendrá descargada por http.

Cómo instalar un sencillo web server para nuestros ejemplos

Si a pesar de todo queremos que nuestra aplicación se descargue mediante http y además queremos visualizarla con Chrome, voy a proponer una solución muy sencilla (hay otras muchas soluciones).
En primer lugar instalamos nodejs (si no lo tenemos ya instalado): nodejs
Abrimos una consola en el directorio que estamos trabajando y ejecutamos el siguiente comando para instalar live-server (un servidor http basado en node):
npm install -g live-server
Ejecutamos el servidor:
live-server
Se abrirá el navegador por defecto y mostrará todos los ficheros. Pulsamos sobre la página html y podremos ver nuestra página React en acción!



miércoles, 13 de junio de 2018

HTTPS explicado con palomas


Cualquier comunicación en internet (leer un artículo, comprar en amazon, subir fotos, etc) implica enviar y recibir mensajes a y desde un servidor.
Imaginemos que estos mensajes son entregados por palomas. Y en lugar de hablar de clientes, servidores y hackers, hablaremos de Alice (cliente), Bob (servidor) y Mallory (hacker).

Comunicación básica

Si Alice quiere enviar un mensaje a Bob, pone el mensaje en la pata de la paloma y lo envía a Bob. La paloma llega a Bob y éste lee el mensaje. Todo es OK
Pero, ¿qué ocurre si Mallory intercepta la paloma de Alice en vuelo y cambia el mensaje? Bob no tiene forma de descubrir que el mensaje que ha recibido es el original o si ha sido modificado durante el vuelo. Tampoco tiene forma de saber si alguien ha podido leer este mensaje durante el trayecto.
Así trabaja HTTP. Como se puede intuir, es bastante peligroso. No es muy adecuado para enviar los datos de una cuenta bancaria por este mecanismo, por ejemplo.

Código secreto

Pero Alice y Bob son muy astutos. Ellos acuerdan que enviarán sus mensajes utilizando un código secreto: desplazarán cada letra 3 posiciones a la izquierda en el alfabeto (por ejemplo, D -- A, E -- B, .. B -- X, A -- Z). Así ,el texto "mensaje secreto", quedaría como "jbkpxgb pbzobql".
Ahora, si Mallory intercepta a la paloma, no será capaz de cambiar el mensaje por algo que tenga sentido, ya que Mallory no conoce el código secreto. Tampoco Mallory será capaz de leer el mensaje, porque está cifrado.
Sin embargo, Bob aplica el código al revés (desplazando cada letra 3 posiciones a la derecha) y obtiene el mensaje original.
Este mecanismo se conoce criptografía de clave simétrica, porque si sabes cómo encriptar el mensaje, también sabes cómo desencriptarlo.
NOTA: este mecanismo de desplazar letras es muy sencillo (se conoce como método "Caesar") y en la práctica se utilizan métodos mucho más complejos de desencriptar, pero la idea es la misma.

¿Cómo se decide la clave?

La criptografía simétrica es muy segura, siempre y cuando sólo el emisor y el receptor conozcan la clave utilizada. En el método Caesar, la clave sería el desplazamiento (3 en nuestro ejemplo, pero podríamos utilizar 4, ó 20, o cualquier otra "clave").
El problema es que si Alice y Bob no acuerdan la clave antes de empezar a enviar mensajes con la paloma, no serán capaces de entenderse.
Podrían enviar la clave en un mensaje previo, pero entonces Mallory podría interceptar ese mensaje previo y descubrir la clave. De esta forma, Mallory podría interceptar los mensajes posteriores y cambiarlos a su conveniencia.
Este es un ejemplo de ataque conocido como "man in the middle" y la única forma de evitarlo es cambiando el sistema de encriptación.

Palomas que llevan cajas

Alice y Bob deciden un sistema más seguro:
  1. Alice envía la paloma a Bob pero con una caja vacía abierta (con un candado abierto). Alice tiene la llave del candado
  2. Bob mete el mensaje en la caja y cierra el candado. Bobo envía la paloma a Alice.
  3. Alice recibe la paloma con la caja cerrada, abre el candado y saca el mensaje.
De esta forma, Mallory no puede cambiar el mensaje interceptando la paloma, porque Mallory no tiene la llave. Tampoco puede leer el mensaje.
Este mismo procedimiento se repite cuando Alice quiere enviar un mensaje a Bob.
Alice y Bob están usando lo que se conoce como criptografía asimétrica. Se llama asimétrica porque incluso aunque Bob puede encriptar un mensaje (meterlo en la caja y cerrar el candado), Bob no puede desencriptarlo (sacarlo de la caja).
En términos técnicos, la caja con candado es la clave pública de Alice, y la llave del candado es la clave privada de Alice.

¿Cómo confiamos en la caja?

Todavía hay un problema en la solución de Alice y Bob: Cuando Bob recibe la caja abierta (con el candado abierto), ¿cómo puede estar seguro de que esa caja viene de Alice? ¿puede ser que Mallory haya interceptado la paloma y haya puesto una caja suya de la cual tiene llave?
Alice decide firmar la caja cuando la envía a Bob, de esta forma, cuando Bob recibe la caja, sabe que viene de Alice porque conoce su firma.
Pero aun así, podemos pensar: ¿cómo hace Bob para identificar la firma de Alice la primera vez que se comunican? Entonces deciden que en lugar de que Alice firme la caja, la firme un tercero: Ted.
Pero, ¿quién es Ted? Ted es alguien muy famoso, y además, una persona de confianza. Ted dio su firma a todo el mundo hace tiempo y todo el mundo confía en que él sólo firma cajas cuando son de personas legítimas. Es decir, Ted firma la caja de Alice cuando está seguro de que esa caja es de Alice.
De esta forma, Mallory no puede coger la caja de Alice, firmada por Ted y cambiarla. Porque Mallory no puede conseguir que Ted firme la caja de Mallory en nombre de Alice.
En términos técnicos, Ted es una autoridad de confianza (CA) y el navegador viene de serie con las firmas de varios CAs.
Así, cuando nos conectemos a un sitio por primera vez, podemos confiar en su caja (vacía y abierta), porque está firmada por Ted y Ted es una persona de confianza que sólo firma cajas que son legítimas.

Las cajas son pesadas

Alice y Bob tienen ahora un sistema de comunicación fiable, pero se dan cuenta de las palomas llevando cajas vuelan muy despacio, porque las cajas pesan mucho. Las palomas vuelan mucho más rápido si llevan sólo el mensaje.
Entonces deciden que utilizarán el método de las cajas (criptografía asimétrica) únicamente para decidir cuál es la clave que utilizarán para encriptar el resto de mensajes (con criptografía simétrica). Por ejemplo, método Caesar.
De esta forma, consiguen lo mejor de los dos mundos. La seguridad de la criptografía asimétrica y la velocidad de la criptografía simétrica.
En el mundo real, la criptografía asimétrica requiere de algoritmos muy complejos que tardan bastante en procesarse. Sin embargo los métodos de criptografía simétrica son mucho más eficientes.

Dedicado a Cecilia




sábado, 7 de octubre de 2017

Mi experiencia con Apple pencil y Goodnotes

Este post va a ser un poco distinto a los demás, ya que no voy a explicar ningún tema concreto, sino que voy a contar mi experiencia (siendo ambiciosos podríamos llamarle 'review') con un producto y una aplicación.

Hasta ahora...

Hasta hace poco, yo era un consumidor casi compulsivo de cuadernos, bolígrafos, lápices y material relacionado.  ¿Por qué? Porque cada vez que leo un artículo, cada vez que empiezo a leer un libro, cada vez que voy a una charla, incluso cada vez que asisto a una reunión, siento la imperiosa necesidad de apuntarlo todo. Y siempre me ha gustado apuntarlo todo en un cuaderno, aunque la realidad es que terminaba rellenando folios de apuntes sin ninguna clasificación ni control, con el riesgo obvio de perderlos o incluso peor, saber que esos apuntes estaban entre un buen montón de folios en algún sitio, pero no poder localizarlos.

Siempre he deseado tomar estos apuntes de forma digital y poder tenerlo todo bien organizado. He probado muchas aplicaciones de notas (con teclado), por ejemplo OneNote de Microsoft es una de las mejores. También Evernote está bastante bien. Pero siempre me he tropezado con el escollo (para mí) de que necesito hacer dibujos en medio de mis notas. No lo puedo evitar, me gusta escribir mientras aprendo o escucho, pero necesito hacer muchos dibujos acompañando los textos. Por este motivo, he intentado utilizar sistemas como IrisNotes, un 'bolígrafo digital' muy interesante. Se trata de un bolígrafo casi normal, y un "aparatito" que se encaja en la parte superior del cuaderno. Cuando escribimos con el bolígrafo, el aparatito recoge la información de movimiento y va almacenando los trazos que vamos haciendo. No está mal la idea.
Pero falla en un pequeño detalle que yo valoro mucho: la espontaneidad. Para empezar a tomar notas hay que preparar: el bolígrafo, el aparatito. No es práctico. Porque cuando quieres tomar notas, quieres espontaneidad.
También he probado sistemas como el stylus de Samsung en sus dispositivos Galaxy Note, tanto móvil como tablet. La verdad es que podrían servir, salvo por otro pequeño detalle: el dichoso 'lag'. ¿Qué es el 'lag'? Pues es algo tan sencillo de definir y tan difícil de reducir como el tiempo que transcurre desde que hago un trazo en la pantalla del dispositivo hasta que la pantalla lo visualiza. Este tiempo son unos pocos milisegundos, pero si se supera cierta cantidad, 100ms más o menos, es inadmisible para el cerebro humano. Y por desgracia, los dispositivos de Samsung tienen un lag tan grande, que la sensación de escribir con naturalidad desaparece. Quizás se pueda utilizar para subrayar un pdf o bien para retocar una fotografía, pero para escribir o dibujar NO VALE.
Entre medias he utilizado algunas tabletas digitalizadoras, pero en este caso, el problema ya no sólo es el lag, sino que se añade el hecho de que estás escribiendo sobre una superficie (la tableta) y el resultado sale en otro sitio: la pantalla del ordenador. Esto es inadmisible para la escritura y casi también para el dibujo (aunque hay artistas digitales que lo utilizan y les encanta). Además, con esta solución se pierde completamente el concepto de portabilidad, tan necesario en la toma de apuntes.

Apple pencil

Y entonces llegó el Apple pencil. ¿En qué se diferencia el Apple Pencil de los demás stylus? En algo fundamental: el lag es prácticamente inapreciable. Sobre todo sobre las pantallas de los iPad Pro con refresco de 120Hz. Esto no sólo es un salto cuantitativo (lag casi cero), sino también cuantitativo: la sensación de estar escribiendo sobre la pantalla y que ésta responda a tus trazos de forma inmediata te hace sentir como si estuvieras sobre un papel, SALVO que la superficie es de cristal, lo cual se hace un poco raro al principio, pero te acostumbras.
La escritura con Apple pencil es sencillamente casi perfecta. Inmediatamente te olvidas que estás escribiendo sobre una pantalla y ves como todas tus ideas fluyen inmediatamente hacia el dispositivo. La sensación es maravillosa. No soy un experto dibujante, pero por lo que me han comentado los profesionales del dibujo tienen una sensación muy cercana a la realidad cuando trazan sus dibujos sobre el iPad con ayuda de un Apple pencil.
Además del lag inapreciable, otro tema muy importante con los stylus es 'palm rejection' o sea, que mientras estás escribiendo/dibujando en la pantalla, puedas apoyar la palma de la mano en la pantalla y que este gesto no dispare otras acciones o que incluso no haga rayas en el dibujo. Y Apple pencil esto lo hace muy muy bien. Mientras la punta del lápiz esta cerca de la pantalla, el resto de interacciones se desactivan. Así que si eres zurdo como yo o bien tienes la costumbre de escribir apoyando la palma de la mano sobre la pantalla, no vas a tener ningún problema.

Goodnotes

Y una vez entusiasmado con el pencil, sólo me faltaba una cosa: una buena aplicación para tomar notas. Sabía que eso no iba a ser difícil de encontrar, que incluso tendría problemas para elegir la que más me convenía. Y así fue.
Las empresas de desarrollo de aplicaciones se han esmerado muy mucho en lanzar aplicaciones que se integran a la perfección con el Apple pencil.
Pasé por algunas de estas aplicaciones, y la verdad es que casi todas me dieron muy buena impresión. Hasta que di con Goodnotes y entonces me di cuenta de que algo a lo que muchas veces no hacemos caso, la experiencia de usuario (UX user experience en inglés) es algo fundamental cuando quieres agilidad y espontaneidad. Tomar notas con Goodnotes es muy parecido a la sensación de tener un cuaderno, varios bolígrafos de distintos colores y una goma de borrar.
No voy a juzgar la forma que tiene Goodnotes de organizar las libretas en carpetas, no es la mejor, pero es suficiente. Tampoco necesito 10000 libretas!!! Lo que hace me vale, aunque esto podría mejorar en un futuro.
Escribir con Apple pencil y Goodnotes es una experiencia fantástica. Una vez te acostumbras a escribir sobre un cristal (la pantalla), la sensación es casi la misma que escribir en un cuaderno. Pero claro, tienes muchas ventajas: puedes hacer 'undo' y 'redo'; puedes borrar cualquier cosa, puedes mover trazados por la pantalla, ampliarlos o reducirlos, cambiarlos de color, etc, etc. Las posibilidades son enormes. Y lo bueno es que la interacción que ha diseñado el equipo de Goodnotes hace que todo esto sea casi natural.

Cómo utilizo Goodnotes con Apple pencil

Casi todas las opciones de Goodnotes aparecen en la línea superior (yo habitualmente utilizo las que tienen un número):

Voy a intentar explicar las opciones que uso yo, pero no en el orden en el que aparecen en la figura.
  • Lápiz (4) : selecciona el modo de dibujo o escritura con lápiz. Si se vuelve a pulsar aparece un menú con opciones de color del lápiz y grosor
  • Subrayador (5) : selecciona el modo de subrayado (el efecto es parecido al de los rotuladores subrayadores que solemos utilizar para resaltar palabras). Al igual que ocurre con el lápiz, si se vuelve a pulsar, aparecen opciones para elegir el color y el grosor
  • Borrador (6) : borra libremente por la página. Si se vuelve a seleccionar, aparecen opciones para el grosor de la goma de borrar
  • Undo (8) : deshace lo último que hayamos hecho
  • Formas geométricas (3) : si esta opción está seleccionada, Goodnotes intentará "arreglar" nuestros trazados para que se conviertan en formas geométricas. Por ejemplo, un trazado más o menos redondo, se convertirá en un círculo. Yo uso mucho esta opción para subrayar texto: la activo, hago una raya más o menos recta, y Goodnotes la transforma en un subrayado perfecto
  • Selección (7) : permite seleccionar cosas trazando un lazo libremente. Hay que tener en cuenta que si la selección corta un trazado por la mitad, entonces Goodnotes lo incluye completamente en la selección. Es muy útil para mover zonas dentro de la página o para redimensionarlas. Aunque también se puede usar para cambiar el color de una zona
  • Visor de páginas (1) : muestra todas las páginas del cuaderno en miniaturas. Permite realizar rápidamente operaciones como borrar páginas, insertar, cambiar de orden
  • Insertar (3) : permite insertar páginas provenientes por ejemplo de un fichero PDF externo 

Además de este menú superior, yo también utilizo las siguientes acciones:

  • dibujo con el pencil sobre la hoja del cuaderno.
  • deslizando con dos dedos paso a la página siguiente o anterior (dependiendo si deslizamos hacia la izquierda o hacia la derecha)
  • en la última página del cuaderno, deslizando con dos dedos hacia la derecha y aguantando un poco, aparece la opción de crear una nueva página al final. 

Uso real

Hasta ahora, he estado utilizando Apple pencil y Goodnotes en:
  • Charlas: la experiencia es fenomenal, porque escribes a tu ritmo y no hay desventajas sobre el papel. Tiene la ventaja de que puedes mover trozos de texto hacia abajo e insertar cosas que se te hayan pasado anteriormente
  • Reuniones: también muy buena experiencia, ya que puedes hacer dibujos rápidamente en el "cuaderno" y mostrarlos a los asistentes
  • Aprendizaje: me encanta seguir cursos online, y ahora mucho más, ya que mientras estoy viendo un vídeo en el ordenador, puedo estar tomando apuntes en el iPad.

Otros dispositivos

Hace unos dos años una startup noruega, reMarkable, y concretamente su CEO Magnus Wanberg, decidió embarcarse en un proyecto muy ambicioso: sustituir el papel, bolígrafos, lápices por un dispositivo de tinta electrónico. Todos conocemos los ebooks, dispositivos de tinta electrónica, que tienen la gran ventaja sobre las pantallas de móviles y tablets, de que no funcionan con luz, sino con una especie de polvo magnético que simula muy de cerca las páginas de un libro. Al tener una pantalla no iluminada con luz, puede utilizarse perfectamente en condiciones lumínicas muy difíciles para una tablet, por ejemplo a pleno sol en una playa. Además, el consumo de batería de estas pantallas es tan bajo, que con una carga podemos tener lectura para varias semanas. Pero no todo podían ser ventajas: la tinta electrónica es monocroma, no hay colores; el refresco de la pantalla completa es muy lento, puede llegar al segundo o más; aunque algunas de estas pantallas son táctiles, el lag es tan alto que lo hace inmanejable como dispositivo de escritura.
Pero Magnus Wanberf se empeñó en conseguir un dispositivo de tinta electrónica con un lag inapreciable, similar al apple pencil. Desde hace unas semanas está distribuyendo los primeros dispositivos, y las críticas son bastante buenas. Me han pedido que evalúe uno de estos dispositivos, así que escribiré en este blog los resultados y mi experiencia. Estad atentos...

sábado, 11 de febrero de 2017

Javascript: use strict

Javascript permite realizar algunos chequeos al código que escribimos. No es que se convierta en un lenguaje con los chequeos de los lenguajes compilados, ni siquiera se aproxima a su primo-hermano typescript, pero con estos chequeos podremos detectar algunos errores de otra forma pasarían inadvertidos y sólo provocarían errores de ejecución. Errores que muchas veces son muy difíciles de detectar.

Modo estricto

Para activar el modo "estricto" de javascript, tenemos que poner en la primera línea del fichero .js lo siguiente:

    "use strict";

Obsérvese que utilizamos comillas, no ponemos directamente use strict. ¿Por qué? Porque de esta forma, un string pasará inadvertido en versiones antiguas de los navegadores. Sin embargo, cuando un navegador moderno, vea este string al comienzo del fichero, activará los chequeos de javascript.
Si se desean activar los chequeos en todo el fichero, entonces "use strict" tiene que ser la primera sentencia del fichero .js Sin embargo, es posible, por ejemplo, colocar la sentencia "use strict" al comienzo de una función, y se aplicarán los chequeos sólo a esa función.

Variables globales

En javascript podemos utilizar una variable en cualquier lugar sin haberla declarado antes. Por ejemplo:

    contador = 1;

Esto funciona, pero no es una práctica recomendable, como sabe muy bien cualquier programador.
Sin embargo, si activamos los chequeos:

    "use strict";
    contador = 1;

Al ejecutar este código, obtendremos un error de javascript: "contador is not defined" indicando que la variable contador no ha sido definida anteriormente. La forma correcta sería:

    "use strict";
    var contador;
    contador = 1;

Variables mal escritas

Otro error típico en javascript es escribir mal el nombre de una variable:

    var contador = 0;
    contdor = 1
    console.log(contador);

Por un error tecleando, hemos asignado el valor 1 a una variable que no es contador, lo cual está permitido en javascript, y la consola nos mostrará el valor cero, en lugar de 1, que es lo que esperábamos. No tendremos ninguna otra pista de que estemos haciendo algo mal, simplemente obtendremos el valor cero en la consola.
Si activamos el modo estricto, tendremos el aviso que nos llevará al error:

    "use strict";
    var contador = 0;
    contdor = 1
    console.log(contador);
Al ejecutar nos mostrará el mensaje: "contdor is not defined"

Palabras reservadas

Otro error común en javascript es el uso de palabras reservadas como nombres de variables:

    var let = 4;

Esta línea se ejecutaría correctamente en javascript. Sin embargo, si activamos el modo estricto, obtendremos un error:

    "use strict";
    var let = 4;

"reserved word"

eval

Los programadores javascript saben que no es recomendable utilizar la función eval() por los peligros que implica. Sobre todo, porque puede cambiar el contexto del código javascript que le rodea.

Por ejemplo:

    var a = 1;
    eval("var a = 12");
    console.log(a)

En la consola veremos un 12, en lugar de 1 que es el valor que esperamos. O sea, eval() ha creado una variable en nuestro código y ha "machacado" la que ya teníamos.
En modo estricto, lo que se ejecute con eval() no tiene consecuencias en el código que le rodea:

    "use strict";
    var a = 1;
    eval("var a = 12");
    console.log(a)

En este caso, la salida es 1, y el código dentro de eval() se ejecuta autónomamente sin efectos laterales con nuestro código.