'''
Created on 2015-03-27

@author: Ian McDowell (sortof, not really)
'''
import re
import os

# The following routine ---taken from 
# http://stackoverflow.com/questions/11130156/suppress-stdout-stderr-print-from-python-functions,
# ---is used to suppress a series of unnecessary warnings that are issued 
# when a deepcopy is made of a GPy model object. Despite the warnings, all attributes necessary
# to the present algorithm are indeed copied.

class suppress_stdout_stderr(object):
    '''
    A context manager for doing a "deep suppression" of stdout and stderr in 
    Python, i.e. will suppress all print, even if the print originates in a 
    compiled C/Fortran sub-function.
       This will not suppress raised exceptions, since exceptions are printed
    to stderr just before a script exits, and after the context manager has
    exited (at least, I think that is why it lets exceptions through).      
    
    '''
    def __init__(self):
        # Open a pair of null files
        self.null_fds =  [os.open(os.devnull,os.O_RDWR) for x in range(2)]
        # Save the actual stdout (1) and stderr (2) file descriptors.
        self.save_fds = (os.dup(1), os.dup(2))
    
    def __enter__(self):
        # Assign the null pointers to stdout and stderr.
        os.dup2(self.null_fds[0],1)
        os.dup2(self.null_fds[1],2)
    
    def __exit__(self, *_):
        # Re-assign the real stdout/stderr back to (1) and (2)
        os.dup2(self.save_fds[0],1)
        os.dup2(self.save_fds[1],2)
        # Close the null files
        os.close(self.null_fds[0])
        os.close(self.null_fds[1])

def sorted_nicely( l ): 
    """ 
    Sort the given iterable in the way that humans expect, e.g. 'gene1' before 'gene10'.
    from http://stackoverflow.com/questions/5491913/sorting-list-in-python
    """ 
    convert = lambda text: int(text) if text.isdigit() else text 
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] 
    return sorted(l, key = alphanum_key)
