Nudos Scoubidou rectangulares

27 Julio, 2010 por Ana Buigues Sin comentarios »

Los scoubidous rectangulares se pueden hacer con el número de tiras que queramos. Siempre hay una tira directriz a la derecha y otra a la izquierda del nudo, así como 2, 3, 4 o más tiras hacia arriba y hacia abajo.

Cuantas más tiras tengamos más grueso será el resultado. El color de las tiras directrices siempre quedan en el lado estrecho del rectángulo.

Scoubidou rectangular

Para explicar como se realiza el nudo he utilizado 6 tiras.

Paso 1: empezamos anundando las tiras con el tipo de Nudo C. Las tiras a y b quedan a la derecha y a la izquierda, son las tiras directrices. Cada 2 o más tiras c, d, e, f hacia arriba y hacia abajo, son las que anudaremos sobre las tiras directrices.

Paso 2: las tiras directrices a y b se colocan en forma de lazo sobre las otras tiras. Siempre en sentido hacia el exterior del nudo.

Paso 3: ahora las tiras de arriba, pasan por encima de la primera tira directriz y por debajo de la segunda tira directriz. Lo mismo con las tiras de abajo.

Paso 4: apretamos las tiras. Vemos como queda un nudo rectangular compuesto por ocho pequeños cuadraditos. Ahora volvemos a colocar las tiras directrices en forma de lazo sobre las otras tiras.

Paso 5: nuevamente repetimos el paso 3. Es importante que las tiras se coloquen siempre en paralelo, sin cruzar las tiras.

Paso 6: volvemos a apretar. El resultado es un nudo plano rectangular. Seguimos al paso 2.

En este video enseño como hacer un nudo

Ejemplo: Muñeco

Para realizar el muñeco necesitamos 6 tiras de scoubidou de diferentes colores, una cuenta de madera para la cabeza y pelo sintético.

Empezamos el muñeco haciendo las piernas. Para cada pierna, anudamos 3 tiras con el comienzo simple nudo A y hacemos sobre 18 nudos scoubidou redondos con 3 tiras. Una vez que tenemos las piernas, las unimos mediante un nudo scoubidou rectangular. Usamos una tira de cada pierna como directriz. Cuando tengamos un primer nudo después de la unión, ponemos un alambre en medio, para que el cuerpo se quede más rígido y hacemos 15 nudos rectangulares alrededor el alámbre. Ahora volvemos a dividir las tiras para hacer los brazos, hacemos 12 nudos scoubidou redondos con 3 tiras. Para finalizar los brazos ponemos un poco de pegamento antes del último nudo y hacemos el último para que quede pegado y no se suelte. Soltamos los nudos de las piernas y hacemos lo mismo. También podemos poner alambre en las piernas y brazos para darles movimiento.

Ahora pegamos la cuenta de madera entre los brazos, le pintamos una cara y pegamos el pelo.

Aquí os dejo una fotito del melenas…

Dale un toque de alegría a tus bebidas con cubitos increíbles

13 Julio, 2010 por Ana Buigues 2 comentarios »

¿Hart@ de tus bebidas de siempre? ¿estás aburrido de beber siempre lo mismo? Lo siento, no tengo remedio para eso pero voy a intentar que tus bebidas sean de lo más divertidas este verano. Sigue leyendo y verás cómo.

Litecubes Colour Changing LED ice cubes: impresionantes cubitos compuestos por un plástico hiperresistente en cuyo interior hay un gel que mantiene el frío (no es tóxico). El funcionamiento es bien sencillo, se introducen en el congeador y antes de echarlos al vaso se activan pulsando un botón e irán cambiando de color entre los 8 que soporta… supongo que antes o después se les acabará la pila o lo que tengan dentro que los haga brillar pero para poder comprobarlo habrá que comprarse unos y destriparlos (aunque el vendedor indique explícitamente que no los abramos con un cuchillo)

Cold Blooded Vampire ice cube tray: si eres un fan de Twilight o True Blood estos cubitos no pueden faltar en tu Bloody Mary.

Brain Freeze ice tray: con estos cubitos podremos crear un cóctel inteligente, ideal para tener ideas frescas.

Frozen Smiles: pon una sonrisa en tu vaso!!

Global Warming ice tray: la partida al Risk más helada de la historia…

Wiskey Stones: con la crisis de la construcción en algo habrá que emplear el material de sobra.

Cool Jazz Guitar ice cube tray: para fanáticos de Rock&Roll

Bone Chillers ice cube tray: para un cubata de muerte!

Gin & Titonic ice cube mold: el nombre lo dice todo.

Ice Invaders ice tray: congelando un clásico

Tetris ice tray: para los fanáticos de tetris

Lego Minifigure ice cube tray: ¿Quién no ha jugado con una figura de lego?

Lego Ice Brick ice cube tray: construyendo el cubito perfecto

Shark fin ice tray: para proteger tu cubata del gorrón de turno

Penguin ice tray: para los más linuxeros!

Fossiliced: parque helado 4

Fishbone ice tray: don gato pasó por aquí

Ice Princess Sippers: para las pequeñas de la casa

Cool Jewels: Jewelicious!

Tipsy Toes High Heel Ice Cubes: ¿será mucho tacón?

Alphabet, Number and Symbol ice tray: aprender a leer nunca ha sido tan fresco

Pi Symbols ice cube tray: tendrás que tomarte 3,141516…. copas

Peace ice tray: paz para todos

Love Heart Ice Cube Tray: los cubitos de San Valentín

My Bye-bye: para los inseparables

Stonerware ice cube tray Marijuana help leaf shape mold: 100% natural

Espero que a estas alturas os hayáis quedado helados!

Cómo sobreescribir los métodos equals y hashCode de Java

6 Julio, 2010 por Ana Buigues Sin comentarios »

En la clase java.lang.Object (y por lo tanto, por herencia, en todas las demás clases) tenemos métodos que a veces olvidamos y que son importantes:

  • public boolean equals(Object o)
  • public int hashCode()

Estos métodos son especialmente importantes si vamos a guardar nuestros objetos en cualquier tipo de colección: listas, mapas… y más aun si los objetos que vamos a guardar en la colección son serializables.

Estos métodos tienen formas explicitas de cómo hay que implementarlos. Sobreescribir estos métodos puede parecer simple, pero en realidad hay muchas formas de hacerlo incorrectamente lo que nos puede llevar a muchos crebraderos de cabeza. Lo vemos a continuación.

Sobreescribir el método equals

Cuando sobreescribimos el método equals tenemos que tener en cuenta lo que se especifica en el API de Java para Object sobre este método. Debe cumplir las siguientes propiedades:

  • Reflexiva: para cualquier referencia no nula para un valor x, x.equals(x) debe devolver true.
  • Simétrica: para cualquier referencia no nula para valores x e y, x.equals(y) debe devolver true sii y.equals(x) devuelve true.
  • Transitiva: para cualquier referencia no nula para valores x, y,z, si x.equals(y) devuelve true y y.equals(z) devuelve true, entonces x.equals(z) debe devolver true.
  • Consistente: para cualquier referencia no nula para valores x e y, múltiples llamadas al método x.equals(y) deben consistentemente devolver siempre true o consistentemente devolver false. Siempre y cuando no se modifique la información usada en las comparaciones.
  • No nulo: para cualquier referencia no nula para un valor x, x.equals(null) debe devolver false.

Ahora que sabemos lo que tiene que cumplir, vamos a ver que pasos podemos seguir para su implementación:

  • Usamos el operador == para comprobar si el argumento es una referencia al mismo objeto.
  • Usamos el operador instanceof para comprobar si el argumento es un objeto de nuestra clase.
  • Hacemos un cast del argumento al nuestro objeto. Ya sabemos que es una instancia de nuestro objeto, por el paso anterior.
  • Para cada campo significativo de nuestro objeto, comprobamos que se corresponda con el que se pasa como argumento. Primero comprobamos los tipos primitivos y luego los más complejos. Para los tipos Float y Double, usamos los métodos Float.Compare y Double.Compare. Para el tipo String, usamos el equals del string. Para comparar arrays usamos Arrays.equals. Tenemos que tener en cuenta que los campos pueden contener referencias a null. No debemos incluir campos que tengan que ver con el estado de un objeto, como por ejemplo tipos Lock. Tampoco tenemos que incluir campos que sean cálculos de otros campos, es redundante.
  • Cuando terminemos, tenemos que preguntarnos: ¿es reflexivo?, ¿es simétrico?, ¿es transitivo?, ¿es consistente? y ¿no nullo?
//Ejemplo de cómo sobreescribir el método equals()
public class Casa {
 private int num;
 private String direccion;
 private double precio;
 private List<Propietario> prop;

 public Casa(int num, String direccion, double precio,
            List<Propietario> prop) {
  this.num = num;
  this.direccion = direccion;
  this.precio = precio;
  this.prop = prop;
 }

 @Override
 public boolean equals(Object o) {
  if (o == null)
   return false;
  if (o == this)
   return true;
  if (!(o instanceof Casa))
   return false;

  Casa c = (Casa) o;

  if (num != c.num)
   return false;

  if (direccion == null || !direccion.equals(c.direccion))
   return false;

  if (Double.compare(precio, c.precio) != 0)
   return false;

  if (prop != c.prop && (prop == null || !prop.equals(c.prop)))
   return false;

 return true;
 }
}

public class Propietario {
 private String nombre;
 private String apellidos;
 private int num;

 public Propietario(String nombre, String apellidos, int num) {
  this.nombre = nombre;
  this.apellidos = apellidos;
  this.num = num;
 }

 @Override
 public boolean equals(Object o) {
  if (o == null)
   return false;
  if (o == this)
   return true;
  if (!(o instanceof Propietario))
   return false;

  Propietario p = (Propietario) o;

  if ((nombre == null) ? (p.nombre != null) : !nombre.equals(p.nombre))
    return false;

  if ((apellidos == null) ? (p.apellidos != null) :
     !apellidos.equals(p.apellidos))
    return false;

  if (num != p.num)
    return false;

  return true;
 }
}

Sobreescribir el método hashCode

Siempre que sobreescribamos el método equals, también tenemos que sobreescribir también el método hashCode. En el API de java para Object del método hashCode se especifica lo siguiente:

  • Cuando este método es invocado sobre el mismo objeto una o más veces durante una ejecución en una aplicación, el hashCode debe de ser consistente devolviendo siempre el mismo valor, siempre que no se modifique el objeto. Este valor no tiene que ser consistente entre ejecuciones distintas de la aplicación.
  • Si dos objetos son iguales segun el método equals, entonces el hashCode de los dos objetos tiene que ser el mismo.
  • Si dos objetos no son iguales, el hashCode no tiene que ser necesariamente distinto, pero es recomendable que lo sea.

Unos pasos para implementar un buen método hashCode son:

  • Declaramos una variable entera y le asignamos un número, por ejemplo result=17.
  • Para cada campo significativo de nuestro objeto, f:
    • Calculamos en int c el valor de:
      • Tipo boolean: hacemos (f?1 : 0)
      • Tipos byte, char, short, o int: hacemos (int) f
      • Tipo Long: hacemos (int)(f^(f>>>32))
      • Tipo Float: hacemos Float.doubleToIntBits(f)
      • Tipo Double: hacemos Double.doubleToLongBits(f) (int)(f^(f>>>32))
      • Si es una referencia a un objeto, llamamos al hashCode del objeto. Si la referencia es nula, devolvemos un 0.
      • Si es un Array, utilizamos el método Arrays.hashCode.
    • Acumulamos el valor de c en result : result = 31 * result + c
  • Devolvemos el valor de result

Podemos excluir los campos que no comprobemos en el método equals, pero no es recomendable.

//Ejemplo de cómo sobreescribir el método hashCode
@Override
public int hashCode() {
  int result = 17;
  result = 31 * result + num;
  result = 31 * result + (direccion != null ?
           direccion.hashCode() : 0);
  result = 31 * result + (int) (Double.doubleToLongBits(precio)
           ^((Double.doubleToLongBits(precio) >>> 32));
  result = 31 * result + (propietarios != null) ?
           propietarios.hashCode() : 0);

 return result;
 }

Fuente: Libro Effective Java de Joshua Bloch