danigm.wordpress.com -> danigm.net

Pues nada, que me he comprado danigm.net, y que mudo mi blog para allá.

Sistema para hacer test

Hoy estando en sugus, Virako ha preguntado por algo para hacer test en linux, para el stand de mañana de la asociación, y ha encontrado algo para hacerlo. Pero entonces a mí se me ha ocurrido implementar un script sencillo que haría más o menos la misma función.

La idea es simple, parsear un fichero con las preguntas y las respuestas, y mostrar con zenity una lista para seleccionar. Por supuesto para hacerlo más divertido, el orden de las respuestas es aleatorio.

El fichero a parsear sería de la forma:

El resultado de multiplicar 25*25 # 2500 # @625 # 825
¿Cuál es la mejor tira cómica de todas? # @la de linuxhispano # la tira ecol # bit & byte

Donde por cada linea se introducirían la pregunta y el conjunto de respuestas, separando cada una por una #. La pregunta siempre será la primera cadena, las respuestas se ordenarán de manera aleatoría. La respuesta correcta está marcada por una arroba al principio, entre # pueden existir tantos espacios como se quieran, ya que hago un strip de la cadena.

Aquí está el código:


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

import os, sys
import random
from datetime import datetime

acertadas = 0

comando = 'zenity --text "¿Cual es tu nombre?" --entry'
entrada, salida = os.popen2(comando)
nombre = salida.read()
nombre = nombre.strip()

n = 0
for line in open(sys.argv[1]):
    n += 1
    opts = line.split('#');
    pregunta = opts[0]
    opts = opts[1:]
    opts = map(str.strip ,opts)

    columnas = []
    correcta = ''
    while len(opts) > 0:
        opt = random.choice(opts)
        opts.remove(opt)
        if opt[0] == '@':
            correcta = opt[1:]
            opt = opt[1:]
        opt = 'FALSE "' + opt + '"'
        columnas.append(opt)

    comando = 'zenity --text "' + pregunta + '" --list --radiolist --width=500 --height=500 --column X --column "Respuestas" ' + ' '.join(columnas)
    entrada, salida = os.popen2(comando)
    respuesta = salida.read()
    if respuesta.strip() == correcta:
        acertadas += 1

comando = 'zenity --scale --value=%(acertadas)d --max-value=%(n)d --print-partial --text "tu puntación %(nombre)s %(acertadas)d/%(n)d"' % dict(acertadas=acertadas, n=n, nombre=nombre)
entrada, salida = os.popen2(comando)
salida.read()

print "%s | %s | %d" % (datetime.now().ctime(), nombre, acertadas)

Se ejecutaría el programa de la siguiente forma:
python test.py fichero_de_test1 >> estadisticas_de_test1

Al principio pedirá un nombre para las estadísticas, y al final mostrará una barra, indicando la puntuación que has sacado.

Limosna

limosna

Domingo de Ramos

En mi pueblo hay una bonita tradición el domingo de ramos. La tradición consiste en que cuando las chicas se van a dormir el sábado, sus novios o pretendientes van con pintura, y pintan una flor, o un “ramo”, en la puerta de su casa. El ramo no se pinta en la misma puerta, sino que se pinta en la calzada.

Así pues cada año, un “artista” como yo, veía la oportunidad de plasmar su arte en el duro asfalto, ya sea con un aerosol, o una buena brocha. Los más sinvergüenzas cantaban con una guitarra o si ella para que la pretendida se asomara al balcón, y si le venía a bien a la madre, sacara unos pastelitos y un poco de alcohol, para amenizar la noche.

Según ha pasado el tiempo, y dada la proliferación de pisos, el pintar los ramos se ha vuelto cada vez más complejo, ya que en un bloque de pisos pueden vivir muchas mujeres bonitas en edad de merecer, y ya no caben los dibujos en la calle. Por otro lado, también han proliferado los gamberros que aprovechan esta tradición para pintar con spray por todas partes, haciendo que pierda todo el sentido que la fiesta podría tener.

Yo hace unos años que ya no practico esto de ir pintando, pero como me gustaba, este año he hecho un dibujito con el estilo que plasmaba en el asfalto, pero en esta ocasión, en versión digital. Aquí dejo el dibujito.

domingo de ramos

EventManager en python

Hoy he estado implementando un sistema de plugins para www.sweetter.net, y para ello he decidido utilizar un modelo de señales, de tal forma que se puedan enlazar funciones a señales, y cuando se lance esta señal, se hace una llamada a todas las funciones enlazadas a esta señal.

La idea es simple, pero la implementación lo es aún más. Solo es necesario implementar un par de clases, Event y EventManager.

La clase Event
Como su propio nombre indica, esta clase representa un evento, o señal. Como atributos de clase tiene:

  • (str)self.name, para nombrar a la señal.
  • (dict)self.listeners, para guardar todas las funciones conectadas a esta señal, junto con los posibles parametros de estas.

Como metodos tiene:

  • add(self, function, data=None)
  • , que conecta una funcion a este evento, en data se pueden pasar los parametros de la función, como una tupla, o un dict. Si no se pasan, se llama a la función sin parametros.

  • def delete(self, function), esta es la inversa a la función anterior, desconecta una función de una señal.
  • def called(self, data=None), en esta función es donde está el meollo de la cuestión, ya que se encarga de llamar a las funciones de este evento. Si se pasa el parametro data, pues se utilizan estos parametros para la llamada a todas las funciones conectadas a esta señal

La clase EventManager
Esta clase es la encargada de gestionar todos los eventos que tengamos, y que emite las señales.
Como atributos:

  • (dict)self.events, en este parametro se almacenan todos los eventos.

Como metodos:

  • def add_event(self, Event), este metodo añade un evento al EventManager.
  • def del_event(self, Event), este metodo es el inverso del anterior, borra un evento.
  • def connect(self, event, function, data=None), con este metodo se conecta una función con un evento, el evento debe existir en el event manager.
  • def disconnect(self, event, function), esta es la función inversa a la anterior.
  • def signal(self, event, data=None), esta es la función encargada de mandar señales, así que se llama cuando queramos generar un evento.

Ejemplo de uso

import events
em = events.EventManager()
em.add_event(events.Event('misenal1'))
...
em.add_event(events.Event('otrasenal'))
em.connect('misenal1', print)
em.connect('misenal1', str.join, [['uno', 'dos', 'tres']])
em.connect('otrasenal', str.split, "cadena dos")
...
em.signal('misenal1', 'esto se imprimiria')
em.signal('otrasenal')
...

Aquí el código completo

class Event():
    def __init__(self, name):
        self.name = name
        self.listeners = {}

    def add(self, function, data=None):
        self.listeners[function] = data
    
    def delete(self, function):
        self.listeners.pop(function)

    def called(self, data=None):
        for function, d in self.listeners.items():
            if data is None:
                if d is None:
                    function()
                else:
                    if type(d) == type([]):
                        function(*d)
                    elif type(d) == type({}):
                        function(**d)
                    else:
                        function(d)
            else:
                if type(data) == type([]):
                    function(*data)
                elif type(data) == type({}):
                    function(**data)
                else:
                    function(data)


class EventManager():
    def __init__(self):
        self.events = {}

    def add_event(self, Event):
        self.events[Event.name] = Event

    def del_event(self, Event):
        self.events.pop(Event.name)

    def connect(self, event, function, data=None):
        self.events[event].add(function, data)

    def disconnect(self, event, function):
        self.events[event].delete(function)

    def signal(self, event, data=None):
        if data is None:
            self.events[event].called()
        else:
            self.events[event].called(data)

Goqajp – 22-07-2353 (07:38)

No sé donde estoy, ni quién soy. Desperté en una vieja casa, sin puertas ni ventanas. Solo huecos en las paredes dónde algún día estuvieron. La luz del sol entra por los numerosos huecos que pueblan las paredes.

Tengo un reloj de pulsera, que parece funcionar perfectamente, así que tengo una referencia de fecha y hora, pero no se cuanto tiempo llevo aquí.

En esta vieja casa sólo he podido encontrar este viejo cuaderno. No tiene nada escrito, aunque me ha extrañado que todas las hojas anteriores a esta, están arrancadas. He decidido utilizar este cuaderno como diario, por si estos problemas de memoría se repiten.

Tengo la sensación de haber estado inconsciente mucho tiempo, tengo hambre y sed, aunque puedo moverme con bastante agilidad. Parece que mi cuerpo está en forma, pero no puedo decir lo mismo de mi mente.

Muchas dudas me rondan la dolorida cabeza. He intentado recordar algo sobre mi vida, sobre cómo he llegado aquí, pero no he conseguido nada más que un incipiente dolor de cabeza.

Consigo alcanzar vagos recuerdos, un niño jugando, un joven estudiando, un hombre. No se si soy yo. Ahora que lo pienso, no recuerdo mi cara, no podría reconocerme.

Quizás mis recuerdos sean sueños, quizás mis sueños sean recuerdos. Ahora mismo todo está borroso, no tengo ni un solo recuerdo fiable, nada a lo que agarrarme.

Este silencio es aterrador. ¿Estoy solo? Tengo que encontrar a alguien. Tengo hambre. Tengo sed. Voy a buscar algo.

Estudios universitarios

Cuando comencé la carrera, tenía muy claro que lo que yo quería era aprender lo máximo posible, y no iba buscando un título, que para mí no tiene la menor importancia.

Con el paso de los años, y creo que por culpa del ambiente universitario que me he ido encontrando, (ya sean profesores, o compañeros), me he dado cuenta de que para la mayoría, la carrera solo consiste en intentar aprobar, y algún día tener un título para poder trabajar, y tener un estatus social un poco más alto.

Tras mi paso por distintas universidades (dos en concreto), y tras ver y conocer a muchos profesores, me he dado cuenta de que hay un error muy común. Muchas asignaturas no están organizadas para enseñar al alumno nuevos conceptos, sino para que el alumno apruebe un tipo de examen. Para estudiar no hay nada mejor que coger exámenes de otros años, y hacerlos.Pero así no estamos aprendiendo nada, simplemente a aprobar este tipo de exámenes.

Yo cada día, cuando voy a clase, cuando estudio para un examen, cuando estoy haciendo un trabajo… Siempre intento pensar que es para aprender cosas nuevas, para fijar conceptos, pero últimamente me estoy dando cuenta de que soy como el resto de personas, y que estudio para aprobar, y no me gusta.

Intento alejar esa idea de mí. No me importa aprobar o suspender un examen.No necesito que un profesor me diga que es lo que se y lo que no se. Yo se lo que he aprendido con cada asignatura, y con eso debería estar contento.Pero no siempre ocurre así, cuando suspendo, me molesta, ahora quiero terminar la carrera, y tener el título.

Quiero volver a mis orígenes, quiero estudiar para aprender, pero está visto que en este sistema es frustrante, que realmente aprendes, si te interesas por un tema, pero te suspenden sabes que conoces los conceptos.

Por último una frase que he llevado en mi firma mucho tiempo, y que no debería olvidar nunca:

“Nunca consideres el estudio como un deber, sino como una oportunidad para penetrar en el maravilloso mundo del saber” [Albert Einstein]