Archivos de la categoría Manual

Introducción a TensorFlow

La web oficial de TensorFlow tiene muy buenos recursos. En esencia lo que hay en este post proviene del “get started” de la web oficial.

En el primer ejemplo importaremos TensorFlow. Crearemos dos constantes y las imprimiremos en pantalla.

import tensorflow as tf
node1 = tf.constant(3.0, tf.float32)
node2 = tf.constant(4.0) # También tf.float32 de forma implícita
sess = tf.Session()
print(sess.run([node1, node2]))
node3 = tf.add(node1, node2)
print("node3: ", node3) #Esta linea muestra las propiedades del tensor
print("sess.run(node3): ",sess.run(node3)) # Aquí se imprime el resultado

También podemos aplicar operaciones a los tensors. Las operaciones producen más tensores. En el siguiente ejemplo sumamos dos variables (tensores) y luego las sumamos. Un tensor es capaz de procesar listas también como veremos.

a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b
print(sess.run(adder_node, {a: 3, b:4.5})) # 7.5
print(sess.run(adder_node, {a: [1,3], b: [2, 4]})) # Itera sobre la lista: 3 y 7

Podemos multiplicar

add_and_triple = adder_node * 3.
print(sess.run(add_and_triple, {a: 3, b:4.5}))

E incluso podemos crear modelos lineales

W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)
x = tf.placeholder(tf.float32)
linear_model = W * x + b

Las constantes son inicializadas con tf.constant, y su valor no puede ser cambiado. Contrariamente las variables son creadas usando tf.Variable y no son inicializadas en el inicio. Para inicializar las variables  tenemos que usar una función especial como en el siguiente ejemplo:

init = tf.global_variables_initializer()
sess.run(init)

Lo importante es usar init. Es un “handle” que inicia el grafo, inicializando las variables que hasta entonces habían permanecido sin inicializar.

Ya que la X es la variable podemos evaluar el modelo usando distintos valores simultáneamente de la siguiente manera:

print(sess.run(linear_model, {x:[1,2,3,4]}))
# Output: [ 0, 0.30000001, 0.60000002, 0.90000004]

La función de pérdida (loss function) puede medir la distancia entre el modelo actual y los datos proporcionados. Usaremos la función de pérdida estándar para hacer una regresión lineal que sume los cuadrados de las distancias entre el modelo actual y los datos. El modelo crea un vector en el que cada posición corresponde a una distancia de error. Cuando usamos tf.square estamos elevando al cuadrado el error. Luego sumamos los errores para crear un simple escalar que abstrae el error de todos los puntos usando tf.reduce_sum:

y = tf.placeholder(tf.float32)
squared_deltas = tf.square(linear_model - y)
loss = tf.reduce_sum(squared_deltas)
print(sess.run(loss, {x:[1,2,3,4], y:[0,-1,-2,-3]}))

El valor producido es:  23.66

Podríamos mejorar el modelo manualmente asignando nuevos valores a W para obtener resultados perfectos de -1 y 1. Una variables es inicializada por el valor proporcionado por tf.Variable pero puede ser cambiada si usamos operaciones como tf.assign. Por ejemplo, W=-1 y b=1 son los parámetros óptimos de nuestro modelo. Podemos cambiar W y b acordemente:

fixW = tf.assign(W, [-1.])
fixb = tf.assign(b, [1.])
sess.run([fixW, fixb])
print(sess.run(loss, {x:[1,2,3,4], y:[0,-1,-2,-3]})
#resultado: 0

Hemos adivinado el valor perfecto para W i b aunque este no es el objetivo de  machine learning. El objetivo es encontrar los parámetros correctos para el modelo automáticamente. Pero esto lo vais a encontrar en la próxima entrega 😉

Bonus: En matemáticas y en física, un tensor es cierta clase de entidad algebraica de varias componentes, que generaliza los conceptos de escalar, vector y matriz de una manera que sea independiente de cualquier sistema de coordenadas elegido. ( wikipedia )

Texmaker al estilo de Sublime text (monokai)

Sublime text, aunque es un editor de texto que me gusta mucho, he estado buscando alternativas. He encontrado textmaker. Texmaker es  un editor de latex que nos permite compilar el documento pdf además de añadir otras interesantes features. Lo que no me gustaba era el tema (theme) que tenía por defecto. Así que buscando di con la solución. Usar el theme de Sublime text, llamado monokai.

Para cambiarlo simplemente tenemos que ir a $HOME/.config/xm1 (tanto en linux, como en MacOS y editar el fichero texmaker.ini y reemplazar las siguientes lineas de la principio del fichero:

Color\Background=@Variant(\0\0\0\x43\x1\xff\xff\0\0++66\0\0)
Color\Command=@Variant(\0\0\0\x43\x1\xff\xff&&\x8b\x8b\xd2\xd2\0\0)
Color\Comment=@Variant(\0\0\0\x43\x1\xff\xffllqq\xc4\xc4\0\0)
Color\Highlight=@Variant(\0\0\0\x43\x1\xff\xff\a\a66BB\0\0)
Color\Keyword=@Variant(\0\0\0\x43\x1\xff\xff\xdc\xdc\x32\x32//\0\0)
Color\KeywordGraphic=@Variant(\0\0\0\x43\x1\xff\xff\x85\x85\x99\x99\0\0\0\0)
Color\Line=@Variant(\0\0\0\x43\x1\xff\xff\a\a66BB\0\0)
Color\Math=@Variant(\0\0\0\x43\x1\xff\xff**\xa1\xa1\x98\x98\0\0)
Color\NumberGraphic=@Variant(\0\0\0\x43\x1\xff\xff\xcb\xcbKK\x16\x16\0\0)
Color\Standard=@Variant(\0\0\0\x43\x1\xff\xff\x83\x83\x94\x94\x96\x96\0\0)
Color\Todo=@Variant(\0\0\0\x43\x1\xff\xff\xd3\xd3\x36\x36\x82\x82\0\0)
Color\Verbatim=@Variant(\0\0\0\x43\x1\xff\xff\xb5\xb5\x89\x89\0\0\0\0)

Generar una barra de progreso en ipython notebooks

Manual con código para generar una barra de progreso en nuestro código para saber en que porcentaje de compleción estamos sin llenar el output con números. Muchos de los que usáis jupyter (el nuevo ipython notebooks) podéis imprimir por pantalla la iteración en la que vuestro loop reside. Eso es solo posible para una cantidad pequeña de iteraciones. Cuando llegamos a varios miles se puede generar un output bastante engorroso. Googleando un poco encontré la solución. Este código nos genera una clase que luego podemos llamar para obtener la barra de progreso junto con el porcentaje completado.

import sys, time
try:
    from IPython.core.display import clear_output
    have_ipython = True
except ImportError:
    have_ipython = False

class ProgressBar:
    def __init__(self, iterations):
        self.iterations = iterations
        self.prog_bar = '[]'
        self.fill_char = '*'
        self.width = 40
        self.__update_amount(int(0))
        if have_ipython:
            self.animate = self.animate_ipython
        else:
            self.animate = self.animate_noipython

    def animate_ipython(self, iter):
        try:
            clear_output()
        except Exception:
            # terminal IPython has no clear_output
            pass
        print '\r', self,
        sys.stdout.flush(),
        self.update_iteration(iter + 1)
        
    def update_iteration(self, elapsed_iter):
        self.__update_amount((elapsed_iter / float(self.iterations)) * 100.0)
        self.prog_bar += '  %d of %s complete' % (elapsed_iter, self.iterations)

    def __update_amount(self, new_amount):
        percent_done = int(round((new_amount / 100.0) * 100.0))
        all_full = int(self.width - 2)
        num_hashes = int(round((percent_done / 100.0) * all_full))
        self.prog_bar = '[' + self.fill_char * num_hashes + ' ' * (all_full - num_hashes) + ']'
        pct_place = int((len(self.prog_bar) / 2) - len(str(percent_done)))
        pct_string = '%d%%' % percent_done
        self.prog_bar = self.prog_bar[0:pct_place] + \
            (pct_string + self.prog_bar[pct_place + len(pct_string):])

    def __str__(self):
        return str(self.prog_bar)
        

Y el siguiente código vemos un ejemplo de como llamaremos la clase para obtener la funcionalidad deseada

c = ProgressBar(1000)
for i in range(1000):
    c.animate_ipython(i)

Para los interesados encontré el código aquí.

Instalar ubuntu desde un USB

Instalar Ubuntu (o la mayoría de distribuciones más o menos conocidas) puede hacerse utilizando un USB sin necesidad de quemar (burn) un CD. Es mucho más simple de lo que parece si se siguen los puntos de la lista:

  1. El primer paso es descargar Ubuntu.
  2. Comprobar el md5um
    • Usar el siguiente el comando en la terminal: md5sum ubuntu-11.10-dvd-i386.iso
    • Comprobar el hash que te da como resultado con los hashes oficiales de canonical.
  3. Para finalizar preparar Ubuntu en un USB vacío. Para esto usaremos UNetbootin y seguiremos las “instrucciones”.

Más fácil imposible. Para más info la página oficial.

 

Manual para instalar OpenVPN en Ubuntu con script

Hace ya algun tiempo me hice con un servidor y lo voy usando para hacer mis cosicas. Como por ejemplo instalar rTorrent para poder bajarme ficheros el cual estuvo acompañado de otro post para mover ficheros entre el servidor y mi ordenador. Esta vez lo que quiero hacer es usar el server como túnel para evitar contenidos restringidos en el país dónde estoy y mejorar la seguridad en redes abiertas.
Primero de todo tendremos que instalar el software necesario. Para ello ejecutando la siguiente linea en la consola bastará:

wget http://git.io/vpn --no-check-certificate -O openvpn-install.sh; chmod +x openvpn-install.sh; ./openvpn-install.sh

Para los que os gusta hacerlo paso a pasa y configurarlo todo al milímetro al final del post hay un link (en inglés) que os ayudará. Para el resto de mortales el siguiente script lo hace todo, es simplemente un autoinstaller que puede generar claves, revocar certificados y desinstalar OpenVPN.

#!/bin/bash
# OpenVPN road warrior installer for Debian-based distros

# This script will only work on Debian-based systems. It isn't bulletproof but
# it will probably work if you simply want to setup a VPN on your Debian/Ubuntu
# VPS. It has been designed to be as unobtrusive and universal as possible.

if [ $USER != 'root' ]; then
echo "Sorry, you need to run this as root"
exit
fi

if [ ! -e /dev/net/tun ]; then
echo "TUN/TAP is not available"
exit
fi

if [ ! -e /etc/debian_version ]; then
echo "Looks like you aren't running this installer on a Debian-based system"
exit
fi

# Try to get our IP from the system and fallback to the Internet.
# I do this to make the script compatible with NATed servers (lowendspirit.com)
# and to avoid getting an IPv6.
IP=$(ifconfig | grep 'inet addr:' | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d: -f2 | awk '{ print $1}' | head -1)
if [ "$IP" = "" ]; then
IP=$(wget -qO- ipv4.icanhazip.com)
fi

if [ -e /etc/openvpn/server.conf ]; then
while :
do
clear
echo "Looks like OpenVPN is already installed"
echo "What do you want to do?"
echo ""
echo "1) Add a cert for a new user"
echo "2) Revoke existing user cert"
echo "3) Remove OpenVPN"
echo "4) Exit"
echo ""
read -p "Select an option [1-4]: " option
case $option in
1)
echo ""
echo "Tell me a name for the client cert"
echo "Please, use one word only, no special characters"
read -p "Client name: " -e -i client CLIENT
cd /etc/openvpn/easy-rsa/2.0/
source ./vars
# build-key for the client
export KEY_CN="$CLIENT"
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" $CLIENT
# Let's generate the client config
mkdir ~/ovpn-$CLIENT
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/ovpn-$CLIENT/$CLIENT.conf
cp /etc/openvpn/easy-rsa/2.0/keys/ca.crt ~/ovpn-$CLIENT
cp /etc/openvpn/easy-rsa/2.0/keys/$CLIENT.crt ~/ovpn-$CLIENT
cp /etc/openvpn/easy-rsa/2.0/keys/$CLIENT.key ~/ovpn-$CLIENT
cd ~/ovpn-$CLIENT
sed -i "s|cert client.crt|cert $CLIENT.crt|" $CLIENT.conf
sed -i "s|key client.key|key $CLIENT.key|" $CLIENT.conf
tar -czf ../ovpn-$CLIENT.tar.gz $CLIENT.conf ca.crt $CLIENT.crt $CLIENT.key
cd ~/
rm -rf ovpn-$CLIENT
echo ""
echo "Client $CLIENT added, certs available at ~/ovpn-$CLIENT.tar.gz"
exit
;;
2)
echo ""
echo "Tell me the existing client name"
read -p "Client name: " -e -i client CLIENT
cd /etc/openvpn/easy-rsa/2.0/
. /etc/openvpn/easy-rsa/2.0/vars
. /etc/openvpn/easy-rsa/2.0/revoke-full $CLIENT
# If it's the first time revoking a cert, we need to add the crl-verify line
if grep -q "crl-verify" "/etc/openvpn/server.conf"; then
echo ""
echo "Certificate for client $CLIENT revoked"
else
echo "crl-verify /etc/openvpn/easy-rsa/2.0/keys/crl.pem" >> "/etc/openvpn/server.conf"
/etc/init.d/openvpn restart
echo ""
echo "Certificate for client $CLIENT revoked"
fi
exit
;;
3)
apt-get remove --purge -y openvpn openvpn-blacklist
rm -rf /etc/openvpn
rm -rf /usr/share/doc/openvpn
sed -i '/--dport 53 -j REDIRECT --to-port/d' /etc/rc.local
sed -i '/iptables -t nat -A POSTROUTING -s 10.8.0.0/d' /etc/rc.local
echo ""
echo "OpenVPN removed!"
exit
;;
4) exit;;
esac
done
else
echo 'Welcome to this quick OpenVPN "road warrior" installer'
echo ""
# OpenVPN setup and first user creation
echo "I need to ask you a few questions before starting the setup"
echo "You can leave the default options and just press enter if you are ok with them"
echo ""
echo "First I need to know the IPv4 address of the network interface you want OpenVPN"
echo "listening to."
read -p "IP address: " -e -i $IP IP
echo ""
echo "What port do you want for OpenVPN?"
read -p "Port: " -e -i 1194 PORT
echo ""
echo "Do you want OpenVPN to be available at port 53 too?"
echo "This can be useful to connect under restrictive networks"
read -p "Listen at port 53 [y/n]: " -e -i n ALTPORT
echo ""
echo "Finally, tell me your name for the client cert"
echo "Please, use one word only, no special characters"
read -p "Client name: " -e -i client CLIENT
echo ""
echo "Okay, that was all I needed. We are ready to setup your OpenVPN server now"
read -n1 -r -p "Press any key to continue..."
apt-get update
apt-get install openvpn iptables openssl -y
cp -R /usr/share/doc/openvpn/examples/easy-rsa/ /etc/openvpn
# easy-rsa isn't available by default for Debian Jessie and newer
if [ ! -d /etc/openvpn/easy-rsa/2.0/ ]; then
wget --no-check-certificate -O ~/easy-rsa.tar.gz https://github.com/OpenVPN/easy-rsa/archive/2.2.2.tar.gz
tar xzf ~/easy-rsa.tar.gz -C ~/
mkdir -p /etc/openvpn/easy-rsa/2.0/
cp ~/easy-rsa-2.2.2/easy-rsa/2.0/* /etc/openvpn/easy-rsa/2.0/
rm -rf ~/easy-rsa-2.2.2
rm -rf ~/easy-rsa.tar.gz
fi
cd /etc/openvpn/easy-rsa/2.0/
# Let's fix one thing first...
cp -u -p openssl-1.0.0.cnf openssl.cnf
# Fuck you NSA - 1024 bits was the default for Debian Wheezy and older
sed -i 's|export KEY_SIZE=1024|export KEY_SIZE=2048|' /etc/openvpn/easy-rsa/2.0/vars
# Create the PKI
. /etc/openvpn/easy-rsa/2.0/vars
. /etc/openvpn/easy-rsa/2.0/clean-all
# The following lines are from build-ca. I don't use that script directly
# because it's interactive and we don't want that. Yes, this could break
# the installation script if build-ca changes in the future.
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --initca $*
# Same as the last time, we are going to run build-key-server
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --server server
# Now the client keys. We need to set KEY_CN or the stupid pkitool will cry
export KEY_CN="$CLIENT"
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" $CLIENT
# DH params
. /etc/openvpn/easy-rsa/2.0/build-dh
# Let's configure the server
cd /usr/share/doc/openvpn/examples/sample-config-files
gunzip -d server.conf.gz
cp server.conf /etc/openvpn/
cd /etc/openvpn/easy-rsa/2.0/keys
cp ca.crt ca.key dh2048.pem server.crt server.key /etc/openvpn
cd /etc/openvpn/
# Set the server configuration
sed -i 's|dh dh1024.pem|dh dh2048.pem|' server.conf
sed -i 's|;push "redirect-gateway def1 bypass-dhcp"|push "redirect-gateway def1 bypass-dhcp"|' server.conf
sed -i "s|port 1194|port $PORT|" server.conf
# Obtain the resolvers from resolv.conf and use them for OpenVPN
cat /etc/resolv.conf | grep -v '#' | grep 'nameserver' | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read line; do
sed -i "/;push \"dhcp-option DNS 208.67.220.220\"/a\push \"dhcp-option DNS $line\"" server.conf
done
# Listen at port 53 too if user wants that
if [ $ALTPORT = 'y' ]; then
iptables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-port $PORT
sed -i "/# By default this script does nothing./a\iptables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-port $PORT" /etc/rc.local
fi
# Enable net.ipv4.ip_forward for the system
sed -i 's|#net.ipv4.ip_forward=1|net.ipv4.ip_forward=1|' /etc/sysctl.conf
# Avoid an unneeded reboot
echo 1 > /proc/sys/net/ipv4/ip_forward
# Set iptables
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to $IP
sed -i "/# By default this script does nothing./a\iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to $IP" /etc/rc.local
# And finally, restart OpenVPN
/etc/init.d/openvpn restart
# Let's generate the client config
mkdir ~/ovpn-$CLIENT
# Try to detect a NATed connection and ask about it to potential LowEndSpirit
# users
EXTERNALIP=$(wget -qO- ipv4.icanhazip.com)
if [ "$IP" != "$EXTERNALIP" ]; then
echo ""
echo "Looks like your server is behind a NAT!"
echo ""
echo "If your server is NATed (LowEndSpirit), I need to know the external IP"
echo "If that's not the case, just ignore this and leave the next field blank"
read -p "External IP: " -e USEREXTERNALIP
if [ $USEREXTERNALIP != "" ]; then
IP=$USEREXTERNALIP
fi
fi
# IP/port set on the default client.conf so we can add further users
# without asking for them
sed -i "s|remote my-server-1 1194|remote $IP $PORT|" /usr/share/doc/openvpn/examples/sample-config-files/client.conf
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/ovpn-$CLIENT/$CLIENT.conf
cp /etc/openvpn/easy-rsa/2.0/keys/ca.crt ~/ovpn-$CLIENT
cp /etc/openvpn/easy-rsa/2.0/keys/$CLIENT.crt ~/ovpn-$CLIENT
cp /etc/openvpn/easy-rsa/2.0/keys/$CLIENT.key ~/ovpn-$CLIENT
cd ~/ovpn-$CLIENT
sed -i "s|cert client.crt|cert $CLIENT.crt|" $CLIENT.conf
sed -i "s|key client.key|key $CLIENT.key|" $CLIENT.conf
tar -czf ../ovpn-$CLIENT.tar.gz $CLIENT.conf ca.crt $CLIENT.crt $CLIENT.key
cd ~/
rm -rf ovpn-$CLIENT
echo ""
echo "Finished!"
echo ""
echo "Your client config is available at ~/ovpn-$CLIENT.tar.gz"
echo "If you want to add more clients, you simply need to run this script another time!"
fi

“Happy tunneling

Bonus: Para los que os guste un poco más el heavy metal aquí un tutorial paso a paso con explicaciones más detalladas.

Como mover ficheros del servidor a mi ordenador y viceversa usando la consola

Como ya comenté en mi anterior post conseguí un server y uno de los problemas que tuve fue mover ficheros de un lado para otro (del servidor a mi ordenador loca y al revés). Buscaba algo que pudiera usarse a través de la consola sin tener que usar otros programas (i.e. FTP, esciptorios remotos, etc.). Finalmente encontré una solución curiosa pero muy buena. Se trata de usar sshfs.

Si no lo tienes instalado (probablemente no)

sudo apt-get install sshfs

Ahora crea un directorio en tu maquina local dónde quieras enlazar el el directorio del servidor. Para enlazar los dos directorios usa el siguiente comando:

sshfs user@server.com:/remote/dir /home/user/test

Con el enlace montado puedes usar tu GUI local o lo que quieras para mover los archivos que desees. Una vez hayas terminado usa el siguiente comando para terminar el enlace.

fusermount -u /home/youruser/remotecomp

(si no te acuerdas del directorio que usaste, pulsando tab puedes ver los que tienes abiertos)

Bonus: Idea original junto con otras ideas para conseguir tal meta.

Como usar rtorrent des de cero

Viviendo en Alemania no puedo usar bitorrent sin que me llegue una factura por más de 500€ por bajar contenido que tiene copyright. Por lo que finalmente conseguí un servidor dónde tal cosa puede hacerse. El problema es que no tengo GUI por lo que tuve que buscar un cliente bittorrent para bajarme las cosas. Sin GUI, rtorrent era la primera opción que encontré. Al principio parece un poco complicado pero sabiendo los cuatro comandos básicos no ocasiona problemas.

Para iniciar el cliente de torrent:

$ rtorrent

Para poner un archivo en la cola de descargas tienes que presionar intro, pegar el enlace de magnet y darle a intro otra vez.
Una vez has hecho esto tienes el archivo en espera por lo que para iniciarlo usas las flechas arriba y abajo para localizar el archivo y con Control+S empiezas la descarga.
Si por algún motivo te dice que has movido el archivo (a mi me lo dice sin motivo) lo puedes solucionar con Control+E. Puedes cerrar el programa con Control+Q.
El fichero de configuración tiene que colocarse en ~/.rtorrent.rc y yo tengo el siguiente (por si lo quieres usar de base o del que me copié).

# This is an example resource file for rTorrent. Copy to
 # ~/.rtorrent.rc and enable/modify the options as needed. Remember to
 # uncomment the options you wish to enable.
 # Maximum and minimum number of peers to connect to per torrent.
 min_peers = 1
 max_peers = 20
 # Same as above but for seeding completed torrents (-1 = same as downloading)
 min_peers_seed = 1
 max_peers_seed = 20
 # Maximum number of uploads single torrent may use
 max_uploads = 10
 # Maximum number of simultaneous downloads
 max_downloads_global = 10
 # Maximum number of simultaneous uploads
 max_uploads_global = 20
 # Global upload and download rate in KiB. "0" for unlimited.
 download_rate = 0
 upload_rate = 300
 # Default directory to save the downloaded torrents.
 directory = /home/rocreguant/rTorrStuff/Downloads
 # Default session directory. Make sure you don't run multiple instance
 # of rtorrent using the same session directory. Perhaps using a
 # relative path?
 session = /home/rocreguant/rTorrStuff/session
 # Watch a directory for new torrents, and stop those that have been
 # deleted.
 schedule = watch_directory,5,5,load_start=./rtactive/*.torrent
 schedule = tied_directory,6,5,start_tied=
 schedule = untied_directory,7,5,stop_untied=
 # Close torrents when diskspace is low.
 schedule = low_diskspace,5,60,close_low_diskspace=2000M
 # Periodically save session data
 schedule = session_save,240,300,session_save=
 # Enable the default ratio group.
 ratio.enable=
 # Change the limits, the defaults should be sufficient.
 # Upload to a minimum ratio of 4.0
 ratio.min.set=400
 # Upload to a maximum ratio of 20.0
 ratio.max.set=2000
 # Upload a minimum of 250 MB
 ratio.upload.set=250M
 # When seeding ratio is reached close the torrent
 system.method.set = group.seeding.ratio.command, d.close=
 # Move files to ./unsorted when download completes
 system.method.set_key = event.download.finished,move_complete,"execute=mv,-n,$d.get_base_path=,./unsorted/;d.set_directory=./unsorted/"
 # Port range to use for listening.
 port_range = 60125-64125
 # Start opening ports at a random position within the port range.
 port_random = yes
 # Encryption options, set to none (default) or any combination of the following:
 # allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
 #
 # The example value allows incoming encrypted connections, starts unencrypted
 # outgoing connections but retries with encryption if they fail, preferring
 # plaintext to RC4 encryption after the encrypted handshake
 #
 encryption = allow_incoming,try_outgoing,enable_retry,prefer_plaintext
 # Sort the main view by ratio
 view.sort_current = main,greater=d.get_ratio=
 view.sort_new = main,less=d.get_ratio=
 view.sort = main
 # Sort the seeding view by the upload rate and only show torrents with peers
 view.sort_current = seeding,greater=d.get_up_rate=
 view.filter = seeding,"and=d.get_complete=,d.get_peers_connected="
 view.sort_new = seeding,less=d.get_up_rate=
 view.sort = seeding
 # Sort the leeching view by name
 view.sort_current = leeching,greater=d.get_name=
 view.sort_new = leeching,greater=d.get_name=
 view.sort = leeching
 # Filter the active view by connected peers
 view.sort_current = active,less=d.get_name=
 view.sort_new = leeching,less=d.get_name=
 view.filter = active,d.get_peers_connected=
 view.sort = active
 schedule = sort_main,11,5,view.sort=main
 schedule = sort_seeding,12,5,view.sort=seeding
 schedule = sort_leeching,13,5,view.sort=leeching
 schedule = sort_active,14,5,view.sort=active
 # Enable DHT support for trackerless torrents or when all trackers are down.
 # May be set to "disable" (completely disable DHT), "off" (do not start DHT),
 # "auto" (start and stop DHT as needed), or "on" (start DHT immediately).
 # The default is "off". For DHT to work, a session directory must be defined.
 #
 #dht = auto
 # UDP port to use for DHT.
 #
 dht_port = 63425 
 # Enable peer exchange (for torrents not marked private)
 #
 #peer_exchange = yes

Como ejecutar una tarea periódicamente en Ubuntu (Linux)

Esta programación periódica de tareas no sirve solamente para el uso en el ordenador personal, si no que también nos puede ser útil en el servidor. Estas tareas consisten en trabajos que el ordenador tiene que realizar cada determinado periodo de tiempo sin interferir con la UI.

Para conseguir tal objetivo todas las distribuciones Linux (incluyendo Ubuntu), y otros sistemas operativos basados en Unix, nos brindan la posibilidad de usar “Crontab”. El nombre proviene del antiguo dios griego Chronos encargado del tiempo.

Para ver las tareas que tenemos ejecutándose de forma periódica en nuestro sistema podremos usar el comando:

crontab -l

Si queremos modificar el fichero y añadir nuevos cronjobs deberemos usar el comando:

crontab -e

Este comando nos abrirá nuestro editor por defecto (en mi caso vi). Una vez dentro deberemos escribir una linea parecida a:

* * * * * /ruta/al/script.sh

 y si guardamos tal script será ejecutado regularmente en el margen de tiempo indicado. Cada asterisco representa una unidad de tiempo distinta. Ordenada en:

  • minutos ( de 00 a 59)
  • horas (de 0 a 23)
  • día del mes (de 1 a 31)
  • mes (de 1 a 12)
  • día de la semana( de 0 a 6) { Se empieza en domingo = 0 }

Los asteriscos tienen el significado de “todos”. Por lo que en este ejemplo significa que el script se ejecutará todos los minutos de todas las horas, de todos los días, de todos los meses, de todos los días de las semanas.

Para ejecutarlo el viernes a la 1 de la mañana:

0 1 * * 5 /ruta/al/script.sh

Si sólo queremos que se ejecute de lunes a viernes (el guión “-” nos permite indicar intervalos de tiempo):

0 1 * * 1-5 /ruta/al/script.sh

Para ejecutarlo cada diez minutos (las comas concatenan tiempos):

0,10,20,30,40,50 * * * * /ruta/al/script.sh

 pero también:

 */10 * * * * /ruta/al/script.sh

Dónde podemos apreciar porciones, evitándonos el uso de comas.

Los asteriscos, o indicaciones de tiempo, se pueden substituir por palabras protegidas.

@reboot Se ejecuta una vez al arranque
@yearly Se ejecuta una vez al año “0 0 1 1 *”
@annually (lo mismo que @yearly)
@monthly Se ejecuta una vez al mes “0 0 1 * *”
@weekly Se ejecuta una vez a la semana “0 0 * * 0″
@daily Se ejecuta una vez al dia “0 0 * * *”
@midnight (lo mismo que @daily)
@hourly Se ejecuta una vez cada hora “0 * * * *”

 

*/10 * * * * /ruta/al/script.sh >> /var/log/script_output.log 2>&1

 Empezando por el final, “2>&1” significa que tipo de información deseamos guardar. El “1” hace referencia al “standard output” y el “2” referencia a los “standard errors”. En el medio vemos “>>” que con solo una flecha significa que el fichero se sobre escribiría pero como lo que queremos es ir guardándolo todo, deberemos poner las dos flechas para que vaya añadiendo las nuevas lineas al final del documento. Tened en cuenta que si el cronjob lo ejecutas a menudo este fichero puede crecer con bastante velocidad causando problemas. Por lo que si queréis desechar lo que salga del script podéis usar

*/10 * * * * /bin/execute/this/script.sh > /dev/null 2>&1

Dónde “/dev/null” es un agujero negro que descarta toda la información que le llega.

Finalmente si queréis hacer limpieza podéis usar el siguiente comando:

crontab -r

Espero que os haya gustado y os haya servido! :)

Moving averages crossovers

Pues si, me ha dado un poquito por el trading. Pero esto des de hace ya algo de tiempo. Leyendo me gustó este “método” (si se le puede llamar así). Sirve para identificar cada vez que hay un cambio de tendencias. La identificación de estas tendencias es usada por los traders para entrar o salir con sus inversiones (aunque supongo que por los traders simplistas).

main-qimg-97e49d176bd84437847ee2bbf5909646

Como se puede ver en el gráfico se indican los puntos de entrada (compra) y salida (venta) teóricos, cuando las lineas se cruzan. Se pueden dar más propiedades a estas “lineas”. Por ejemplo de puede usar el Exponential Moving Average (EMA) que consiste en darle más peso a los datos recientes que a los pasados. Cuanto más atrás en el pasado estén menos afectarán a las proyecciones del momento. La EMA puede adecuarse a un día y a un año. Cuando la de a largo plazo (inferior) se cruce con la de corto plazo (superior) tocaría comprar. Y al revés, cuando se vuelvan a cruzar tocaría vender.

Siempre para desarrollar teorías de trading tienes que marcarte un límite en el que estás dispuesto a perder. Si mantienes acciones por el mero hecho de que ya has perdido bastante tiene toda la pinta que vas a seguir perdiendo mucho más. Por lo que he visto la mayoría de traders recomiendan algún valor entre 3% y 7 % según el apetito de riesgo que quieras correr.

Cabe tener en cuenta que para repentinas bajadas de precios o cambios continuos puede ocasionar “problemas”.

Vocabulario (en):

Idea (y gráfico):

Disclaimer: No se nada del otro mundo y aun no vivo en las Bahamas.

PD: Recordad que pase lo que pase, aproximadamente se acierta la mitad de las veces (sube/baja).

Instalar MongoDB en Ubuntu

Uno de los propósitos de año nuevo, como ya visteis, ya me he puesto manos a la obra en aprender MongoDB. Para esto necesito tenerlo instalado en el ordenador (con SO Ubuntu) para poder trastear. Así que al turrón!

Primero de todo MongoDB nos recomienda importar la “public key” usada por el gestor de paquetes.

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

Luego crearemos una lista en un fichero para MongoDB

echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list

Seguidamente actualizaremos la base local de paquetes con:

sudo apt-get update

Finalmente instalaremos la última versión estable de MongoDB

sudo apt-get install -y mongodb-org

Y así se instala MongoDB en nuestro ordenador local con Ubuntu! :)

Para iniciar MongoDB tendremos que ejecutar en la consola “mongod”. Pero para acceder a la consola y poder ejecutar queries en la base de datos tendremos que usar el comando “mongo”.

Bonus: Para los curiosos, la versión de 32bits permite un límite teórico de 4,3GB de datos (2^32). Teniendo en cuenta padding, espacios vacíos y otras ineficiencias la empresa estima que el espacio disponible para datos es de entre 2GB y 4GB.