Manuales curiosos

Llevo toda la semana con dolor de cabeza más garganta todo en uno, agitado no mezclado y por ello no estoy ni escribiendo aquí, ni estudiando, ni haciendo nada salvo dormir y sobrevivir mediante la ingestión de pizzas y alimentos ricos en hidratos de carbono (sobres de pasta para los friends).

Hoy que ya me encuentro con ganas de hacer algo sin que tenga ganas de darme cabezazos contra la pared, para que se me vaya el dolor de cabeza. Revisando mis RSS, me encuentro en el blog de JJ las transparencias que usó en su charla/taller sobre Perl en la Campus party. Leyendo un poco por encima, me arrepiento por no haber ido, sobre todo por la ironía y sentido del humor que parece que tiene el mozo, debió de estar muy ameno (y no como el puto taller de python al que fuí, que aunque didactico era, fue un coñazo en mayusculas, los talleres tienen que ser divertidos xD, si no es así, casi mejor leerte tu un pdf).

Además de este corto, irónico y práctico tutorial, hay otro sobre ruby también con bastante humor en él. He aquí enlaces a ambos, si alguien conoce más tutoriales/manuales/howtos/* del mismo estilo, comentario pero ya! xD

HowTo: Integrando Rails con apache

railsApache.pngBueno, como dije en el anterior post, voy a explicar como integrar Rails con Apache, para que sea éste nuestro servidor Web. El servidor de Rails WEBrick (ejecutando script/server en el directorio de nuestra aplicación de Rails) cumple su función, sobre todo es útil para el desarrollo, pues muestra mucha información. Pero para un entorno real, no puede competir con un servidor web "de los de verdad" (estaría bien respaldar ésto con números, para otro día que me aburra...). Otra opción sería usar Rails con lighttpd, ésto lo he visto mucho por la red, y parece dar buenos resultados, pero como Apache es mucho Apache, prefiero usarlo :P.

Seguiré desde el HowTo anterior, es decir, tenemos una aplicación básica en ~/dev/rails la cual al final de este tutorial será servida a los clientes mediante apache. Supongo que estamos usando Ubuntu Dapper, para otra distro sería todo perfectamente aplicable, pero habría que cambiar, posiblemente, algunos de los binarios/directorios/archivos/nombres_de_paquetes por otros ligeramente diferentes. Intentaré ir explicando las cosas de la forma más generica posible... ok, entonces ¿qué necesitamos para poder servir aplicaciones RoR con apache?

  • Mod_rewrite (para apache)
  • Mod_fcgid (para apache)
  • fcgid en nuestro sistema
  • Modulo fcgid para ruby
  • Configurar apache, añadiendo un virtualhost (o un Directory + Alias)

Vayamos por partes, como dijo Jack el destripador. Mod_rewrite lo tendrás casi 100% seguro, a no ser que hayas compilado apache indicandole que no quieres ese modulo. ¿Cómo sabemos que lo tenemos?

$ /usr/sbin/apache2 -l # [el binario de apache] -l
Compiled in modules:
core.c
(...)
mod_alias.c
mod_so.c
$ ls /etc/apache2/mods-enabled/ # aquí aparecerán los módulos activos

Debe de salir en uno de esos dos comandos, si lo tienes instalado de los repositorios de ubuntu, saldrá en mods-enabled ;).

Mod_fcgid para apache, ok. Instalemoslo o si eres un autentico macho ibérico que compila todo, compila tu apache con este modulo!. Para el resto de mortales, simplemente esto:

$ sudo aptitude install libapache2-mod-fcgid
$ sudo /etc/init.d/apache2 force-reload
$ more /etc/apache2/mods-enabled/fcgid.conf # ahora tendremos estos dos ficheros, este

AddHandler fcgid-script .fcgi
SocketPath /var/lib/apache2/fcgid/sock

$ more /etc/apache2/mods-enabled/fcgid.load # y este!
LoadModule fcgid_module /usr/lib/apache2/modules/mod_fcgid.so

Ahora instalemos fcgi en nuestro sistema como librería compartida, podemos hacer un aptitude search fcgi para ver paquetes candidatos, en el caso de Ubuntu Dapper, simplemente:

$ sudo aptitude install libfcgi0

Ahora solo nos queda por instalar el modulo fcgi para ruby, para ello hacemos un:

$ sudo aptitude install libfcgi-ruby1.8 # o la que nos corresponda

Ahora hagamos la prueba definitiva, para saber si todo va bien:

$ irb
irb(main):001:0> require 'fcgi.so'
=> true
irb(main):002:0> require 'fcgi'
=> true

Muy bien!, ya tenemos todo preparado, ahora configuremos apache!. Haré la configuración con un Virtualhost, pues lo veo más cómodo (pero se podría hacer también con un "Directory" más un alias). Añadimos a la configuración de apache lo siguiente:

$ sudo vi /etc/apache2/sites-available/default # en dapper, sería en este fichero


ServerName rails
DocumentRoot /home/blaxter/dev/rails/public/
ErrorLog /home/blaxter/dev/rails/log/apache.log

Options ExecCGI +FollowSymLinks
AllowOverride all
Allow from all
Order allow,deny



$ sudo vi /etc/hosts # añadimos un linea como esto:
127.0.0.1 rails
$ sudo /etc/init.d/apache2 force-reload # reiniciamos apache

Debes cambiar /home/blaxter/dev/rails por la ruta de tu aplicación rails!.

Ahora debemos hacer un par de cosas antes de dejar todo listo. Primero borrar las sesiones actuales

$ cd ~/dev/rails # dir de nuestra aplicación
$ rm tmp/sessions/* # es importante hacer esto, hazlo!

luego permitir al servidor leer y escribir en nuestra aplicación, Apache corre como usuario www-data, una forma de permitirle leer los archivos y escribir (concretamente debe escribir en ./tmp/*), sería poner el proyecto con nombre de usuario www-data y luego añadirnos a nosotros como miembro de www-data, esta es una opción, puede haber cientas, dependiendo del sistema de cada uno...

$ chown www-data:www-data -R . # apache corre como usuario www-data
$ sudo vigr # modificamos la linea de www-data, si teníamos algo como esto:
www-data:x:33:
la modificamos a algo como esto:
www-data:x:33:blaxter

Ahora, ya para finalizar, solo nos queda modificar el .htaccess, concretamente ~/dev/rails/public/.htaccess, que debe quedar así:

Options +FollowSymLinks +ExecCGI
RewriteEngine On
#####################################
# Si configuramos la aplicacion con un Directory mas un alias tipo
# Alias /rails /home/blaxter/dev/rails/public
# Deberíamos descomentar la siguiente linea
# RewriteBase /rails
#####################################
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

ErrorDocument 500 "Application error. Rails application failed to start properly"

Ok, todo hecho. Ya solo queda entrar a http://rails/ o http://rails/adminDeCosas o http://rails/prueba y todo funcionará!. Además podremos ver el log en ~/dev/rails/log/apache.log :). Suerte!

HowTo: Instalando unos buenos Railes [RoR]

rails.pngRuby es un lenguaje de script similar a python, que aunque no era muy conocido anteriormente (antes de RoR), gracias al framework RoR, está creciendo en popularidad a pasos agigantados y además por méritos propios.

El framework Rails se basa en el patrón de diseño MVC (model view controller). Igual otro día explico en detalle este patrón, pues es muy interesante. Ahora vayamos con la instalación de Rails, que es de lo que se trata en este post.

Podríamos hacer la instalación con un simple $ sudo aptitude install rails, pero es mejor instalarlo mediante Gem, un gestor de paquetes para ruby (algo así como PEAR para php o cpan.org para perl, o el propio apt-get para Debian)

Supongo que tenemos instalada una base de datos, por ejemplo MySQL, y repositorios universe de Ubuntu dapper (para otras distros se podrían aplicar todos los pasos, realizando, quizás, ciertas modificaciones...). Primero instalaremos Ruby y unos paquetes adicionales necesarios para el correcto funcionamiento de Gem

$ sudo aptitude install ruby irb rdoc libzlib-ruby libyaml-ruby liberb-ruby rdoc libdrb-ruby libyaml-ruby libzlib-ruby

irb es un entorno de ejecución interactivo de ruby, podemos ejecutarlo y hacer un hola mundo xD

$ irb
irb(main):001:0> print "hola mundo!"
hola mundo!=> nil

innncreible xD. Ahora instalemos Gem


$ cd /tmp && wget http://rubyforge.org/frs/download.php/28174/rubygems-0.9.5.tgz
$ tar xfz rubygems-0.8.11.tgz
$ cd rubygems-0.8.11/
$ sudo ruby setup.rb

Ok, ya lo tenemos instalado, para información de como funciona, ver aquí. Ahora para instalar rails solo tenemos que hacer:

$ sudo gem install rails --include-dependencies

Ya está!, tenemos Ruby On Rails instalado! Mooola. Vale, pero y ahora que hago?. Vamos a hacer un par de pruebas para ver que realmente funciona todo bien.

Suponemos que nuestro directorio de trabajo será ~/dev/rails, por ejemplo:

$ cd ~/dev
$ rails rails # el parametro es el nombre de la carpeta que creará
$ cd rails
$ script/server

Ok, ahora si entramos en http://localhost:3000/ veremos la pantalla de bienvenida de Rails. Vale, funcionar, funciona, o algo sale. Pero como pongo hago yo cosas?, eh?, eh?. Vamos a hacer un hola mundo!.

Paramos el servidor (ctrl+c) y ejecutamos

$ script/generate controller prueba
$ vim app/controllers/prueba_controller.rb # lo modificamos tal que asi:
$ more app/controllers/prueba_controller.rb
class PruebaController < ApplicationController
def index
render_text "hola mundo!"
end
def lalala
render_text "como mola esto nano!"
end
end

$ script/server

Y al entrar a http://localhost:3000/prueba veremos nuestro gran hola mundo! :). Y entrando a http://localhost:3000/prueba/lalala veríamos el otro texto que hemos escrito. Inncreible xD.

Vale, ya hemos hecho una tontería, hagamos otra más cool. Al inicio de este coñazo HowTo dije que suponía que teníamos instalada MySQL (u otra BD). Instalemos soporte para ruby para nuestra base de datos

$ sudo aptitude install libmysql-ruby1.8 # o el equivalente para nuestra BD!
$ irb
irb(main):001:0> require "mysql"
=> true
irb(main):002:0> exit

Creamos un par de bases de datos y por temas de seguridad también sería aconsejable crear un usuario con permisos más restrictivo, usaré "root" por simplificar este howto

$ sudo mysql -u root -p
mysql> create DATABASE rails;
mysql> create DATABASE rails_test;
mysql> quit

Ahora vamos a decir a Rails cual es nuestra base de datos, editamos ~/dev/rails/config/database.yml quedando algo como esto:

$ more config/database.yml
development:
adapter: mysql
database: rails
username: root
password: NUESTRAPASS
host: localhost

test:
adapter: mysql
database: rails_test
username: root
password: NUESTRAPASS
host: localhost

production:
adapter: mysql
database: rails
username: root
password: NUESTRAPASS
host: localhost

Vale, todo perfecto. Ahora hagamos lo siguiente:

$ script/generate model Thing
$ vim db/migrate/001_create_things.rb
algo como esto (por ejemplo...):

class CreateThings < ActiveRecord::Migration
def self.up
create_table :things do |t|
t.column :nombre, :string
t.column :uso, :string
t.column :cantidad, :integer
end
end

def self.down
drop_table :things
end
end

$ rake db:migrate
$ script/generate scaffold Thing AdminDeCosas
$ script/server

Ahora entrando a http://localhost:3000/AdminDeCosas podremos añadir entradas de "cosas", verlas, editarlas y borrarlas. Curioso, eh?

Para próximos posibles post me apunto integrarlo con apache y profundizar más en las posibilidades de Rails. Para cualquier duda, crítica, opinión, insulto o desvario mental, los comentarios ;).

Vencido por un par de alfombras

logo_CodeJamEurope.gif

Hoy era el tan esperado Google Code Jam, lo estaba esperando con bastantes ganas desde hace unos días y despues de volver de la rutina diaria, me he puesto a intentar resolver los problemas que te planteaban (dos, uno de 500ptos. y otro de 250ptos.) en un tiempo de 60minutos.
Al entrar te indicaban la sala que te correspondía (había 30 con unos 50-60 participantes, es decir unos 1500 en total así aproximadamente), con lo cual se evitarían (más o menos...) de posibles lammers que hubiesen registrado dos cuentas para entrar, ver los problemas, resolverlos con tiempo y luego entrar con otra cuenta (lo cual no apruebo :P, prefiero caer con honor que pasar haciendo trampas). Veo las puntuaciones de mi sala (así a ojo quedandote entre los 15 primeros te asegurabas pasar) y compruebo que eran relativamente bajas en general (con hacer 1pto, te ponías el 12º), como suponía que aún faltaría mucha gente de participar y veo que haciendo el segundo (el dificil) conseguiría ponerme entre los 5primeros aprox.(todo depende del tiempo...y no se, si de lo optimo que lo hicieras), así que todo afanoso abro el primer problema

Problema de los 500ptos, dado un entero 'n' que corresponda con la longitud de una cadena compuesta por A's y B's, cuenta el número total de cadenas posibles que se pueden formar que no tengan más de 'w' subcadenas invertibles (por ejemplo, BA invertible en AB). Realmente era algo más complejo, pero no me aclaraba y he empezado a pensar en la representación como binario de las cadenas (te dicen A y B, pero te podías representarlo con 0 y 1, y por lo tanto operar como un numero la cadena total) y despues de estar 20minutos y ver que a los 20minutos estaba igual que hace 10minutos, he decidido dejarlo e ir a por el otro problema. :( Estaba pensando más en el tiempo que en el propio problema realmente...
El segundo problema, (de 250ptos, más facil) iba de alfombras, te daban las medidas de una habitación y tenías que dar las posibles posiciones de poner un par de alfombras con unas restricciones concretas:

  • No se podían solapar
  • Un lado de la alfombra no podía ser dos veces mayor que el otro
  • Se debía dejar, al menos, una unidad cuadrada libre de parqué, representaría la entrada de la habitacion
  • El par de alfombras podían ser de cualquier tipo de medidas, diferentes, iguales...
  • SOLO DEBÍA DE HABER UN HUECO

El último punto lo pongo en mayusculas, porque como estaba al final del todo, yo agil cual gorrión, no lo he leido hasta despues de ponerme como un cosaco a programar sin parar. Termino el caso y cuando voy a hacer las pruebas veo que los casos grandes no me salían (salían muchos más), y repasando el enunciado (por si algo lo había traducido mal...) veo que no había leido esa restricción. Despues de buscar un cuchillo para el suicidio y como debería de levantarme e ir a la cocina para ello, me pongo a intentar arreglar la cosa como sea, quedaban 5min y el contador iba bajando. No me ha dado tiempo :(. Si hubiese perdido algo más de tiempo leyendo atentamente este segundo problema hubiese podido completarlo a tiempo. Mala suerte y poca sangre fria he tenido :-/, no pasa nada, ha sido una hora muy divertida :), para el proximo año espero que lo hagan de nuevo! ahí estaré :). Espero que otros que participaban hayan tenido más suerte.

Null types

Lenguajes fuertemente tipados como C++, C#, java, etc... no soportan valores null para sus tipos primitivos. Erase una persona llamada Mihhon, programador perito, sabio entre todos los peritos, que venía de programar mucho en C a pelo, como los verdaderos hombres, como él deseaba seguir tratando con sus maravillosos y amados NULL's se hizo una pequeña librería para arreglar este gran e inquietante problema:

static public final boolean isNull(double _value)
{
return (Math.abs(_value) < 0.0001);
}

static public final boolean isVeryNull(double _value)
{
return (Math.abs(_value) < 0.0000000001);
}

Posiblemente otros métodos de la librería serían:

boolean isTruelyNull(double _value)
boolean isReallyQuiteSpectacularlyNull(double _value)
boolean isNullToEndAllNull(double _value)
boolean isMoreNullThanTheOtherNull(double _value)

Script para coding time

Despues de casi 24h programando nonstop, al final se me ha ocurrido hacerme un mini-script para ir viendo como iba progresando xD, se que el número de las lineas que se van escribiendo no es muy importante (y muy variable dependiendo de cada uno y del lenguaje u otros aspectos), pero mientras escribes asqueroso código en Java (odio escribir código con Awt/Swing) sube la moral ver como aumentan las lineas xD. Vamos paranoya de estar programando demasiado tiempo seguido. Se podría hacer en bash en una linea, pero mola mas perl :P


#!/usr/bin/perl
sub lineas
{
open(javaF, $_[0]);
@lines = ;
close(javaF);
scalar @lines;
}

$lines=0; $n = 0;
opendir(DIR, ".");
foreach(readdir(DIR))
{
if(/\.java$/io)
{
$n++;
$lines += lineas $_;
}
}
close DIR;
print "Hay $lines lineas en $n ficheros\n";

Ejemplo de ejecución:

[blaxter@helicon]:~/CPS/Proyectos/RegisterUp$ ./suma
Hay 2011 lineas en 9 ficheros

Ahora me acuerdo de un dato que había en mis apuntes de la asignatura de "Proyectos" que decían que la media productiva de un programador era de 20lineas/día o algo asi. Venga que llevo 10000% de productividad jaja. (En verdad el programa que estoy escribiendo es lo más tonto del mundo, así que debería haberme costado la mitad realmente :P, es lo que tiene ser a littlecico gork)

Creative Commons License Esta obra está bajo una licencia de Creative Commons.

Este blog funciona gracias a WordPress con el theme GimpStyle diseñado por Horacio Bella y adaptado por un servidor.
Feed entradas