Archivos para Python

Interfase pythonera a Commandlinefu

Buenas gente!

Hace rato que no escribía :( . Bueno, ahora tengo algo bueno por lo menos para postear, ja ja. Estuve trabajando en una interfase para el espectacular sitio Commandlinefu que a tantos linuxeros/unixeros ha ayudado.

Basado en la API publicada por el sitio, hice este script, que por el momento está en su versión 0.01, pero por lo menos anda. Posiblemente luego le agregue más funciones. Por lo pronto, me falta documentar todo, y darle una función real a los manejadores de json y rss.

Espero que les sirva! Las sugerencias serán bien recibidas.

Saludos a todos.

#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http ://www.gnu.org/licenses/>.

import re
import sys
import urllib
import getopt
import pprint

available_libraries = { 'json':False,
                        'feedparser':False,
                    }

try:
    import json
except ImportError:
    try:
        import simplejson as json
    except ImportError:
        pass
    else:
        available_libraries['json'] = True
else:
    available_libraries['json'] = True

try:
    import feedparser
except ImportError:
    pass
else:
    available_libraries['feedparser'] = True

import string
import binascii

interface_url = string.Template('http://www.commandlinefu.com/commands/${command}/${format}/')

formats = ['json', 'rss', 'plaintext']

browse_all_commands = 'browse/sort-by-votes'

def tagged_commands(a_command, sort_criteria=163):
    return 'tagged/%d/%s' %(sort_criteria, a_command)

def matching_commands(query):
    b64_query = binascii.b2a_base64(query).strip()
    return 'matching/%s/%s' %(query, b64_query)

short_opts = 'fjhst'
long_opts = 'feed json help search tag'.split()

def process_plaintext (data):
    """ Function doc """
    print data.read()

def process_json (data):
    """ Function doc """
    if not available_libraries['json']:
        return
    data_json = json.loads(data.read())
    pprint.pprint(data_json)

def process_rss (data):
    """ Function doc """
    if not available_libraries['feedparser']:
        return
    data_rss = feedparser.parse(data.read())
    pprint.pprint(data_rss)

def main (argv=sys.argv[1:]):

    prefered_format = 'plaintext'
    command_to_query = browse_all_commands

    try:
        opts, args = getopt.getopt(argv, short_opts, long_opts)
    except getopt.GetoptError, err:
        print "Uso:"
        return
    for op, arg in opts:
        if op in ('-f', '--feed'):
            if available_libraries['feedparser']:
                prefered_format = 'rss'
        elif op in ('-j', '--json'):
            if available_libraries['json']:
                prefered_format = 'json'
        elif op in ('-h', '--help'):
            print "help!"
        elif op in ('-s', '--search'):
            try:
                command_to_query = matching_commands(args[0])
            except Exception, e:
                pass
        elif op in ('-t', '--tag'):
            try:
                command_to_query = tagged_commands(args[0])
            except Exception, e:
                pass
        else:
            print "Not implemented, will not handle %s" %op

    process = { 'plaintext': process_plaintext,
                'json': process_json,
                'rss': process_rss,
            }

    url = interface_url.substitute(command=command_to_query, format=prefered_format)
    process[prefered_format](urllib.urlopen(url))

if __name__ == '__main__':
    main()

    sys.exit(0)   

Dejar un comentario

Ejemplo de lógica difusa en Python

Continuando con el post anterior, aca hay un ejemplo que usa lógica difusa. El programa es muy tonto, pero mi intención es que se vea la manera de utilizar la lógica difusa.

Este programa simula un sistema en donde un ventilador impulsa hacia arriba un objeto dentro de un cilindro vertical, de manera que el objeto se mantenga suspendido a una altura determinada.


    |     |
    |     |
    |     |
    |     | <-- altura buscada
    |  *  |
    |  '  |
    |     |
    | { { |
    | } } |
     vent

El ventilador variará la potencia de soplo de acuerdo a la altura en que se encuentra el objeto.

Utilicé mucho las funciones lambda porque permite definir funciones con muchos de sus parámetros ya fijados, de manera que puedo hacer el código más ”significativo”.

Leer el resto de esta entrada »

Dejar un comentario

Metaclases en Python (parte 1)

Para hacerlo corto, metaclases son “clases de clases”. En los lenguajes orientados a objetos, en donde las clases también pueden ser manipuladas como “objetos”, lo que actúa como plantilla de las mismas son las metaclases. Si desean leer más sobre el tema, en está plagado de artículos en otros lados que les darán una mejor idea de lo que yo puedo darles en éste momento.

Desde Python 2.2 el sistema de metaclases se ha mejorado mucho. Pero vamos a comenzar con algo simple.
Hagamos una función que retorne una clase. La función recibirá los componentes de la clase (atributos y métodos) en un diccionario.
Leer el resto de esta entrada »

Dejar un comentario

Programación funcional en Python (01)

Como dijo McCarthy , LISP es un óptimo local en el espacio entre los lenguajes actuales, pero no por éso vamos a despreciar un lenguaje como Python. Más cuando están implementando de a poco tantas herramientas de lenguajes funcionales ;) .

En Python 2.5 existe la librería functools, que permite trabajar con Funciones de Alto Orden y Aplicación Parcial, o lo que es lo mismo, hacer currying.

Acá les voy a mostrar un pequeño ejemplo de lo divertido y útil que puede ser el currying creando wrappers para funciones.


import functools

def log (message, who):
    "Escribe el mensaje proveniente de del objeto 'who' "
    print '%s: %s' % (who, message)

def make_logger(an_object):
    "Crea un logger específico utilizando la representación en cadena de un objeto "
    return functools.partial (log, who=str(an_object))

class Un_Objeto:
    "Un objeto cualquiera"
    nombre = 'UnObjeto'
    mi_logger = None 

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

    def __init__(self):
        self.mi_logger = make_logger(self)

    def decir_hola:
         mi_logger(' Dice hola!')

Lo que hacemos con esto es definir una función “envoltorio” make_logger que devuleve una función log con uno de sus parámetros ya seteados. De esta manera podemos almacenar esa función como un miembro de nuestro objeto, y poder llamarlo siempre sin necesidad de de declararle a la función log quién la está llamando.

Aunque (por fortuna para aquellos que no tienen Python 2.5) un ejemplo como éste puede escribirse utilizando expresiones lambda de la siguiente manera:


def make_logger(an_object)
     return lambda s: log(s, who=str(an_object))

Funciona de la misma manera.

La idea de ésto es transformar funciones de muchos parámetros en funciones con menos parámetros para simplificarnos la vida y tener soluciones más elegantes.

Dejar un comentario