jueves, 28 de julio de 2011

Decoradores en python (I)

Llevo poco tiempo programando en python, y una de las cosas que más me ha sorpendido es el tema de los decoradores. Estan basado en el patron decorador, y existen tambien en otros lenguajes, pero en python esta muy bien integrado. Los decoradores nos sirven para añadir nuevas funcionalidades a codigo ya existente, o reutilizar código de forma más eficiente, y sobre todo tambien, para que quede el codigo más legible. En está pagina podemos ver que lo utiliza para evitar la repetición de código, y para que quede más clara. A continuación voy a poner un ejemplo muy simple de decorador, que simplemente nos dice cuando se ejecuta la parte perteneciente al decorador con un print: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # Nuestro decorador def saluda_antes(funcion): print "Codigo antes de decorar la funcion" def nueva_funcion(*args, **kwargs): print "Ejecuto la funcion decorada" return funcion(*args, **kwargs) print "Codigo despues de decorar la funcion" return nueva_funcion # Nuestra funcion def sumar(a, b): print "Ejecutando suma" return a+b # Main if __name__ == '__main__': sol = sumar(2, 3) print "Solucion {0}\n".format(sol) print "Decoramos la funcion_______________" sumar = saluda_antes(sumar) print "Funcion ya decorada________________\n" sol = sumar(2, 3) print "Solucion {0}".format(sol) Que nos genera la siguiente salida: Ejecutando suma Solucion 5 Decoramos la funcion_______________ Codigo antes de decorar la funcion Codigo despues de decorar la funcion Funcion ya decorada________________ Ejecuto la funcion decorada Ejecutando suma Solucion 5 En el primer bloque vemos la funcion sumar a secas. En el segundo la salida que nos muestra es la que obtenemos mientras se aplica el decorador. Y por ultimo tenemos el resultado de lanzar la funcion con el decorador aplicado. Otra manera de lanzar el decorador es poniendo la @nombre_decorador encima de la función. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # Nuestro decorador def saluda_antes(funcion): print "Codigo antes de decorar la funcion" def nueva_funcion(*args, **kwargs): print "Ejecuto la funcion decorada" return funcion(*args, **kwargs) print "Codigo despues de decorar la funcion" return nueva_funcion # Nuestra funcion @saluda_antes def sumar(a, b): print "Ejecutando suma" return a+b # Main if __name__ == '__main__': sol = sumar(2, 3) print "Solucion {0}".format(sol) Que genera una salida ligeramente diferente: Codigo antes de decorar la funcion Codigo despues de decorar la funcion Ejecuto la funcion decorada Ejecutando suma Solucion 5 Podemos ver que lo primero que se ejecuta es el código que hay al decorar la funcion, seguido por el código del decorador, y por último el de la funcion. Creo que queda claro, pero solo quiero aclarar que el codigo que se ejecuta al decorar la funcion (al principio), sólo se ejecuta una única vez. Si hicieramos 4 llamadas seguidas, tendriamos algo tal que así: Codigo antes de decorar la funcion Codigo despues de decorar la funcion Ejecuto la funcion decorada Ejecutando suma Solucion 5 Ejecuto la funcion decorada Ejecutando suma Solucion 5 Ejecuto la funcion decorada Ejecutando suma Solucion 5 Ejecuto la funcion decorada Ejecutando suma Solucion 5 Y hasta aquí lo que se daba. Volvere con más operadores cuando aprenda un poco más sobre ellos (paso de parametros, autocreacion de decoradores, etc).

viernes, 3 de junio de 2011

Instalación de Redmine sobre Debian Squeeze

La versión de Redmine que vamos a instalar es la 1.2.

Instalamos dependencias:
sudo aptitude install mysql-server
sudo aptitude install apache2
sudo aptitude install ruby
sudo aptitude install rails
sudo aptitude install rake rubygems
sudo aptitude install libmysql-ruby libopenssl-ruby
sudo gem install rails -v=2.1.2
sudo aptitude install g++ make ruby-dev apache2-dev
sudo aptitude install libcurl4-openssl-dev
sudo aptitude install subversion

Configuración MySQL
mysql -u root -p

create database redmine character set utf8;
grant all on redmine.* to ‘redmine’ identified by ‘*****’;

Si queremos que se utilice como motor de búsqueda InnoDB, creamos el fichero innodb.cnf:
sudo vi /etc/mysql/conf.d/innodb.cnf

Con la siguiente información:
[mysqld]
default-storage-engine = InnoDB

Y reiniciamos el servidor:
sudo /etc/init.d/mysql restart

Instalamos passenger
Version instalada: 3.0.9
sudo gem install passenger
cd /var/lib/gems/1.8/gems/passenger-3.0.9/bin/
sudo ./passenger-install-apache2-module
sudo ln -s /var/lib/gems/1.8/gems/passenger-3.0.9/ /usr/lib/passenger

Configuración de Apache para Passenger
En la ruta /etc/apache2/mods-available/ creamos los ficheros passenger.load y passenger.conf, con la siguiente informacion:

PASSENGER.LOAD
sudo vi /etc/apache2/mods-available/passenger.load

LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-3.0.7/ext/apache2/mod_passenger.so

PASSENGER.CONF
sudo vi /etc/apache2/mods-available/passenger.conf
PassengerRoot /usr/lib/passenger
PassengerRuby /usr/bin/ruby1.8
PassengerDefaultUser www-data

Y ahora los habilitamos:
cd /etc/apache2/mods-enabled/
sudo ln -s ../mods-available/passenger.load
sudo ln -s ../mods-available/passenger.conf

Y reiniciamos apache:
sudo /etc/init.d/apache2 reload

Instalamos RedMine
Descargamos RedMine (Version instalada 1.2)
cd /usr/local/lib
sudo svn co http://redmine.rubyforge.org/svn/branches/1.2-stable redmine-1.2

Instalamos dependencias
sudo gem install -v=0.4.2 i18n
sudo gem install -v=2.3.11 rails
sudo gem install rake -v'0.8.7'
sudo gem uninstall rake -v'0.9.0'

Configuramos fichero enviroment:
sudo nano redmine-1.2/config/environment.rb

y añadimos la siguiente línea:
config.action_controller.session = { :key => "_myapp_session", :secret => "tengoqueponeraqui30caracteresynosequecojonesponer" }

Instalamos la base de datos de RedMine:
cd /usr/local/lib/redmine-1.2/
sudo cp config/database.yml.example config/database.yml
sudo rake db:migrate RAILS_ENV="production"

Terminamos de configurar el RedMine:
cd /usr/local/lib/redmine-1.2/
sudo mkdir tmp public/public_assets
sudo chown -R www-data:www-data files log tmp public/public_assets
sudo chmod -R 755 files log tmp public/public_assets

Configuracion de Apache para soportar Redmine
cd /etc/apache2/sites-enabled
sudo rm 000-default

Creamos el fichero /etc/apache2/sites-available/redmine
sudo nano /etc/apache2/sites-available/redmine

Con la siguiente información:
<VirtualHost *:80>
  DocumentRoot /usr/local/lib/redmine-1.2/public
  <Directory /usr/local/lib/redmine-1.2/public>
     AllowOverride None
  </Directory>
</VirtualHost>

Y lo habilitamos:
cd /etc/apache2/sites-enabled
sudo ln -s ../sites-available/redmine 000-default

Y por ultimo reiniciamos apache:
sudo /etc/init.d/apache2 reload

Con esto ya debería estar funcionando.
Por lo menos así fue en mi caso, problem?

viernes, 25 de marzo de 2011

Mantener programas activos al cerrar el terminal

Muchas veces hemos abierto programas desde una terminal y queremos dejarlos activos al cerrar.
O bien si queremos dejar abierto algo en una maquina remota, también podemos hacerlo.

Para ello segun se esta ejecutando el programa presionamos Ctrl + z y después escribimos:
bg
disown


Ahora ya podemos cerrar el terminal sin problemas.

Borrar una palabra en un terminal

Es un poco chorra crear una entrada para esto, pero bueno, a mi me vale.

Podemos cortar una palabra entera cuando estemos con el terminal si hacemos Ctrl + w, o presionamos Esc y luego (no a la vez) backspace (la de borrar).

Se comporta de igual manera a cuando hacemos Ctrl + backspace en un editor de textos.

Relacionadas:
Terminal: buscar un comando ejecutado antes
Corta y pega en bash

lunes, 21 de marzo de 2011

Ejemplo /etc/network/interfaces

Para configurar dinámicamente la ip:
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp


Para configurar estáticamente la ip:
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.1.128
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1


La verdad es que las opciones de network y broadcast nunca las había configurado antes, pero en este caso (en Debian 6), no se porque pero me iba demasiado lenta la configuración si no ponía estos parámetros (quizás tenga otra cosa mal :?).

Pidgin - Esperando la conexión a la red

Esto me ocurrió en Debian 6 "escuiss".
Este es un problema que me daba el Pidgin, me aparecía el mensaje "Esperando la conexión a la red".

Todo porque el network manager me dejo de funcionar al configurar estáticamente la dirección IP.

Así que lo solucioné desinstalando el network manager (pa lo que sirve):
sudo aptitude remove network-manager network-manager-gnome

No lo he probado pero recomiendan por ahí wicd para la gestión de la red (sobretodo en portátiles, para el wifi).

Saludos varios (pa cuando me autolea :()

viernes, 11 de marzo de 2011

Script para convertir ficheros en linux (ffmpeg)

Este es un pequeño script para convertir ficheros con ffmpeg.

No tiene casi opciones, y las opciones de video puestas son que mantenga la misma calidad de entrada que de salida. Y en el audio esta puesto para que codifique a mp3 sin mas.
Lo único que se puede elegir es el tipo de fichero de salida (con -f) y el número de threads (con -t) con el que lo vamos a convertir.

Yo lo utilizo para pasar los vídeos flv a avi, sin tener que andar tocando mucho, y después me los puedo pasar al móvil.

El tamaño de salida no lo he tocado porque mi móvil se come todos los vídeos, pero podéis modificarlo y dejadlo al gusto.

Aquí esta, creáis un fichero con éste contenido, le dais permisos de ejecucion (chmod +x archivo) y ya lo tenéis.
Ej: Yo lo he llamado conv, así que quedaría: conv -t 4 jl.flv

#!/bin/bash
# Default values
THREADS="1"
VFORMAT="avi"

# Parse options
while (($#))
do
case $1 in
-t)
shift
THREADS=$1
echo "Number of threads $THREADS"
;;
-f)
shift
VFORMAT=$1
echo "Video Format = $VFORMAT"
;;
-h)
echo "Usage: $0 [-t threads] [-f format] [-h help] file"
echo " by default threads=2, format=avi"
exit
;;
*)
FICHERO_IN=$1
FICHERO_IN_TRUNK=${FICHERO_IN%.*}
echo "Fichero entrada: $FICHERO_IN"

FICHERO_OUT="$FICHERO_IN_TRUNK.${VFORMAT}"
echo "Fichero salida: $FICHERO_OUT"
;;
esac
shift
done

ffmpeg -threads $THREADS -sameq -i $FICHERO_IN -acodec libmp3lame $FICHERO_OUT