Volpe's Blog

Opiniones, viajes y código

🇬🇧 Read in English

Porque Donnees apesta

Apesta por muchas razones. En este post voy a explicar los errores mas escalofriantes, porque se implementó de esa forma y como pienso que debería corregirse en futuras versiones.

Donnees fue diseñado para una feria de ciencia, para monitorear cultivos de peces (si, cultivos de peces!) y con una fecha límite. Yo fui el unico usuario desde el inicio del desarrollo hasta ahora. Eso me llevó a cometer algunos errores intolerables: todos las direcciones de los archivos son relativas en lugar de absolutas, la base de datos y los archivos de configuración están en la misma carpeta que el código. Al principio esto parecía una idea genial, yo quería poder transportar el soft y la base de datos en un pendrive sin ningún tipo de configuración y pensaba que esa era la forma “correcta de hacerlo”.

Faltan un montón de variables para configuración, como era el único usuario (y desarrollador) la forma mas rápida de configurar algo era editar el código. Desde el principio supe que eso estaba mal, pero recuerda que tenía un deadline. Lo peor de todo es que algunas configuraciones están en archivoS de texto, un archivo por variable (!), otra vez, no me culpen, tenía un fecha límite!.

Esos y algunos otros problemas que Donnees tiene no eran importantes mientras trabajaba en el, porque la información que recolectaba era mas importante que el software en si mismo.

Continuar leyendo →

Donnees liberado como proyecto de software libre

Que es Donnees?, Es un Software de Adquisición de datos enteramente programado en Python, mas información aquí.

Así que acá estoy liberando un proyecto en el cual estuve trabajando por mas de un año, Donnees (significa “datos” en francés). Donnees tiene un par de características interesantes, o a lo sumo puede ser utilizado como código de ejemplo para algunas librerías.

Este programa fue originalmente diseñado para ser usado con un proyecto de feria de ciencia (que terminó 4to en la categoría de ingeniería mecánica y eléctrica en ISEF). Actualmente incluye las siguientes características:

  • Gráfico de datos en tiempo real
  • Fuente de datos extensible, puerto serie es soportado por defecto
  • Opción de guardar todos los datos en la base de datos
  • Gráficos exportables
  • Reportes y alarmas por e-mail
  • Interfaz web incluida
  • Multiplataforma, Linux y Windows
  • Cliente Scada Incluido

Como está el proyecto hoy?

La verdad es que apesta, desde el punto de vista de la calidad del código y la capacidad de configuración. Es muy probable que todavía no se útil para nadie (sin contarme a mi), pero yo sigo trabajando en el para que en algún momento se pueda transformar en un genial proyecto de software libre. El resto de los problemas (y algunas posibles soluciones) pueden ser encontradas aquí.

Siéntase libre de jugar con el, enviar código al repo (aunque no esté testeado, ya va a haber tiempo para eso) o usarlo para cualquier cosa piensas que pueda ser útil, mientras cumplas con su licencia GPL. También sería muy amable de tu parte que te contactes conmigo si usaste el código de Donnees para otra cosa.

Continuar leyendo →
en Programación, PyGTK, Python, Twisted

Twisted + PyGTK

Hace unas semanas empece a interesarme en Twisted y en programacion asincronica en general. La verdad es que encuentro muy amigable la forma en la que Twisted maneja los callbacks y los eventos.

He estado trabajando en un programa con una interfaz grafica hecha con Pygtk que usa un thread para cada tarea y me pregunte si es posible tener ese mismo programa corriendo en un solo thread asincronicamente. Es verdaderamente simple implementar codigo twisted en aplicaciones escritas en PyGtk, los dos son basados en eventos y Twisted tiene una API nativa para ese objetivo.

Empecemos con un ejemplo simple de PyGTK:

import gtk

class Gui:
    def __init__(self):
        self.window = gtk.Window()
        self.window.set_default_size(200,200)
        self.window.set_title("Simple PyGTK program")

        self.vbox = gtk.VBox()

        self.button = gtk.Button("I'm a button!")
        self.label = gtk.Label("Nothing here")

        self.vbox.pack_start(self.button)
        self.vbox.pack_start(self.label)

        self.window.add(self.vbox)

        self.button.connect("clicked", self.on_clicked)
        self.window.connect("destroy", lambda x: gtk.main_quit())
        self.window.show_all()
        self.window.show()

    def on_clicked(self, widget):
       self.label.set_text("You clicked the button!") 

if __name__ == "__main__":
    app = Gui()
    #Empezamos el bucle de GTK
    gtk.main()

Este ejemplo usa el bucle de Gtk. Una aplicacion hecha en Twisted usa el Twisted reactor, por lo tanto, necesitamos que el reactor “entienda” las señales emitidas por GTK

from twisted.internet import gtk2reactor # for gtk-2.0
gtk2reactor.install()

#Tu código
#...

from twisted.internet import reactor
#this starts the reactor
reactor.run()

Ahora podemos reimplementar nuestro primer ejemplo y sería algo parecido a esto: Now we can re-implement or first example and it would look like this

import gtk
from twisted.internet import gtk2reactor # for gtk-2.0
gtk2reactor.install() #Instalamos de gtk2 reactor
#NOTE: This have to be at top always, before starting the reactor
#NOTA: Esto tiene que estar siempre al principio, antes de importar el reactor

class Gui:
    def __init__(self):
        self.window = gtk.Window()
        self.window.set_default_size(200,200)
        self.window.set_title("Simple PyGTK program")

        self.vbox = gtk.VBox()

        self.button = gtk.Button("I'm a button!")
        self.label = gtk.Label("Nothing here")

        self.vbox.pack_start(self.button)
        self.vbox.pack_start(self.label)

        self.window.add(self.vbox)

        self.button.connect("clicked", self.on_clicked)
        self.window.connect("destroy", lambda x: gtk.main_quit())
        self.window.show_all()
        self.window.show()

    def on_clicked(self, widget):
       self.label.set_text("You clicked the button!") 

if __name__ == "__main__":
    app = Gui()
    #Basta de GTK!
    #gtk.main()
    from twisted.internet import reactor
    #Empezamos el loop
    reactor.run()

Ahora podemos felizmente disfrutar el poder de Twisted en nuestras aplicaciones graficas :) . Para terminar, este es un simple ejemplo de callbacks al estilo Twisted

import gtk
from twisted.internet import gtk2reactor # for gtk-2.0
gtk2reactor.install() #Instalamos de gtk2 reactor
#NOTE: This have to be at top always, before starting the reactor
#NOTA: Esto tiene que estar siempre al principio, antes de importar el reactor

class Gui:
    def __init__(self):
        self.window = gtk.Window()
        self.window.set_default_size(200,200)
        self.window.set_title("Simple PyGTK program")

        self.vbox = gtk.VBox()

        self.button = gtk.Button("I'm a button!")

        self.time = time.time()

        self.label = gtk.Label("0")

        self.vbox.pack_start(self.button)
        self.vbox.pack_start(self.label)

        self.window.add(self.vbox)

        self.button.connect("clicked", self.on_clicked)
        self.window.connect("destroy", lambda x: gtk.main_quit())
        self.window.show_all()
        self.window.show()
        self.time = time.time()

    def on_clicked(self, widget=None):
        self.label_text = time.time() - self.time
        self.label.set_text("%.2fs" % self.label_text)
        #Twisted va a llamar a la funcion self.on_clicked cada 100ms
        reactor.callLater(.1, self.on_clicked)

if __name__ == "__main__":
    app = Gui()
    #Basta de GTK!
    #gtk.main()
    from twisted.internet import reactor
    #Empezamos el loop
    reactor.run()

Twisted tiene otras APIS para otros toolkits como Tkinter, wxPython, Win32(Windows) y PyUI. Para mas info consultar la documentación oficial.

Continuar leyendo →