Lugaru. Controla a un conejo badass que sabe karate do

Lugaru Screenshot

 
 

Descripción

Luguro es el primer juego comercial realizado por Wolfire Games. El personaje principal de Luguro es Turner, un conejo antropomorfo con unas curiosas y bien desarrolladas habilidades de combate. Después de ver cómo su familia y amigos fueron asesinados por lobos, éste se embarca en una misión de venganza, solo para descubrir un profundo plan que envuelve a la isla entera. Usando una gran variedad de técnicas de combate, el jugador luchará contra lobos y conejos hostiles a través de distintos paisajes ( praderas, montañas, desiertos).

Lee el resto de esta entrada »

Anuncios

Listas por Comprensión en Python

Las listas por comprensión proporcionan una forma muy sencilla de crear listas a partir de secuencias (list/listas, tuple/tuplas, dict/diccionarios, set/conjuntos, str/cadenas). El uso más común de esta característica es el de construir listas, donde cada uno de sus elementos son el resultado de alguna operación aplicada a cada uno de los elementos de la secuencia, o para crear una sub-secuencia de elementos que cumplan ciertas condiciones.

Las listas por comprensión están compuestas por corchetes, los cuales encierran una expresión seguida por una cláusula for y, a continuación cero o más cláusulas for o cláusulas if.

Aquí tomamos una lista de números y retornamos una lista con sus cubos

>>> numeros = range(1, 5)     # Equivalente a 'numeros = [1, 2, 3, 4]'
>>> [x**3 for x in numeros]
[1, 8, 27, 64]

Podemos realizar operaciones tales como convertir una tupla de cadenas a una lista de enteros:

>>> cadenas = ("23", "2", "465")
>>> [int(x) for x in cadenas]
[23, 2, 465]

Lee el resto de esta entrada »

Sobrecarga de operadores en Python

En la Programación Orientada a Objetos (OOP por sus siglas en ingles), la sobrecarga se refiere a la posibilidad de contar con dos o mas funciones con el mismo nombre pero con comportamiento diferentes. La sobrecarga de operadores trata básicamente de lo mismo, solo que en el ámbito de los operadores (+, , *, /, etc).

¿Cuál es la ventaja de contar con esta característica? Para responder esta pregunta deseo mostrarles el siguiente código Java

/*
 * Supongamos que la clase Matriz existe y que su constructor genera un arreglo
 * bidimensional de enteros, relleno de ceros, es decir, para toda celda de la
 * matriz, matriz[i][j] == 0
 */

Matriz mi_matriz = Matriz(10, 20);
Matriz otra_matriz = Matriz(10, 20);

/*
 * Para sumar nuestras matrices, tendríamos que invocar al método del objeto
 * de tipo Matriz llamado Sumar
 */
Matriz matriz_suma = mi_matriz.Sumar(otra_matriz);

Todo bien, pero ¿Y si pudiéramos utilizar el símbolo suma (+) para realizar la última línea del código anterior? ¿No sería eso genial? Pues, de eso se trata la sobrecarga de operadores y ahora les mostraré como hacerlo en Python.

Lee el resto de esta entrada »

Personalizando UNIX: Variables de Entorno y Alias

export PYTHONSTARTUP=$HOME/.pythonrc.py

Alias y el archivo .env

¿Sueles escribir una orden con un número relativamente grande de opciones, tal y como la siguiente?

fmt -c -s -u -w 80 -p "#"

Yo utilizo la instrucción anterior para limitar los comentarios de una sola línea en mis programas Python a ochenta caracteres, dividiéndolos en dos o más líneas. fmt se encarga de agregar como prefijo el símbolo numeral/almohadilla (#) a las nuevas líneas. Indudablemente escribir esta orden u otras de similar apariencia es frustrante si se hace con frecuencia, por suerte contamos con alias. Para crear un alias tan solo debemos abrir nuestro emulador de terminales favorito y escribir

alias mi_orden=orden_unix

Pero aun no resolvemos el problema de escribir la tediosa línea de mi ejemplo, ya que en la misma, la orden tiene opciones asociadas. Solucionar esto ultimo es fácil, debido a que alias acepta opciones en el segundo operando, tal y como podemos ver a continuación

alias mi_orden='orden_unix -op1 arg -op2 arg...'

Algunos ejemplos

alias cambiar=cd
alias fmtpy='fmt -c -s -u -w 80 -p "#"'

La próxima vez que necesite formatear mis comentarios solo tendré que escribir fmtpy en lugar de aquella irritantemente larga orden.

Pero las cosas no terminan aquí, porque una vez que el emulador de terminal sea cerrado el alias dejará de existir. Si deseas que el alias perdure en el tiempo, necesitas incluirlo en un archivo especial localizado en tu directorio home llamado .env (si no existe debes crearlo), éste será similar al siguiente

# .env
alias cambiar=cd
alias fmtpy='fmt -c -s -u -w 80 -p "#"'

Lee el resto de esta entrada »

Crear un menú en python (no GUI)

En esta ocasión deseo compartir una forma (muy personal) de realizar menús en Python. Tal y como se puede ver en el título, no me refiero a un menú gráfico sino a uno muy tradicional, de línea de comandos. Debo aclarar que el menú que verán a continuación puede ser implementado sin la utilización de una clase, sin embargo, este enfoque brinda la ventaja de contar con código bien organizado, fácil de leer, depurar y modificar.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# menu.py

#----------------------------------------------------------------------- Módulos
import os
import sys

#-------------------------------------------------------------------- Constantes
LIMPIAR = "clear" if sys.platform.startswith("linux") else "cls"

#------------------------------------------------------------------------ Clases
class Menu(object) :
    """Lista de funciones opcionales, las cuales le permitirán al usuario
    realizar operaciones matemáticas básicas.

    Argumentos
        prompt -- Es el prompt del menú (default '>')
    """

    def __init__(self, prompt=">") :
        self.prompt = prompt + " "
        self.opciones = [
            self.opcion_sumar,
            self.opcion_restar,
            self.opcion_multiplicar,
            self.opcion_dividir,
            self.opcion_salir,
        ]
        self.presentacion = "------------------ Bienvenido ------------------\n"

        for numero, opcion in enumerate(self.opciones, 1) :
            self.presentacion += "{0}. {1}\n".format(numero, opcion.__name__[7:])

    def loop(self) :
        while True:
            print self.presentacion

            try:
                seleccion = int(raw_input(self.prompt))

                if seleccion >= 1 and seleccion < len(self.opciones) :
                    op1, op2 = self.pedir_operandos()
                    # Los indices van desde 0 hasta len(self.opciones)-1
                    resultado = self.opciones[seleccion - 1](op1, op2)
                    raw_input("\nEl resultado es {0}".format(resultado))

                # Caso especial para la opción "salir"
                elif seleccion == len(self.opciones) :
                    self.opciones[seleccion - 1]()

                else:
                    raw_input("Error: Opción invalida")

            except ValueError:
                raw_input("Error: Debes introducir un número")

            except ZeroDivisionError:
                raw_input("Acaso quieres destruir el universo!?")

            except KeyboardInterrupt:
                break

            os.system(LIMPIAR)

    def pedir_operandos(self) :
        while True:
            print "Por favor, ingrese el primer operando"

            try:
                op1 = int(raw_input(self.prompt))
            except ValueError:
                print "Error: Debes introducir un número\n"
            else:
                break

        while True:
            print "Por favor, ingrese el segundo operando"

            try:
                op2 = int(raw_input(self.prompt))
            except ValueError:
                print "Error: Debes introducir un número\n"
            else:
                break

        return op1, op2

    def opcion_sumar(self, op1, op2) :
        return op1 + op2

    def opcion_restar(self, op1, op2) :
        return op1 - op2

    def opcion_multiplicar(self, op1, op2) :
        return op1 * op2

    def opcion_dividir(self, op1, op2) :
        return op1 / op2

    def opcion_salir(self) :
        # Aquí podría ir un mensaje de despedida
        raise KeyboardInterrupt()

Para poder ver nuestro menú andando solo necesitamos importarlo en el script (archivo python o incluso el interprete interactivo) en el cual será utilizado

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# main.py

import menu

mi_menu = menu.Menu()
mi_menu.loop()

Y listo. Espero que les haya sido de ayuda 😉

Crear matrices en python utilizando listas

A diferencia de lenguajes como C, en Python no resulta intuitivo el proceso de creación de una matriz. Este post está escrito con el objetivo de brindar una solución a este problema a través de la utilización de listas. A continuación, pongo a su disposición fragmentos de código que yo mismo he escrito y utilizado a la hora de implementar una matriz en mis scripts.

# La mas sencilla e intuitiva
matriz = []
for i in range(numero_filas):
    matriz.append([])
    for j in range(numero_columnas):
        matriz[i].append(None)

# Menos intuitiva pero mas eficiente
matriz = [None] * numero_filas
for i in range(numero_filas):
    matriz[i] = [None] * numero_columnas

# Mal
matriz = [[None] * numero_columnas] * numero_filas

# Versión mas compacta
matriz = [range(numero_columnas) for i in range(numero_filas)]

# Variación de la anterior
matriz = [[None] * numero_columnas for i in range(numero_filas)]

El recetario para mostrar matrices lo debo para una próxima entrega del blog 😉

Nota del pie:

La razón por la cual el código de la línea 14 esta mal es muy fácil de entender, Python evalúa una y solo una vez la expresión que posteriormente sera copiada y concatenada numero_filas-veces, es decir, la expresión

[[None] * numero_columnas]

siempre hará referencia a la misma lista y en consecuencia al escribir

matriz[i][j] = valor

estaremos modificando mas de una celda a la vez (porque dichas celdas harán referencia al mismo objeto).

Publicado en Recetas. Etiquetas: , , . Leave a Comment »

Evangelistas de Python

Hace un par de semanas atrás logré aventurar a un amigo en el mundo de Python, debo admitir que no fue nada fácil. Él, al igual que yo lo hice hace mucho tiempo, consideraba que todas las libertades que brinda este poderoso lenguaje le quitarían el derecho a controlarlo todo, lo harían vulnerable, brindando tanta flexibilidad que su autoridad como amo y señor del código que se dispondría a desarrollar sería capaz de hacer cosas que él nunca había visto y por lo tanto, tales cosas no eran de su agrado.

Uno de los aspectos de Python que no fue de su gusto es el radical token que indica el final de una instrucción o mejor dicho, la falta del token tradicional destinado a esta tarea: el famoso punto y coma (;); afirmaba que lo extrañaría, que no podía vivir sin él y que veía feo el código escrito en Python por utilizar el carácter de fin de línea en su lugar. Pero creo que su malestar mas grande provenía de la forma empleada por el lenguaje para definir los bloques de instrucciones: la identación; realizó las mismas quejas y afirmaciones anteriores pero esta vez con las muy odiadas llaves ({}).

A pesar de que mi amigo experimentaba toda esta incomodidad con el lenguaje, yo no me dí por vencido y decidí enseñarle un pequeño programa que desarrollé para simular el conocido Juego de la Vida. A raíz de esta pequeña introducción, decidió darle una oportunidad a Python (YAY!!); ya ha comenzado a leer y a experimentar con el interprete interactivo, y comienza a plantearme ciertas dudas.

¿Cuál es la moraleja? Somos evangelistas! No se den por vencidos, como pythoneros tenemos la responsabilidad de hacer conocer este excelente, poderoso y versátil lenguaje de programación.

Siempre hay una forma de traer luz a los ojos que no quieren ver 😉

Publicado en El Día a Día. Etiquetas: . Leave a Comment »