Archivo

Archivo para agosto, 2007

Youtube usa Python

Martes, 14 de agosto de 2007 Sin comentarios


En esta página hay un poquito de detalle sobre la arquitectura que utiliza YouTube, que sirve alrededor de 100.000.000 (sí, cien millones) de videos por día.

Adivinen qué? Usa Linux + un Application Server escrito en Python. 😀

Psyco es un “acelerador” de python, digamos que compila “al vuelo” el código que interpreta python y lo convierte a código nativo de la plataforma (como si se hubiera escrito en C, digamos). Si a ellos les da resultados, se podría probar para casos donde se necesite performance.

También me sorprende que usen lighthttpd, que es un webserver “liviano” (traducido: “más liviano que Apache”); en ese caso, quiere decir que está listo para utilizar en producción. 🙂

Para más detalles lean la página, está muy interesante.

Saludos
Marcelo

Categories: codear, linux, python Tags:

Krita: Mezcla de Colores

Martes, 14 de agosto de 2007 3 comentarios

Krita es una aplicación para edición fotográfica/bitmaps al estilo Photoshop/Gimp/etc.

El video muestra la implementación de la “mezcla de colores” (yo no entendía qué era hasta que lo ví). Muy bueno, Krita pinta como alternativa a Gimp desde hace rato y ojalá sigan poniéndole pilas los desarrolladores.

Además de eso, calculo que a fines de año (gracias a QT 4.x GPL para todas las plataformas) va a estar disponible para Windows y Mac.


Visto en Barrapunto.

Saludos
Marcelo

Categories: codear, linux, ubuntu-ar Tags:

Metaprogramación en Python

Sábado, 4 de agosto de 2007 Sin comentarios

Python está bárbaro, es sencillo y todo… siempre leí que era muy fácil hacer metaprogramming con él, pero el problema es que uno haga metaprogramming de una forma fácil en su mente. 😛

Veamos, la función getattr(), disponible en el módulo __builtins__ (o sea, disponible en todo momento), me permite cambiar esto:

def get_transportistas_custodia(id_custodia):
  """ Devuelvo todos los transportistas que están relacionados con una custodia """
  c = Custodia.objects.get(id=1)
  # Necesito el conjunto de transportistas de la custodia
  return c.transportistacustodia_set.all()
 
def get_asegurados_custodia(id_custodia):
  """ Devuelvo todos los asegurados que están relacionados con una custodia """
...

(lo malo es que tengo que hacer una función por cada tipo de empresa relacionada con custodia).

Por esto:

def get_empresas_relacionadas_custodia(id_custodia, empresa_relacionada='transportista'):
  """ Devuelvo todos los objetos de la empresa relacionada que están
      relacionados con una custodia.
      empresa_relacionada es un string que contiene el tipo de empresa con la cual
      relacionar a custodia.
  """
  c = Custodia.objects.get(id_custodia)
  # Necesito el conjunto de empresas relacionadas de la custodia
  return getattr(c, empresa_relacionada + 'custodia_set').all()

Esto es muy bonito. Lo que no había podido hacer hasta ahora era parametrizar con una variable las llamadas a función. Hablo de cosas como esta:

def has_empresa_relacionada_custodia(id_custodia, empresa_relacionada='transportista',
                                      id_empresa):
  """ Devuelve true si la empresa + id de la empresa especificados están
      relacionados con el id_custodia """
 
  c = Custodia.objects.get(id_custodia)
  # Necesito el conjunto de empresas relacionadas de la custodia
  empresas = getattr(c, empresa_relacionada + 'custodia_set')
  resultado = eval('empresas.get(' + empresa_relacionada + ',' + id_empresa + ')')
  if resultado:
      return True
  else:
      return False

Acá evidentemente no sabía cómo hacer para “poner” en la llamada a una función el nombre del parámetro que tengo en una variable (empresa_relacionada en este caso). Siempre leí que el “eval is evil” (además de muy lento en su ejecución), pero hasta ahora no podía evitar esto.

Jugando hace un rato descubrí que puedo hacer esto!

def has_empresa_relacionada_custodia(id_custodia, empresa_relacionada='transportista',
                                   id_empresa):
  """ Devuelve true si la empresa + id de la empresa especificados están relacionados
      con el id_custodia """
 
  c = Custodia.objects.get(id_custodia)
  # Necesito el conjunto de empresas relacionadas de la custodia
  empresas = getattr(c, empresa_relacionada + 'custodia_set')
  # En la siguiente línea está la magia
  resultado = empresas.get(**{empresa_relacionada : id_empresa})
  if resultado:
      return True
  else:
      return False

Groso! Al leer que las funciones con keywords son simples llamadas con
diccionarios, me fijé en esta página:

http://docs.python.org/ref/calls.html

Y ví que se puede llamar a funciones con ** o con * también.

Es un avance importante, ahora puedo parametrizar con valores de variables las llamadas a funciones, y sin usar el eval() (no usen eval, siempre tiene que haber una manera de no usarlo).

Saludos
Marcelo

Categories: codear, programación, python Tags: