<commit_before>"""
Package contains interfaces for using existing functionality in other packages

Exaples  FSL, matlab/SPM , afni

Requires Packages to be installed
"""

import os
import subprocess
from copy import deepcopy
from string import Template

__docformat__ = 'restructuredtext'


def load_template(name):
    """Load a template from the script_templates directory

    Parameters
    ----------
      name : str
        The name of the file to load

    Returns
    -------
      template : string.Template

    """

    full_fname = os.path.join(os.path.dirname(__file__),
                              'script_templates', name)
    template_file = open(full_fname)
    template = Template(template_file.read())
    template_file.close()
    return template

class Bunch(object):
    """ Provide Elegant attribute access

    (Also provide inelegant dict-style access to make Satra's life easier)

    Notes
    -----
    
    The Bunch pattern came from the Python Cookbook:
    .. [1] <NAME>, <NAME>, "Collecting a Bunch of Named
    Items", Python Cookbook, 2nd Ed, Chapter 4.18, 2005.

    """
    def __init__(self, **kwargs):
        self.__dict__.update(**kwargs)

    def update(self, **kwargs):
        self.__dict__.update(**kwargs)

    def iteritems(self):
        return self.__dict__.iteritems()

    def get(self, *args):
        '''Need to consider how much of the dict interface we will support'''
        return self.__dict__.get(*args)

    def __setitem__(self, key, value):
        '''deprecated, except for Satra'''
        self.__dict__[key] = value

    def __getitem__(self, key):
        '''deprecated, except for Satra'''
        return(self.__dict__[key])

    def dictcopy(self):
        return deepcopy(self.__dict__)

    def dict2str(self, anydict):
        # Converts a dict to an ordered representation
        outstr = '{'
        for f in sorted(anydict):
            if type(anydict[f]) is not type({}):
                outstr = ''.join((outstr,str(f), ':', str(anydict[f]),',\n'))
            else:
                outstr = ''.join((outstr,str(f), ':', 
                                  self.dict2str(anydict[f]),',\n'))
        outstr = ''.join((outstr,'}'))
        return outstr

    def __str__(self):
        return self.dict2str(self.__dict__)

    def __repr__(self):
        outstr = 'Bunch('
        pairs = []
        for k, v in self.iteritems():
            pairs.append('%s=%s, ' % (k, v))
        outstr += ''.join(pairs)
        outstr += ')'
        return outstr

class InterfaceResult(object):
    '''Describe the results of .run()-ing a particular Interface'''
    def __init__(self, interface, runtime, outputs):
        self.interface = interface
        self.runtime = runtime
        self.outputs = outputs


class Interface(object):
    """This is the template for Interface objects.

    It provides no functionality.  It defines the necessary attributes
    and methods all Interface objects should have.

    Everything in inputs should also be a possible (explicit?) argument to
    .__init__()
    """

    def __init__(self, *args, **inputs):
        """Initialize command with given args and inputs."""
        raise NotImplementedError

    def run(self):
        """Execute the command."""
        raise NotImplementedError

    def _runner(self):
        """Performs the call to execute the command."""
        raise NotImplementedError

    def _populate_inputs(self):
        """Initialize the inputs attribute."""
        raise NotImplementedError

    def _compile_command(self):
        """Generate the command line string from the list of arguments."""
        raise NotImplementedError
    
    def _aggregate_ouputs(self):
        """Called to populate outputs"""
        raise NotImplementedError


class CommandLine(Interface):
    """Encapsulate a command-line function along with the arguments and options.

    Provides a convenient mechanism to build a command line with it's
    arguments and options incrementally.  A `CommandLine` object can
    be reused, and it's arguments and options updated.  The
    `CommandLine` class is the base class for all nipype.interfaces
    classes.

    Parameters
    ----------
    args : string
        A string representing the command and it's arguments.
    inputs : mapping


    Attributes
    ----------
    args : tuple
        The command, it's arguments and options store in a tuple of strings.

    Returns
    -------
    
    cmd : CommandLine
        A `CommandLine` object that can be run and/or updated.

    Examples
    --------

    >>> lscmd = CommandLine('ls') # Create a command object
    >>> output = lscmd.run() # Execute the command
    >>> output.out # Get output from the command
    >>> output.err # Get error from command, if any

    # You could also pass in args like this
    >>> lscmd = CommandLine('ls', '-l', '-t')
    # Or
    >>> lscmd = CommandLine('ls -l -t')
    # Or
    >>> lscmd = CommandLine(args=['ls','-l'])

    # One way to view your stdout is to print
    >>> print output.runtime.messages
    >>> output.runtime.returncode
    >>> print output.runtime.errmessages

    Notes
    -----
    
    When subclassing CommandLine, you will generally override at least:
        _compile_command

    Also quite possibly __init__ but generally not run or _runner

    """

    def __init__(self, *args, **inputs):
        self._populate_inputs()
        self.inputs.update(**inputs)
        if args:
            self.inputs.args = args
        self.cmdline = ''

    def run(self):
        """Execute the command.
        
        Parameters
        ----------
        N/A
        
        Returns
        -------
        results : Bunch
            A `Bunch` object with a copy of self in `interface`
        
        """

        # This is expected to populate `command` for _runner to work
        self._compile_command()
        returncode, out, err = self._runner(cwd=self.inputs.get('cwd', None))
        runtime = Bunch(returncode=returncode,
                        messages=out,
                        errmessages=err)

        return InterfaceResult(deepcopy(self), runtime, outputs=None)

    def _populate_inputs(self):
        self.inputs = Bunch(args=None)

    def _compile_command(self):
        # This handles args like ['bet', '-f 0.2'] without crashing
        self.cmdline = ' '.join(self.inputs.args)

    def _runner(self, shell=True, cwd=None):
        """Run the command using subprocess.Popen."""
        proc  = subprocess.Popen(self.cmdline,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 shell=shell,
                                 cwd=cwd)
        out, err = proc.communicate()
        returncode = proc.returncode
        return returncode, out, err

    def get_input_info(self):
        """ Provides information about file inputs to copy or link to cwd.
        
        Notes
        -----
        see `spm.Realign.get_input_info`
            
        """
        return []

<commit_msg>changed Bunch in interfaces.base to use __repr__ instead of dict2str to return a string representation of sorted Bunch<commit_after>"""
Package contains interfaces for using existing functionality in other packages

Exaples  FSL, matlab/SPM , afni

Requires Packages to be installed
"""

import os
import subprocess
from copy import deepcopy
from string import Template

__docformat__ = 'restructuredtext'


def load_template(name):
    """Load a template from the script_templates directory

    Parameters
    ----------
      name : str
        The name of the file to load

    Returns
    -------
      template : string.Template

    """

    full_fname = os.path.join(os.path.dirname(__file__),
                              'script_templates', name)
    template_file = open(full_fname)
    template = Template(template_file.read())
    template_file.close()
    return template

class Bunch(object):
    """ Provide Elegant attribute access

    (Also provide inelegant dict-style access to make Satra's life easier)

    Notes
    -----
    
    The Bunch pattern came from the Python Cookbook:
    .. [1] <NAME>, <NAME>, "Collecting a Bunch of Named
    Items", Python Cookbook, 2nd Ed, Chapter 4.18, 2005.

    """
    def __init__(self, **kwargs):
        self.__dict__.update(**kwargs)

    def update(self, **kwargs):
        self.__dict__.update(**kwargs)

    def iteritems(self):
        return self.__dict__.iteritems()

    def get(self, *args):
        '''Need to consider how much of the dict interface we will support'''
        return self.__dict__.get(*args)

    def __setitem__(self, key, value):
        '''deprecated, except for Satra'''
        self.__dict__[key] = value

    def __getitem__(self, key):
        '''deprecated, except for Satra'''
        return(self.__dict__[key])

    def dictcopy(self):
        return deepcopy(self.__dict__)


    def __repr__(self):
        outstr = 'Bunch('
        pairs = []
        for k, v in sorted(self.iteritems()):
            pairs.append('%s=%s, ' % (k, v))
        outstr += ''.join(pairs)
        outstr += ')'
        return outstr

class InterfaceResult(object):
    '''Describe the results of .run()-ing a particular Interface'''
    def __init__(self, interface, runtime, outputs):
        self.interface = interface
        self.runtime = runtime
        self.outputs = outputs


class Interface(object):
    """This is the template for Interface objects.

    It provides no functionality.  It defines the necessary attributes
    and methods all Interface objects should have.

    Everything in inputs should also be a possible (explicit?) argument to
    .__init__()
    """

    def __init__(self, *args, **inputs):
        """Initialize command with given args and inputs."""
        raise NotImplementedError

    def run(self):
        """Execute the command."""
        raise NotImplementedError

    def _runner(self):
        """Performs the call to execute the command."""
        raise NotImplementedError

    def _populate_inputs(self):
        """Initialize the inputs attribute."""
        raise NotImplementedError

    def _compile_command(self):
        """Generate the command line string from the list of arguments."""
        raise NotImplementedError
    
    def _aggregate_ouputs(self):
        """Called to populate outputs"""
        raise NotImplementedError


class CommandLine(Interface):
    """Encapsulate a command-line function along with the arguments and options.

    Provides a convenient mechanism to build a command line with it's
    arguments and options incrementally.  A `CommandLine` object can
    be reused, and it's arguments and options updated.  The
    `CommandLine` class is the base class for all nipype.interfaces
    classes.

    Parameters
    ----------
    args : string
        A string representing the command and it's arguments.
    inputs : mapping


    Attributes
    ----------
    args : tuple
        The command, it's arguments and options store in a tuple of strings.

    Returns
    -------
    
    cmd : CommandLine
        A `CommandLine` object that can be run and/or updated.

    Examples
    --------

    >>> lscmd = CommandLine('ls') # Create a command object
    >>> output = lscmd.run() # Execute the command
    >>> output.out # Get output from the command
    >>> output.err # Get error from command, if any

    # You could also pass in args like this
    >>> lscmd = CommandLine('ls', '-l', '-t')
    # Or
    >>> lscmd = CommandLine('ls -l -t')
    # Or
    >>> lscmd = CommandLine(args=['ls','-l'])

    # One way to view your stdout is to print
    >>> print output.runtime.messages
    >>> output.runtime.returncode
    >>> print output.runtime.errmessages

    Notes
    -----
    
    When subclassing CommandLine, you will generally override at least:
        _compile_command

    Also quite possibly __init__ but generally not run or _runner

    """

    def __init__(self, *args, **inputs):
        self._populate_inputs()
        self.inputs.update(**inputs)
        if args:
            self.inputs.args = args
        self.cmdline = ''

    def run(self):
        """Execute the command.
        
        Parameters
        ----------
        N/A
        
        Returns
        -------
        results : Bunch
            A `Bunch` object with a copy of self in `interface`
        
        """

        # This is expected to populate `command` for _runner to work
        self._compile_command()
        returncode, out, err = self._runner(cwd=self.inputs.get('cwd', None))
        runtime = Bunch(returncode=returncode,
                        messages=out,
                        errmessages=err)

        return InterfaceResult(deepcopy(self), runtime, outputs=None)

    def _populate_inputs(self):
        self.inputs = Bunch(args=None)

    def _compile_command(self):
        # This handles args like ['bet', '-f 0.2'] without crashing
        self.cmdline = ' '.join(self.inputs.args)

    def _runner(self, shell=True, cwd=None):
        """Run the command using subprocess.Popen."""
        proc  = subprocess.Popen(self.cmdline,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 shell=shell,
                                 cwd=cwd)
        out, err = proc.communicate()
        returncode = proc.returncode
        return returncode, out, err

    def get_input_info(self):
        """ Provides information about file inputs to copy or link to cwd.
        
        Notes
        -----
        see `spm.Realign.get_input_info`
            
        """
        return []


{'fraction_non_alphanumeric': 0.10646636185499674, 'fraction_numerical': 0.0018869293852964656, 'mean_word_length': 2.1204710144927534, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3363307', 'n_tokens_mistral': 3809, 'n_tokens_neox': 3651, 'n_words': 1210}