Personal Website

My Web: MindEchoes.com

Friday, August 28, 2009

Foto-Relato Mar Del Plata

Estaba pensando el Titulo apropiado para este post...
Me decidi al final por: "Foto-Relato Mar Del Plata", pero los otros titulos posibles eran:
  • Relato De Una Tragedia
  • Aplicación Practica De La Ley De Murphy (si algo puede salir mal... va a salir mal...)

Comienzo del viaje... teniamos pasajes en colectivo para salir de Córdoba el Martes 25 a las 15:45... para nuestra sorpresa... HABIA PARO DE COLECTIVOS!!!
Que Hacemos??!! fue la pregunta... y la respuesta fue: "y bueno... nos vamos en avion!"...
Fue una decisión dura... pero no quedaba otra... (de paso me sacaba las ganas de viajar en avión que tenia hace tiempo), pero el lado ALTAMENTE NEGATIVO... quedabamos en la ruina economica!!

Pero... para ser sinceros... valio la pena viajar en avion!!! en 1 hora ya estabamos en Buenos Aires!! y que emoción que es viajar en avionnnnnnn!!!!!!!!!!!!! yo no puedo entender como algunos iban durmiendo...... yo no me podia quedar quieto y miraba por la ventana todo el tiempo!


Al final en el avión terminamo viajando con Marianiten... claro que el no estaba sufriendo de la debacle economica que estabamos sufriendo nosotros...

En el avión viajamos con unas """estrellas""" (si... leer con muchas comillas...) de la televisión... el unico que las reconocio fue Luisito... Mariano y Yo deciamos... "na... esa vieja no puede ser..." pero si... si lo era.... Luisito el farandulero tenia razon...

Una vez llegados a Mar Del Plata... nos acordamos que nunca habiamos anotado la dirección del Hotel... (como para variar)... por suerte si teniamos el telefono... asi que llamamos para preguntar la dirección.

Llegamos al Hotel... y habiamos hecho una reserva para el día Miercoles y para una habitación de 3 camas... y estabamos yendo solo 2 personas... y un día antes... improvisación de viaje total! por suerte nos pudieron acomodar sin que gastemos mas...
Al entrar a la habitación obviamente lo primero fue sacar las notebooks jeje

Despues Luisito se empezo a poner paranoico con que nos podian afanar las notebooks cuando salieramos... asi que inspecciono toda la habitación... y encontro un escondite para las notebooks debajo de los cajones del armario... (donde las guardamos todos los dias)... sin palabras...

Veniendo de una Crisis Economica... despues de dejar las cosas, salimos a buscar donde comer... obviamente los primeros locales que vimos fueron descartados porque se salian de nuestro "acotado" presupuesto jeje... hasta que de repente... LLEGAMOS AL CIELO!!!
"Soul Rebel"... IMPRESIONANTE!!! pagamos muy poco......... y comiamos mucho!!



Despues volvimos a la habitación... y a descansar...
Al otro dia... nos despertamos para desayunar... obviamente con las notebooks...

Todo el día en la JAIIO... y despues a la noche... a pasear un poco por la costanera para que no se diga que no hicimos nada...
Como buen informatico recluido de la luz natural... fuimos a la playa de noche jeje

Siguiendo con el paseo... encontramos el Casino, y dijimos... entremos a conocerlo... ya venimos con mala suerte... tiene que mejorar...

Obviamente estabamos equivocados...

Estando totalmente en la quiebra... habia que buscar un lugar donde dormir:

Despues de dormir un rato... seguimos paseando y empezamos a pensar como recuperar algo de plata y comer...
Probamos con la pesca...

Pero nos fue mejor vendiendo artesanias:

Por ultimo dijimos... Somos Programadores... usemos ese recurso...
Por eso utilizamos la estrategia:


(Somos Programadores Queremos Comer)

Aplicamos Metodologias Agiles de Desarrollo... "Lustram"... uno le programaba un sistema en el tiempo en el que el otro le lustraba el zapato...
Con esto salimos de la ruina...
Y decidimos salir a Pasear...



Como no podia ser de otra forma... nos perdimos... en la dirección que creiamos que estabamos volviendo al hotel... al parecer estabamos yendo TOTALMENTE PARA CUALQUIER LADO Y NO SE COMO ESTABAMOS RE LEJOS!!

A todo esto... me habia olvidado mi cepillo de dientes en Cba y venia buscando donde comprar... encontre un lugar donde comprar el cepillo de dientes.. y cuando pudimos volver cerca del Hotel fuimos a comer... para variar... el cepillo de dientes me lo deje en el local de comida... otra vez estaba sin cepillo...

Despues del día donde estuve exponiendo en la JAIIO



Llegamos filtrados al Hotel... y mirando tele... cada uno se quedo dormido... a las 12 de la noche nos depertamos con el celular y se dio el siguiente dialogo:

"no puedo dormir"
"yo tampoco... salgamos"
"dale"

NOTABLE LA RESISTENCIA!!
Salimos a buscar algún Pub que no habiamos visto ninguno las noches anteriores...
Preguntamos en la calle como hacer para llegar a alguno... ibamos caminando.. y veo una farmacia abierta!!
OH SII!! CEPILLO DE DIENTES!!

Compre mi cepillo de dientes y nos quedamos charlando con el farmaceutico que nos termino recomendando adonde salir que estaba muy bueno el Pub y que cualquier cosa le dijeramos al tipo de la entrada que nos mandaba el señor de la farmacia!

El Pub la verdad Muy Bueno!! Hasta metio Karaoke despues!!
(a todo esto... sali al Pub con el Cepillo de Dientes en el bolsillo...)

Despues volvimos a dormir... y al otro dia cuando nos liberamos de la JAIIO... nos fuimos a comer la Super "Hamburguesa Soul Rebel"


Ahi terminan nuestras desventuras en Mar del Plata... mientras escribo esto Luisito me dice que hay cortes de ruta y en un rato tenemos que salir en Colectivo para Córdoba... esperemos no seguir con la racha de mala suerte...

Monday, August 24, 2009

QuickDB - 0.5-BETA

Bueno, ya llegue a una version BETA de QuickDB que se encuentra en un estado con muchas funcionalidades incorporadas y posible de ser usada (eso si... tendria que probarla alguien que no sea el desarrollador para ver que pasa).

La documentación para ver todo lo que se puede hacer actualmente con la libreria, se puede consultar en la Wiki.

Aca dejo 2 screencast paso a paso de como trabajar con la Creación de un Objeto cuya Tabla no existe y que la libreria se encargue de Crear la Tabla y Guardar los Datos en la primera inserción:


Y este otro screencast muestra como la Libreria maneja automaticamente la herencia de las clases para dividir dicha información en otras Tablas (tambien en este caso no existen ninguna de las Tablas y son creadas automaticamente al hacer la inserción):

Charla de Richard Stallman

La verdad estubo MUY BUENA la charla... muy bueno los chistes y "palitos" que tiraba Stallman!
Y cuando se disfrazo de "Clerigo" de la Iglesia de Emacs fue genial!!!

Algunas fotos:






En la ultima foto estoy YO!! jeje el que tiene la remera negra CON EL LOGO DE ESTE BLOG!! JEJE

Diagrama de Flujo para el Soporte Informatico

[basado en la caricatura original de XKCD y tomado de MundoGeek]

Friday, August 14, 2009

Mudanza Del LIS

Mudanza del LIS (Laboratorio de Investigación de Software) al Edificio Maders.




El resto de las fotos pueden verse en el Album Laboratorio

Thursday, August 13, 2009

QuickDB - 1.2-SNAPSHOT


QuickDB ya tiene su propia pagina de Proyecto (lo saque de incubación :P), y esta disponible la Version 1.2-SNAPSHOT.

La página del Proyecto es la siguiente: http://code.google.com/p/quickdb/

También se encuentra disponible la Documentación del Proyecto en Español y en Ingles:

Esta Versión soporta las siguientes caracteristicas:
  • save
  • saveAll
  • modify
  • modifyAll
  • obtain
  • obtainAll
  • obtainNext
  • obtainPrevious
  • delete
  • executeQuery
Y los siguientes modos de operación:
  • Verbose
  • DropDown
Los cuales son explicados en la Documentación y lo que intentan hacer es brindar mas herramientas para que el usuario se dedique unicamente al desarrollo de las Entidades y la librería se encargue de hacer el mapeo a la Base de Datos correspondientes.

Wednesday, August 12, 2009

QuickDB - 1.1-SNAPSHOT

Bien, hace unos dias venia programando esta libreria de Persistencia, y aunque todavia esta en desarrollo, ya tiene muchas funcionalidades implementadas que pueden usarse y queria mostrar como el uso de esta libreria puede facilitar mucho el manejo de persistencia.

Para mostrar las cosas que se pueden hacer con la libreria desarrolle un ejemplo utilizando una Base de Datos MySQL (la unica soportada por el momento).
El script de creación de la Base de Datos puede obtenerse del siguiente link.

Las Tablas de la Base de Datos estan representadas en la siguiente imagen:


Bien ahora que tenemos nuestra Base de Datos con nuestras Tablas, vamos a ir creando nuestras clases Entidades que se mapean con nuestras tablas y explicando el uso de QuickDB con ejemplos concretos.

Primero vamos a crear la Clase Person:
import cat.inkubator.annotation.*;

@Table
public class Person{

@Column(type=Properties.TYPES.PRIMARYKEY)
private int id;
@Column(name="name")
private String personName;
@Column(getter="getPersonAge", setter="setPersonAge")
private int age;
@Column(type=Properties.TYPES.SQL)
private String sql;

public Person(String name, int age){
this.id = 0;
this.personName = name;
this.age = age;
this.sql = "";
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getPersonName() {
return personName;
}

public void setPersonName(String personName) {
this.personName = personName;
}

public int getPersonAge() {
return age;
}

public void setPersonAge(int age) {
this.age = age;
}

public String getSql() {
return sql;
}

public void setSql(String sql) {
this.sql = sql;
}

}
Bueno, la libreria utiliza solo 2 Anotaciones para el manejo de los datos de la Entidad:
  • Table
  • Column
Table puede estar acompañada de un parámetro o no, el parametro de Table indica a que tabla de la Base de Datos se mapeara esta entidad. Al no incluir el parametro simplemente se asume que la Tabla lleva el mismo nombre que la Clase.
Por el contrario si la Tabla tuviera otro nombre simplemente se podria hacer:
@Table("[nombre-tabla]")
public class Person{

En cuanto a las anotaciones Column, estas pueden recibir 4 parámetros:
  • name: Nombre del Campo de dicha Tabla en la Base de Datos (si no se especifica toma el mismo nombre del atributo).
  • type: Indica el tipo de dato del atributo, el cual puede ser [PRIMITIVE, PRIMARYKEY, FOREIGNKEY, SQL]. PRIMITIVE hace referencia a aquellos tipos que se mapean directamente a la base de datos como enteros, cadenas, etc (si no se especifica se asume que el tipo es PRIMITIVE).
  • getter: Este atributo presenta la posibilidad de poder expresar explicitamente cual sera el metodo del cual obtendremos el valor de dicho atributo (si no se especifica se asume que si el atributo lleva el nombre "atributo" el metodo getter sera "getAtributo").
  • setter: El mismo caso anterior pero para los metodos de seteo.
Como se puede ver en el ejemplo de la Clase Person, al atributo "id" se le especifica que es el atributo que se mapeara con la PRIMARYKEY en la Base de Datos, esto es de importancia para que al realizar una inserción, no intente ingresar este dato si lo tenemos configurado para que se auto-incremente.
Al Atributo "personName" se le especifica en su anotacion cual sera el nombre del Campo en la Tabla de la Base de Datos al que se mapeara su valor al no tener una relación directa.
En cuanto al Atributo "age" se le especifican explicitamente los metodos de "set" y "get" al no seguir la convención por defecto.
Y por ultimo al ultimo atributo "sql" se le asigna tipo SQL lo cual nos indica que a traves de ese atributo podremos realizar algunas interacciones directas con la Base de Datos o especificar simplemente la parte del WHERE para las busquedas como ya se vera.

Ahora que ya se encuentran explicadas el uso de las anotaciones, veamos el resto de las Entidades:

Address:
(Es necesario tener en nuestras entidades todos los Getters y Setters, pero en los ejemplos no se mostraran para que el código no quede tan largo)
import cat.inkubator.annotation.*;

@Table("address")
public class Address{

@Column(type=Properties.TYPES.PRIMARYKEY)
private int id;
@Column
private String street;
@Column(type=Properties.TYPES.FOREIGNKEY)
private District idDistrict;

public Address(){
this.street = "";
this.idDistrict = new District("");
}

public Address(String street, District district){
this.street = street;
this.idDistrict = district;
}

}
En este caso al ser MySQL case-sensitive (al menos en Linux) y la Tabla llevar el nombre "address" con la primer letra en minuscula, se utiliza el parametro de @Table para especificar la Tabla a la que se mapeara.
En el caso del Atributo "street" al seguir las convenciones y valores por defecto simplemente se le agregar la anotación @Column arriba sin parametros y listo.
Y para el tercer caso "idDistrict" es en realidad un objeto de otra Clase nuestra, que a su vez se mapea en otra Tabla como se ve en el diagrama de arriba, por esto se indica en su tipo FOREIGNKEY, y la libreria automaticamente se encarga de guardar ese objeto en su respectiva Tabla y luego obtener su "id" para insertarlo en el campo de la Tabla "address".

District:
import cat.inkubator.annotation.*;

@Table("district")
public class District{

@Column(type=Properties.TYPES.PRIMARYKEY)
private int id;
@Column
private String name;

public District(String name){
this.name = name;
}

}
Ahora vamos a utilizar estas clases creadas para hacer algunas operaciones antes de seguir con el resto.
Ahora creamos nuestro main donde crearemos distintas instancias de nuestras Entidades y realizaremos operaciones sobre la Base de Datos:
import cat.inkubator.db.AdminBase;
import java.util.ArrayList;

public class App
{

public static void main( String[] args )
{
AdminBase admin = new AdminBase("localhost", "3306", "testQuickDB",
"root", "", AdminBase.DATABASE.MYSQL);
Person person = new Person("diego", 23);
admin.save(person);
}

}
De esta forma, creamos un Objeto "AdminBase" pasandole los parametros necesarios para que realice la conexión a la Base de Datos correspondiente, y luego simplemente nos dedicamos a utilizar AdminBase pasandole a sus distintos metodos nuestro objetos para que haga operaciones con ellos.
Como en el ejemplo que se ve arriba, se crea una instancia de la Clase Person, y se ejecuta el método "save" de AdminBase para guardar ese objeto.

Ahora si quisieramos guardar un conjunto de Objetos Person, simplemente hariamos lo siguiente:
        ArrayList array = new ArrayList();
array.add(new Person("name1", 20));
array.add(new Person("name2", 20));
admin.saveAll(array);
Para realizar busquedas, y por ejemplo obtener un Objeto Person, de una persona que tenga edad 23 (como se cargo en el primer ejemplo de aplicación) se empezaria a utilizar el atributo marcado como SQL de la siguiente forma:
        Person p = new Person("",0);
p.setSql("age=23");
admin.obtainSingle(p);
Es importante antes de cualquier operación crear una instancia (vacía) del objeto al que se esta haciendo referencia para que la librería pueda inferir cuales son los atributos que debe manejar.

Para realizar una modificación y luego eliminar ese objeto de la Base de Datos simplemente hacemos (en este caso se sigue trabajando con el objeto obtenido en el ejemplo anterior):
        p.setPersonName("utopia");
admin.modify(p);

admin.delete(p);
Ahora supongamos que queremos hacer una busqueda de aquellas personas que tengan edad 20 y obtener todos los resultados posibles. AdminBase tiene un metodo que nos permite realizar esta operación y nos devuelve un boolean indicando si se pudieron encontrar objetos o no y nos completa los datos del objeto que le pasamos por parametro. Luego para ir explorando la lista completa de los objetos obtenidos se utilizan los metodos "obtainNext" y "obtainPrevious", los cuales nos devuelven true si existe el dato que queremos ver o false si por el contrario ya no hay mas datos en esa dirección.
Ahora si quisieramos tener de una sola vez nuestro Array de objetos completo podriamos hacer lo siguiente:
        Person per = new Person("",0);
per.setSql("age=20");
ArrayList results = new ArrayList();
if(admin.obtainAll(per)){
results.add(per);
App app = new App();
app.loadArray(admin, array);
}

public void loadArray(AdminBase admin, ArrayList array){
Person per = new Person("",0);
if(admin.obtainNext(per)){
array.add(per);
this.loadArray(admin, array);
}
}
Ahora supongamos que tenemos un Objeto compuesto por otro Objeto, lo que se mapearia en la Base de Datos como una Tabla con una referencia de Foreign Key hacia otra Tabla como es el caso de las Tablas: "Address" y "District".
Bueno, para este caso simplemente marcamos cual de nuestro atributos es una Foreign Key (como hicimos en la clase Address), y QuickDB se encargara de guardar todos los objetos en sus respectivas Tablas y asignar el "id" obtenido en la inserción a la Tabla que la referencia.
Entonces para realizar la inserción de un Objeto Compuesto simplemente hacemos:
        District d = new District("nva cba");
Address a = new Address("puey 600", d);
admin.save(a);
AdminSave tambien permite la inserción de objetos compuestos de forma masiva utilizando como se vio antes "saveAll".

Ahora supongamos que nuestras Entidades en nuestro programa se mapean DIRECTAMENTE a nuestra Base de Datos, es decir, nuestras Tablas se llaman igual que nuestras Clases y nuestro Campos igual que nuestros Atributos, en ese caso podriamos optar simplemente por crear las Clases sin anotación alguna como en los siguientes ejemplos:

Dog:
public class Dog{

private int id;
private String name;
private String color;
private Race idRace;
private String sql;

public Dog(){
this.idRace = new Race();
this.name = "";
this.color = "";
}

}
Race:
public class Race{

private int id;
private String name;
private String sql;

public Race(){
this.name = "";
}

}
(Los metodos de "set" y "get" fueron obviados para el ejemplo pero deben estar presentes)

Como podemos ver estas 2 clases no presentan ninguna de las anotaciones presentadas anteriormente. Cuando trabajamos con clases asi que pueden ser mapeadas directamente a la Base de Datos, podemos desactivar el modo "Verbose" de AdminBase y trabajar con estas Clases de la misma forma que hariamos si contuvieran las anotaciones, incluso para objetos compuestos como puede verse en el ejemplo:
        admin.setVerbose(false);
Dog dog = new Dog();
dog.setName("sasha");
dog.setColor("black");

Race race = new Race();
race.setName("collie");

dog.setIdRace(race);
admin.save(dog);

dog.setSql("name='sasha'");
admin.obtainSingle(dog);
En el ejemplo anterior se crea un objeto "Dog" y un objeto "Race" se asigna a Dog el objeto Race y despues se guardan esos datos, de esta forma se guardara el Objeto Race en su respectiva Tabla, devolvera el Id de la posición en la que se guardo y luego se guardara el Objeto Dog en su respectiva Tabla colocando en el campo de Foreign Key de Race el Id obtenido previamente.
Luego simplemente se realiza un "obtainSingle" para obtener un objeto con los mismos valores que se acaban de guardar para mostrar que tambien se pueden realizar consultas de objetos compuestos sin necesidad de anotar las clases.

El código fuente del Proyecto se encuentra en: QuickDB
Y el ejemplo que se presento puede ser descargo completamente junto con los fuentes y la libreria compilada de QuickDB y el script de creación de la Base de Datos del siguiente link: Ejempo

Saturday, August 8, 2009

Resumen ECI 2009

Bueno... acabo de volver de la ECI 2009, y la verdad que este año me parecieron GENIALES los cursos!!
El nivel en general me parecio muy bueno, la organización fue impecable desde mi punto de vista, y pude reencontrarme con algunos de los amigos de Salta que habia hecho el año pasado y conocer algunos nuevos.

Ahora... Resumen de la semana en Buenos Aires:

Llegue a Buenos Aires, ni idea de nada... me pierdo en cualquier lado, y Buenos Aires con lo grande que es no iba a ser la excepción...
Por eso el primer día voy a la parada del colectivo que me dijeron que me lleva a Ciudad Universitaria, pero en Buenos Aires parece haber un gran complot porque los mismos colectivos van para distintos lados... no se... un lio para mi jeje
Entonces la estrategia era: "Ir a la parada, buscar alguien que tuviera cosas de arquitectura o algo asi y seguirlo en el colectivo que se suba!"

Una vez que llegas a la Ciudad Universitaria ya esta facil, porque la ECI es la primera universidad donde para el colectivo...

Luegooooooo el gran desafio!! la vuelta en Colectivo... aca se complica un poco mas... porque no paraba en la puerta de donde estaba parando... entonces tenia 2 opciones... bajame en cualquier lado (como paso el primer día)...


O ponerme a charlar con alguien y que me avise cuando me tengo que bajar (esa fue la solución el resto de los días de la semana jeje).

El Curso que mas me gusto... fue "Computational Cognitive Neuroscience" dictado por Peggy Seriès, muy pero muy buena la forma de dar clases, realmente quede impresionado con muchas de las cosas del Curso... y con la Universidad de Edinburgo sobre los programas de Doctorado que tienen...

Despuesssssss como no podia faltar... el ultimo día me quede sin bateria en el celular y el cargador no lo habia llevado... por ende no tenia donde fijarme la hora ni nada, asi que andaba mas perdido que de costumbre...
Cuando volvi a Córdoba, pude sacar estas fotos del mecanismo que tuve que aplicar para recordar cual era el colectivo que tenia que tomar para irme a Retiro, ya que no tenia el celular donde anotarlo:

Y por las dudas:

(En caso de olvido... mirar el otro brazo)

En sintesis... el viaje estuvo muy bueno... los cursos estuvieron geniales y es una oportunidad especial para aprender muchas cosas y conocer mucha gente que tambien le interesan las mismas cosas que a vos... a cualquier que lea esto REALMENTE LE RECOMIENDO LOS CURSOS DE LA ECI!

Saludos!... y ahi estaremos devuelta el año que viene! :D (si se puede jeje)

Nueva Notebook!

Bueno! por fin llego!!
La INSPIRON 1545!!

Cambiamos por modelo nuevo... despedimos a la Inspiron 1525 que se la banco con honor!!


Y le damos la bienvenida a la Inspiron 1545!! (como siempre la integración con Ubuntu es Genial!!)



Tuesday, August 4, 2009

Si Los Humanos Desaparecieran...


"Si todos los insectos desaparecieran de la
tierra, en 50 años habría desaparecido
toda forma de vida sobre la tierra.
Si los seres humanos desaparecieran de la
tierra, en 50 años todas las demás formas
de vida podrían florecer"




[Jonas Salk]