Comparativa I: Cliente en Ruby

Pasamos de Java a Ruby, un lenguaje que a pesar de ser aproximadamente tan viejo como el primero, aún sigue siendo desconocido por algunos europeos. Hace poco ha tenido un auge en el viejo continente gracias, en gran medida, a RubyOnRails.

Puesto que vamos a necesitar realizar conexiones, lo primero es:

require 'socket'

Acto seguido, se define el método mensaje_aleatorio:

def mensaje_aleatorio
msg = ["Hola, Mundo","Melón.","Larga y próspera vida.","La Quinta Raza.","So long, and thanks for all the fish.","Spain is different.", "Com va això?","Bona tarda."]
msg[rand(msg.length)]
end

Y ahora llega la magia Ruby. Para crear diez hilos diferentes simplemente se utiliza el método times y la clase Thread:

num_hilos = 10
num_hilos.times do |i|
Thread.start do

En él, se crea un bucle infinito en el que se conecta al servidor (simplemente con TCPSocket.new(servidor,puerto) ), envía el mensaje y espera la respuesta, comprobando que es el texto enviado.

while(true)
puts "Abriendo socket #{j}"
begin
socket = TCPSocket.new("localhost",7777)
puts "Abierto socket #{j}"
s = mensaje_aleatorio
socket.puts s
puts "Enviado \"#{s}\" en #{j}"
puts (s == (s1=socket.gets().strip())) ? "Correcto" : "Falló\nEsperado: #{s}\nDevuelto: #{s1}"
rescue Exception => bang
puts bang.to_s
ensure
socket.close unless socket.nil?
end
end

Ya, por último y fuera del método times, se crea un bucle infinito para evitar que termine el script sin hacer lo que se le pide.

Aquí el código completo.

Matemáticas egipcias.

Hace medio mes empecé mis clases en la Universidad. En Historia de la matemática estamos a punto de llegar a los egipcios, cuya matemática resulta curiosa.

Fracciones unitarias.
Los egipcios ya conocían las fracciones aunque no todas le “gustaban”. De hecho, sólo le gustaban las fracciones unitarias (aquellas en las que el numerador es la unidad) y sólo tenía como excepción (o capricho, según se mire): la fracción 2/3. Así, si se encontraban con una distinta, la transformaban en un sumatorio de fracciones unitarias.

Para pasar una fracción del tipo 2/2k a fracción unitaria es muy sencillo: 2/2k = 1/k. El problema viene con fracciones del tipo 2/n con n impar. En el papiro de Ahmes o de Rhind se encuentra una tabla con algunas descomposiciones con fracciones de dicho tipo, exactamente para todos los impares comprendidos entre 3 y 101, ambos inclusive. Sorprende que dichas descomposiciones no son las más “lógicas”, es decir, si tenemos 2/k usar 1/k+1/k. De hecho, nadie sabe porqué se eligieron esas descomposiciones y no otras, aunque la mayoría son una de las opciones más simples de descomposoción.

Multiplicación.
Para multiplicar usaban un sistema muy interesante, el de la duplicación. Básicamente, no es muy diferente a la técnica que todos usamos en un principio: la de sumar repetidamente. La única diferencia es que iban multiplicando por dos de forma consecutiva. Así, para multiplicar 4×13:

1 ————- 4
2 ————- 8
4 ————- 16
8 ————- 32

Así se tiene que 52 = 32 + 16 + 4 = 4·8 + 4·4 + 4·1 = 4·(8 + 4 + 1) = 4 · 13. Que es lo que buscábamos. Para demostrar que es posible con cualquier número, sólo hace falta reseñar que se basa en que cualquier número es expresable en base 2.

El rival más débil

Leo en No me puedo creer la creación de un maravillos invento: el Natural deselection. Este artilugio me ahorrará trabajo, puesto que mientras mis padres están de vacaciones, yo hago de selección natural. Con dicha máquina será mucho más divertido puesto que, pasada una cantidad de tiempo, las dos plantas más pequeñas serán cortadas por unas tijeras colocadas en la base del tallo.

Comparativa I: Servidor en Java

Segunda entrega de esta comparativa. Le toca el turno al servidor echo. Este servidor constará de dos clases: EchoServer, la clase pública con el método main, y EchoConnection, que extiende la clase Thread y es la que realiza la mayor parte del trabajo.

EchoServer.

Aquí nos encontramos el método main(), el cual es muy, pero que muy simple:

public static final void main(String[] args){
new EchoServer();

}

El constructor de la clase es un poco más interesante, con él se explicará el funcionamiento básico de la clase ServerSocket del paquete java.net.

int port = 7777;
try{
ServerSocket server = new ServerSocket(port);
System.out.println("Servidor a la escucha en el puerto: "+port);

El constructor de la clase ServerSocket recibe como parámetro el número del puerto en el que ha de escuchar. En el siguiente trozo de código se crea un bucle infinito y se lanzan hilos que manejen las peticiones recibidas. Para ello se utiliza el método accept() de la clase ServerSocket. Este método espera una conexión y devuelve el objeto Socket que la representa. Finalmente se capturan las excepciones.
while(true) new EchoConnection(server.accept());
}catch(Exception e){
System.out.println("Error en el servidor.\n"+e.toString());
}

EchoConnection.

La clase EchoConnection extiende la clase Thread y contiene dos variables estáticas: connections y visits. Estas variables sirven para contabilizar el número de clientes totales y el de clientes conectados actualmente. Por otra parte, se declara una variable privada socket, en la que se almacena la conexión pasada al constructor. Dicho constructor, consta de la asignación del socket recibido al privado y de la sentencia que inicia el hilo (this.start()).

El último método a comentar es el método run(). Dicho método es rápido de explicar. En primer lugar, se aumenta el número de conectados y el de las visitas:

EchoConnection.connections++;
int numCliente = ++EchoConnection.visits;

Después se capturan los flujos de entrada y de salida:

BufferedReader entrada = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
PrintWriter salida = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream()),true);

Ahora se ha de realizar lo que se supone que debe hacer. Recibir una cadena…

String cadena = entrada.readLine();

…y reenviarla:

salida.println(cadena);

Para terminar, se cierran los flujos y el socket:

entrada.close();
salida.close();
this.socket.close();

Después se capturan las excepciones y en el finally se resta 1 al número de conectados.

El código completo se puede encontrar aquí.

Nota: el código no es todo lo limpio que debería ser. Todos los cierres deberían ir en el finally, por ejemplo.

Mi primer día (fue ayer).

Ayer empecé mis andaduras por la facultad. Al llegar en coche, me encontré el siguiente panorama lo que hizo que me tuviese que ir al otro lado del Paraninfo. Esto me permitió tomar algunas fotos de camino a mi facultad, como esta del Parque de las Ciencias (prometo retocar el color…) o el tramo final del camino al matadero. Y por fin llegué a la puerta, y me encontré algunas cosas curiosas, como la ristra de botellines o una cosa llamada Rafa.

Después de tres horas (geometría proyectiva, cálculo diferencial y probabilidad y estadística) llegó el momento de los reencuentros con antiguos compañeros, colegas y demás.

Cuando parecía que todo había terminado… no. Quedaban dos horas más: historia de las matemáticas I y lógica matemática. Aunque, al final, conseguí ver la salida.