¿Tienes miedo? — ~El carpe diem en su mejor verso

a través de ¿Tienes miedo? — ~El carpe diem en su mejor verso

La libertad de elegirte o no — ~El carpe diem en su mejor verso

a través de La libertad de elegirte o no — ~El carpe diem en su mejor verso

La Fama…

La Fama, la más veloz de todas las plagas, que vive con la movilidad y corriendo se fortalece; pequeña y medrosa al principio, pronto se remonta a los aires, y con los pies en el suelo esconde su cabeza entre las nubes. Cuéntase que irritada de la ira de los dioses, su madre la Tierra la concibió, última hermana de Ceo y Encéndalo, rápida por sus pies y sus infatigables alas; monstruo horrendo, enorme, cubierto el cuerpo de plumas, que debajo de ellas tiene otros tantos ojos, siempre vigilantes ¡oh maravilla! y otras tantas lenguas y otras tantas parleras bocas, y aguza otras tantas orejas. De noche tiende su estridente vuelo por las sombras entre el cielo y la tierra, sin que cierre nunca sus ojos el dulce sueño; de día se instala cual centinela en la cima de un tejado o una alta torre, y llena de espanto las grandes ciudades, mensajera tan tenaz de lo falso y de lo malo como de lo verdadero.

—Publio Virgilio Marón
«La Eneida»

Fama es la mensajera de Júpiter, para los romanos representaba la “Voz pública”, habita en el centro del mundo y vive en un palacio sonoro, con mil aberturas por las que penetran las voces, rodeándose de la Credulidad, el Error, la Falsa Alegría, el Terror, la Sedición y los Falsos Rumores.

En nuestro tiempo, la Fama, esa voz pública, se ha convertido en un ser más monstruoso, si es posible, y completamente inmanejable, a merced de los medios de comunicación masivos y las redes sociales, a los cuales poco les importa la naturaleza de las voces o rumores que propaga.

Algunos comandos muy útiles de Git que uso a diario

Como muchos de vosotros, hace tiempo comencé a utilizar Git como herramienta de control de versiones, después de haver pasado por CVS y Subversion. Comenzar a usarlo fue sencillo y, las operaciones básicas diarias no resultaron ser ningún problema y era fácil acordarse de ellas. Poco a poco mi vocabulario de Git fue ampliándose a base de leer artículos en diferentes blogs y revistas y, cómo no, el manual de Git.

Esta no es la primera recopilación de comandos útiles, trucos o tips (como queráis llamarlo) que hay en internet, pero recopila algunas instrucciones que para mí resultan de utilidad con frecuencia y, solo tal vez, son menos conocidas. En cualquier caso, si has llegado aquí (aunque sea por casualidad), espero que también sean útiles para ti.

Cuando se te olvida agregar un archivo

Situación: acabas de realizar un commit a tu repositorio, cuando te das cuenta que te has dejado un archivo por incluir.

Una posibilidad es agregarlo y hacer un nuevo commit, como normalmente haces, reutilizando el mensaje anterior o utilizar el siguiente comando después de agregar el archivo olvidado.

$ git commit --amend --no-edit

Este comando reutiliza tu último commit y agrega nuestro archivo olvidado como si nada ubiese sucedido. Según la documentación de Git equivale (aproximadamente) a la siguiente secuencia de comandos:

$ git reset --soft HEAD^
$ git add <nuestro_archivo_olvidado>
$ git commit -c ORIG_HEAD

Eso sí, hay que tener cuidado con no haber ejecutado un comando push. La historia se puede reescribir sólo hasta cierto punto.

Situación: hemos cambiado muchos archivos y el comando status ofrece un listado muy laaaaargo

El comando status es posiblemente el comando más usado de Git, pero, en algunas ocasiones, el resultado de su ejecución devuelve un listado muy largo. Pues bien, la salida de este comando puede compactarse utilizando el parámetro --short. Veamos un ejemplo:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   folder4/dummy1.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   dummy2.txt
        deleted:    dummy3.txt
        modified:   folder1/dummy1.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        folder4/dummy2.txt
        folder4/dummy3.txt
        folder4/dummy4.txt
        new_dummy.txt

En cambio podemos ver todo más compacto:

$ git status --short
 M dummy2.txt
 D dummy3.txt
 M folder1/dummy1.txt
A  folder4/dummy1.txt
?? folder4/dummy2.txt
?? folder4/dummy3.txt
?? folder4/dummy4.txt
?? new_dummy.txt

Ahora solamente se muestra una línea por archivo donde además se especifica su estado abreviado:

  • M modificado (modified)
  • D eliminado (deleted)
  • A agregado (new file)
  • ?? sin seguimiento (untracked)

Situación: quieres ver claramente y de forma compacta en la consola la distribución de ramas del proyecto.

Muy a menudo necesitamos revisar la evolución de nuestro proyecto utilizando el comando git log para ver los últimos commits. En algunas plataformas como BitBuckect podemos ver de forma gráfica las diferentes ramas y en qué puntos han sido fusionadas con la rama master. Aunque con una estética limitada (la que puede ofrecer una consola de texto) podemos representar algo parecido. Esta secuencia la tomé prestada de algún blog que no puedo recordar…

git log --graph --abbrev-commit --decorate --all --format=format:"%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(dim white) - %an%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n %C(white)%s%C(reset)"

El resultado es algo como esto:

* f6fe4f7 - 2016-08-16 11:38:23 +0200 - Tony G. Bolaño (3 months ago)
|  Modificado diseño de la sección lateral
* c8a3332 - 2016-08-16 11:29:05 +0200 - Tony G. Bolaño (3 months ago)
|  reconfigurando la ejecución de los tests
* a0da8f9 - 2016-08-16 10:30:08 +0200 - Tony G. Bolaño (3 months ago)
|  Traducidas cadenas a español
*   7bc4a44 - 2016-08-16 09:57:16 +0200 - Tony G. Bolaño (3 months ago)
|\   Uniendo con la rama master
| * ec3c59b - 2016-08-16 13:40:54 +0200 - Tony G. Bolaño (3 months ago) (origin/courses-init)
| |  Cambiado menú superior de usuario
| * e7a8440 - 2016-08-16 13:16:13 +0200 - Tony G. Bolaño (3 months ago)
| |  Personalizada plantilla base
| * 22ed23a - 2016-08-16 13:01:22 +0200 - Tony G. Bolaño (3 months ago)
| |  Mejorando la imagen del perfil.
| * b60b2fe - 2016-08-16 12:52:47 +0200 - Tony G. Bolaño (3 months ago)
| |  Creada versión inicial de la portada
| * 2fa956b - 2016-08-16 11:34:57 +0200 - Tony G. Bolaño (3 months ago)
| |  Creando primeras vista y plantillas
| * 6a27293 - 2016-08-16 09:44:53 +0200 - Tony G. Bolaño (3 months ago)
| |  Movida la ubicación de las plantillas base al módulo del proyecto principal
| * eca38a3 - 2016-08-16 09:44:17 +0200 - Tony G. Bolaño (3 months ago)
| |  Preparado esqueleto de la documentación
| * f29d705 - 2016-08-16 09:30:54 +0200 - Tony G. Bolaño (3 months ago)
| |  Renombrado proyecto principal
| * 0b41ff0 - 2016-08-11 15:09:11 +0200 - Tony G. Bolaño (3 months ago)
| |  Primera aproximación a los modelos
| *   bf850f0 - 2016-08-11 13:24:16 +0200 - Tony G. Bolaño (3 months ago)
| |\   Agregando las modificaciones de múltiples perfiles
| * | 30d66b5 - 2016-08-10 15:12:13 +0200 - Tony G. Bolaño (3 months ago)
| | |  Iniciando el diseño del nuevo módulo
* | | b0d8ed4 - 2016-08-15 15:17:04 +0200 - Tony G. Bolaño (3 months ago)
| | |  Más tests y eliminación de rutas fijas en los tests con archivos
* | | 1dc3d52 - 2016-08-15 14:21:44 +0200 - Tony G. Bolaño (3 months ago)
| | |  Agregado nuevo test y eliminando archivos temporales tras tests
* | | fcffdce - 2016-08-15 13:40:25 +0200 - Tony G. Bolaño (3 months ago)
| | |  Reorganizando tests en el módulo principal
* | | e65fca0 - 2016-08-15 13:34:29 +0200 - Tony G. Bolaño (3 months ago)
| | |  Escribiendo más tests
* | | 2597253 - 2016-08-15 12:56:29 +0200 - Tony G. Bolaño (3 months ago)
| | |  Agregado logging. Solucionado problema de creación de perfil al crear usuario.
* | | 9479465 - 2016-08-15 11:36:00 +0200 - Tony G. Bolaño (3 months ago)
| | |  Agregada información breve sobre lanzamiento de tests en el archivo léame
* | | 4cdd9c5 - 2016-08-15 11:28:58 +0200 - Tony G. Bolaño (3 months ago)
| | |  Agregado seguimiento de cobertura de tests
* | | 87101d3 - 2016-08-15 10:59:29 +0200 - Tony G. Bolaño (3 months ago)
| | |  El acceso a un objeto no publicado devuelve un error 404
* | | 3d9ccc4 - 2016-08-15 10:56:49 +0200 - Tony G. Bolaño (3 months ago)
| | |  Agregados tests para las vistas
* | | 21435e8 - 2016-08-15 09:53:46 +0200 - Tony G. Bolaño (3 months ago)
| | |  Agregados tests de URL al módulo de perfiles
* | | 72dc7ed - 2016-08-15 09:41:08 +0200 - Tony G. Bolaño (3 months ago)
| |/   Agregados test de URL para el módulo principal
|/|
* | 13e571f - 2016-08-11 13:21:31 +0200 - Tony G. Bolaño (3 months ago) (origin/multiprofiles)
| |  Extendiendo datos del perfil
* | 223416b - 2016-08-11 09:48:12 +0200 - Tony G. Bolaño (3 months ago) (tag: v0.1)
| |  Separación de los settings de producción
* | 614beab - 2016-08-11 09:37:40 +0200 - Tony G. Bolaño (3 months ago)
|/   Agregada traducción
| * ef622fc - 2016-08-10 14:40:29 +0200 - Tony G. Bolaño (3 months ago) (origin/deps)
|/   Preparando la app y las dependencias
* a1c7e81 - 2016-08-09 15:18:56 +0200 - Tony G. Bolaño (3 months ago)
  Inicio del proyecto

Como podéis ver es mucho más compacto y muestra la distribución de las ramas del proyecto.

  • --graph: muestra la distribución de ramas
  • --abbrev-commit: muestra el hash de cada commit de forma abreviada
  • --decorate: agrega etiquetas y nombres de rama
  • --all: muestra todos los commits referenciados en /refs
  • --format: aplica un formato personalizado para cada commit (como por ejemplo aplicando colores)

Este último comando es demasiado largo para escribirlo cada vez, así que esto me lleva a la creación de comandos personalizados utilizando el comando config. Para crear un comando personalizado podemos usar la siguiente sentencia:

$ git config --global alias.<nombre> '<comando_completo>'
  • Utilizando --global el nuevo comando está accesible en todo momento por Git para cualquier proyecto.
  • <nombre>: corresponderá con el comando tal y como lo usaremos (justo después de Git).
  • <comando_completo>: encerrado entre comillas escribiremos el comando al que queremos crearle un alias con todos los parámetros necesarios.

Como muestra supongamos que queremos crear un alias llamado glog para nuestro graphical log del apartado anterior, que nos facilite su ejecución de forma habitual. El comando sería:

$ git config --global alias.glog 'log --graph --abbrev-commit --decorate --all --format=format:"%C(yellow)%h%C(reset) - %C(cyan)%ai%C(dim white) - %an%C(reset) %C(green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n %C(white)%s%C(reset)"'

Ahora, cada vez que queramos ver un log personalizado bastará con ejecutar en nuestro terminal:

$ git glog

¿Tenéis algún comando no tan habitual que vosotros uséis a menudo? Los espero en los comentarios.

python tip #1: generadores

Cuando definimos una función estándar acostumbramos a ejecutar todo el código de la función y devolver el valor calculado a través de una sentencia return, pero python nos ofrece una alternativa: la sentencia yield. En este caso, la función no se ejecuta de una sola vez, sino que devuelve un valor y permanece en un estado pausado hasta que solicitamos el siguiente valor. Este tipo de funciones se conocen como generadores o generators.

En la mayoría de aspectos una función generatriz se parece mucho a una función estándar. La diferencia principal es que cuando se compila una función generatriz, se convierte en un objeto que soporta iteración. La ventaja de esto es que en lugar de calcular una serie completa de valores, se van calculando de uno en uno a medida que se solicitan. Una característica llamada suspensión de estado.

En la mayoría de referencias sobre cómo funcionan estas funciones aparece como ejemplo la generación de la serie de Fibonacci… aquí también:

def fibonacci():
    """
    Generador de la serie de Fibonacci.
    Definición de la serie: el primer término es 1,
    el segundo término es 1, a partir de ahí cada término
    se calcula como la suma de los dos términos anteriores
    """
    a, b = 1, 1
    while True:
        yield a
        a, b = b, a + b

Una vez definida la función podemos ir obteniendo cada término siguiente utilizando el método next().

>>> f = fib()
>>> f.next()
1
>>> f.next()
1
>>> f.next()
2
>>> f.next()
3
>>> f.next()
5

A la hora de crear y utilizar generadores una lectura imprescindible consiste en la documentación del módulo itertools. Por ejemplo, si queremos obtener una lista con los diez primeros términos de la sucesión:

>>> from itertools import islice
>>> list(islice(fib(10),10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

El primer ejemplo utiliza una función con un loop infinito, pero los generadores pueden tener una longitud finita. Definamos la siguiente función:

def dias_semana():
    dias = [
        'lunes', 'martes', 'miércoles', 'jueves', 
        'viernes', 'sábado', 'domingo'
    ]

    for dia in dias:
        yield dia

Podemos usar la función en el shell de python para ver cómo funciona:

>>> d = dias_semana()
>>> d.next()
'lunes'
>>> d.next()
'martes'
...
>>> d.next()
'domingo'
>>> d.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Como vemos, una vez alcanzado el último elemento, si llamamos al método next() se procude una excepción del tipo StopIteration (ver documentación).

En el último ejemplo vemos que podemos pasar parámetros a este tipo de funciones de la misma forma que una función estándar:

def fibonacci_num(nterm):
    """
    Genera `nterm` términos de la sucesión de Fibonacci.
    """
    a, b = 1, 1
    for i in range(nterm):
        yield a
        a, b = b, a + b

Si ahora queremos obtener crear una lista con los diez primeros números de Fibonacci:

>>> list(fibonacci_num(10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Aunque cualquier generador puede definirse como una función estándar: ¿por qué usar generadores?

1. Algunos conceptos tienen una definición más clara cuando se definen como generadores.

2. En lugar de definir una función que devuelve una lista de valores, es posible hacerlo con un generador que calcula cada término &laquo;en el momento&raquo; optimizando el uso de la memoria, sobre todo en conjuntos de valores muy grandes.

3. Imprescindible en el caso de series infinitas como el caso de los números de Fibonacci que hemos visto en los ejemplos.

Es posible pasar parámetros de vuelta a las funciones generatrices. Este es un concepto más avanzado que podemos usar cuando dominemos el concepto y la implementación básica de generadores, pero si queréis profundizar en el tema la sección «Yield expressions» de la documentación habla del método send().

Divorcios

Un sistema de desvínculos: para que los callados no se hagan preguntones, para que los opinados no se vuelvan opinadores. Para que no se junten los solos, ni junte el alma sus pedazos.
El sistema divorcia la emoción y el pensamiento como divorcia el sexo y el amor, la vida íntima y la vida pública, el pasado y el presente. Si el pasado no tiene nada que decir al presente, la historia puede quedarse dormida, sin molestar, en el ropero donde el sistema guarda sus viejos disfraces.
El sistema nos vacía la memoria, o nos llena la memoria de basura, y así nos enseña a repetir la historia en lugar de hacerla. Las tragedias se repiten como farsas, anunciaba la célebre profecía. Pero entre nosotros, es peor: las tragedias se repiten como tragedias.

—Eduardo Galeano

Fotografías de menores: ¿protegemos su intimidad?

Llevo tiempo queriendo escribir algo sobre la protección de datos y, en especial, en referencia a los niños. Recientemente me he encontrado con alguna petición inusual de acceso a datos de carácter personal. Unido a esto y, coincidiendo con las Fallas, veo las redes inundadas de fotografías de niños menores y siempre pienso lo mismo: antes de publicar una fotografía de un menor en internet hay que hacerse dos preguntas

  1. ¿cuál es el objetivo de publicar la foto?
  2. ¿va en contra de los derechos y la intimidad del menor?

Buscando información al respecto, la propia Agencia Española de Protección de datos nos ofrece dos documentos realmente interesantes y que invito a todos a leer.

El primero al que quiero hacer referencia incluye unas recomendaciones donde se incluyen los Derechos de niños y niñas y Deberes de los padres y madres. Aunque el documento está muy orientado a padres y madres en unos apartados y a los menores en otros, creo que puede ser de utilidad no sólo al plantearnos la gestión o cesión de datos de los menores, sino para cualquiera que se enfrente por primera vez a una reflexión sobre la protección de datos.

Podéis descargar el archivo desde la propia agencia en el siguiente enlace:

https://www.agpd.es/portalwebAGPD/canal_joven/common/pdfs/recomendaciones_menores_2008.pdf

El segundo documento es algo más técnico, pero creo yo, de obligada lectura, fundamentalmente para padres, madres (incluyo aquí a las AMPAs) y personal docente.

Este documento es la respuesta a una consulta sobre la publicación no consentida en la página web de un centro escolar de fotografías de una alumna con motivo de la realización de diversas actividades extraescolares. Se trata del informe 0194/2009 del gabinete jurídico de dicha agencia.

Podéis leer el documento en la web de la Agencia Española de Protección de Datos a partir del siguiente enlace:

https://www.agpd.es/portalwebAGPD/canaldocumentacion/informes_juridicos/derecho_acceso_rectificacion_cancelacion_oposicion/common/pdfs/2009-0194_Fotos-de-menor-publicadas-en-p-aa-gina-web-del-colegio.-Ejercicio-de-derecho-de-cancelaci-oo-n.pdf

Debemos empezar a tener conciencia de que las fotografías que podamos tomar a cualquiera, no pueden ser publicadas sin consentimiento expreso de la persona (si es mayor de 14 años) o de sus tutores (si son menores de 14 años). Esto es especialmente importante si hablamos de la difusión tecnológica: una fotografía que difundimos por cualquier medio electrónico, queda inmediatamente fuera de nuestro control. Incluso, en las condiciones de uso de muchos de estos sitios, en el acuerdo de uso del servicio (que normalmente pasamos de largo sin una lectura detallada) realizamos una cesión explícita de los derechos de nuestras publicaciones. Esto es especialmente sensible en menores sobre los que nosotros mismos debemos tomar la decisión… sobre su intimidad. Dicha publicación constituye una cesión o comunicación de datos de carácter personal, definida por el artículo 3j) de la LOPD como «Toda revelación de datos realizada a una persona distinta del interesado».

Por último, como recomendación más importante, entendamos que la cesión de datos siempre es para un fin concreto y, por tanto, tendremos que desconfiar de los formulario de cesión donde no se explica quién, cómo y para qué se van a usar los datos, ni las consecuencias de la «no cesión».

El candado rojo de Gmail

Basta buscar un poco por internet para conseguir averiguar cuál es el significado. Para los técnicos, la explicación está en la propia documentación de gmail que podéis leer en este artículo de la base de conocimiento donde, básicamente, nos cuenta que el remitente del destinatario se puso en contacto con nosotros a través de un servidor de correo electrónico que no utiliza protocolos para cifrar o encriptar el contenido del mensaje.

¿Y esto qué tiene que ver conmigo? Te estarás preguntando. Pues bien, seguramente, si respondes al mensaje o escribes al remitente de un correo electrónico que ha sido marcado con el candado rojo, significará que, probablemente, el mensaje que tú envíes tampoco irá encriptado porque el servidor de correo de dicho remitente no usa esos protocolos. Esto significa, que cualquier información que incluyas en el mensaje es «relativamente» fácil de leer por cualquiera que se ponga a olisquear por internet con un poco de curiosidad y algo de mala intención.

Que los mensajes vayan encriptados no implica que nadie vaya a poder interceptarlos y leerlos, pero desde luego, es mucho más difícil que lo consigan. Por eso en la configuración de las cuentas de correo es importante usar servidores que soporten TLS o SSL por los puertos 25 o 465 con SSL yo 587 con TLS. Esta conversación habría que tenerla con el proveedor del servicio de correo electrónico.

En cualquier caso, siempre hay que recordar que mandar información sensible por correo electrónico siempre es un riesgo, pero que además aumenta si el correo electrónico viaja por la red sin cifrar de ninguna manera.

Esto es un paso adelante de Gmail por asegurar las comunicaciones, ahora, sólo falta que podamos encriptar con nuestro certificado digital sin necesidad de usar plugins de terceros, lo que sí que garantizaría de forma eficiente la privacidad de la comunicación entre dos usuarios por correo electrónico. Confío en que Google se esté planteando agregar estas y alguna que otra característica que echo de menos en el gestor de correo de Gmail por web y que me obliga, en ciertas ocasiones, a usar un cliente de escritorio «de los de toda la vida».