miércoles, 17 de octubre de 2012

Campos calculados en django

Las operaciones sobre los objetos model de django se mapean a SQL mediante el ORM (Object-relational mapping). Un problema que tiene el ORM de django es que no tiene soporte directo para los campos calculados, que son aquellos que se obtienen a partir de los valores de los campos del registro para cada registro.

Por ejemplo, tenemos unos movimientos en los que interviene cantidad, precio y comisión. ¿Qué sentido tiene guardar en la BD el campo importe si en realidad ya tenemos toda la información para calcularlo?.

class Movimiento(models.Model):
   cantidad=models.DecimalField()
   precio=models.DecimalField()
   comision=models.DecimalField()

¿Cómo calculamos entonces el importe?. Hay dos alternativas: Una usando una property de python en el propio objeto model y otra usando extra en el queryset. Veamos:

class Movimiento(models.Model):
   cantidad=models.DecimalField()
   precio=models.DecimalField()
   comision=models.DecimalField()

   def _get_importe(self):
      return self.cantidad*self.cambio*(1-self.comision)
   importe = property(_get_importe)

Y ahí tenemos el importe del movimiento via movimiento.importe

La otra solución es usar extra en el queryset para añadir "a mano" el campo en la consulta SQL, sería:

target=movimiento.objects.extra(select={
          'importe': 'cantidad*cambio*(1-comision)',})
for f in target:
    print f.importe

Entonces, ¿Cuál es el problema?. Pues que todo esto son soluciones "de mentirijilla" puesto que realmente el campo importe no existe como tal en el gestor de BD y no podemos hacer cosas como sumar todos los importes haciendo una agregación, así esto

total_importe=modelo.aggregate(Sum('importe'))

Nos genera un error diciendo que el campo importe no existe.

Sin duda, el soporte para campos calculados es uno de las mejoras del ORM que puede trabajarse.


Fuentes:
http://stackoverflow.com/questions/3690343/django-orm-equivalent-for-this-sql-calculated-field-derived-from-related-table

lunes, 8 de octubre de 2012

Localizar las plantillas

Si queremos que los importes monetarios de nuestras plantillas nos salgan (en España) así:

1.256,56 €

en vez de así:

1256.56 €

tenemos que localizar la plantilla y dejar que django haga el trabajo duro.

Para empezar, en settings.py indicamos que queremos usar la localización añadiendo:

DEFAULT_CHARSET='utf-8'
THOUSAND_SEPARATOR= '.'
DECIMAL_SEPARATOR = ','
NUMBER_GROUPING = 3
USE_THOUSAND_SEPARATOR = True
FIRST_DAY_OF_WEEK = 1
LANGUAGE_CODE = 'es-es'
USE_L10N = True


En la plantilla, cargamos l10n y activamos la localización así:

{% load l10n %}
{% localize on %}

blah, blah, blah...

{% endlocalize %}


Y de forma mágica los importes aparecerán correctamente formateados. Para controlar la cantidad de decimales diferentes del estándar también podemos usar el filtro floatformat:precision así:

{{ importe|floatformat:6 }}


Error de codificación de caracteres al generar pdf con django y pisa

Hacía tiempo que me perseguía un pequeño problema al generar pdf desde django/pisa con caracteres utf8>255. Por defecto, pisa usa latin-1/ISO 8859-1 (un byte) para generar los pdf y al transcodificar los caracteres de la template (p.e. el símbolo euro €) me saltaban errores.

En la doc oficial de pisa tenemos que:


pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), result)


Pero buscando en stackoverflow he encontrado que pisaDocument acepta además el parámetro encoding con el que en realidad le indicamos la codificación que debe usar con lo que queda:

pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), result, encoding='UTF-8')  

;-)

Minimizar y maximizar en gnome3

Una forma de configurar los botones que queremos en el marco de la ventana es instalar el programa


sudo apt-get install gnome-tweak-tool

Y desde él configurar este y otros aspectos del entorno.

jueves, 4 de octubre de 2012

Los versos dorados (o áureos) de Pitágoras

Atribuido a Lisis, un alumno de Pitágoras, parece ser un resumen de la forma de vida que profesaban los pitagóricos.

Hay muchas versiones en Internet pero me quedo con esta. El original está escrito en hexámetro dactílico que es un tipo de verso de la poesía griega. La traducción está sacada del libro Les Vers Dorés de Pythagore de Fabre-d’Olivet, Éditions L’Age d’Homme, Collection Delphica, 1991. Traducción del francés por M.A.Aguirre.

PREPARACIÓN. 


RINDE a los Dioses inmortales el culto consagrado;
Guarda después tu fe (2): Reverencia la memoria De los Héroes bienhechores, de los Espíritus semi-Dioses (3).

PURIFICACIÓN. 

Sé buen hijo, hermano justo, esposo cariñoso y buen padre (4).
Escoge por amigo, al amigo de la virtud;
Cede a sus suaves consejos, instrúyete por su vida,
Y por un daño ligero no le dejes nunca (5);
Si lo puedes al menos: pues una ley severa Sujeta la Potestad a la Necesidad (6).
Se te ha dado sin embargo combatir y vencer
Tus locas pasiones: aprende a dominarlas (7).
Sé sobrio, activo y casto; evita la cólera.
En público, en secreto no te permitas nunca
Nada malo; y sobretodo respétate a ti mismo (8).
No hables ni hagas nada sin haber reflexionado.
Sé justo (9).
Acuérdate que un poder invencible
Ordena morir (10);  que los bienes, los honores
Fácilmente adquiridos, son fáciles de perder (11).
En cuanto a los males que arrastra consigo el Destino,
Júzgalos tal cual son: sopórtalos; y trata,
En lo que puedas, de dulcificar sus rasgos:
Los Dioses, a los más crueles, no han entregado a los sabios (12).
Como la Verdad, el Error tiene sus amantes:
El filósofo aprueba, o reprueba con prudencia;
Y si el Error triunfa, se aleja; espera (13).
Escucha, y grava en tu corazón mis palabras:
Cierra el ojo y el oído a la prevención;
Recela del ejemplo ajeno; piensa por ti mismo (14):
Consulta, delibera, y escoge libremente (15).
Deja los locos quehaceres sin fin, sin causa.
Debes, en el presente, contemplar el porvenir (16).
Lo que no sepas, no pretendas hacerlo.
Instrúyete: todo se concede a la constancia, al tiempo (17).
Vigila tu salud (18): dispensa con medida,
Al cuerpo los alimentos, al espíritu el reposo (19).
Hay que evitar demasiados o demasiados pocos cuidados; ya que la envidia,
A uno y otro exceso, se ata igualmente (20).
El lujo y la avaricia tienen consecuencias semejantes.
Es necesario escoger en todo, un medio justo y bueno (21).

PERFECCION. 


Que nunca el sueño cierre tus párpados,
Sin haberte preguntado: ¿Qué he omitido? ¿Qué he hecho? (22)
Si está mal, abstente: si está bien, persevera (23).
Medita mis consejos; ámalos; síguelos todos:
A las divinas virtudes podrán conducirte (24).
Lo juro por aquel que gravó en nuestros corazones,
La Tétrada sagrada, inmenso y puro símbolo,
Fuente de la Naturaleza, y modelo de los Dioses (25).
Pero que ante todo, tu alma, fiel a su deber,
Invoque con fervor a estos Dioses, cuyos socorros
Pueden únicamente acabar tus obras comenzadas (26).
Instrúyete por ellos, entonces nada te engañará:
De los diferentes seres sondearás la esencia;
Conocerás de Todo el principio y el fin (27).
Sabrás, si el Cielo lo quiere, que la Naturaleza,
Semejante en todo, es la misma en todo lugar (28).
De manera que iluminado sobre tus derechos verdaderos,
Tu corazón no se alimentará de vanos deseos (29).
Verás que los males que devoran a los hombres,
Son fruto de su elección (30); y que estos desdichados
Buscan lejos de ellos los bienes de los que llevan la fuente (31).
Pocos saben ser dichosos: juguetes de las pasiones,
zarandeados por el vaivén de las olas,
En una mar sin orilla, dan vueltas, cegados,
Sin poder resistir ni ceder a la tempestad (32).
¡Dios! los salvarías abriéndoles los ojos... (33).
Pero no: corresponde a los humanos, cuya raza es divina,
Discernir el Error, ver la Verdad (34).
La Naturaleza les sirve (35). Tú que la has penetrado,
Hombre sabio, hombre dichoso, respira en el puerto.
Pero observa mis leyes, absteniéndote de las cosas
Que tu alma debe temer, distinguiéndolas bien;
Dejando en el cuerpo reinar a la inteligencia (36):
A fin de que, elevándote en el Éter radiante,
Al seno de los Inmortales, ¡seas tú mismo un Dios! (37)


Filtrar entre fechas con django

Siempre se me olvida la sintaxis de range que selecciona entre dos valores inclusives:


self.modelo.objects.filter(fecha__range=(desde, hasta))

viernes, 31 de agosto de 2012

MSL Curiosity NavCams: Anaglyph Panorama of Bradbury Landing Site/ Panorama anaglifo del sitio de aterrizaje Bradbury

Bradbury Landing Site anaglyph panorama
Click para ampliar / Click to zoom

Este es mi segundo trabajo con las imágenes de las cámaras de navegación (NavCams) del MSL tomadas el Sol22. Se trata del sitio de aterrizaje del Curiosity bautizado como Bradbury Landing Site en honor al escritor de ciencia ficción Ray Bradbury, recientemente fallecido. El monte Aeolis queda a la derecha.

La panorámica se ha realizado uniendo 4 fotografias y generando una proyección esteroscópica. El campo de visión es de unos 136 grados horizontales. He usado el pedrusco central como foco.

Algunos datos de las NavCams (Cámaras de navegación)

El sistema de cámaras de navegación del Curiosity tienen las siguientes características:
  1. Determinar el contexto del terreno para planificar la travesía y ayudar al apuntado de las cámaras Mastcam y Chemcam.
  2. Generar una vista de 360 grados con una resolución angular menor que 1 mrad/pixel.
  3. Generar vistas estéreo hasta unos 100 m.
  4. Uso de un filtro en visible.
Las NavCams están montadas en el mástil, en la misma pletina que las cámaras MastCam/ChemCam y están sincronizadas para tomar fotos en estéreo siendo su línea de base de 42cm y quedando a 1.9 m del suelo de Marte.

Posición de las NavCams en el mástil



Como sistema fundamental del Curiosity, las NavCam están duplicadas para redundancia (pares A y B) estando conectadas a placas electrónicas diferentes. Sólo un par está activo al mismo tiempo.

Las CCD provienen de material sobrante del programa MER y tienen 1024x1024 píxeles cuadrados de 12 micrones. Debido a la calidad de los detectores y a las condiciones de operación (-55 grados C) el ratio de señal-ruido es >200:1. Las lecturas son de 12 bits por pixel y tarda 5.4 s en leer una imagen.

Con la óptica que montan, queda un sistema a f/12 sin relación de aumento y con un campo de 45x45 grados que es casi equivalente a un objetivo de 40 mm en una cámara de 35 mm. La resolución angular en el centro es de 0.82 mrad/pixel. La profundidad de campo va de los 0.5 m a infinito con la distancia hiperfocal a 1 m. Con esta configuración, el tiempo de exposición a medio día es de 0.25 s. El sistema usa un sistema de filtros centrado en los 650 nm (que vendría a ser entre el anaranjado y el rojo).


Fuente: THE MARS SCIENCE LABORATORY (MSL) NAVIGATION CAMERAS (NAVCAMS). J. N. Maki1, D. Thiessen1, A.Pourangi1, P. Kobzeff1, L. Scherr1, T. Elliott1, A. Dingizian1, Beverly St. Ange1, 1Jet Propulsion Laboratory/California Institute of Technology, 4800 Oak Grove Drive, Pasadena, CA 91109. Fecha de consulta: 31/08/2012.