Sound up your Python !

Long simulations and optimisations are a plea to the modern modelist. Worst of all are the programs of average length (say, 5 to 15 minutes) that do not let you the time to start anything else during the runs, and have you lose your day before you know it. I wrote a few Python functions to ease the pain. The first is called ring() and produces… a ring (like an egg timer ! but if you have office-mates you may use a more neutral sound like somenone coughing, or scratching, etc…). You can use it like this:

def myLongFunction():
        for i in range(100000):
            print "I'm the world's most useless function !"

myLongFunction();ring()

In case you want your function to always ring at the end, you can also use my decorator @ringatend when you define the function :

@ringatend
def myLongFunction():
        for i in range(100000):
            print "I'm the world's most useless function !"

myLongFunction() # will ring at the end, no need to call 'ring()'

Now, if you really want to make your colleagues jealous (or crazy) you can ask Python to play some music in the background while the function runs, with my decorator @inmusic

@inmusic
def myLongFunction():
   .................

myLongFunction() # will play music during the function's run !

Believe me, simulations look way shorter with on some Beny Hill (but they are actually slower 🙂 )

You can also combine the decorators to get a function that will play some music, and ring at the end:

@ringatend
@inmusic
def myLongFunction():

Here is the code for all that. You will need to install Pygame to play the sounds. I have also included some functions to splash popups: popup and @popupatend:

rom Tkinter import *
import tkMessageBox
import time
import pygame

# RING

def ring(sound='./cough.wav'):
    
    pygame.mixer.init()
    sound = pygame.mixer.Sound(sound=)
    sound.play()
    time.sleep(sound.get_length())
    pygame.mixer.quit()



def ringatend(target):
    """ a decorator to make your functions rings when they are done """
    
    def f(*args,**kwargs):
        
        result = target(*args,**kwargs)
        ring()
        return result
        
    return f



# IN MUSIC !

def inmusic(target):
    """ a decorator to play your functions in music """
            
    def f(*args,**kwargs):
        
        pygame.mixer.init()
        sound = pygame.mixer.Sound('./music.wav')
        sound.play()
        result = target(*args,**kwargs)
        sound.stop()
        pygame.mixer.quit()
        return result
            
    return f



# POPUPS

def popup(txt='Finished'):
    root = Tk()
    tkMessageBox.showinfo('Finished!',txt)
    root.destroy()
    root.mainloop()



def popupatend(target):
    
    
    def f(*args,**kwargs):
        
        # Run the function
        result = target(*args,**kwargs)
        
        # Make a pretty text
        fname = target.func_name
        pretty_args = ','.join([str(a) for a in args])
        pretty_kwargs = ','.join(['%s=%s'%(str(k),str(v))
                       for k,v in kwargs.iteritems()])  
        descr ='%s(%s,%s)'%(fname,pretty_args, pretty_kwargs)
        descr = descr[:100] # in case it really is too long
        
        # popup description
        popup(txt='%s done !'%(descr))
    
        return result
    
    return f



### EXAMPLES

@ringatend
@inmusic
def myLongFunction():
        for i in range(100000):
            print "I'm the world's most useless function !"

myLongFunction()

@popupatend
def myLongFunction():
        for i in range(100000):
            print "I'm the most useless function !"

myLongFunction()

If you want to go further with the decorators, here are versions of the decorators with options that let you choose the sound or music you want to be played.



def ringatend2(soundFile):
    """ a decorator generator using a specified soundfile """
        
    def decorator(target):
        """ a decorator using the specified soundfile """
        
        def f(*args,**kwargs):
            
            result = target(*args,**kwargs)
            ring(soundFile)
            return result
            
        return f
    
    return decorator

def inmusic2(soundFile):
    """ a decorator generator using a specified soundfile """
        
    def decorator(target):
        """ a decorator to play your functions in music """
                
        def f(*args,**kwargs):
            
            pygame.mixer.init()
            sound = pygame.mixer.Sound(soundFile)
            sound.play()
            result = target(*args,**kwargs)
            sound.stop()
            pygame.mixer.quit()
            return result
                
        return f
    
    return decorator


### EXAMPLES

@ringatend2('./tarzan.wav')
@inmusic2('./diesIrae.wav')
def myLongFunction():
        for i in range(10000):
            print "The world's most useless function !"