Esta práctica ha sido más llevadera que la anterior. Se trataba de hacer una lista de “trucos” de un videojuego, aunque esa ha sido más bien la excusa para meternos de algún modo las tablas hash, que son lo que importaba de esta práctica. El truco está en no dejarse liar por el atrezzo que envuelve a la práctica, y en saber separar los granos de trigo de la paja. No es necesario para esta práctica saber cómo funcionan por dentro, a priori, las hashtables, porque estamos ordenando un número muy pequeño de datos (nos piden almacenar 10 trucos) y con imaginarse una matriz o un vector en el que van entrando y saliendo datos, y saberse los comandos, es suficiente. Pero para el futuro, y para aprobar el examen, es necesario saber de un modo algo profundo el funcionamiento de este particular objeto. Se trata de una lista de clases de tipo Object (en versiones más recientes de java ya no es necesario que sea de tipo Object) que se organizan de una manera muy particular: La posición que ocupan en la lista (un array) no es una cualquiera, si no una definida por un código asociado al objeto que está almacenado en esa posición. Así, si queremos leer un objeto de una tabla hash, para buscarlo no necesitamos pasar por todos los anteriores, sino que basta con que sepamos qué es lo que queremos buscar para que al iniciar la búsqueda, la tabla comience a buscar directamente por donde el código del objeto que buscamos “apunta”. Todo esto se consigue con ese código asociado al objeto, que es una clave que tenemos que definir para cada objeto al introducirlos en nuestra tabla hash.
Editando…..

Algoritmia III
Mayo 8, 2008
Ay la madre
Abril 22, 2008Sinceramente, esta práctica no tenemos por dónde cogerla. Hay que hacer una cola sin utilizar ninguno de los “contenedores” habituales de Java para estas cosas, como un array (estático, con el que ya hicimos una pila y una cola, y observamos sus deficiencias), o un vector, stack, queue o parecidos (dinámicos, que ofrecen mejores posibilidades y consumen menos memoria a priori). Queremos creer que no nos han puesto esta práctica con mala intención…

Lo hemos intentado haciendo una clase auxiliar para crear instancias de ella, y que cada instancia contenga la información que queremos encolar, pero no es nada fácil, porque no sabemos cómo automatizar el proceso o cómo llamar a cada instancia de una manera de manera que no quede muy cutre, como hacer un bucle que introduzca un identificador (un número) al final de la cadena de caracteres que defina nuestra instancia de esa clase (ClaseAuxiliar instanciaXXXXXX = new ClaseAuxiliar) rellenando en el ejemplo las “X” con numeritos. Investigando un poco, creemos que se puede hacer con el método clone() que para usarlo, necesitaríamos implementar una interfaz… no me acuerdo de cuál. Con este método podemos “clonar”, copiar instancias de una clase, con el mismo nombre, y sobre cada copia, trabajar con unos datos que no afectan al original sino a la copia tan sólo. Aunque no nos dio tiempo en la clase de prácticas a razonar y comprobar esta posibilidad, así que el trabajo que nos queda es de casa únicamente, para ver si la manera posible de hacer esto es de esta manera.
Resumiendo un poco, si queremos encolar enteros, pues creamos una clase que tenga una variable int entero y otra int apuntador; y creamos instancias de esas clases, clonándolas para poder tener muchas con el mismo nombre y erradicar el problema comentado anteriormente, y hacemos que se apunten entre ellas dichas instancias, para poder identificarlas y acceder al número entero guardado. Es lo que tenemos, mandriles, aunque no sabemos si está bien o no por el momento. Meditaremos profundamente sobre ello… hasta entonces, no os emborrachéis en la fiesta del árbol, que luego no podréis donar en el autobús que nos espera a la salida de clase!

Algoritmia I
Abril 11, 2008No os vamos a desvelar el algoritmo secreto que utiliza Google en sus búsquedas (por ahora), pero en cambio, de momento, sí que vamos a echar mano de la cabeza (aunque suene paradójico o cacofónico) para optimizar nuestros programas reduciendo ciclos de reloj consumidos y aumentando el rendimiento de nuestros métodos. Hoy se trataba de escribir un código para un tetris, código que se encargaría de la generación de piezas nuevas listas para mostrar en pantalla. ¿Cómo hacer esta tarea? Pues bien, hay varias opciones; por ejemplo, llamar a un método “creaPieza(tipo)” cada vez que la necesitemos. Sin embargo, a “golpe de ojo” se ve que no es la mejor solución, porque si justo cuando la necesitamos, vamos a necesitar invertir unos cuantos ciclos de reloj para crearla (además de dibujarla, etc), se ve que puede que no vaya a ir tan fluído como quisiéramos.

La mejor opción que está a nuestro alcance ahora mismo es crear todas las piezas al principio del juego (o del nivel en el que estemos, más bien), que es un punto donde no nos importa esperar un poco a que cargue el juego, meterlas todas en una pila o una cola, e irlas sacando una a una según las vayamos necesitando. Lógico, ¿no? No hemos tenido demasiados problemas en esta práctica (solamente al hacer el método main, con lo de siempre… el maldito error de compilación de non-satic variable X cannot… from a static context referente a variables que tenemos que declarar estáticas para que funcione el asunto…), así que, nos limitaremos por esta vez a escribir el código que ideamos para resolver este problema, haciéndolo (según pedían), con una cola.
/** Esta será mi piececita */
public class Pieza {
char tipo = ‘L’;
int x;
int y;
void mover()
{
y = y + 10;
}
public Pieza(char tipo)
{
this.tipo = tipo;
x = 50;
y = 0;
}
public String toString()
{
String str = (“Tipo = ” +tipo+ “, Posición = ” +x+ “, ” +y);
return (str);
}
Pieza contenido[] = new Pieza [100];
/** Hacemos la cola */
protected void encolar(Pieza piecina)
{
for(int i=0; i<contenido.length; i++)
{
if ((contenido[i] != null)&&(i==contenido.length – 1))
System.out.Println(“Cola llena”);
if (contenido[i] == null)
{
contenido[i] = piecina;
break;
}
}
}
protected Pieza desencolar()
{
Pieza piececita;
for(int i=0; i<contenido.length; i++)
{
if (contenido[i] != null)
{
piececita = contenido[i];
for(int j=0; i<contenido.length; j++, i++)
{
contenido[j] = contenido [i];
}
break;
}
}
if (i == (contenido.length – 1) && (piececita == null))
{ System.out.println(“Llamar al encolador”); piececita = null; }
return(piececita);
}
protected boolean estaVacia()
{
for(int i=0; i<contenido.length; i++)
{
if ((contenido[i] == null) && (i == contenido.length – 1))
{
return (true);
}
if (contenido[i] != null) return false;
}
}
protected boolean estaLlena()
{
for(int i=0; i<contenido.length; i++)
{
if ((contenido[i] != null) && (i == contenido.length – 1))
{
return (true);
}
if (contenido[i] == null) return false;
}
}
}
Sólo me quedaría el main por poner para probar el código,que creemos que funciona, pero por el maldito error del contexto estático/no estático, no lo conseguimos hacer funcionar.
public static void main(String [] args)
{
Pieza piezoelectrica = new Pieza(tipo);
encolar(piezoelectrica);
Pieza piezoelectrica2 = new Pieza (tipo);
encolar(piezoelectrica2);
piezoelectrica2.desencolar();
piezoelectrica2.toString();
}
Simplemente haciendo esas declaraciones (sin mayores pretensiones) obtenemos el error mencionado. Nos tendremos que leer bien algún tutorial en el que nos expliquen bien el por qué; debe ser que llegaríamos tarde a alguna clase el cuatritrimestre pasado ^^’ Saludos mandriles!

Comienza lo bueno…
Abril 3, 2008Comienza a dejarse notar ese calor veraniego de estos tiempos locos, pero a la vez, comienza lo bueno de OCA, el uso de interfaces gráficas… y es que no hemos dedicado más tiempo a ninguna práctica que a esta. La primera parte de la práctica es relativamente sencilla, mucha paja en el enunciado pero luego pocas nueces, y claro, es que lo bueno comienza en el ejercicio 3, que nos introduce la clase Canvas (“Lienzo” para el poco familiarizado con el inglés) y nos insta a pintar un cuadrado de un color predefinido en una ventada creada en runtime. Conseguir entender el “chorongo” de código que nos dan, es, a priori, poco menos que lo que sería para una civilización extraterrestre entender los jeroglíficos del “Golden Record” que seleccionó cuidadosamente la NASA (en un comité presidido por nuestro conocido amigo Carl Sagan) allá a finales de los 70…:
… y es que no es para menos que nos metan toda la teoría que nos han metido del funcionamiento de estas clases así de golpe. Vamos a comentar algunas cosillas de estos últimos ejercicios…:
Un problema que tuvimos por querer ir un poco “más allá”, fue en la clase Boton, de la que hicimos una versión 2.0 llamada Botono. En esta nueva versión, tratábamos de meter el Color del Rectángulo, así como del borde, como argumentos al ejecutar el programa, para que no tuviese que ser algo predefinido, y hacerlo así un pelín más “realista”. Lo primero que se nos ocurrió fue meter dentro de la antepenúltima línea de código, “f.add(new Botono(new…))” un par de argumentos de tipo color que introduciríamos directamente al escribir en la consola “java Botono x x x x x x x x“. No sabíamos que declaración teníamos que hacer, pero se la copiamos un poco a las que ya venían “new Integer (args[0]).intValue()”, poniendo cosas como “new Color (….)”, pero nada funcionaba. Luego decidimos leer un String por teclado, y hacer la asignación “Color color1 = (Color) str” me parece que era, pero no daba resultado, lanzaba un error de tipos. ¿No habrá un método algo así como “parseColor”? Conociendo únicamente el parseInt, y no queriendo tener que escribir mucho código “if str = “BLUE” { Color color1 = Color.BLUE } …” y así con todos los colores, pues, conociendo el parseInt… escribimos los siguiente:
/** Método main para probar la clase.*/
public static void main (String [] args) {
System.out.println(“Introduce colores en RGB”);
try{
BufferedReader color11 = new BufferedReader(new InputStreamReader(System.in));
colora11 = color11.readLine();
c11 = Integer.parseInt(colora11);
}
catch(Exception ex)
{
ex.printStackTrace();
System.out.println(“Inválido: Ha de estar entre 0 y 255, valor numérico entero”);
}
Y así 3 veces por cada color, para luego hacer un “Color colorin1 = new Color(c11, c12, c13);” Esto nos permite meter un gran número de colores como argumentos al ejecutar, 256^3, que corresponde a un color de 24 bits de densidad. Sin embargo, es poco práctico, y si alguien conoce algún método mágico…
Otro punto a destacar es la implemetación de estos métodos, escribiendo este Blog ahora sospechamos que haberlos implementado dentro del “main” fue el motivo por el que, para que no diera el error de “cannot no sé qué… from a non-static reference”, tuvimos que declarar las variables c11, c12 etc, como estáticas, lo cual de una desventaja enorme. ¿Es ese el motivo, señores lectores? Es una duda que puede parecer estúpida, pero para unos pobres ignorantes que han estudiado otros lenguajes de programación más rudimentarios, estas cosas no son triviales…
Bueno, no queremos enturbiaros vuestras mentes más con chorongos de código. Este poquito que hemos puesto nos parece bastante interesante… disfrutad con él! Hasta otra, mandriles.

Cuarta Práctica de OCA
Marzo 28, 2008Hola a todos!
Volviendo al mundo real tras una relajada Semana Santa, y poniendo la cabeza donde debe estar… hemos de reconocer que ha sido una práctica bastante dura, al menos para nosotros. En esta práctica nos han explicado con bastante detalle en qué consiste la herencia, y qué problemas nos podemos encontrar al usarla. Un caso patológico que nos han enseñado es el siguiente:
Al crear un array de Personas, siendo Persona una clase, si le introduzco objetos del tipo Alumno (Alumno extends Persona), Java se queja. Java es un poco tonto en este aspecto, porque nosotros tenemos bastante clarito que un alumno es una persona, pero… el dichoso compilador no se lo cree. Si escribimos un poquito de código, que tampoco es para pegarse un tiro…:
(…) Alumno a = new Alumno();
Persona[] cola = new Persona[100]; \\ Un array con 100 personas
Persona per;
per = (Persona) a; \\ Aquí está el truco con el que podemos meter alumnos en un array de personas; con este código trato a “a” como si fuera una persona, para que el compilador se crea que un alumno es una persona. Hasta aquí todo bien, y entonces sabemos que podríamos hacer la asignación “cola[i] = per” sin problemas, ya que “per” sería un alumno tratado como una persona “normal”. Sin embargo a nosotros se nos plantea la cuestión, ¿qué significa que Java tome a una subclase como una superclase? Esperamos que algún compañero nos pueda resolver dicha duda, que va encaminada sobre todo hacia lo que hace Java para que esto sea posible; ¿descarta la parte del código -métodos, asignaciones, variables- de Alumno que no está en Persona? ¿Cómo es este nuevo objeto “per” de nuestro ejemplo?
Bien, dicho eso, sólo nos queda resaltar que tuvimos muchos problemas intentando hacer compilar los ejercicios, y es que hubo algunos casos muy problemáticos que incluso el profesor dijo que tenía que mirarlo bien… volviendo con un poco de código:
public class Miembro {
protected String nombre = null;
protected int modificadores = 0;
public Miembro(String nombre, int modificadores )
{
this.nombre = nombre;
this.modificadores = modificadores;
}
public Miembro()
{
this(“ninguno”, 0);
}
public String toString()
{
return (“El nombre es “+nombre+”, y sus modificadores son “+modificadores);
}
public String a = this.toString();
public static void main (String [] args)
{
Miembro primero = new Miembro(“Pepe”, 1);
System.out.println(a);
}
}
La escritura puede ser un poco precaria, pero vale para ilustrar nuestra preocupación, y es que creemos estar almacenando el contenido del objeto “primero” en la cadena “a” gracias al método toString() que implementamos, pero al imprimir por pantalla el contenido, nos dice que el miembro se llama “ninguno” y que los modificadores son “0″, como si hubiésemos hecho la llamada Miembro primero = new Miembro() en vez de la hecha. Esto no ocurría con distintas implemetaciones del método toString, pero sí con esta. ¿Por qué? Por favor, si alguien lo sabe, o cree saberlo, que nos ponga un comentario con su opinión/solución sobre el caso. Bueno, como son tantas las dudas, para no saturar, sacamos estas a la luz, que son las que nos parecen las más importantes.
Salu2 a to2 y gracias por leer “The Magic Bullet”, como siempre, en Mandril Publicaciones, S.A.
P.D.: ¿A nadie le suena esa escena? Oh, gran momento.

Práctica 3
Marzo 6, 2008“Esto son dos informáticos que deciden hacer un viaje en coche. Justo cuando están a mitad de camino, en la carretera, se les para el coche… y después de varios intentos de volverlo a arrancar le dice un informático al otro… ‘¡Espera, espera! ¿…Y si salimos y volvemos a entrar?’”
Bueno, se acabaron los chistes. Volviendo a la vida real… y a la práctica del viernes 7 de marzo, hay unas cuantas cosas que decir. En primer lugar, que fue una práctica muy interesante, aunque hay que reconocer que fue más bien una clase teórica que práctica… Bueno, pues para empezar hablemos del modificador static. El funcionamiento de este modificador es bastante interesante, y sirve, si hemos entendido bien, para relacionar una variable o un método directamente con la clase a la que pertenece, en vez de estar relacionada con cada objeto de esa clase. Por si nos lee algún compañero con dudas, lo que nosotros entendemos por una variable con modificador static, es una variable cuyo valor está almacenado “en la clase” (para entendernos); no sabemos exactamente en qué lugar de la memoria ni dónde se sitúa jerárquicamente, pero está ahí, modificando su valor único para esa clase en el mismo instante según las llamadas a distintos métodos. Por ejemplo, el más sencillo de todos: El contador de objetos de una misma clase. Si fuese una variable normal, habría una variable en memoria para cada objeto de esa clase, pero en este caso sólo hay una (eso creemos, que luego puede que haya una por objeto, todas iguales siempre…) y se puede definir de tal modo que cada vez que se cree un objeto de una clase, esta variable haga un “i++”. Por otro lado, los métodos estáticos… no los tenemos muy claros, a ver si alguien nos echa un cable. Nuestra idea de lo que puede ser un método estático, es la de uno que devuelve el valor de una variable estática (aparte del método main, que es void; no devuelve nada).
El otro punto interesante de esta práctica fue el investigar sobre el funcionamiento interno de los métodos en Java en lo que se refiere a los parámetros de entrada. Teníamos que buscar información sobre si Java pasa los parámetros por valor o por referencia. Leyendo un poco, sacamos conclusiones: Los pasa por referencia. Conclusiones precipitadas. Hay que leer mucho más para darse cuenta de (y comprender) lo contrario: los pasa por valor. ¿Qué significa esto? Pues bueno, no es fácil de explicar, pero lo que hemos creído entender es lo siguiente: Java es un lenguaje de programación que sólo permite pasar los parámetros por valor (otros lenguajes permiten decidir), esto es, sólo permite pasar parámetros en un método de manera que están protegidos frente a cambios que puedan intentar invocar sobre ellos los métodos en los que estén involucradas. Esta protección se debe a que se realiza una copia del atributo (si se mete un atributo) sobre la que se va a trabajar, conservando el valor original del atributo fuera del método. Cuando salimos del método, aunque hayamos modificado el valor dentro del mismo, la variable original conserva su valor. Esto parece ser que no sucede así cuando el parámetro es un objeto, porque, a fin de cuentas, en Java no trabajamos con objetos, sino con referencias a objetos, y al meter un objeto en un método (una referencia), realizas una copia de esta referencia, y trabajas sobre la copia de la referencia afectando al objeto guardado en memoria, de manera que al salir del método, conservas tu referencia a la posición de memoria original donde tenías el objeto, pero el objeto ha podido cambiar. También hemos leído que esto no pasa para los objetos de la clase String, a ver si hemos entendido el porqué:
Metemos en nuestro método “funcioncilla” una String “cadena”: funcioncilla(cadena){…} y metemos la cadena ‘cadena 1 = “hola” ‘ asignada previamente. En realidad hemos metido una referencia a la cadena ‘cadena1′, ¿no es así?, Pues bien ahora, dentro de nuestra funcioncilla, hacemos: cadena1 = “adiós”. Salimos del método. ¿Qué ocurre si hacemos un S.O.Pln(cadena1)? Teóricamente, al haber hecho la asignación ‘cadena1 = “adiós”‘, hemos dado un nuevo valor al objeto cadena1 de la clase String. Al salir del método, por contra, recuperamos el valor del objeto original, por lo que entendemos que necesariamente una asignación de este tipo para objetos de la clase String, lleva consigo la creación de una nueva cadena con una referencia distinta, quedando intacta la que está “fuera” del método.
Que nos corrijan si todo esto es una gran pirada de pinza… mucho leer me parece jajaja.
Bueno, que tengáis una buena práctica mañana y una bonita Semana Santa! Nos vamos a nuestros respectivos locales de ensayo.
Saludos Mandriles

No ejecuta
Marzo 3, 2008Así podemos resumir la práctica 2 de programación, desgraciadamente. Nos hemos tirado las 2 malditas horas para que nos compilase un programa que ni si quiera pedían hacer explícitamente, sólo lo ponían como ejemplo… Había que calcular las 2 soluciones de una ecuación de segundo grado. Claro que antes de nada teníamos que hacer una cosita que nos omitieron en
. . . . Nota: El texto de la imagen puede diferir en algunas letras de la original (NullPointer… NoDefClass…) . . . .
el primer cuatrimestre, y era que teníamos que agregar nuestro directorio de trabajo al classpath, y lo que pasaba es que lo habíamos HECHO MAL, si es que somos unos cazurros… primero estuvimos diez minutos pensando cómo hacerlo, porque no sabemos qué hay que hacer (ni si es posible) para que un método te devuelva varios valores con un return; al final hicimos 2 métodos distintos, uno para la primera raíz, y otro para la segunda. Tras un cuarto de hora arreglando los pequeños fallos que nos daba la compilación, llegó el error gordo en la ejecución, el de NoDefClass… que encontramos en el API de java como un error posible en la declaración de la sentencia “new” o un error producido por llamar a la clase de forma distinta a la del archivo, pero el problema estaba en el classpath que no habíamos escrito bien del todo.
Bueno, así es como dejamos constancia de la segunda práctica, en lo referente a lo hecho en clase, porque nos dio para poco más con el maldito problema. Al menos aprendimos algo muy importante… NO DEFINAS MAL EL DIRECTORIO DE TRABAJO, ES DECIR, EL CLASSPATH!
Un saludo!
P.D.: Dejamos abierta la duda de lo del return. ¿Puede un método almacenar mediante un return, dos valores de dos variables distintas? Tal vez se podría haber hecho almacenando cada valor en un vector 2×1…? (eso se me acaba de ocurrir, tal vez sea la solución, almacenarlo en vectores…)

¡Hola Mundo!
Febrero 28, 2008Hola Mundo, de nuevo.
Así comienza este cuatrimestre de programación, recordando los primeros pasos que todo programador da, el famoso “Hola Mundo” que imprimimos por primera vez en pantalla. No fue suficiente imprimirlo una vez para estar contentos; para repasar bucles lo imprimimos 20, 200 veces o incluso, algún despistado no puso condición de salida al bucle y se imprimía el mensaje hasta que le decías “BASTA!”. De hecho en ese momento sentimos curiosidad por lo de los bucles infinitos, y el programa no mostraba nada por pantalla si ponías una condición de salida estúpida (empezar a contar en i=1 y decirle que pare cuando llegue a i=0, con i++), y sí imprimía si no ponías nada (int i=1; ;i++).
Luego estuvimos investigando por el API de Java, buscando la clase para leer del teclado que nos dijo el profesor de prácticas, pero no logramos recordar cómo se llamaba esa clase… langthread acaso…
Ya nos extenderemos más adelante, que ahora nos vamos a una jam session en Caminos!
Bueno, actualizando después de la vuelta de la Jam de Caminos… no hay mucho que decir, sólo que esperemos que nos sea leve en la práctica de mañana y que no tengamos muchos problemas para compilar el programa más estúpido de todos los programas estúpidos que hay, como un programa que no haga nada, ni le metas valores, ni los devuelva^^
Hasta la próxima!

Hello world!
Febrero 28, 2008Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!




