Manipulación de columnas con numpy

Cuando se manipulan datos es habitual tener que trabajar con columnas, sobre uno o varios archivos.

Dada una serie de archivos alojados en un directorio. Utilizaremos la función loadtxt de la librería de python numpy para capturar el contenido almacenado en columnas, lo cual nos permitirá manipularlo por medio de índices. Con savetxt, guardaremos la información en archivos de texto.

Para finalizar, con la librería matplotlib, se generarán varias imágenes en png con gráficos de los datos.

Teniendo archivos de la forma:

   0.0        0.9
   1.0        1.2
   2.0        1.8
   3.0        1.3
   4.0        1
   5.0        0.9
   6.0        0.8
   7.0        0.7
   8.0        0.7
   9.0        0.6

El siguiente script suma la segunda columna de un par de archivos, repitiendo el proceso para todas las combinaciones de dos archivos en el directorio.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import numpy as np
import matplotlib.pyplot as plt

files = {}

# almacenar nombres de archivo y contenido
dname = 'input/'
for f in os.listdir(dname):
    fname = dname + f
    files[f] = np.loadtxt(fname)

# recorrer todos los archivos
for fi in files.keys():
    for fj in files.keys():
        if fi != fj:
            namei = fi.replace('.txt','')
            namej = fj.replace('.txt','')
            outfile = 'sum_' + namei + '_' + namej

            # primera columna del archivo
            c1 = files[fi][:,0]
            # segunda columna del archivo
            fi_c2 = files[fi][:,1]
            fj_c2 = files[fj][:,1]

            # suma de columnas
            sum_c2 = fi_c2 + fj_c2

            # guardar suma en texto
            np.savetxt(outfile + '.txt',
                    np.column_stack([c1,sum_c2]),
                    fmt = '%10.2f')

            plt.clf()
            # curva archivo i
            plt.plot(c1,fi_c2)
            # curva archivo j
            plt.plot(c1,fj_c2)
            # curva archivo suma
            plt.plot(c1,sum_c2)
            # guarda curvas en png
            plt.savefig(outfile)

Una de las imágenes de salida, donde la linea azul y verde representan los datos en las columnas leídas y la roja la suma de ambas.

png

Enlaces

Nbody con Three.js

Three.js es una librería de javascript para 3D.

Para mostrar lo simple que es usarla, un ejemplo del problema de los n cuerpos ( nbody problem ). Donde la interacción de las partículas está determinada principalmente por sus distancias, masas y una constante gravitacional.

El script que determina las posiciones en base a la velocidad, aceleración y fuerzas involucradas:

container = document.getElementById('container');

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera(45, window.innerWidth /
        window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);

renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);

pointlight = new THREE.PointLight(0xffffff);
ambientlight = new THREE.AmbientLight(0x101010);

directlight = new THREE.DirectionalLight(0xffffff, 1);
directlight.position.set(1, 1, 0).normalize();

scene.add(ambientlight);
scene.add(pointlight);
scene.add(directlight);

sgeometry = new THREE.SphereGeometry(3,16,16);
smaterial = new THREE.MeshPhongMaterial({color: 0x0000ff});

// algunas constantes
var spheres = new Array();
var n = 10 ;
var g = 6.670*0.01;
var m = 0.5;

// posiciones iniciales
for (var i = 0; i < n ; i += 1) {
    spheres[i] = new THREE.Mesh(sgeometry, smaterial);
    scene.add(spheres[i]);
    spheres[i].position.x += -50 + Math.random()*100;
    spheres[i].position.y += -50 + Math.random()*100;
    spheres[i].velocity = new THREE.Vector3(0,0,0);
    spheres[i].m = m;
}

container.appendChild(renderer.domElement);
var fx, fy, fz, dx, dy, dz, d2, d, f, ax, ay, az;
function render() {
    requestAnimationFrame(render);
    // fuerzas
    for (var i = 0; i < spheres.length; i += 1) {
        fx = 0;
        fy = 0;
        fz = 0;
        for (var j = 0; j < spheres.length; j += 1) {
            if (i != j ) {
                dx = spheres[i].position.x - spheres[j].position.x;
                dy = spheres[i].position.y - spheres[j].position.y;
                dz = spheres[i].position.z - spheres[j].position.z;
                d2 = dx*dx + dy*dy + dz*dz;
                d2 = d2 + 1;
                d = Math.sqrt(d2);
                f = -1 * g * spheres[i].m * spheres[j].m / d2;
                fx += f * dx/d;
                fy += f * dy/d;
                fz += f * dz/d;
            }
        }
        ax = fx / m;
        ay = fy / m;
        az = fz / m;
        spheres[i].velocity.x +=  ax;
        spheres[i].velocity.y +=  ay;
        spheres[i].velocity.z +=  az;
        spheres[i].position.x += spheres[i].velocity.x;
        spheres[i].position.y += spheres[i].velocity.y;
        spheres[i].position.z += spheres[i].velocity.z;
    }
    renderer.render(scene, camera);
}
render();

Referencias

Google script filtro de tiempo para Gmail

Hace algunos días que buscaba algún filtro para Gmail que se activara a cierta hora.

Me explico, todos los días me llegan algunas notificaciones por mail, las cuales me gusta tener presente durante el día, pero al final del mismo ya no tienen importancia, por lo que buscaba alguna forma para que se archivaran automáticamente todos los días a cierta hora. Un filtro común no era adecuado, ya que al llegar la notificación se archivaría inmediatamente.

Cuando estaba creando un documento en google docs, vi que estaba la opción de crear scripts, revise un poco la documentación, y realizar lo que necesitaba no fue muy complejo.

Desde google docs se crea un script

function archiveNotification() {
  var threads = GmailApp.getInboxThreads();

  for ( var i = 0 ; i < threads.length; i++){
    var subject = threads[i].getFirstMessageSubject();

    if ( subject == "Notification Subject" ){
      //Logger.log(subject);
      GmailApp.moveThreadToArchive(threads[i])
    }

  }
}

Básicamente, consiste en revisar la bandeja de entrada y buscar el thread que tenga el subject de las notificaciones.

Al ejecutarlo la primera vez es necesario conceder algunas autorizaciones para que el script pueda tener acceso a Gmail.

El la zona superior del editor, en Resources, se puede agregar el trigger de tiempo, entre otros.

De la misma forma se puede interactuar con varios de los servicios de Google.

Referencias

Multicore con python

Si nos dicen programación paralela seguro que lo primero en que pensamos es MPI o openMP, incluso en CUDA.

Pero en algunos casos lo único que necesitamos es aplicar, de manera simple, una operación sobre muchos elementos, y aprovechar el procesador multicore del que disponemos.

El python, al usar map aplicamos una misma función a cada elemento de una lista. Lo que ofrece el paquete multiprocessing, entre otras cosas, es poder dividir esta tarea entre el número de procesadores que se especifique.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import multiprocessing
from datetime import datetime
def f(x):
    n = int(1e2)
    for i in range(n):
        for i in range(n):
            # computo
            i
    return i*i

def main():
    n = int(1e5)
    np =  multiprocessing.cpu_count()
    pool = multiprocessing.Pool(processes=np)
    l = range(n)
    t0 = datetime.now()
    map(f,l)
    print datetime.now() - t0

    t0 = datetime.now()
    pool.map(f,l)
    print datetime.now() - t0

if __name__ == "__main__":
    main()

En un core demoró 50 segundos, versus los 12 al usar cuatro cores.

0:00:50.793201
0:00:12.689651

Los tiempos fueron medidos en un Intel(R) Xeon(R) E5504 2.00GHz.

Enlaces

CSS con stylus

Como ahorrar tiempo con al momento de trabajar con CSS?

He probado un poco con less, y es una gran ayuda, especialmente con el uso de variables. Pero después de probar estas soluciones, te preguntas ¿es necesario usar las llaves ({})?.

Supongo que lo mismo se pregunto stylus, bueno en la página dice lo mismo.

“Que tal si pudiéramos omitir las llaves, los punto y como y los dos puntos ?”

Lo primero es tener instalado nodejs y su gestionador de paquetes npm.

E instalar stylus

npm install stylus -g

Y ahora teniendo un archivo font.styl como este

font-size = 14px

body
    font font-size Arial, sans-serif

Usamos stylus

stylus font.styl

Genera

body {
    font: 14px Arial, sans-serif;
}

No puedo dejar de mencionar el argumento

style --watch style.styl

Con esto cada vez que modifique el archivo style.styl se generara automáticamente el archivo style.css.

Más detalles en el sitio de stylus

dvtm sobre screen

Hace algunos años usé awesome window manager, probando el tiling en todo su potencial.

El recuerdo perduro en la memoria y se hacia presente cada vez que tenía que trabajar con varias terminales, o más aun, a pantalla completa. Surgía la necesidad de moverse entre ellas aprovechando lo mejor posible la pantalla.

Una solución clásica es usar screen que soportan varias terminales a la vez y cosas como split. Sin olvidar que puedes dejar corriendo tareas en background y recuperarlas.

Pero la gestión de los espacios sigue siendo tarea del usuario.

Ahí es donde entra dvtm. Como awesome, se encarga de gestionar las ventanas con tiling, cada vez que lanzas una shell se acomoda al estilo de layout que tengas seleccionado.

En screen como en dvtm la tecla por defecto es a, por ejemplo con

crtl-a c

Lanza una nueva terminal. Por lo cual, con un alias, cambie dvtm

alias dvtm='TERM=rxvt-256color ; dvtm -m ^q'

Hubiera sido mejor especificar estas opciones al momento de la compilación, pero en Lion he tenido algunos problemas, compila bien, aunque al intentar lanzara más de tres windows, se cae. Por suerte Steve Losh dejó unos binarios compilados en Snow leopard, que funcionan bien en Lion.

Enlaces

rxvt-unicode con 256 colors para dvtm

El problema comenzó cuando desde dvtm iniciaba una conexión ssh a una maquina ubuntu, obtenía este mensaje

tput: unknown terminal "rxvt-256color"
tput: unknown terminal "rxvt-256color"
tput: unknown terminal "rxvt-256color"
tput: unknown terminal "rxvt-256color"
tput: unknown terminal "rxvt-256color"
tput: unknown terminal "rxvt-256color"
...

Entraba con TERM=rxvt-256color ya que dvtm necesita esta terminal para mostrar los 256 colores.

Lo que sigue es una traducción rápida de Get rxvt-unicode with 256 color support on Ubuntu

Descargar el src de rxvt-unicode y aplicar el parche para 256 colores

# descar el fuente
cd ~/src
mkdir rxvt-unicode
cd rxvt-unicode
apt-get source rxvt-unicode
cd rxvt-unicode-9.07

# aplicar parche
patch -p1 < doc/urxvt-8.2-256color.patch

# construir los paquetes
sudo apt-get build-dep rxvt-unicode
dpkg-builpackage -us -uc -rfakeroot

# instalar
cd ..
sudo dpkg -i rxvt-unicode_9.07-2_amd64.deb

Teniendo rxvt-unicode instalado modificar el terminfo

cd ~
infocmp -L rxvt-unicode rxvt-unicode.terminfo

vim rxvt-unicode.terminfo
# cambiar la linea
lines_of_memory#0, max_colors#88, max_pairs#256,
# a
lines_of_memory#0, max_colors#256, max_pairs#32767

# crear el directorio ~/.terminfo
install -d .terminfo
# reconstruir terminfo de rxvt-unicode
tic -o .terminfo/ rxvt-unicode.terminfo
rm rxvt-unicode.terminfo

Y finalmente para que dvtm tenga 256 colores

cd ~/.terminfo/r
cp rxvt-unicode rxvt-256color

Con esto dvtm no debería mostrar más problemas.

Referencias

Verbatim en beamer

Cuando se intenta usar Verbatim en Beamer para hacer una presentación con latex, se pueden presentar problemas al momento de la compilación. La solución está en usar

[fragile]

en el frame.

\documentclass{beamer}
\usepackage[spanish]{babel}
\usepackage[utf8]{inputenc}
\usetheme{Antibes}
\begin{document}
\title{Simple Beamer}
\frame{\titlepage}
\begin{frame}[fragile]
    \frametitle{Hello world}
        \begin{verbatim}
            #!/usr/bin/python
            print "Hello World!"
        \end{verbatim}
\end{frame}
\end{document}

Pasa lo mismo con el paquete listings

\documentclass{beamer}
\usepackage[spanish]{babel}
\usepackage[utf8]{inputenc}
\usetheme{Antibes}
\usepackage{listings}
\begin{document}
\title{Simple Beamer}
\frame{\titlepage}
\begin{frame}[fragile]
    \frametitle{Hello world}
        \begin{lstlisting}
            #!/usr/bin/python
            print "Hello World!"
        \end{lstlisting}
\end{frame}
\end{document}

Referencias

Automata celular con HTML5

Para probar canvas de HTML5 un automata celular con la regla 110

Y el código :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
	<script type="text/javascript" charset="utf-8">
		function bloques () {
			var canvasContext = document.getElementById("canvas").getContext("2d");
			canvasContext.fillStyle = "rgba(200,200,200,0.0)";
			var dx=2;
			var a=new Array();
			var b=new Array();
			for (var i = 0; i < 200; i += 1) a[i]=Math.round(Math.random());
			for (var j = 0; j < a.length; j += 1)
				for (var i = 0; i < a.length; i += 1) {
					canvasContext.fillRect(i*dx,j*dx,dx-1,dx-1);
				};
			canvasContext.fillStyle = "rgba(200,200,200,0.9)";
			var alpha=0.9;
			for (var j = 0; j < a.length*3/2; j += 1){
				for (var i = 0; i < a.length; i += 1) b[i]=a[i];
				for (var i = 0; i < a.length; i += 1) {
					bj=b[(i+1)%a.length];
					bk=b[i];
					bl=b[(i+a.length-1)%a.length];
					a[i]=r110(bj,bk,bl);
					if (a[i]==1) {
						canvasContext.fillRect(i*dx,j*dx,dx-1,dx-1);
					}
				};
				alpha-=0.004;
				canvasContext.globalAlpha=alpha;
			}
		}
		function r110 (j,k,l) {
			// [rule 110](http://en.wikipedia.org/wiki/Rule_110)
			if( j==1 && k == 1 && l==1) return 0;
			if( j==1 && k == 1 && l==0) return 1;
			if( j==1 && k == 0 && l==1) return 1;
			if( j==1 && k == 0 && l==0) return 0;
			if( j==0 && k == 1 && l==1) return 1;
			if( j==0 && k == 1 && l==0) return 1;
			if( j==0 && k == 0 && l==1) return 1;
			if( j==0 && k == 0 && l==0) return 0;
		}
	</script>
  </head>
  <body onload="bloques()">
	  <canvas id="canvas" width="400" height="400">
	  </canvas>
  </body>
</html>

Referencias

Una vista rápida a virtualenv

Más de alguna vez he querido instalar alguna lib de python para probarla sin tener que modificar mucho el sistema.

La solución virtualenv.

Se puede instalar desde easy_install

sudo easy_install virtualenv

O teniendo pip, para instalar pip

sudo su -
curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python

Ahora virtualenv

pip install virtualenv

Crear un directorio para probar

mkdir 001 ; cd 001

Crear un virtual environment, sin ningún paquete previo

virtualenv venv --no-site-packages

Activar el entorno

source venv/bin/activate

El prompt debería haber cambiado mostrando la activación del entorno.

Ahora se pueden instalar paquetes que solo tendrán efectos sobre sobre el entorno.

pip install django

Para verificar que tenemos instalado podemos usar yolk

sudo pip install yolk

Este nos permite ver que tenemos, con

yolk -l

Y para salir de entorno

deactivate

Debería haber un cambio en el prompt mostrando la salida.

Edit 2012-07-12

Para instalar pip es necesario tener instalado python-setuptools.

En ubuntu/debian basta con

apt-get install python-setuptools

Referencias

virtualenv tutorial

Mono 10 y ironpython en Ubuntu 10.10

Mono 10

Si necesitas .NET v4 en Linux la opción es mono 10.
Para facilitar la instalación es recomendable el script mono_build.sh.

Basta descargar, dar permisos y ejecutar

$ wget -c https://raw.github.com/firegrass/mono-installer-script/master/mono_build.sh
$ chmod u+x mono_build.sh
$ ./mono_build.sh -c -v 2.10 -p ~/mono -m mono

Donde -m especifica lo que se quiere instalar, estando disponible incluso monodevelop.
Cuando se complete la instalación debería verse un mensaje de tipo

...
--  Your parallel environment is installed in /home/juanpablo/mono/mono-2.10
--  To start a mono-2.10 environment, run: source mono-2.10-environment
--  To use mono-2.10 to run a cli app, run: mono-2.10 (eg mono-2.10 mono -V)

Por lo que hay que agregar algunas variables al entorno desde mono-2.10-environment

$ source mono-2.10-environment

Y para verificar

$ mono-2.10 mono -V
Mono JIT compiler version 2.10.5  ....

Es recomendable agregar esto a ~/.bashrc
Para utilizar mono 10 es necesario anteponer siempre mono-2.10.

Ironpython

Ahora a clonar ironpython y construir

$ git clone https://github.com/IronLanguages/main.git IronLanguages
$ cd IronLanguages
$ xbuild Solutions/IronPython.Mono.sln

Con lo cual ipy, el interprete, debería estar en IronLanguages/bin/Release/ipy.exe, como depende de mono 10 para utilizarlo es necesario

mono-2.10 $HOME/IronLanguages/bin/Release/ipy.exe

Para simplificar agregué estos alias a ~/.bashrc

alias mono="mono-2.10 mono"
alias ipy="mono $HOME/IronLanguages/bin/Release/ipy.exe"

Referencias

  • http://patrick.qmtech.net/blog/?p=41
  • http://www.mentby.com/doug-blank/building-ironpythonironruby-for-mono-yes.html
  • http://ironpython.codeplex.com/wikipage?title=IronPython%20on%20Mono

Rails con Passenger nginx en Squeeze

Pre requisitos

$ aptitude install build-essential zlib1g-dev libssl-dev libpq-dev libcurl4-openssl-dev curl libreadline-dev

Dependiendo de la base de datos a usar van a ser necesarios algunos paquetes, si se va a ocupar sqlite3

$ wget http://www.sqlite.org/sqlite-amalgamation-3.7.2.tar.gz
$ tar xzf sqlite-amalgamation-3.7.2.tar.gz
$ cd sqlite-3.7.2/
$ ./configure
$ make
$ make install

RVM

Instalar rvm como root

$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile
$ source ~/.bash_profile

Rails

$ rvm install 1.9.2
$ rvm use 1.9.2 --default 

Otros necesarios

$ rvm rubygems current
$ gem install rails
$ gem install bundle

Si falto algún paquete se puede instalar con rvm

rvm package install zlib
rvm remove 1.9.1
rvm install 1.9.1

Passenger

Gem instala passenger

$ gem install passenger

Passenger se debería encargar del resto

$ passenger-install-nginx-module

Dirá si falta algo, incluso se encargar de instalar nginx de ser necesario. La instalación debería terminar con algo como

	This installer has already modified the configuration file for you! The
	following configuration snippet was inserted:

	  http {
		  ...
		  passenger_root /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7;
		  passenger_ruby /usr/local/rvm/wrappers/ruby-1.9.2-p180/ruby;
		  ...
	  }


	server {
	  listen 80;
	  server_name www.yourhost.com;
	  root /somewhere/public;   # <--- be sure to point to 'public'!
	  passenger_enabled on;
	}

El archivo para administrar nginx en /etc/init.d/nginx

	#! /bin/sh

	### BEGIN INIT INFO
	# Provides:          nginx
	# Required-Start:    $all
	# Required-Stop:     $all
	# Default-Start:     2 3 4 5
	# Default-Stop:      0 1 6
	# Short-Description: starts the nginx web server
	# Description:       starts nginx using start-stop-daemon
	### END INIT INFO

	PATH=/opt/nginx/sbin:/sbin:/bin:/usr/sbin:/usr/bin
	DAEMON=/opt/nginx/sbin/nginx
	NAME=nginx
	DESC=nginx
	test -x $DAEMON || exit 0

	# Include nginx defaults if available
	if [ -f /etc/default/nginx ] ; then
			. /etc/default/nginx
	fi

	set -e

	case "$1" in
	  start)
			echo -n "Starting $DESC: "
			start-stop-daemon --start --quiet --pidfile /opt/nginx/logs/$NAME.pid \
					--exec $DAEMON -- $DAEMON_OPTS
			echo "$NAME."
			;;
	  stop)
			echo -n "Stopping $DESC: "
			start-stop-daemon --stop --quiet --pidfile /opt/nginx/logs/$NAME.pid \
					--exec $DAEMON
			echo "$NAME."
			;;
	  restart|force-reload)
			echo -n "Restarting $DESC: "
			start-stop-daemon --stop --quiet --pidfile \
					/opt/nginx/logs/$NAME.pid --exec $DAEMON
			sleep 1
			start-stop-daemon --start --quiet --pidfile \
					/opt/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
			echo "$NAME."
			;;
	  reload)
			  echo -n "Reloading $DESC configuration: "
			  start-stop-daemon --stop --signal HUP --quiet --pidfile     /opt/nginx/logs/$NAME.pid \
				  --exec $DAEMON
			  echo "$NAME."
			  ;;
		  *)
				N=/etc/init.d/$NAME
				echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
				exit 1
				;;
		esac

		exit 0

Darle los permisos de ejecución

chmod +x /etc/init.d/nginx

Subirlo

/etc/init.d/nginx start 

Rails

Para testar

$ rails new blog 
$ cd blog
$ bundle install
$ rake db:migrate
$ rails s

Pueden presentarse problema en el archivo /opt/nginx/conf/nginx.conf con las variables

    server_name  1.2.3.4;
	...
	passenger_enabled on;
	rails_env development; 

Referencias

Instalar passenger
Debian squeeze redmine nginx phusion passenger
Rails en debian

Rails en Apache con Passenger

Teniendo instalado rails3 y apache2 vamos a instalar passenger

$ gem install passenger
$ gem passenger-install-apache2-module

passenger irá guiando la instalación, si necesita dependencias y mostrara las lineas que hay que agregar a los archivos de configuración de apache

Please edit your Apache configuration file, and add these lines:
LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7
PassengerRuby /usr/local/rvm/wrappers/ruby-1.9.2-p180/ruby

terminará con un mensaje similar a este

Suppose you have a Rails application in /somewhere. Add a virtual host to your
Apache configuration file and set its DocumentRoot to /somewhere/public:

   <VirtualHost *:80>
      ServerName www.yourhost.com
      DocumentRoot /somewhere/public    # <-- be sure to point to 'public'!
      <Directory /somewhere/public>
         AllowOverride all              # <-- relax Apache security settings
         Options -MultiViews            # <-- MultiViews must be turned off
      </Directory>
   </VirtualHost>

And that's it! You may also want to check the Users Guide for security and
optimization tips, troubleshooting and other useful information:

moverse al archivo de los mods de apache

$ cd /etc/apache2/mods-available

crear el archivo passenger.conf y agregar las lineas antes mostradas

PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7
PassengerRuby /usr/local/rvm/wrappers/ruby-1.9.2-p180/ruby

y passenger.load

LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7/ext/apache2/mod_passenger.so

subir el modulo y reiniciar apache

$ sudo a2enmod passenger
$ sudo /etc/init.d/apache2 restart

crear el archivo de virtualhost

   <VirtualHost *:80>
      ServerName www.yourhost.com
      DocumentRoot /somewhere/public    # <-- be sure to point to 'public'!
      <Directory /somewhere/public>
         AllowOverride all              # <-- relax Apache security settings
         Options -MultiViews            # <-- MultiViews must be turned off
      </Directory>
   </VirtualHost>

Este es un punto importante, public debe ser el directorio public de la aplicación creada por rails.

Referencias

Rails en Debian Lenny

Pre requisitos

  • curl
  • build-essential
  • zlib1g-dev

Instalar

Instalar rvm como root

$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

Agregarlo a ~/.bash_profile y recargar

$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile
$ source ~/.bash_profile

Instalar ruby

$ rvm install 1.9.2 

Este comando me mostraba el siguiente error

rvm install 1.9.2
-su: /usr/local/rvm/scripts/manage: Permission denied

Por lo que le di permisos de ejecución al archivo

$ chmod u+x /usr/local/rvm/scripts/manage

ruby 1.9.2 por defecto

$ rvm use 1.9.2 --default

Instalar gem

$ rvm rubygems current 

Instalar rails y bundle

$ gem install rails
$ gem install bundle

Rails

Probar rails

$ rails new blog 
$ cd blog
$ bundle install
$ rake db:migrate
$ rails s

debería estar visible en localhost:3000

Problemas frecuentes

sqlite3

Si hay problemas para instalar sqlite-ruby y sus extensiones, hay que actualizar sqlite3 desde el código fuente

$ wget http://www.sqlite.org/sqlite-amalgamation-3.7.2.tar.gz
$ tar xzf sqlite-amalgamation-3.7.2.tar.gz
$ cd sqlite-3.7.2/
$ ./configure
$ make
$ make install
$ gem install rails sqlite3-ruby

rake

si al hacer

$ rake db:migrate 

se presentan problemas con rake 0.9.0 es recomendable modificar el archivo Rakefile

Referencias

Tocando Mongolab desde rails3

Si rails no está instalado

$ gem install rails

Crear una aplicación

$ rails new touchMongoLab --skip-active-record
$ cd touchMongoLab

Editar el archivo Gemfile

# Edit this Gemfile to bundle your application's dependencies.
require 'rubygems'
require 'mongo'
source 'http://gemcutter.org'

gem 'rails', '3.1.0.beta1'
gem "mongo_mapper"

Instalar las gemas necesarias

$ bundle install

Crear el archivo config/initializers/mongo.rb

MongoMapper.connection = Mongo::Connection.new('namexyz.mongolab.com', port )
MongoMapper.database = "dbname"
MongoMapper.database.authenticate('user','passwd')

if defined?(PhusionPassenger)
   PhusionPassenger.on_event(:starting_worker_process) do |forked|
	 MongoMapper.connection.connect_to_master if forked
   end 
end

Crear el modelo en el archivo app/models/user.rb

class User
  include MongoMapper::Document
  key :name
end

Crear un usuario desde la consola

$ rails console
ruby-1.9.2-p180 :006 > user= User.new(:name => "hola mundo")
 => #<User _id: BSON::ObjectId('4dd097464cfad1e8ab000003'), name: "hola mundo"> 
ruby-1.9.2-p180 :006 > user.save()
 => true 

Verificar la existencia del usuario en la db

> db.users.find()
{ "_id" : ObjectId("4dd097604cfad1e8ab000004"), "name" : "hola mundo" }

Referencias

mongoDB && Rails 3 - Getting Started
user.rb