Archivo de Octubre 2005

Copia este libro

Martes, 25 de Octubre de 2005

Me cuenta mi amigo Mario que el fragmento que publiqué el otro día no es anónimo, sino que forma parte del libro de David Bravo Bueno, llamado Copia este libro.
Esta sujeto a la licencia Creative Commons y es de libre distribución. No se puede alterar ni utilizar para fines comerciales y se puede copiar libremente, siempre citando el origen de la obra.
Todavía no me lo he leido, pero será lo próximo que haga, seguro, y lo comentaré por aquí.
Por ahora el índice no pinta nada mal:

Beneficios
Falsos dogmas
La invitación al miedo
La industria y los artistas
Titiriteros
La ley y las redes P2P
Haz lo que debas
Manual para empresarios forrados y sus defensores
Que el mercado venga a Mahoma
En la búsqueda de alternativas

Descárgatelo, leelo y compártelo.

Algunas reseñas interesantes a este libro son:

Si ya te lo has leido, puedes escribir un comentario en este post.

Java básico: String (I)

Lunes, 24 de Octubre de 2005

Cuando aprendemos Java, vamos aprendiendo aspectos del lenguaje muy peculiares. Uno de ellos es que “todo es un objeto”, incluso las cadenas de texto que son del tipo java.lang.String. Después aprendemos que Java no sabe concatenar cadenas y que el operador “+” es el único que está “sobrecargado”. Es decir, el operador “+” en Java equivale a crear un nuevo objeto String distinto cuyo contenido es la suma de los dos objetos String que acabamos de concatenar.
Y por esta razón a veces vemos código como el siguiente:

long result = System.currentTimeMillis();
System.out.println("El resultado final es "+result+ " milisegundos");

E, ingenuos de nosotros, nos entra una desagradable sensación de culpabilidad, por lo que nos apiadamos de Java y decidimos ponérselo más fácil, sustituyéndo el código tan costoso por esta versión supuestamente optimizada:

long result = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
sb.append("El resultado final es ");
sb.append(result);
sb.append(" milisegundos");
System.out.println(sb.toString());

Pues no ha servido para nada. Los dós códigos son equivalentes (que no iguales). Y es que cómo Java no sabe sumar cadenas, cuando se encuentra un código como el primero, el compilador lo sustituye raudo y veloz por un código como el siguiente:

long result = System.currentTimeMillis();
System.out.println(
    new StringBuffer().append("El resultado final es ")
    .append(result).append(" milisegundos").toString());

Por lo que nuestra optimización inicial, aunque bien intencionada, no ha servido para nada. Java ya sabe hacer eso por nosotros. Caer en la tentación del principiante de intentar optimizar el código de nuestra aplicación, sustituyendo cada concatenación que vemos por la utilización de StringBuffers es un esfuerzo innecesario que no debemos malgastar.

Es más, si por un casual intentamos concatenar constantes:

System.out.println("Pulsa cualquier teclan"+
                   "para continuarn");

Java lo detecta y las concatena en tiempo de compilación, sin generar código redundante:

System.out.println("Pulsa cualquier teclanpara continuarn");

Pero vayamos a otro caso distinto. Supongamos este codigo:

String numeros = "";
for (int n=1;n<100;n++) {
    numeros = numeros + n + " ";
}
System.out.println(numeros);

?Qué está pasando aquí? Bueno, pues si sabemos que Java no sabe concatenar y que, por cada concatenación va a construir un objeto String nuevo, podemos llegar a la conclusión de que así, a ojo, va a crear 100 objetos String intermedios para solo quedarse con uno, el último de ellos.
Tomando como ejemplo el caso anterior, veamos lo que haría el compilador:

String numeros = "";
for (int n=1;n<100;n++) {
    numeros = new StringBuffer().append(numeros).append(n).append(" ").toString();
}
System.out.println(numeros);

Está claro que no hemos ganado nada. Se siguen creando y destruyendo 100 objetos String y StringBuffer, y solo nos quedamos con la última instancia del String resultante. Nada óptimo, sin lugar a dudas (el consumo másivo de objetos en memoria sin justificación es el mayor enemigo del rendimiento de nuestra aplicación). Así que la solución es fácil: ya que sabemos usar StringBuffer, aprovechemos lo que sabemos para ahorrarle trabajo a Java. El código ideal sería así:

StringBuffer numeros = new StringBuffer();
for (int n=1;n<100;n++) {
    numeros.append(n).append(" ");
}
System.out.println(numeros.toString());

Ahora si que le hemos ahorrado a Java trabajo, pero le hemos ahorrado el trabajo de la generación innecesaria de objetos, no la de concatenar.
Conclusión:

  • Java si sabe concatenar: Cada vez que aparece una concatenación, crea un objeto StringBuffer y sustituye el operador “+” tantas veces cómo sea necesario por llamadas a métodos append() de la clase StringBuffer. Esta sustitución es atómica y solo se realiza una vez por cada línea, por lo que cada vez que queramos concatenar cadenas, intentaremos siempre hacerlo en la misma línea.
  • Java no sabe ahorrar: Si utilizamos la concatenación dentro de un bucle, Java realizará la sustitución anterior en el interior del mismo, con el consiguiente desperdicio de memoria al crear tantas instancias de String y StringBuffer como repeticiones tenga el bucle. Solo en este caso, si procede utilizar StringBuffer.

Os invito a que probeis diferentes versiones de concatenación de Strings, las compileis y después las decompileis. Un buen descompilador que utilizo con frecuencia es Jad. Veréis como Java es más listo de lo que parece… en algunas ocasiones.

La ley y la propiedad intelectual

Martes, 18 de Octubre de 2005

Me ha llegado por correo el siguiente mail. Su autor es desconocido y no he verificado el código penal (o preguntado a algún amigo abogado) si los datos son correctos, pero probablemente sea así. Además me ha hecho bastante gracia (que no es sinónimo de gracioso).
Y es que las penas por quebrar la propiedad intelectual en España son realmente desproporcionadas.

Elegid cuál es la acción, entre las siguientes parejas, considerada de mayor gravedad:

CASO 1

a.- Pedro y Susana van a un colegio y distribuyen entre los alumnos de preescolar copias de películas educativas de dibujos animados protegidas por copyright y sin autorización de los autores.

b.- Pedro y Susana van a un colegio y distribuyen entre los alumnos de preescolar películas pornográficas protagonizadas y creadas por la pareja.

RESPUESTA: La acción menos grave es la de distribuir material pornográfico a menores según el artículo 186 del C.P. La distribución de copias de material con copyright sería un delito al existir un lucro consistente en el ahorro conseguido por eludir el pago de los originales cuyas copias han sido objeto de distribución.

CASO 2

a.- Juan fotocopia una página de un libro.

b.- Juan le da un par de puñetazos a su amigo por recomendarle ir a ver la película “Los ángeles de Charlie”.

RESPUESTA: La acción más grave desde un punto de vista penal sería la “a” puesto que la reproducción, incluso parcial, sería un delito con pena de 6 meses a dos años de prisión y multa de 12 a 24 meses. Los puñetazos, si no precisaron una asistencia médica o quirúrgica, serían tan solo una falta en virtud de lo dispuesto en el artículo 617 en relación con el 147 del Código Penal.

CASO 3

a.- Ocho personas se intercambian copias de su música favorita.

b.- Ocho personas participan en una riña tumultuosa utilizando medios o instrumentos que pueden poner en peligro su vidas o su integridad física.

RESPUESTA: Es menos grave participar en una pelea que participar en el intercambio de compactos. Participar en una riña tumultuosa tiene una pena de tres meses a un año (art. 154 del Código Penal) y el intercambio tendría una pena de 6 meses a 2 años (art. 270 del Código Penal). Si algún día te ves obligado a elegir entre participar en un intercambio de copias de CDs o participar en una pelea masiva, escoge siempre la segunda opción, que es obviamente menos reprobable.

CASO 4

a.- Juan copia la última película de su director favorito de un DVD que le presta su secretaria Susana.

b.- Juan, aprovechando su superioridad jerárquica en el trabajo, acosa sexualmente a Susana.

RESPUESTA: Por supuesto, el acoso sexual tendría menos pena según el artículo 184.2 CP.

CASO 5

a.- Alfonso se descarga una canción de Internet.

b.- Alfonso decide que prefiere el disco original y va a El Corte Inglés a hurtarlo. Una vez allí, y para no dar dos viajes, opta por llevarse toda una discografía. La suma de lo hurtado no supera los 400 euros.

RESPUESTA: La descarga de la canción sería un delito con pena de 6 meses a dos años. El hurto de la discografía en El Corte Inglés ni siquiera sería un delito sino una simple falta (art. 623.1 CP).

CASO 6

a.- Alfonso se descarga una canción de Internet.

b.- Alfonso va a hurtar a El Corte Inglés y, como se la va la mano, se lleva cincuenta compactos por valor global de 1.000 euros.

RESPUESTA: Seguiría siendo más grave la descarga de Internet. El hurto sería un delito porque supera los 400 euros, pero sería de menor pena que la descarga (artículo 23 C.P.).

CASO 7

a.- Ramón, que es un bromista, le copia a su amigo el último disco de Andy y Lucas diciéndole que es el “Kill’em All” de Metallica.

b.- Ramón, que es un bromista, deja una jeringuilla infectada de SIDA en un parque público.

RESPUESTA: La segunda broma sería menos grave a tenor del artículo 630 del Código Penal.

CASO 8

a.- Pedro se graba la película “El Resplandor” del VHS de su amigo.

b.- Pedro, irritado por el doblaje de la película, amenaza de forma leve

a Verónica Forqué exigiéndole que no vuelva a hacerlo nunca más. Pedro usó un arma blanca en la amenaza.

RESPUESTA: La copia sería un delito y la amenaza, incluso con un arma, una simple falta (620.1 C.P).

De todas formas, si te preocupa estar fuera de la ley, lo primero que tienes que hacer es informarte. En www.nosoypirata.com tienes toda la información necesaria para conocer tus derechos y obligaciones, además de desmitificar la piratería en la red y más cosas útiles.
Como resumen te diré que si te bajas música y/o peliculas pero no la vendes y solo la usas en privado (no en una radia pública, local comercial, etc) entonces no estás infringiendo la ley. Haz el test en ?Eres realmente un pirata?

Ikaruga

Lunes, 17 de Octubre de 2005

Ikaruga es un “matamarcianos” para PS2 que es endemoniadamente dificil.
A la dificultad normal que tienen estos juegos (grandes enemigos, huecos estrechos por los que introducir tu nave, la pantalla llena de disparos que se dirigen a por ti, estrategias para pasar por determinados sitios, etc) se le añade una nueva: tu nave puede alternar entre dos colores. Estos dos colores coinciden tambien con el de los enemigos y, por lo tanto, con el de sus disparos. Si tu nave es de color blanco y tus enemigos son blancos, sus disparos no te harán nada y puedes incluso destruirlos tocandolos con tu nave. Si de repente se acerca una horda de naves negras, cambias de color y de nuevo eres inmune a estos enemigos y sus disparos. Lo malo es que los enemigos no aparecen en orden, sino mezclados, y toda la dificultad del juego en si, se acentua al tener que estar teniendo mucho cuidadito en cambiar al color correcto en el momento adecuado, o tu nave saltará por los aires.
Hasta aquí todo bien, no? Si lo has probado, conocerás la desesperación que conlleva llegar a dominar minimanente este juego.
Pero siempre hay alguien que sabe más que tu. Y que juega mejor tu. O mejor que nadie. Incluso con dos jugadores. Dos jugadores, a la vez: uno en cada mano.
Visualiza este increible video. Es realmente mi heroe. Es OVERKILL. Ikaruga

Indigo

Lunes, 17 de Octubre de 2005

Fragmento del libro “CRIPTONOMICóN 1. El Código Enigma” de Neal Stephenson. Traducido por Pedro Jorge

Copiando de un bloc de notas, escribe lo siguiente:

19 17 17 19 14   20 23 18 19   8   12 16 19  8  3
21  8 25 18 14   18  6  3 18   8   15 18 22 18 11


Cuando aparece el cuarto o quinto número en la pizarra, Waterhouse siente cómo se le eriza el pelo de la nuca. Antes de que termine de escribir el tercer grupo de cinco números, ya ha percibido que ninguno de ellos es mayor que 26, el número de letras del alfabeto.

Para cuando el hombre de la bata ha terminado de escribir el último grupo de números, Whaterhouse está inmerso en un en un recuento de frecuencia. Lo completa cuando el Hombre de la Bata está diciendo algo como: ?Para ustedes esto podría ser una secuencia sin sentido, pero para los oficiales navales nipos es algo completamente diferente.?

El recuento de frecuencia de Waterhouse se limita simplemente a anotar el número de veces que cada cifra aparece en la pizarra. Tiene este aspecto:

1        14  ||
2        15  |
3 |||        16  |
4        17  ||
5        18  ||||||
6 |        19  |
7        20  |
8 ||||        21  |
9        22  |
10        23  |
11 |        24  
12 |        25  |
13        26  


Lo más interesante del asunto es que diez de los posibles símbolos (es decir, 1, 2, 4, 5, 7, 9, 10, 13, 24 y 26) ni siquiera se usan. En el mensaje sólo aparecen dieciséis números diferentes. Dando por supuesto que cada uno de esos dieciséis representa una, y solo una, letra del alfabeto, ese mensaje tiene (Lawrence lo calcula de cabeza) 111136315345735680000 posibles significados.
Es un número curioso porque empieza con cuatro unos y termina con cuatro ceros; Lawrence deja escapar una risita, se limpia la nariz y sigue con el asunto.
El número más repetido es el 18. Probablemente representa la letra E. Si sustituye E en el mensaje cada vez que aparece un 18, entonces…

Antes de que te roben el móvil

Domingo, 16 de Octubre de 2005

Via recreando leo que es posible, sino evitar, al menos “fastidiar” al ladron que te robe tu teléfono movil.
El truco es sencillo: primero tienes que sacar el código IMEI de tu movil y apuntarlo en un lugar seguro. Entonces, el dia que te roben el movil (ojala no sea nunca) puedes llamar a tu operadora y, con este número, bloquearán el movil, dejándolo inservible, aunque cambien la tarjeta SIM.
El IMEI se saca marcando *#06#

Lee el post entero en Paremos el robo de celulares en recreando.bitacoras.com

Anchor y Javascript

Sábado, 15 de Octubre de 2005

Todos conocemos la etiqueta anchor <a> de HTML. Es, casi, la etiqueta elemental, pues gracias a ella se inventó el hipervínculo, y con él, la navegación Web.
Pero, ?y si queremos hacer algo más que navegar de un sitio a otro?
Veamos unos trucos básicos para trabajar con estas etiquetas.

El atributo “href” indica la página donde queremos ir. Así, <a href=”/sitio.html”>click</a> nos llevara a la página /sitio.html.
Si queremos añadir Javascript dentro del atributo href, debemos añadir la cadena Javascript:____. Por ejemplo:

<a href="javascript:alert('hola')">saludame</a>

Pinchando el enlace, nos mostrará un diálogo sencillo. Y no sucede nada más.
Esto es así porque la función alert() no devuelve nada (es void)
Pero, ?Qué sucede cuando usamos una función Javascript nuestra que no devuelve void (como hace la función alert()), sino que retorna algún valor de cualquier tipo?
Supongamos que, aún más sencillo todavía, queremos asignar el valor de una variable a otra, por ejemplo:

<script>
var clicks=0;
</script>
<a href="javascript:clicks=clicks+1">suma uno</a>

?Cuál es el resultado? El enlace sustituye el contenido de la página actual por el el resultado de evaluar la expresión clicks=clicks+1 cuyo resultado es 1, y eso es lo que nos está mostrando.
Esto tiene su utilidad: podemos generar HTML dinámicamente en cliente y mostrarlo al pinchar en el enlace sin recargar la página. Por ejemplo:

<script>
function f() {
    return "<html><body><font color='red' size='6'>Hoy es "+(new Date())+"</font></body></html>"
}
</script>
<a href="javascript:f();">dinamico</a>

Pero probablemente no estemos buscando esto, sino todo lo contrario: que al hacer click se ejecute la función de Javascript pero que no se recargue la página ni haga nada. Para ello tenemos que englobar nuestra función en otra que no nos devuelve nada: void();

<script>
var clicks=0;
</script>
<a href="javascript:void(clicks=clicks+1)">suma uno</a>

Otra solucion es utilizar el evento onclick. Este evento nos permite ejecutar codigo Javascript cuando hacemos click encima de el.

<script>
var clicks=0;
</script>
<a href="#" onclick="clicks=clicks+1">suma otro uno</a>

Sin embargo, el viejo truco del “#” para no enlazar a ningún sitio parece tener un efecto muy feo: hace que la página se desplace hasta la parte superior, aunque no recargue. Para evitarlo, mejor utilizaremos href=”javascript:;” que no hace nada, no devuelve nada y no desplaza la página:

<script>
var clicks=0;
</script>
<a href="javascript:;" onclick="clicks=clicks+1">suma otro uno (sin desplazamiento)</a>

Mejor, ?verdad?
Pero, ?y si queremos ejecutar un Javascript y, además, ir a otro HTML?
Podemos combinarlo, claro está:

<script>
var clicks=0;
</script>
<a href="http://www.google.com" target="_blank" onclick="clicks=clicks+1">suma otro uno y enlaza a Google</a>

Pero onclick puede sernos todavia más util: el valor que retorne este evento servirá para indicarnos si el href ha de funcionar o no. Es decir, si ponemos “return true” dentro del evento onclick, el enlace funciona. Si ponemos “return false”, no funciona.

<script>
var clicks=0;
</script>
<a href="http://www.google.com" target="_blank" onclick="clicks=clicks+1; return confirm('?Seguro?')">suma otro uno y enlaza a Google con confirmacion</a>

En resumen:

<a href=”#”>click</a> No hace nada, pero desplaza hacia arriba
<a href=”javascript:;”>click</a> No hace nada y no desplaza
<a href=”javascript:f()”>click</a> Ejecuta la funcion f() y sustituye el contenido de la página actual con resultado de esta función (excepto si f() no devuelve nada)
<a href=”javascript:void(f())”>click</a> Ejecuta la funcion f() pero no hace nada más, aunque f() devuelva algun valor.
<a href=”javascript:void(a())” onclick=”b()”>click</a> Ejecuta primero la funcion b() y después a() pero no hace nada más
<a href=”javascript:void(a())” onclick=”return c()”>click</a> Ejecuta primero la funcion c() y, si esta devuelve true entonces ejecuta la función a(). Después no hace nada más
<a href=”javascript:a()” onclick=”return c()”>click</a> Ejecuta primero la funcion c() y, si esta devuelve true entonces ejecuta la función f() y sustituye el contenido de la página actual con resultado de la función.

Con esto ya podemos manejar la etiqueta <a> en todas sus múltiples variedades sin que sucedan cosas extrañas.

Star Wars nerds

Viernes, 14 de Octubre de 2005

Increible, a través de una Web con la que comparto apellido (http://www.vilches.tk), he visto que han traducido un video realmente genial de la televisión americana. Diez minutos de risa viendo como un presentador se mete con los “frikis” que están en la cola del estreno de una de las películas. Todos disfrazados de personajes de la película y el presentador… a machete a por ellos! (Todos riendose, eso si). Increible. Me he meado de la risa.

Se trata de una traducción al español de un vídeo de risa que estaba en inglés. Es una sección del programa estadounidense de Conan O’Brien en la que una marioneta con forma de perro hace reportajes (en realidad lo que hace es reírse de la gente ). Es un cabronazo el perro, tiene muchísima chispa, sería, para que os hagáis una idea, el equivalente americano a Xavier Deltell. En este vídeo, va a entrevistar a un grupo de frikis de Star Wars, que estaban en la cola del estreno de una de estas películas.

La noticia entera aqui
Y el video, como no, a través de google vids aqui

Paginacion (y II)

Miércoles, 12 de Octubre de 2005

El otro día comenté en Paginacion (I) como obtener resultados paginados desde la base de datos, mostrando dos formas distintas para hacerlo.
El resultado final es que se devolvía un objeto Page que contenía una coleccion de resultados (los beans de la página) y algunos valores numéricos con información de la página, como el tamaño de la misma, el número de página y el número total de páginas (última página) y elementos (último elemento).

Veamos antes de continuar, un ejemplo de utilización del metodo “getPage” de obtencion de páginas. Esto sería el código de un Servlet cualquiera que recibe como parametros “page” y “size” en su url la página a mostrar y el tamaño de la página. Despues el objeto Page devuelto se introduce en la request con el nombre “vuelos”.
Además, se muestra un “truquillo” para recoger el parametro “page” y “size” sin muchos quebraderos de cabeza. Es el método getParameterInt.

public static final int DEFAULT_PAGE_SIZE = 20;

protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
    int numPage = getParameterInt(req, "page", 1);
    int pageSize = getParameterInt(req, "size", DEFAULT_PAGE_SIZE);

    Page pageVuelos = getPage(numeroPagina, pageSize);

    request.setAttribute("vuelos", pageVuelos);
    req.getRequestDispatcher("/mipagina.jsp").forward(req, res);
}

public int getParameterInt(HttpServletRequest req, String name, int defaultValue) {
    try {
        return Integer.parseInt(req.getParameter(name));
    } catch (NumberFormatException e) {
        // Si llegamos hasta aqui es que número recibido como parámetro es null o no es númerico.
        // Por lo tanto, retornamos el valor por defecto
        return defaultValue;
    }
}

A partir de aqui, el trabajo consiste, desde el JSP, recoger el objeto Page que hemos dejado en el atributo “vuelos” y pintar, con un Iterator (o con lo que se quiera) la coleccion de objetos que en el método getResults()

Una vez pintado la lista de objetos de nuestra página, queremos que el usuario pueda elegir cualquier otra página para poder navegar por todo el conjunto de resultados real. Esto se puede hacer de varias maneras. Podríamos, por ejemplo, hacer un bucle que pintase todas las páginas posibles:

     <%
        Page vuelos = (Page)request.getAttribute("vuelos");
        int n = 1;
        for (n=1; n <= vuelos.getLastPage(); n++) {
        %>
           <a href="/consultaVuelos?page=<%=n%>"><%=n%></a>
        <%
        }
     %>

(more…)

Google en 2084

Lunes, 10 de Octubre de 2005

Aspecto de la página de Google en 2084.

Escalofriante, ?no?. Vía Microsiervos. Sacado de la tira cómica de Siegel en NY Times