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 !"