Personal Website

My Web: MindEchoes.com

Wednesday, May 27, 2009

Si UTNEmall Lo Hace Yo Igual!!

Bueno, si la gente de UTNEmall festeja el lanzamiento del ejemplo que hicieron para Microsoft, yo tambien quiero festejar... la relevancia de esto no es ni parecida jeje pero por lo menos ya NADIE va a estar preguntando: "y para cuando esta el sistema?" (encima que uno se ofrece a hacerlo de onda...)


SUPER LANZAMIENTO DE:
LisBio

Conocido por todos como:
Dedieitor!

Sistema de Gestión del Laboratorio de Investigación de Software.
Realizado en conjunto con el Daro, Yo y... (lo ponemos o no lo ponemos?? jeje) el Pichi!

Toda la información y código del proyecto se encuentra en: Dedieitor

Disclaimer: No nos hacemos cargo de nada...

Akinator Si Que Sabe!!


Para los que no conocen la página, Akinator es un "Genio" que te hace preguntas y adivina en que personaje estas pensando...
http://www.akinator.com/

Thursday, May 21, 2009

UML de la Matrix!

Bueno, en una mision suicida... logra obtener el UML creado por el Arquitecto de La Matrix!!
Y como el conocimiento es Libre aca por primera vez se hara publico EL UML DE LA MATRIX!!

Click en la imagen para Ampliar

Proximamente sera implementado!!

Logo HPC

Bueno, ya que al parecer perdi 6 HORAS haciendo un logo que el Grupo de HPC (High Performance Computing) no va a usar... aunque sea lo posteo en mi blog!



P.D.: Maldito Puza!! jeje

Tuesday, May 19, 2009

PyQt: Algunos Trucos (Mini Tutorial)

Bueno, estos dias estuve jugando con PyQt, y queria postear un par de cosas por si le llega a servir a alguien.

Primero que nada PyQt es un binding de la libreria grafica Qt para Python (y es Multiplataforma).
Vamos a mostrar como crear una aplicación basica con PyQt usando un par de cosas interesantes:

Primero que nada las librerias que necesitamos importar en nuestro archivo que llamaremos "pyExample.py":

import sys
from PyQt4 import QtGui, QtCore


Importando el modulo de "sys" podemos usar varias variables y funciones para manipular varias partes del runtime del ambiente de Python.
Importando QtGui estaremos trayendo los modulos necesarios para trabajar con los componentes graficos, y QtCore nos sera necesario para el manejo de la conexión de señales en este caso.

Ahora creamos nuestra Clase y su constructor:

Codigo fuente

class PyQtExample(QtGui.QMainWindow):

def __init__(self):
QtGui.QMainWindow.__init__(self)
self.resize(550, 100)
self.setWindowTitle("Main Program")

style = self.style()
self.setWindowIcon(style.standardIcon(
QtGui.QStyle.SP_ComputerIcon))

self.languages = {}
self.languages['c'] = 'cout << "Hello World";'
self.languages['java'] = 'System.out.println("Hello World");'
self.languages['python'] = 'print "Hello World"'

self.create_widgets()
self.create_menu()
self.create_radio_menu()

Esta clase "PyQtExample" hereda de la clase QtGui.QMainWindow para ser un contenedor del tipo ventana que se mostrara en la pantalla.
Luego con:

self.resize(550, 100)
self.setWindowTitle("Main Program")


Le damos el tamaño a la ventana (ancho, alto) y el titulo de la ventana ("Main Program") respectivamente.

Con el siguiente codigo consigo utilizar los recursos de las imagenes standard que posee Qt (las cuales pueden ser consultadas aqui)
Obtengo una instancia de "style", y luego seteo el icono de la ventana usando los Standard Pixmap con los que cuenta Qt.

style = self.style()
self.setWindowIcon(style.standardIcon(
QtGui.QStyle.SP_ComputerIcon))

Y con el código restante todo lo que se hace es crear un diccionario para utilizarlo luego en otra parte de la aplicacion, y se llama a 3 funciones que se veran a continuación para setear distintos aspectos de la interfaz y el programa.

-----

Ahora agregamos a nuestra clase 3 nuevas funciones, la primera de ellas "create_widgets":

Codigo fuente

def create_widgets(self):
self.label = QtGui.QLabel("Results")
self.text = QtGui.QLineEdit()
self.exit = QtGui.QPushButton('&Close')

QtCore.QObject.connect(self.exit,
QtCore.SIGNAL("clicked()"),
self, QtCore.SLOT("close()"))

h_box = QtGui.QHBoxLayout()
h_box.addWidget(self.label)
h_box.addWidget(self.text)
h_box.addWidget(self.exit)
central_widget = QtGui.QWidget()
central_widget.setLayout(h_box)
self.setCentralWidget(central_widget)

Analizando la función "create_widget" vemos que con el siguiente código creo 3 elementos, un Label, un Campo de Texto y un Boton:

self.label = QtGui.QLabel("Results")
self.text = QtGui.QLineEdit()
self.exit = QtGui.QPushButton('&Close')


Luego le agrego comportamiento al boton uniendo la "señal" de cuando el boton es presionado, al fragmento de código ya predefinido de cerrar la ventana que posee la ventana.

QtCore.QObject.connect(self.exit, QtCore.SIGNAL("clicked()"),
self, QtCore.SLOT("close()"))


De esta forma como se ve dentro de la función "connect" estoy teniendo los siguientes parametros: "Objeto que emite la señal", "señal que emite(y se desea conectar)", "Objeto que va a recibir la señal", "Acción/Código a ejecutar".
Luego con el código restante seteamos un Layout a utilizar para definir como se acomodaran los componentes graficamente en la interfaz, le agregamos a ese layout los componentes que habiamos creado. Luego creamos un Widget, le asignamos ese Layout al Widget y terminamos agregando ese Widget a la ventana principal:

h_box = QtGui.QHBoxLayout()
h_box.addWidget(self.label)
h_box.addWidget(self.text)
h_box.addWidget(self.exit)
central_widget = QtGui.QWidget()
central_widget.setLayout(h_box)
self.setCentralWidget(central_widget)


Luego creamos la siguiente función "create_menu":

Codigo fuente

def create_menu(self):
self.menuBar = QtGui.QMenuBar(self)
self.setMenuBar(self.menuBar)
self.menu = self.menuBar.addMenu('&Menu')

actionC = self.menu.addAction('c')
QtCore.QObject.connect(actionC, QtCore.SIGNAL("triggered()"),
self.print_from_c)

actionJava = self.menu.addAction('java')
QtCore.QObject.connect(actionJava, QtCore.SIGNAL("triggered()"),
lambda: self.print_from_language('java'))

actionPython = self.menu.addAction('python')
QtCore.QObject.connect(actionPython, QtCore.SIGNAL("triggered()"),
lambda: self.repeat_from_language('python', 3))

En esta función primero se crea una Barra de Menu, se agrega esa Barra de Menu a la ventana principal y luego a esta Barra se le agrega un Menu.

self.menuBar = QtGui.QMenuBar(self)
self.setMenuBar(self.menuBar)
self.menu = self.menuBar.addMenu('&Menu')


Como se puede ver al menu que se agrega se le pasa la cadena '&Menu' esto indica que a ese menu podremos acceder presionando "Alt+M".

Luego se ven 3 conceptos interesantes, se crean 3 acciones (se podria trabajar de otra forma, pero se hace asi a modo de ejemplo), esas acciones son agregadas al menu como parte de este y luego se conecta la señal que producen esas acciones al ser ejecutadas con cierto código.
Cabe aclarar que en los menus solo se pueden agregar Acciones o Menus, pero las Acciones en realidad pueden tomar la forma que necesitemos para representar otros componentes como RadioButton, CheckButton, etc. Como se vera mas adelante.

En el primer caso:

actionC = self.menu.addAction('c')
QtCore.QObject.connect(actionC, QtCore.SIGNAL("triggered()"),
self.print_from_c)


Creamos nuestra acción "actionC" en base a la acción que es devuelta al agregar una acción al menu directamente a través de "addAction" y luego conectamos esa acción, con su señal "triggered()" (que para los menus es cuando son presionados) junto con una función dentro de nuestra clase que recibira el nombre de "print_from_c".
Hay que tener en cuenta que la función que estamos seteando que sera conectada a la señal no lleva los parentesis, es decir:

self.print_from_c [CORRECTO]
self.print_from_c() [INCORRECTO]

Ademas otra cosa a tener en cuenta, es que como veremos mas adelante al definir esta función, la misma no recibe ningun argumento, es por eso que no presenta problema al realizar esta conexión, pero si quisieramos que se invocara una función que recibe argumentos, estariamos en el segundo caso:

actionJava = self.menu.addAction('java')
QtCore.QObject.connect(actionJava, QtCore.SIGNAL("triggered()"),
lambda: self.print_from_language('java'))


En este caso se hace lo mismo que antes, se crea la acción y luego se conecta su señal con una función, pero como en este caso necesitamos llamar a una función que recibe argumentos, y estos no pueden especificarse directamente en el metodo "connect" por la forma en que se especifican las funciones a ser conectadas, se recurre al uso de "lambda". Como se ve en el código para la conexión de "actionJava" se utiliza "lambda" para que se tome esta como la función a utilizar, siendo que ahi mismo definimos el comportamiento de lambda y por lo tanto podemos utilizar llamadas a funciones con la cantidad de argumentos que necesitemos.

En el caso anterior se llama a una función con 1 argumento, pero bien podria hacerse con 2 argumentos como el caso de "actionPython" o con cualquier otra cantidad de argumentos segun definamos.

actionPython = self.menu.addAction('python')
QtCore.QObject.connect(actionPython, QtCore.SIGNAL("triggered()"),
lambda: self.repeat_from_language('python', 3))


Es muy importante mencionar, que en Python se permite conectar una señal de un componente a cualquier función de Python, sin necesidad de especificar que dicha función es un SLOT como deberia hacerse en Qt/C++.

Luego definimos la ultima función que nos estaba faltando: "create_radio_menu":

Codigo fuente

def create_radio_menu(self):
self.menuRadio = self.menuBar.addMenu('Menu &Radio')
self.radio1 = self.menuRadio.addAction('Results (en)')
self.radio2 = self.menuRadio.addAction('Resultados (es)')

group = QtGui.QActionGroup(self.menuRadio)
self.radio1.setCheckable(True)
self.radio2.setCheckable(True)
self.radio1.setActionGroup(group)
self.radio2.setActionGroup(group)
self.radio1.setChecked(True)

QtCore.QObject.connect(self.radio1,
QtCore.SIGNAL("triggered()"),
lambda: self.label.setText('Results'))
QtCore.QObject.connect(self.radio2,
QtCore.SIGNAL("triggered()"),
lambda: self.label.setText('Resultados'))

Esta función como podemos ver, crea un Menu utilizando la misma tecnica empleada en la función anterior, y luego crea 2 acciones que agregara a este menu:

self.menuRadio = self.menuBar.addMenu('Menu &Radio')
self.radio1 = self.menuRadio.addAction('Results (en)')
self.radio2 = self.menuRadio.addAction('Resultados (es)')


Hasta este momento estas son acciones simples como las definidas anteriormente, pero si deseamos que nuestras acciones cumplieran la función de un CheckButton en el menu utilizariamos la función:

self.radio1.setCheckable(True)

De esta forma nuestra acción "radio1" pasaria a convertirse en un CheckButton situado en el menu, pero si quisieramos en realidad que nuestras 2 acciones ingresadas fueran 2 RadioButton donde solo uno a la vez pueda estar seleccionado, solo necesitariamos crear un ActionGroup y setearla a nuestras acciones la pertenencia a este grupo, tal como se ve en el código siguiente:

group = QtGui.QActionGroup(self.menuRadio)
self.radio1.setCheckable(True)
self.radio2.setCheckable(True)
self.radio1.setActionGroup(group)
self.radio2.setActionGroup(group)
self.radio1.setChecked(True)


Luego, lo unico que queda es conectar dichos componentes con su respectivo comportamiento, y eso es lo que hace el código siguiente utilizando el recurso "lambda" para realizar la operación que se desea directamente en ese lugar sin tener que andar llamando a otras funciones:

QtCore.QObject.connect(self.radio1,
QtCore.SIGNAL("triggered()"),
lambda: self.label.setText('Results'))
QtCore.QObject.connect(self.radio2,
QtCore.SIGNAL("triggered()"),
lambda: self.label.setText('Resultados'))


-----
Ahora vamos a definir las 3 funciones utilizadas en la función "create_menu":

Codigo fuente

def print_from_c(self):
self.text.clear()
self.text.setText(self.languages['c'])

def print_from_language(self, lang):
self.text.clear()
self.text.setText(self.languages[lang])

def repeat_from_language(self, lang, num):
self.text.clear()
self.text.setText(self.languages[lang] * num)

El código en estas funciones es simple y no requiera de mucha explicación, simplemente se presentan los 3 casos mencionados anteriormente de funciones sin argumentos, con 1 argumento y con 2 argumentos, las cuales eliminan primero el contenido del componente de Texto y luego le setean el contenido dependiendo del valor que devuelve el diccionario definido dentro de la clase. En el caso de la ultima función se imprime ese valor devuelto por el diccionario un numero "n" de veces especificado por el argumento "num" recibido por la función.

-----
Para ir finalizando, vamos a mostrar como hariamos si quisieramos redefinir una función de la clase de la que estamos heredando para que, por ejemplo, al intentar cerrar la aplicación se ejecute algún comportamiento definido por nosotros:

Codigo fuente

def closeEvent(self, event):
reply = QtGui.QMessageBox.question(self, "Exit",
"Quit Application?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

if reply == QtGui.QMessageBox.Yes:
event.accept()
else:
event.ignore()

Mediante este código, al intentar cerrarse la aplicación con la X, o con el Boton "Close" definido por nosotros, aparecera un mensaje que nos preguntara si queremos salir de la aplicación o no, y dependiendo si nuestra respuesta es positiva o negatica, se aceptara o se rechazara dicho evento.

-----
Ahora si para terminar, una vez escrita nuestra clase, solo debemos agregar al final de nuestro archivo, sin identación, el siguiente código para hacer ejecutable nuestra aplicación:

Codigo fuente

app = QtGui.QApplication(sys.argv)
main = PyQtExample()
main.show()

sys.exit(app.exec_())

Ahora solo queda ejecutar nuestra aplicación escribiendo en consola: "python [nombre_archivo]" Y LISTO!!

El archivo fuente generado para este ejemplo puede ser descargado en este link.
Cualquier sugerencia o mejora es Bienvenida!

Ejemplo realizado con:
Python Version: 2.6.2
Qt Version: 4.5

Sunday, May 17, 2009

Usar USB en VirtualBox 2.2.2 (Jaunty)

Para aquellos que hayan luchado en versiones anteriores de VirtualBox por intentar hacer que funcione leyendo los dispositivos USB, ahora es posible y MUY FACIL!

Vamos a una consola y tecleamos lo siguiente:
  • sudo grep vbox /etc/group
Con esto obtendremos en id del grupo vboxusers, en mi caso: vboxusers:x:125: puede que en lugar de 125 te de otro número, recuerdalo.
  • sudo gedit /etc/init.d/mountkernfs.sh

buscamos la siguente línea:

domount proc "" /proc proc -onodev,noexec,nosuid

y justo debajo escribimos esta otra:

domount usbfs usbdevfs /proc/bus/usb
-onoexec,nosuid,nodev,devgid=125,devmode=664
El valor de Devgid es el que antes hemos tenido que comprobar y recordar, ahora vamos a editar fstab:
  • gedit /etc/fstab

y al final agregamos la siguiente línea:

#usbfs
none /proc/bus/usb usbfs devgid=125,devmode=664 0 0

Y ahora sí, nos aseguramos de tener el usb habilitado en VirtualBox, reiniciamos la máquina y listo, ya podemos meterle un pendrive a VirtualBox 2.2.2 sin miedo, este nos lo reconocerá de inmediato.

Fuente: www.ociolinux.blogspot.com (Muy Bueno!)

Friday, May 15, 2009

Plugin4J - Syriox

Bueno, acabo de terminar de escribir 2 papers para la JAIIO-EST 2009, y me dieron ganas de postearlos en el blog para que esten disponibles los links donde se pueden leer en Google Docs:

Tuesday, May 12, 2009

Correccion Ortografica Open Office

Este post va dedicado para aquellos que se han vuelto locos tratando de hacer funcionar el corrector ortografico del Open Office.
Esta solución es para Linux (igual para que me iba a molestar en windows jeje).

Si te paso que escribiste un documento, no prestaste atención a los acentos, etc. y cuando terminas de escribir apretas el boton de chequear la ortografia y te tira que ya termino pero no hace nada... y despues googleas y googleas para ver como arreglarlo, instalas diccionarios y nada funciona... esta debe ser tu solución:

Abris una consola y escribis:

sudo apt-get install myspell-es

Y Listo!!

Thursday, May 7, 2009

Wednesday, May 6, 2009

Cosmos


Video hecho con 3d Studio Max por Alexval5.
Musica de: Mike Oldfield - Let There Be Light

Sunday, May 3, 2009

Sum 41 - Pieces

Uno de los Mejores Temas que conozco con imagenes de Final Fantasy!
Nada mas que decir...