Archivos para Computadoras

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

Xmonad, o la belleza austera de lo simple

Ayer me decidí por probar Xmonad, un window manager programado en Haskell.

No voy a cubrir temas de instalación y configuración, porque éso ya está en otros lados. Sölo voy a decir que fué simple, pero que hubo que instalar muchos paquetitos. Conste que a pesar de que uso Ubuntu 8.04, prefiero compilar las cosas desde las fuentes, para estar siempre al día. Si, así de retorcido. Y no, no quiero Gentoo. ;)

La instalación, basada en el sistema de paquetes Cabal de Haskell, fué muy al estilo “configure/make/make-install“, pero según Haskell. Todo funcionó de maravilla, no tuve problemas.

Salvo que, es un sistema muy espartano. Por lo menos en ésta versión.
Comenzamos con una pantalla en negro. Si, nada. Si no se acuerdan los atajos de teclado están fritos, porque a diferencia de otros window managers como Openbox, acá el mouse no tira un menucito ni nada.

This is Sparta

This is Sparta

Así que salvo que vayan preparados, van a tener que rebotar varias veces a su window-manager anterior hasta que lo configuren.

La configuración no es para nada amigable. No hay un lenguage de script simple, es un archivo fuente Haskell, así que para manejarlo hay que saber rudimentos de ése lenguaje para saber que lo que se escribe/edita no va a explotar.

Sin embargo, todo el sistema está documentado de manera sufuciente en la web, y si uno se fija, tiene un montón de archivos de configuración de ejemplo, con los que si se da maña, puede mejorar el aspecto, personalizar atajos de teclado, alterar el comportamiento de Xmonad, etc.

El sistema está diseñado para programadores. La idea es simplicidad máxima, para eficiencia máxima. El eye-candy no existe (digamos que es la antítesis de KDE 4 y similares) salvo el que se ingenie uno, a fuerza de hackear la configuración.

Screenshot de Xmonad

Screenshot de Xmonad

El sistema es muy robusto, a pesar que está todavía en desarrollo (no ha llegado a la versión 1). Para aquellos como yo que aman el minimalismo y la eficiencia a toda costa les va a encantar. El sistema casi no consume recursos, parece mentira! Y por supuesto es super rápido.

El mouse casi no se usa. Se puede manejar todo por teclado. Así que si sin programadores expertos, o power users, sabrán apreciar ésto. Una vez aprendidos los atajos, es todo muy rápido y simple.

Supongo que si mantienen su filosofía, lo que les queda por mejorar es el sistema de instalación y configuración, para que sea menos pedregoso. Es el detalle que faltaría para que esté a la altura de otros manejadores como Openbox.

En resumen, es el sistema que andabas buscando si querés eficiencia y productividad a toda costa.

Dejar un comentario

Siftables

Desde una de las mecas de la ciencia y la tecnología, en este caso el MIT, llegan unos aparatitos de lo más simpáticos y prometedores. Básicamente son como pequeños módulos parecidos a fichas de algún juego, que incluyen una pantalla y unos cuantos sensores, y permiten trabajar con la información de manera gestual y física, utilizando las manos.  En el sitio [1] se muestran videos de cómo estos pequeños módulos interactúan entre ellos, o con una PC, para catalogar información, crear música como con el ReacTable, etc.

Sospecho que en cuanto se popularice la tecnología de los memristores, estos aparatitos o algunos similares van a ser la manera en la que vamos a interactuar con las computadoras, o mejor dicho, la manera en que vamos a procesar la información. Posiblemente no sea como aquella famosa interfaz de “Minority Report”[2][3], pero a me parece que es más factible a corto plazo.

[1] : http://web.media.mit.edu/~dmerrill/siftables.html

[2] :

[3] :

Dejar un comentario

Conociendo Factor

Como estoy de vacaciones y soy un geek, no podía hacer otra cosa que aprender un lenguaje de programación nuevo y raro.

Pues bien. Hace meses que estoy dando vueltas como mosca sobre www.factorcode.org bajando los binarios del lenguaje, pero nunca me decidí a comenzar con el aprendizaje.

Pues bien. Hoy estaba aburrido y me puse manos a la obra. Para empezar, Factor tiene unas cuantas peculiaridades:

  • concatenativo
  • basado en pila
  • basado en Forth
  • requiere un procesador con instrucciones SSE 2 (posterior a Pentium 4) . Update ( 10/02/09 ): Si se compila desde el código fuente, se puede correr sobre procesadores más viejos. Las versiones precompiladas de Factorcode son las que requieren las instrucciones especiales.

Lo primero significa en términos rápidos y groseros, que los operandos van primero y el operador al final. Por ejemplo:

(1 + 2) / 5 en Factor se escribe 1 2 + 5 /

Lo segundo indica que la estructura principal de almacenamiento de datos es una pila. Es decir, todos los datos se insertan y quitan de una pila que maneja el lenguaje. Ésto permite simplificar un montón las cosas, sobre todo en lo que es la forma de “decir” las cosas.

Continuando con el ejemplo anterior, lo que sucedió es lo siguiente:

  1. al escribir 1 2 se “pushean” en la pila los elementos 1 y 2
  2. ” + ” es una función que toma dos elementos de la pila y le inserta el resultado, por lo que queda un 3 en la pila.
  3. luego se le inserta un 5, por lo que en la pila queda ” 3 5 “
  4. y finalmente ” / ” toma dos operandos de la pila y “pushea” el resultado nuevamente, por lo que queda ” 3/5 ” (si, queda como fracción, no como punto flotante).

Pero para cosas más interesantes viene lo tercero. Forth es un lenguaje bastante viejo, pero muy visionario en su época. Combina un intérprete interactivo con un compilador. El usuario escribe de manera interactiva las subrutinas que en Forth se denominan “palabras” ( “words” ). Previsiblemente un conjunto de palabras forman un “vocabulario”. Las palabras se compilan, debuggean y reescriben de manera interactiva, todo mediante una máquina virtual.

De la misma manera, en Factor trabajamos en un entorno, definiendo palabras, que trabajan sobre una pila.

Entorno de Factor

Entorno de Factor

Por ejemplo, una secuencia se escribe entre llaves.

{ 1 2 3 4 }

Para definir una función que obtenga el promedio de la secuencia anterior hacemos

: average ( seq -- n ) dup sum swap length / ;

Y por supuesto podemos probar haciendo

{ 1 2 3 4 } average .

que retorna “2+1/2″.

Lo que hace la palabra “average” es duplicar el contenido de la cima de la pila (queda la secuencia repetida), luego hacer la sumatoria del la primer secuencia, y se deposita el resultado en la cima de la pila. Intercambiamos (“swap”) el primer elemento de la pila por el segundo (queda la secuencia en la cima). Obtenemos la longitud de la secuencia y depositamos el resultado en la pila. Finalmente obtenemos el resultado final realizando el cociente entre los dos elementos que hay en la pila.

Por supuesto que esto no demuestra todo el lenguaje ni su potencial, pero mi intención es introducirlos un poco en el tema.

Un punto feo de Factor es que no existe mucha documentación para el principiante. Si bien el lenguaje incluye muchísimo código y documentación, es para gente ya “fluente” en el lenguaje. Los que comenzamos tenemos que ir dilucidando por prueba, error y algún que otro chispazo de inspiración.  Pero la gente de Factor está trabajando en éso. Piensen que el lenguaje todavía está en “beta”, aunque es funcional y ya sirve para realizar un montón de cosas.

Si quieren investigar más al respecto pueden consultar los siguientes enlaces:

http://en.wikipedia.org/wiki/Stack-oriented_programming_language

http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_basado_en_pila

http://concatenative.org/

http://factor-language.blogspot.com/2009/01/advantages-of-concatenative-and-stack.html

http://learnfactor.org/

Esta es una charla de Slava Pestov, el mismísimo creador de Factor. Si entienden inglés, se la recomiendo.

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

Lógica difusa

La lógica difusa ( “fuzzy logic” ) es una manera de trabajar con lógica, utilizando valores continuos, a diferencia de los tajantes valores discretos de la lógica tradicional ( 0 y 1, Verdadero y Falso….).

Básicamente la idea es ésta. Las computadoras trabajan con lógica de Verdadero y Falso. Todas las cosas tienen que caer necesariamente en alguna de esas dos categorías. En cambio los seres humanos pensamos con diversos grados de verdad, los cuales son difusos, es decir, no tienen un grado definido y exacto de verdad. Palabras como “mucho”, “poco”, “más o menos”, “quizás”, “posiblemente”, “seguro” indican los diferentes grados de verdad que le podemos asignar a un predicado. Entonces la lógica difusa sirve para hacer que la computadora trabaje con nuestros términos o grados de verdad.
Leer el resto de esta entrada »

Dejar un comentario

Pensamientos sobre programación (01)

Leyendo el blog de Fabio, leo esta pequeña lista de “12 señales que indican que eres un mal programador”, cuyo autor es Damien Katz.

Más allá de los razonamientos obvios del tipo “hay más de 12 razones por las que uno podría darse cuenta de que programa mal”, me quedé pensando en alguno de los ítems de la lista.

“Java es todo lo que necesitas” . Esto tiene bastante que ver con lo que escribió PaulGraham en “Beating the Averages”. Básicamente existen dos factores que inclinarían a alguien a decir algo como “<lenguaje X> es todo lo que necesito” o como la conocemos acá, la ley del martillo. El primero es que es más fácil. El factor “facilidad” es poderoso en muchas áreas de la vida de todo el mundo, ya que es natural inclinarse a hacer lo fácil, no así lo mejor. Es más fácil usar lo que ya conozco, que (en nuestro caso) investigar la herramienta más adecuada, posteriormente aprender a utilizarla y finalmente resolver el problema. El segundo factor es el “mercado” o mejor dicho el factor de “la mayoría”. Por varias razones, las cosas son “más fáciles” cuando hacemos lo que hace la mayoría. Si la mayoría es inducida (por una cuestión de mercado o por la que sea) a utilizar el producto X, tendremos mayores posibilidades de soporte, de encontrar un trabajo, de que otros utilicen nuestro producto, comprensión de nuestro código por parte de una mayor cantidad de programadores…
Leer el resto de esta entrada »

Dejar un comentario

Peleando con la PC (001)

Esto es el resultado de mi pelea con Kubuntu en la última semana.

La historia es así. Yo vivía en mi casa muy contento, programaba, programaba sin cesar :) . Pero un día me pongo a configurar el sistema, de aburrido que estoy, desde el Centro de Control de KDE. Tengo Kubuntu 7.10 por si se lo preguntaban.

El tema es que no tengo mejor idea que comenzar a cambiar los servicios que se ejecutan al arranque, y para colmo, fijar mi atención en udev. Se me ocurre activarlo al arranque. Mala idea.

A partir de allí tuve problemas al arranque. Para comenzar, era imposible iniciar cualquier clase de sesión en cualquier clase de sistema de ventanas. Lo que era problemático, considerando que necesitaba editar un archivo odt con OpenOffice. Así que intento iniciar una sesión desde una terminal. Y obtengo algo como ésto

[...]
bash: /dev/null: Permission denied
bash: /dev/null: Permission denied
bash: /dev/null: Permission denied
bash: /dev/null: Permission denied
bash: /dev/null: Permission denied
bash: /dev/null: Permission denied
[...]

Por lo que llegué a la conclusión de que la cosa se estaba pasando de castaño oscuro.

Así que como primera medida (al estilo “lo atamo’ con alambre”) hice como root un

chmod 666 /dev/null

lo que permite salir del paso, hasta que la máquina vuelva a ser reiniciada, y el problema se reanude.

Luego, investigando por Internet, me entero de que existe un error, declarado varias veces en launchpad.net bajo los números #63031, #69516 y #53040.

En resumen, la mano viene así.

  • algo hace que udev funcione mal . Podría decirse que es el editor de servicios de KDE, como afirman aquí. Pero luego responden que no es así.
  • soluciones para éso hay varias, aquí paso a listar algunas.

Soluciones al problema:

  1. Borrar las entradas espúreas, causadas aparentemente por el editor de servicios de KDE. Estas entradas tienen la forma

    /etc/rc2.d/S*udev

    así que con un simple rm /etc/rc2.d/S*udev el problema tendría que estar arreglado. Los post que afirman ésto son éste y éste.
  2. Según éste post se debe ejecutar la siguiente línea: sudo chmod a+rw /lib/udev/devices/null
  3. Agregar la línea chmod 666 /dev/null al archivo rc.local

Espero que ésto les sirva como me sirvió a mí. :)

PD:  para la gente de *ubuntu o KDE o Udev, ponganse las pilas y arreglen ésto che!

Dejar un comentario

Momento introspectivo 01

Como diariamente hago, me dedico a leer los threads de cierta lista de programación a la que estoy subscripto. De repente leo lo siguiente:


> Mi duda es esta,
> Si tengo una funcion a() que devuelve la llamada a funcion b(), quiero que
b() devuelva el nombre de la funcion a, o de la funcion que la llame.
>>> import inspect
>>> def f():
print inspect.stack()[1][3]


>>> f()
<module>
>>> def zaraza():
f()


>>> zaraza()
zaraza
>>>

Mi primera reacción es pensar “WOW! Qué interesante!”, a lo que sigue “qué bonito!”.

Instantáneamente, varios pensamientos se agolpan en mi mente, mientras me siento extraño a mí mismo. Parte mía se rebela, no puede aceptar cómo es posible que sea tan geek.

  • Estaré perdiendo parte de mi humanidad?
  • Existirá un balance entre lo que gano y lo que pierdo al entender ésto?
  • Soy yo el único al que le pasa ésto?
  • Por qué además lo estoy blogueando?

Demasiados interrogantes, y hace calor para pensar…. El tiempo dirá.

Comentarios (1)

El protocolo que faltaba

Esto me lo mandó mi amigo Nahuel :

http://www.blug.linux.no/rfc1149/

Implementación del protocolo IP… mediante palomas mensajeras! Por supuesto que no habría problemas, ya que IP ofrece un servicio unreliable.  Pero, me cacho con la latencia de red!

Ahora bien. todavía faltan…

  • UDP por botella flotante
  • ping mediante piedrazos a la ventana
  • o como anunció Falken, en la inolvidable SET, el “ladrillo de las comunicaciones

Comentarios (1)

Entradas más antiguas »