miércoles, 24 de julio de 2013

Mysql borrado rápido filas duplicadas

En este sitio he encontrado una forma muy rápida de eliminar duplicados. Tan rápida que puede hacerse con una sola línea, se trata de crear ununique index con la palabra clave IGNORE. Tal que esto:

ALTER IGNORE TABLE dupTest ADD UNIQUE INDEX(a,b);


Guay eh?

martes, 23 de julio de 2013

Django filtro de query usando un string

Es común que queramos pasar directamente un string al filtro de una consulta, por ejemplo, desde una url. Dado que el parámetro de filter es un diccionario, lo podemos hacer mediante el operador de desempaquetado de diccionarios **.

Recordemos que para desempaquetar una lista usamos el operador * y para desempaquetar un diccionario el **:

Ejemplo de *


>>> pepe=(1,10,)
>>> range(pepe)
Traceback (most recent call last):
File "", line 1, in
TypeError: range() integer end argument expected, got tuple.
>>> range(*pepe)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Ejemplo de **



>>> pepe={ "venus" : "blanco", "tierra": "azul", "marte": "rojo" }
>>> '{tierra}'.format(pepe)
Traceback (most recent call last):
File "", line 1, in
KeyError: 'tierra'
>>> '{tierra}'.format(**pepe)
'azul'
>>>


En ambos ejemplos observamos que al usar * o ** pasamos con el tipo correcto. Pero ¿Cómo aprovecharlo para pasar directamente un filtro a la consulta?. Yo lo hago de la siguiente forma:


# un string
filtro="nacionalidad__exact@ESP"
# lo parseamos en clave-valor
f=filtro.split("@")
# pasamos como diccionario
p=Persona.objects.filter(**{f[0]:f[1]})
# el efecto es el mismo que hacer
p=Persona.objects.filter(nacionalidad__exact='ESP')

Y ahora veamos cómo implementarlo.

En la página web:

$('a.pais').click(function() {
   var pais=$(this).attr("pais");
   $('#{{entidad}}').load("?filtro="+escape('nacionalidad__exact@'+pais)+"&type=ajax");
});


Notemos que en la url pasamos,
  1. Un interrogante: Hará un get sobre la página actual.
  2. Un nombre de parámetro (filtro). Si queremos añadir más parámetros los separamos con &
  3. El valor del parametro poniendo un igual después del nombre, por ejemplo,  filtro=nacionalidad__exact@ESP 
En la parte del servidor lo que hacemos es procesar directamente el filtro pasando de string a diccionario así:


def get_filtro( self, request):
  """ aplica el filtro y devuelve el modelo filtrado """
   filtro=request.GET.get('filtro', False)
   if filtro:
  try:
     f=filtro.split('@')
     return Persona.objects.filter(**{f[0]:f[1]})
   except Exception, e:
    logger.error('desempaquetando filtro '+str(e))

   return Persona.objects.all()


La ventaja de este método es que es muy sencillo crear toda clase de filtros directamente en la página web teniendo un solo código que los gestiona en el servidor. 

Una última puntualización: Si no todos los usuarios pueden ver todo el modelo i.e. ver todas las personas Persona.objects.all() hay que ir con cuidado ya que es muy sencillo manipular a mano la url para que nos devuelva cualquier registro. Por ejemplo:

?filtro=moroso__exact@1

Nos devolvería todos los morosos ;-)



lunes, 22 de julio de 2013

Reproducir vídeos en la Nexus 10 por USB

De forma nativa no podemos conectar un disco externo o pen drive a la Nexus para reproducir vídeo. Para poderlo hacer precisamos dos cosas:

  1. Que la Nexus nos haga de "host" USB para que pueda leer desde dispositivos USB.
  2. Eventualmente, poder reproducir el formato AVI.

Conexión del dispositivo USB a la Nexus 10

Necesitamos un cable OTG (USB On-the-go) para poder conectar el dispositivo (hembra) en el micro-usb de la tablet. Son muy baratos y se encuentran en cualquier tienda de componentes o electrónica.






También necesitamos que el sistema operativo nos reconozca el dispositivo. Como android no lo hace, tenemos que instalar software. Una aplicación que funciona sin problemas (no es necesario entrar como root) es Nexus Media Importer. Basta con conectar el dispositivo y ya tendremos acceso al contenido del disco.



Reproducción de AVI

Hay muchos buenos programas que reproducen AVI y mantienen los códecs actualizados. Yo uso el MX Player Pro, al que podemos activar la decodificación por hardware (en la pestaña de Configuración-Decodificación)


lunes, 15 de julio de 2013

Django error "name field too short" generando permisos en el admin si verbose_name está presente

El verbose_name de un modelo sirve para dar una descripción extendida de él. Si está presente, es usada por el admin para describir el modelo, si no, se usa el nombre de la clase. Por ejemplo:

class Cliente(models.Model):
  ...
  ...
   verbose_name=u"Esta descripción saldrá en el admin, es un poco larga para mostrar el error"
   verbose_name_plural=u"Esta es la descripción que se usa en plural"


Para poder administrar el modelo, lo incluimos y registramos en admin.py:

class ClienteAdmin(admin.ModelAdmin):  
    list_display=('nombre','codigo',)
    ....
admin.site.register(Cliente, ClienteAdmin)  


En el primer runserver que hagamos, el admin intentará registrar el modelo y crear los permisos de add, change y delete. El problema es que la descripción del permiso es del estilo de "Can add "+verbose_name y se almacena en el campo name de la tabla auth_permission que está definido con 80 caracteres de largo. Por lo tanto, la creación de permisos fallará si se supera esa longuitud y nos encontraremos con el modelo registrado en el admin pero sin poderle asignar permisos.

Registré el bug y resulta que lo han cerrado como duplicado  de otro de hace cinco años!!!. Claro que es fácil quejarse y no currar en el proyecto....

De momento, para resolverlo basta con editar a mano la longitud del campo:

ALTER TABLE auth_permission MODIFY name VARCHAR(500);


Consola linux en utf8 (debian, ubuntu)

Un problema común cuando usamos la cónsola para pasar datos de una aplicación a otra o para pasar un dump de mysql a otro servidor es que la cónsola no acepta utf8 y nos corrompe los caracteres extendidos.

Para que podamos usar la cónsola en utf8 con es_ES, hemos de asegurarnos, en primer lugar, de que los locales están generados haciendo:

sudo locale-gen es_ES.UTF-8
sudo dpkg-reconfigure locales


y para que la sesión de bash use dicha configuración añadir en el .bashrc

export LANG=es_ES.UTF-8
export LANGUAGE=es_ES.UTF-8


Si no funciona y estamos iniciando la sesión desde otra máquina hemos de asegurarnos de que el cliente también tenga dicha configuración. Si estamos usando putty para una sesión ssh hay que ir a Preferences-Window-Translation y poner el remote character set en UTF-8 y guardar el perfil.

viernes, 12 de julio de 2013

Calidad de imagen en cámaras digitales: La aberración cromática

Voy a intentar explicar, desde mi perspectiva de fotógrafo aficionado, qué es la aberración cromática y cómo afecta a la calidad final de la fotografía digital. Empezaremos repasando unos conceptos.

Índice de refracción

La medida relativa de la velocidad de la luz en un medio respecto de la del vacío se llama índice de refracción.
n es índice de refracción del material.
C es la velocidad de la luz en el vacío
v es la velocidad de la luz en el material

n siempre será mayor o igual que 1 puesto que la máxima velocidad de la luz se da en el vacío.

Refracción de la luz

Cuando la luz cambia de medio se produce el fenómeno de la refracción. El fenómeno está relacionado con la distinta velocidad de propagación de la luz en diferentes medios materiales.

Observamos que cuando pasamos de un medio como el aire a otro más "denso" como el agua o el vidrio (mayor índice de refracción) la dirección de los rayos de luz cambian, acercándose a la normal.




El fenómeno es aprovechado por las lentes para enfocar rayos de luz en un punto y conseguir aparatos como la lupa, el microscopio, el telescopio o el objetivo de una cámara fotográfica.

Los ángulos del rayo incidente y el refractado están relacionados mediante la Ley de Snell:


Dispersión de la luz

Pero claro, decir que la onda "cambia la velocidad" tal vez sea un poco simplista. Vamos a ver, la velocidad es el cambio de posición respecto al tiempo, el "espacio partido por tiempo" de toda la vida. En el caso de las ondas este "espacio" se llama longitud de onda (la letra griega lambda)
es la distancia que separa dos máximos consecutivos y el "partido por tiempo" se llama frecuencia (la letra f), o sea:


O resumiendo,

Mientras la onda se propaga en otro medio, cambia su longitud de onda y la frecuencia se mantiene constante. Entonces, para que la igualdad se mantenga con f y v constantes, vemos que las ondas que tienen menor frecuencia cambiarán más su longitud de onda (lambda) que las que tienen mayor frecuencia. En una palabra, las ondas con frecuencias más altas se refractarán en ángulos más grandes que las ondas con con frecuencias más bajas. Este fenómeno genera la llamada "dispersión de la luz".

Sabemos que la luz que proviene del Sol está formada en realidad por la combinación de diferentes ondas con longitudes diferentes.

Podemos observarlo haciendo pasar un rayo de luz del sol (que vemos blanco) por un prisma.


Los colores que aparecen están ordenados por su longitud de onda. A mayor frecuencia, menor longitud de onda. El violeta tiene mayor frecuencia y menor longitud de onda que el rojo y por tanto se desvía más. Una luz que tiene un solo color (monocromática) sólo tiene una longitud de onda y por lo tanto no habría dispersión.

Aberración cromática

El problema de la aberración cromática viene entonces porque en el momento en que usamos una lente para enfocar una luz no monocromática en un punto, las diferentes longitudes de onda se enfocarán en puntos diferentes debido a que se refractan en ángulos diferentes.



Esto causa una merma en la calidad de las imágenes. El fenómeno es más acusado cuanta más curvatura y diámetro de la lente, o sea, en los objetivos gran angular. Veamos abajo cómo afecta la aberración cromática en función del diámetro efectivo de la lente. F1,4 es el doble de apertura que F1,7 y F2 el doble que F1,7. Se observa que así como vamos cerrando la lente (número F mayor) va disminuyendo la aberración y va mejorando la calidad.



Peeeero (siempre hay un pero) esto no es todo. Aparte de otro tipo de aberraciones ópticas, existe un factor adicional que afecta a la calidad de imagen digital; Está relacionado con la forma de capturar el color de la propia cámara

Cámaras digitales

El capturador de la cámara posee una matriz de elementos fotosensibles y es capaz  de contar la cantidad de fotones que inciden durante un determinado periodo de tiempo en cada uno de esos elementos. El proceso de conversión nos da una medida del "nivel" de luz que ha alcanzado cada elemento. En principio, esta medida no nos da información de color; Vendría a ser la imagen en blanco y negro. ¿Cómo pues obtiene la cámara la información de color?.

El filtro de Bayer

La información de color se obtiene disponiendo un filtro de colores sobre el sensor de esta forma:



Se observa que el patrón es RGB (Rojo, Verde, Azul) de 2x2. Se da más importancia al verde porque el ojo humano es más sensible en esa longitud de onda. Para cada cuatro elementos, tendremos la información de color de un pixel en la imagen final. La determinación del color de ese pixel se realiza a partir se la medida de las cuentas de rojo, verde y azul. La conversión de la información en crudo ("raw") a los valores de pixel se ha dado en llamar "revelado digital". El algoritmo de conversión se llama interpolación de Bayer.

El problema de la aberración cromática

Todo esto viene a cuento de que, como es evidente, el sensor es plano pero la aberración hace que los diferentes colores se enfoquen un poco "antes" o "después" de ese plano y por tanto confunden al algoritmo de interpolación. Esto causa una degradación adicional de la calidad de la imagen.


Soluciones

Las soluciones son de dos tipos:

  1. Ópticas: Se usan lentes de distintos tipos e índices de refracción para enfocar mejor los diferentes colores.
  2. Software: Que tiene en cuenta la aberración de cada objetivo y lo compensa en el momento del revelado.


Espero que esta entrada os haya ayudado a entender qué es la aberración cromática y cómo influye en la calidad final de la fotografía.

Un saludo a los estudiantes de Física II del Grado de Telecomunicación de la UOC.

Nota:
Cabe decir que cuando nos referimos a la "luz", queremos decir cualquier onda electromagnética.


Imagen refracción crédito: By Josell7 (Own work) [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC-BY-SA-3.0-2.5-2.0-1.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons

Imagen dispersión crédito: Wikimedia Commons

Imagen aberración cromática crédito: By Andreas 06 (Own work) [Public domain], via Wikimedia Commons

Imagen mosaico de Bayer: By en:User:Cburnett [GFDL (http://www.gnu.org/copyleft/fdl.html), CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0/) or GPL (http://www.gnu.org/licenses/gpl.html)], via Wikimedia Commons

miércoles, 10 de julio de 2013

Django name field on auth_permission too short

If the verbose_name of the table is over 80 characters the syncdb command will silently fail.
The name field on auth_permissions table is too short to store if verbose_name are that long, so it doesn't update and you cannot assign permissions.
The obvious workaround is to manually change the field length on the table.
I have opened the ticket 20728

Thanks Victor!

lunes, 8 de julio de 2013

Guiado de un cohete

Los de Copenhagen Suborbitals están que no paran. Sus vídeos de cohetería amateur son una joya para cualquier afcionado; Resumen en pocos minutos los aspectos más complejos de la construcción y diseño de un cochete.

Un vídeo que me ha parecido especialmente interesante es el de guiado: