martes, 18 de diciembre de 2007

PFC: nombres, "entre comillas"

Uso pgAdminIII para administrar la base de datos de mi proyecto. Y la gestión que hago de los datos almacenados en ella esta programada en código JAVA.

En alguna ocasión tengo que recurrir al uso de alguna función o procedimiento para la gestión de estos datos. Así que usando pgAdminIII y su asistente para la creación de funciones o procedimientos es bastante sencillo crearlas.
¿Cómo accedo a la creación de éstas? Lee con atención: de la jerarquía de objetos que cuelgan de una base de datos, en el marco dónde cuelgan las base de datos que administrar, encuentra los objetos Funciones o Procedimientos (o Functions o Procedures). Al clicar con el botón derecho encima de estas... llamémoslas entradas, seleccionar la opción Nueva Función o Nuevo Procedimiento - la diferencia entre estas dos es que la primera devuelve un valor o conjunto de valores con parámetros de entrada, mientras que la segunda no devuelve nada pero trabaja con parámetros de entrada i salida -.

Al clicar sobre el nombre de la función o procedimiento, en el marco de abajo se puede ver la instrucción SQL que las crea. Observa que el nombre se halla entre comillas dobles; e aquí el problema. Porque desde JAVA no hay manera de crear un String con comillas dobles en su interior, ya que un String se delimita por comillas dobles (lector, si hay una manera de hacerlo, ¡dímelo!). Entonces ¿no se puede llamar a un procedimiento/función desde JAVA? Si se puede. Ese código SQL se puede editar, basta con copiarlo en el editor SQL (el icono de una hoja con un lápiz) de pgAdminIII y ejecutarlo desde el mismo editor - se puede crear una Función o Procedimiento sin necesidad de asistente -. En el editor le quitamos las comillas dobles al nombre y tenemos creada la función con un nombre accesible desde JAVA.

PFC: hint o tooltip

Quiero que, para cada componente contenido en los formularios de la aplicación de mi proyecto, se muestre el típico mensaje de ayuda, que aparece cuando se pasa el ratón por encima.
Bueno, he tenido que encontrar en la red, y más concretamente en este artículo que no existe una propiedad Hint en para los componentes de los formularios en las nuevas versiones de .NET.
Lo que si que existe es un componente llamado ToolTip que se añade a cada formulario. Este componente no es más que el componente que codifica el mensaje que queremos que aparezca cómo ayuda. Lo que en versiones viejas de Visual Studio, el Visual Basic antepasado de .NET, se hacia directamente con darle valor a la propiedad Hint de los componentes, ahora se hace con el componente ToolTip.

Y ¿cómo añado yo ese comentario de ayuda? Nada más sencillo que añadir un componente ToolTip al formulario y, automáticamente, aparece para cada componente una propiedad llamada ToolTip in tooltip1 (o cómo llamemos al componente).
En esta propiedad se escribe el mensaje que queremos mostrar, mientras que en las propiedades del componente ToolTip se cambian valores cómo AutomaticDelay, BackColor, IsBalloon, ... (ya sabes que dejo para ti, estimado lector/aprendiz, divagar por ti solo, y si tienes dudas, no tienes que hacer más que preguntar.)

martes, 27 de noviembre de 2007

PFC: proceso con estados

El ciclo de vida de un agente se pude entender como una sucesión de estados. El comportamiento de un agente se puede programar con varios comportamientos o con un comportamiento compuesto continente de otros.
FSMBehaviour es uno de estos comportamientos compuestos. De manera secuencial, y definiendo transiciones entre estados, se implementa la acción que debe realizar el comportamiento. Pero FSMBehaviour carece de método action(), con lo que la implementación de estados y transiciones debe realizarse en el constructor o en su método onStart() o justo después de añadir el comportamiento en el nacimiento del agente.

public class MaquinaEstados extends FSMBehaviour
{
private static final String STATE_1 = "1";
private static final String STATE_2 = "2";
private static final String STATE_3 = "3";

public MaquinaEstados(Agent _agente)
{
super(_agente);
}

public void onStart()
{
registerFirstState(new OneShotBehaviour1(agente));
registerState(new OneShotBehaviour2(agente));
registerLastState(new OneShotBehaviour3(agente));

Los estados de un agente, con FSMBehaviour, son los distintos comportamientos que forman parte de este comportamiento compuesto.
Se definen unas constantes cómo etiquetas para identificar los estados. Hay que registrar los distintos comportamientos que componen FSMBehaviour a modo de estados, registrando cada cual cómo primer estado, último estado y estado intermedio.

registerDefaultTransition(STATE_1, STATE_2);
registerTransition(STATE_2, STATE_1, 0);
registerTransition(STATE_2, STATE_3, 1);
}
}

Para controlar el flujo de ejecución, basta con definir varias transiciones entre los estados registrados. Las transiciones puede ser por defecto - el flujo de ejecución siempre va del estado/comportamiento origen al estado/comportamiento destino - o teniendo en cuenta un valor de salida del comportamiento origen, que será devuelto por el método onEnd() de cada comportamiento. Este valor va a depender de las condiciones de ejecución que se implementen en cada estado/comportamiento.

public class OneShotBehaviour2 extends OneShotBehaviour
{
private int exitValue;
...
public void action()
{
if (true)
exitValue= 1;
else
exitValue= 0;
}
...
public int onEnd()
{
return exitValue;
}
}

sábado, 17 de noviembre de 2007

PFC: nacer y morir

En la POA con JADE, existe un agente llamado DF (Directory Facilitator) . Dicho agente se encarga de guardar la descripción y dirección de los agentes que viven en un mismo sistema. Proporciona un servicio de páginas amarillas al cual los demás agentes acceden para saber la dirección de otros y poder comunicarse entre ellos.

Cuando se crea un agente, la primera tarea que debe hacerse en su nacimiento, en su método setup(), es la de registrarse en el DF.

public class Jane extends Agent
{
...
public void setup()
{
DFAgentDescription dfd = new DFAgentDescription();
dfd.setName(this.getAID()); //una descripción con su identificador
ServiceDescription sd = new ServiceDescription();
sd.setType("agente_recomendador");
sd.setName(this.getName());
dfd.addServices(sd);
DFService.register(this, dfd);
...
}

Para registrarlo, utilizamos el método estático register(Agent, DFAgentDescription) del DF, pasándole por parámetros el tipo de agente que es (instancia de la clase que implementa) y su descripción. Y aquí ya tenemos listo al agente para ser localizado dentro del sistema.
Al terminar la aplicación, todos los agentes mueren al mismo tiempo que se cierra la JVM dónde residen todos los agentes. Pero ¿si queremos dar por terminado un agente sin tener que cerrar la JVM?
Cuando un agente termina su actividad, pasa de estado ACTIVE a DELETED, ejecuta su método interno takeDown(). En este método tenemos que quitar el agente del DF para que ningún otro se pueda comunicar con él.

...
public void takeDown()
{
...
DFAgentDescription dfd = new DFAgentDescription();
dfd.setName(this.getAID());
ServiceDescription sd = new ServiceDescription();
sd.setType("agente_recomendador");
sd.setName(this.getName());
dfd.addServices(sd);
DFService.deregister(this, dfd);
}
}

Basta con llamar al método estático deregister(Agent, DFAgentDescription) para acabar con él. La API de este método permite varias maneras de quitar del DF a un agente. Fijaros que he incluido la misma descripción para registrarlo que para quitarlo del registro. Así me aseguro que sólo ese agente va a ser eliminado.
Pero, ¿porqué no llamar a DFService.deregister(), sin parámetros? Con esta última solución eliminaría a todos los agentes que implementan la misma clase, cosa que para mi proyecto no me interesa, porque en el sistema tengo varios agentes de la misma clase y se puede dar el caso que un agente recomendador tenga que hacer cálculos mientras que otro ya ha acabado.

sábado, 10 de noviembre de 2007

PFC: entender un mensaje

Cómo un agente puede tener varios comportamientos, cada uno de ellos va a actuar según el tipo de mensajes que reciba.
Habéis leído ( o decido de la lectura) que un mensaje se lo identifica por un tipo o performativa. Con el envío y recepción de mensajes de performativas relacionadas se puede identificar una conversación entre agentes, con la cual se maneja el flujo de datos y la ejecución de algoritmos entre ellos. Por ejemplo,

CFP (Call For Proposal)
ACCEPT-PROPOSAL
REJECT-PROPOSAL
PROPOSE

son performativas que pueden ayudarnos a crear una comunicación de negociación entre agentes. Pero, ¿cómo se sabe que mensaje ha de recibir un comportamiento? Basta con declarar una variable de tipo jade.lang.acl.MessageTemplate e indicarle que patrón debe tener el mensaje que tiene que recibir. Siguiendo el ejemplo visto en el mini artículo anterior:

template= MessageTemplate.and(
MessageTemplate
.MatchConversationId("consulta_bd"),
MessageTemplate.MatchInReplyTo(mensaje.getReplyWith()));

indico al agente que el mensaje que tiene que identificar y tratar debe contener un conversationId = "consulta_bd" y que debe ser una respuesta o réplica del mensaje que le he enviado. Mirad la documentación de jade.lang.acl.MessageTemplate para más detalles.

PFC: comunicacion interagente

Uno de los puntos fuertes de la POA es la programación de mensajes. Con éstos, se establece comunicación entre agentes que estan en ejecución. A modo de conversación entre ellos, en una POA tiene que haber mensajes que se envian o se reciben por uno u otro agente, a modo de ejecución de órdenes y devolver respuestas.

Un primer agente crea un mensaje :
ACLMessage mensaje = new ACLMessage(ACLMessage.REQUEST);
mensaje.addReceiver(agente); //destinatario del mensaje
mensaje.setConversationId("consulta_bd"); //un identificador de la conversación
mensaje.setReplyWith("consulta_bd"+System.currentTimeMillis());
mensaje.setContent("te envio un mensaje"); //contenido del mensaje
myAgent.send(mensaje);

El mensaje es de tipo jade.lang.acl.ACLMessage. El destinatario de éste se define mediante la variable jade.core.AID agente, y con setContent(String msg) se indica el qué va a contener el mensaje. Los otros métodos sirven para identificar el mensaje, para quién hay que responderlo, etc.

Y para contestar a este mensaje, otro agente crea una réplica del mensaje recibido por el primer agente:
ACLMessage recibido = myAgent.receive(template); //recibe un tipo de mensaje
ACLMessage replica= recibido.createReply();
replica.setPerformative(ACLMessage.INFORM); //tipo de mensaje
replica.setContent("te envio una respuesta");
myAgent.send(replica);

Un punto a destacar de la comunicación es cómo definir el tipo de mensaje empleado. Existen varios actos comunicativos que permiten distinguir una comunicación de otra, pudiendo ser procesados, en paralelo, por varios comportamientos de un agente.

miércoles, 31 de octubre de 2007

sumar valor a una fecha

Una de las muchas complicaciones de la programación en JAVA es la programación de fechas. En mi proyecto necesito incrementar el valor de una fecha para trabajar con periodos de tiempo.
El uso de fechas no es trivial, requiere mirar mucha documentación y aprender de ejemplos para no cometer fallos. Y mirando por la red, esta vez si, he encontrado una solución.

Basta con crear un objeto jade.util.Calendar y añadirle valores posteriormente, para luego añadirle un incremento, más o menos siguiendo estas lineas:

String [] dataTemp;
DateFormat df= new SimpleDateFormat("dd/MM/yyyy");

dataTemp= _data.split("/");
Calendar c= Calendar.getInstance();
c.set(Integer.parseInt(dataTemp[2]), Integer.parseInt(dataTemp[1])- 1, Integer.parseInt(dataTemp[0]));
c.add(Calendar.DATE, incremento);

siendo incremento el valor que quiero sumar, en este caso, al día de la fecha (se indica o Calendar.MONTH o Calendar.YEAR si se incrementa el valor del mes o del año, respectivamente).
Con el método set(int, int, int), introduzco al Calendar los valores de año, mes y día, por este orden (fijaros que al valor del mes lo decremento en uno, porque Calendar trata los meses desde 0 a 11).
He podido comprobar, también, que al sumar un incremento que pueda dar un valor superior al valor máximo de un mes, el valor del mes también se incrementa, por sí solo, dando lugar a una fecha correcta.

jueves, 25 de octubre de 2007

... y manejar componentes a la vez

El uso de Thread, del que hablo en el anterior mini artículo, lo aplico a controlar algoritmos que se ejecutan en los formularios de la aplicación cliente. Y al crear un hilo distinto, y toquetear componentes del formulario lleva a un conflicto.
Existe un primer hilo de ejecución (¡supongo que anda por ahí!, o al menos eso dice el compilador) que retiene el funcionamiento de los componentes y no deja que otros hilos modifiquen el estado de éstos. P.ej. desde un segundo hilo quiero escribir cosas a un listBox que tiene el formulario, la ejecución falla.
Y para subsanar está pequeña herida hay que utilizar el código siguiente:

//en los atributos del formulario
delegate void metodoCallback(parámetros);
...
public void recomendation()
{
metodo(parámetros)
}
public void metodo(parámetros)
{
if (this.listBox1.InvokeRequired)
{
metodoCallback process = new metodoCallback(metodo);
this.Invoke(process, new object[] { parámetros });
}
else
{
this.listBox1.Add(parámetros) //por ejemplo
}
}

Aquí, yo quiero llenar una lista, así que la lleno en la condición else del método. Todo lo demás es para hacer que este método manipule el contenido del listBox.
Cómo no he investigado más a fondo para entenderlo; sólo he buscado resultados, no puedo ofreceros una explicación más detallada. No es parte fundamental de mi proyecto así que esto ya sirve.

miércoles, 24 de octubre de 2007

varias tareas... (usando Threads)

Parte de la programación del proyecto se centra en seguir un diseño cliente/servidor. La parte cliente, implementada en c#, es la encargada de enviar peticiones y recibir resultados. Las peticiones son mensajes para obtener datos de una base de datos.
El proceso que debe ejecutar el cliente es largo: incluye varios envíos y recibimientos, por lo que no quiero que se quede bloqueado a la espera de que acabe dicho proceso (no es un requerimiento indispensable para el proyecto, pero ¡me picaba el gusanillo!)

He estado probando implementaciones, consultando de aquí para allá para utilizar Thread en c#, y quiero dejar parte de lo que he estado aprendiendo.
Cuando se inicia el proceso, el código del botón que lo pone en marcha ejecuta lo siguiente:

using System.Threading;
...
Thread hilo =
new Thread(new ThreadStart(recomendation));
hilo.name = "hilo";
if (!hilo.IsAlive)
{
hilo.Start();
}

Al constructor del Thread se le pasa un parámetro, que es el nombre del método que ejecutará, siendo:

private void recomendacion()
{
//lógica del algoritmo
...
hilo.Abort();
}

un método que ni lleva parámetros ni devuelve ningún valor. El código de este método será el que ejecute el hilo recientemente creado.
Y así puedo toquetear otras tareas de la aplicación, mientras el proceso está en marcha. Fijaros que añado el método Abort(). Lo llamo nada más acabar el proceso que ejecuta el método, para terminar el Thread. Este método lanza una excepción System.Threading.ThreadAbortException que no cojo porque no es necesario.

martes, 23 de octubre de 2007

PFC: seguimiento de la comunicación

El agente software se comporta a modo de hilo de ejecución o Thread. Sabiendo esto, uno se puede imaginar que seguir el camino por dónde pasa el código es un poco difícil, debido a su carácter concurrente, que no se sabe si ha pasado por aquí, si está interrumpido... y más si aportas al Thread una autonomía a base de estados, que si active, wait, suspended, running, blocked - los tres primeros estados pertenece a la clase Agent y los dos últimos a la clase Behaviour -.

Habéis leído que para ejecutar código java con agentes hay que escribir en el intérprete de comandos lo siguiente:

java jade.Boot -gui "nombre_agente_1":"clase_java_agente_1"(parámetros)

Fijaros que utilizo la opción -gui. Ésta lanza el agente RMA (Agente de Monitorización Remota o Remote Monitoring Agent para los cultos) que permite ver que agentes están activos dentro de la JVM. (RMA es un agente con una pantalla gráfica asociada). Desde el RMA se pueden lanzar otro agentes que ayudan a controlar la existéncia de los nuestros.
Uno de mucha utilidad (y que utilizo bastante) es el agente Sniffer. Dicho agente permite monitorizar la comunicación que existe entre los nuestros y el contenido de dicha comunicación. Se puede ver el paso de mensajes de unos a otros aún estando creados y en ejecución, porque el agente mostrará cómo ha sido la comunicación entre ellos; en que dirección se han enviado los mensajes.

viernes, 19 de octubre de 2007

PFC: ... digo main

Ya os hablé que en POA no hay un método main, ni nos hace falta una clase main porque JADE tiene su manera de arrancar una aplicación. Pero ha surgido una cuestión que era necesaria utilizar en mi proyecto fin de carrera. Me he visto en la obligación de implementar unas líneas de código para crear agentes en tiempo de ejecución; es decir, que debo crear agentes por código y no sólo tener varios agentes creados inicialmente, al lanzar la aplicación.

El trozo de código que me permite crear agentes dinámicamente es:

Object[] arguments = new Object[]{"a", "b"};
PlatformController plataforma = this.getContainerController();
AgentController control =
plataforma.createNewAgent("nombre_agente"+ _numero, "paquete.claseAgente", arguments);
control.start();

Cómo parámetros hay que pasar un nombre para el agente (yo añado el parámetro _numero para distinguir a los diferentes agentes que voy a crear), la clase que implementa el código del agente y los argumentos del agente.

Los agentes viven en un contenedor ubicado en la JVM. Con este código se obtiene dicho contenedor, que está creado debido a que al lanzar la aplicación, lanzo también varios agentes que sí quiero que estén siempre activos, mientras el código servidor esté funcionando (esto ya prepara a la JVM para acoger a agentes). Tiene que existir otra solución para poder crear dicho contenedor en la JVM y poder crear agentes desde código. Sospecho que las clases PlatformController y AgentController tiene algo que ver.

jueves, 18 de octubre de 2007

sin imágenes

No darlo todo mascado. Los que leáis este blog se supone que tenéis conocimientos suficientes para entenderlo todo. Y si no lo entendéis se supone que sois lo suficiente despiertos - ¡culos inquietos! - para preguntar, buscar, moveros por la red de conocimiento que existe vía internet para entenderlo todo.

No voy a acompañar ningún mini artículo con imágenes. Me gusta la plantilla utilizada para el blog y creo que incluir imágenes le va a quitar el encanto. Sin embargo, si que voy a enlazar imágenes. Que no quiera incluir dibujos en los escritos no significa que no se puedan ver, a razón de ayuda visual para cada escrito.
Dejémoslo así entonces, cómo si cada mini artículo estuviera escrito como si de un manuscrito se tratara; tiene un toque antiguo que favorece la lectura y el interés.

PFC: dónde digo Boot ... (con Eclipse)

Sin irme del proyecto que tengo entre manos, cómo escribo en JAVA gracias al editor Eclipse, deciros que no puedo (o no quiero) ejecutar los agentes desde intérprete de comandos tal y como describo en el mini artículo anterior. Surge la pregunta: ¿cómo ejecuto mis agentes desde Eclipse?

Abrid las propiedades de Run o Debug desde Run>Run o Run>Debug, o desde los iconos correspondientes. Cread una nueva configuración a modo de Java Application. En la pestaña Main, opción Main class escribid jade.Boot y activad la casilla que activa (valga la redundancia) la opción de incluir librerías cuando se busque la clase main.
Id a la pestaña Arguments. En la casilla Program arguments escribid los agentes que deseéis que se ejecuten, de igual modo que habéis leído en el mini artículo anterior.

Con estas instrucciones tenemos una configuración de Run o Debug lista para ejecutar y lanzar nuestro código con agentes.

PFC: dónde digo Boot ...

En una POA, uno debe de olvidarse del main. No existe el tratamiento secuencial de una aplicación: ahora creo la clase, luego hago el cálculo y sigo. ¡No! Nos encontramos ante un tratamiento concurrente, una ejecución en paralelo de algoritmos - algoritmos secuenciales o concurrentes, dependiendo de la lógica de cada aplicación - y cada agente se comporta como un programa independiente que se comunica con otros programas independientes. Aún así, JADE nos proporciona una clase que lleva un método main encargado de dar vida a los agentes: jade.Boot.

Con esto, me ha surgido una duda. ¿Si debo tener varias tareas ejecutándose (cada agente tiene una tarea diferente) cómo ejecuto la aplicación si no hay una clase con un main?
La respuesta es tan sencilla como escribir el nombre de todos los agentes que se haya implementado, a razón de parámetros de la instrucción java, en el intérprete de comandos . Algo cómo:

java jade.Boot -gui "nombre_agente_1":"clase_java_agente_1"(parámetros) "nombre_agente_n":"clase_java_agente_n"(parámetros)

Lo que va entre paréntesis son los parámetros que se le puede pasar a un agente, separados por un espacio en blanco. Desde código se recogen con el método:

Object[] getArguments()

de la clase jade.core.Agent

miércoles, 17 de octubre de 2007

PFC: para usar JADE

Antes de seguir con el mundillo de la implementación de agentes, seguro que preguntais qué IDE utilizo para desarrollar en JAVA. Deciros que utilizo Eclipse cómo editor de código. A otra posible pregunta que se os pasa por la cabeza, que responde al título de este mini artículo, deciros, de manera resumida, que basta con añadir las librerias de JADE al proyecto. (No hay enlace directo a la página de descarga. Debeis registraros con e-mail y contraseña y se os permitirá descargar todo el paquete de .jar; descargar la última versión. Yo trabajo con la 3.5 del 25/06/2007)

Eclipse permite gestionar carpetas del proyecto creado, así que es recomendable crear una carpeta lib, como subcarpeta del proyecto, para guadar ahí los .jar adicionales que se utilizen para el proyecto. Descomprimir el .zip que acabis de descargar y guardar los .jar dentro de esa carpeta lib - los .jar que se necesitan son: http.jar, iiop.jar, jade.jar y jadeTools.jar -

Luego, id al menú Project>Properties, elegid la opción Java Build Path y, en la pestaña Libraries, hay la opción de añadir .jar locales o .jar externos. Cómo los tenemos en la propia carpeta lib del proyecto, nos basta con la primera opción (si los quereis agregar desde otra ubicación, ningún problema). Buscadlos y se puede hacer una selección multiple para no tener que añadirlos uno por uno.

Ya tenemos los .jar de JADE listos para utilizar. Ahora toca leer las API que acompañan al .zip antes descargado y escribir los import pertinentes en cada clase agente a implementar.

PFC: POA

De lo que he podido entender de la documentación que he leído acerca de agentes, y acerca de JADE, un agente es un objeto que actúa siguiendo uno o varios comportamientos. A un objeto Agent se le añaden objetos Behaviour los cuales llevan programado la lógica de un algoritmo concreto.
El agente, cuando nace - los vamos a tratar como seres - llevan a cabo una... puesta a punto con la cual se registran en un directorio virtual de nombres y recogen información del entorno para llevar a cabo su funcionamiento

public class Jane extends Agent
{
...
protected void setup()
{
Object[] args = this.getArguments();
...
DFService.register(this, new DFAgentDescription());
...
addBehaviour(new Smart(this));
...
}
...
}

Por si sólo, el agente no hace nada, solamente existe en la JVM (Java Virtual Machine). Para que haga algo debe llevar asociado algún comportamiento como un SimpleBehaviour o un CyclicBehaviour: ejecutándose una sola vez durante la vida del agente o ejecutándose repetidamente, respectivamente. En código, y de manera esquemática seria algo cómo:

public class Smart extends SimpleBehaviour
{
...
public void action()
{
//lógica del algoritmo que se debe ejecutar
}
public boolean done()
{
//¿ha terminado?
}
}

Como un agente lleva asociados comportamientos que debe utilizar - la clase Agent puede tener varios Behaviours, en la jerga se dice que contiene un pool de Behaviour- se pueden implementar dentro de la clase Agent que hayamos creado, o cómo clase externa, en su correspondiente fichero
El método action() es el encargado de ejecutar los pasos del comportamiento del agente, mientras que el método setup() se encarga de inicializar variables de estado que pueda usar un agente.

Con esto, y sabiendo que un agente se comporta como un Thread - siempre está ahí hasta que lo matas o muere por algún fallo - el estilo de programación cambia bastante. De usar simples clases controladoras, por las que pueda pasar el flujo importante de una aplicación y se ejecutan de manera secuencial, podemos tener varios objetos Agent y ejerciendo el control de la aplicación o código servidor o como gusten. Pasamos a desarrollar una POA o Programación Orientada a Agentes.

martes, 16 de octubre de 2007

primer objetivo: PFC

Empiezo una serie de breves artículos/escritos acerca de mi PFC (Proyecto Fin de Carrera).
Para los que leáis mis delirios psicológicos, el viaje que ahí describo se basa en el transcurso de mi vida diaria desde el punto de vista de este proyecto.

Toca investigar y desarrollar la parte con más chicha del proyecto. Y para empezar debo aprender cómo utilizar agentes software y aplicarlos en él.
De bote pronto podría decir que, con aprender la teoría de threads, tener conocimientos en POO (Programación Orientada a Objetos) y saber utilizar el lenguaje de programación JAVA, uno podría implementar su particular sistema de agentes. Pero cómo no hace falta indagar tanto en este mundillo, voy a utilizar JADE.

De lo que he leído hasta ahora sobre JADE, puedo decir que el uso de agentes software se basa en utilizar clases programadas en JAVA.
Un agente no es más que un objeto, que lleva programado unas operaciones que ayudan a comprender, mediante su uso, el comportamiento de un agente. Ya empecé a escribir algo en la terraza de un club de programación, pero por motivos técnicos (vamos a llamarlos obras en la terraza) voy a continuar el trabajo en este cuarto de derrota, que iré llenando también de otros conceptos.

sitio de trabajo

Existe un espacio reservado para lo personal, un camarote dónde hay espacio para todos los aspectos personales de uno, pensar sobre la vida en sí.
Existe otro espacio reservado para el trabajo. Espacio dónde se experimenta, se estudia, se investiga, se obtienen resultados o productos acabados. Y en todo trabajo de investigación hay una parte de estudio previa, para adquirir conocimientos; hay una parte de desarrollo, para aplicar dichos conocimientos; y hay una parte de documentación, para reflejar qué se ha aprendido y que se ha elaborado.
Toda persona debe trabajar para vivir. El trabajo es lo que nos aporta los beneficios económicos personales que luego emplearemos en gastarlos cómo nos convenga.

Abro este blog para ir escribiendo todo aquello que voy aprendiendo relacionado con el estudio personal. Iré publicando lo que aprendo, para tener un lugar de consulta tanto para mi cómo para la persona que esté interesada.
No sólo con ejemplos se aprende, una explicación acompañante hace mejor su lectura y entendimiento.