Xiki, el shell del futuro

Estándar

Kickstarter tiene su miga. A veces encuentras cosas realmente absurdas, pero otras te sientes asombrado con las cosas tan útiles que quedan por hacer en este mundo. Esta semana he encontrado una de las últimas.

Enter Xiki

Os recomiendo que echéis un vistazo al vídeo de presentación de Xiki: The command revolution, porque si usais la línea de comandos habitualmente os va a encantar. Imaginaos un shell en vuestra terminal que actúa como un editor corriente, en el que puedes ejecutar comandos y navegar por su salida estándar de una manera más cómoda, filtrar dichos resultados como si estuvieseis en el propio Vim y guardar vuestra sessión de comandos en un fichero de texto que otra persona podrá abrir posteriormente y ejecutar los comandos uno a uno en el orden que quiera. Repito de nuevo, os recomiendo encarecidamente que veáis el video de presentación, porque es muy difícil de explicar con palabras lo que podrá ser capaz de hacer esta utilidad si sale adelante el proyecto.

Además de todo esto, ¡el proyecto es Open Source! Y para los que os guste y os veais capaces de poder ayudar, el creador, Craig Mutt (@trogdoro), hace sesiones de pair programming para beneficiarse de la opinión de otros desarrolladores a la hora de programar distintas características del shell.

Kickstarter: Xiki Kickstarter
Twitter: @xiki
Web: www.xiki.org

[Vim] Objetos de texto

Estándar

Una de las cosas que me gustan de los editores de texto es que siempre acabas aprendiendo algo nuevo que desearías haber sabido mucho tiempo atrás. Esto sucede comúmmente con Vim, que al ser uno de los editores más complejos (y completos) que existen multiplica la probabilidad de pasar por alto esa característica que aumenta tu productividad de manera notable.

Continuar leyendo

[TIP] Eliminar ficheros por fecha de modificación

Estándar

Cuando tratamos con una buena cantidad de ficheros, a menudo nos vemos con la necesidad de borrar muchos archivos tanto por razones de limpieza, como de espacio en disco. Una de mis herramientas favoritas para esto es find. A menudo desconcida, esta herramienta nos permite bastante flexibilidad a la hora de buscar y ejecutar comandos automáticamente sobre el conjuntos de elementos encontrados con los filtros aplicados, además de poder usar los clásicos comodines y expresiones regulares.

Continuar leyendo

Va de mecanografía y teclados

Estándar

Cuando yo iba al colegio, gran parte de lo que se consideraba dar clase de informática era simplemente mecanografía. No se a los demás, pero a mi me encantaba escribir correctamente en el teclado (aunque los ejercicios no eran nada agradables). El simple hecho de colocar bien los dedos en las teclas correctas mejoraba considerablemente tu velocidad de escritura, y eso en la época de auge de los servicios de mensajería instantánea y las salas de chat, era toda una ventaja. Cuando aprendemos a escribir en un teclado a veces adquirimos ciertas malas costumbres debido a nuestro uso específico del teclado (usamos más algunas teclas y eso deforma nuestro uso normal), o porque nunca nos paramos a aprender correctamente.

Continuar leyendo

Cuando todo es una excepción

Estándar

Hoy os vengo a hablar de algo que me ha pasado personalmente trabajando con Python. Si vienes de un lenguaje de programación compilado, te habrás visto, como yo, envuelto en ciertas situaciones en las que tu código funciona perfectamente hasta el punto en el que cierta parte es ejecutada y contiene un error. Estos errores en tiempo de ejecución son difíciles de encontrar y de evitar en muchas ocasiones, y los despistes comunes que podamos tener no aydudan.

En un lenguaje como Python en el que la gran mayoría de esos errores, que otros lenguajes lanzarían en tiempo de compilación, son excepciones, hemos de ser especialmente cautos con nuestro control de éstas, o podemos encontrarnos con casos como el siguiente:

if __name__ == "__main__":
    var = 1
    try:
        new_var = wrong_var + 1
        print('Your new var value: {0}'.format(new_var))
    except:
        pass

El código por supuesto es una versión muy simplificada de lo que podría ser un programa real, pero la captura de de cualquier tipo de excepción es una técnica real que se utiliza en muchos casos. En este ejemplo, wrong_var podría ser un residuo de una refactorización de la variable new_var, que cambió de nombre, pero no en todas sus apariciones en el script. En este caso nuestro script no proporcionaría ningún tipo de aviso o mensaje que nos advierta de este error, dado que el bloque de captura de la excepción elimina esa posibilidad.

Repito, en este caso ese bloque no tiene mucho sentido, pero estoy seguro que en otro tipo de situaciones puede parecer una buena idea. Mejor pensárselo dos veces.

[Python] Recurring Timer

Estándar

Hoy os dejo un pequeño snippet de código en Python para disponer de un temporizador recurrente que ejecute una función cada cierta cantidad de tiempo. Python dispone de un temporizador en el módulo Threading, pero sólo se puede utilizar para ejecutar la función después de pasada el tiempo de espera configurado, sin volver a repetirse.

class RecurringTimer(threading._Timer):
    """ Own implementation of timer to make it recurring

    Timer (based on threading._Timer)
    that invokes a method at a certain interval of seconds

    """
    
    def __init__ (self, *args, **kwargs):
        threading._Timer.__init__ (self, *args, **kwargs) 
        self.setDaemon (True)
        self._running = 0
        self._destroy = 0
        self.start()

    def run (self):
        while True:
            self.finished.wait (self.interval)
            if self._destroy:
                return;
            if self._running:
                self.function (*self.args, **self.kwargs)

    def start_timer (self):
        self._running = 1

    def stop_timer (self):
        self._running = 0

    def is_running (self):
        return self._running

    def destroy_timer (self):
        self._destroy = 1;

Como podéis ver, nos aprovechamos de la propia clase _Timer del módulo Threading (ya que Timer una función de conveniencia para crear una instancia de la clase _Timer) y reimplementamos el método run para hacer esperar al hilo la cantidad de tiempo necesaria y ejecutar el método si el temporizador no ha sido cancelado.

Lo podemos ejecutar de la siguiente manera:

if __name__ == "__main__":
    def sayhi (name):
        print 'hi %s' % name

    t = RecurringTimer(1.0, sayhi, ['alex952'])
    t.start_timer()

Este ejecución imprimirá hi alex952 cada segundo, de manera indefinida. Si deseamos parar el timer para poder reanudarlo posteriormente, los métodos stop_timer y start_timer están disponibles, y si, por el contrario deseamos deshacernos por completo del hilo que ocupa el temporizador, lo podemos hacer llamando el método destroy_timer.

Espero que os resulte de ayuda🙂