#!/usr/bin/python -tt
#=======================================================================
#                        General Documentation

"""Define a class to create/manipulate a list of filenames.

   Many times the output of a climate model run is specified by a list 
   of filenames, each of which while unique nonetheless share 
   commonalities.  For instance, a list of netCDF history files may
   be:  [ha0001.nc, ha0002.nc, ha0003.nc, ...].  This module defines a 
   class that creates and manipulates such a list, given a set of 
   attributes that often characterize the output of climate model runs.

   Example:
   >>> import filelist
   >>> a = filelist.FileList([10, 13, 3], 'test', '.nc')
   >>> a.files
   ['test010.nc', 'test011.nc', 'test012.nc', 'test013.nc']
"""

#-----------------------------------------------------------------------
#                       Additional Documentation
#
# RCS Revision Code:
#   $Id: filelist.py,v 1.7 2003/04/30 22:50:00 jlin Exp $
#
# Modification History:
# - 30 Apr 2003:  Original by Johnny Lin, Computation Institute,
#   University of Chicago.  Email:  air_jlin@yahoo.com.  Passed
#   passably reasonable tests.
#
# Notes:
# - Written for Python 2.1.3.
# - No non-built-in packages and modules required.
#
# Copyright (c) 2003 by Johnny Lin.  For licensing, distribution 
# conditions, contact information, and additional documentation see
# the URL http://www.johnny-lin.com/pylib.html.
#=======================================================================




#---------------- Module General Import and Declarations ---------------

__all__ = ["FileList"]   #- List of methods and classes in this module


#- Define additional examples for doctest to use:

__test__ = { 'Additional Example 1':
    """
    >>> import filelist
    >>> seq_dims = [0, 7, 3, 2]    #- Dimensions of sequence
    >>> prefix = 'test'            #- Prefix for file list
    >>> suffix = '.txt'            #- Suffix for file list
    >>> a = filelist.FileList(seq_dims, prefix, suffix)
    >>> a.files
    ['test000.txt', 'test002.txt', 'test004.txt', 'test006.txt']
    >>> a.chg_suffix('.nc')
    >>> a.files
    ['test000.nc', 'test002.nc', 'test004.nc', 'test006.nc']
    >>> a.chg_prefix('ctrl')
    >>> a.files
    ['ctrl000.nc', 'ctrl002.nc', 'ctrl004.nc', 'ctrl006.nc']
    """ }




#------------ Class FileList:  Implementation of the Module ------------

class FileList:
    """Class FileList is the implementation of the module.

       Class attributes:
       * end:  Last value, inclusive (or less than this value, if
         stride would exceed end), in sequence (integer).
       * files:  The files list (this is the key output of the 
         class).
       * nchar:  Minimum number of characters in each element of 
	     sequence, including leading zeroes.  If nchar is 0, the 
	     width of each entry in sequence is just the numeral value 
	     itself (integer).
       * prefix:  Prefix to each member of the files list.
       * sequence:  String list of filenumbers.
       * start:  First value, inclusive, in sequence (integer).
       * stride:  Stride of sequence (integer, defaults to 1).
       * suffix:  Suffix to each member of the files list.
    """



#------------ FileList Function __init__:  Initialize Class ------------

    def __init__(self, in_dims, prefix, suffix):
        """Initialize/calculate all class attributes.

        Method Arguments:
        * in_dims:  List or tuple of these attributes:
          [start, end, nchar, [stride]].  Note stride is
          optional, and if left out that attribute is set 
          to 1.  Copied to local variable dims.
        * prefix:  Prefix to each member of the files list 
          (string).
        * suffix:  Suffix to each member of the files list 
          (string).
        """
        dims = list(in_dims)    #- Make copy of argument in_dims
        dims.append(1)          #- Way to make stride=1 if not in dims
        self.start  = dims[0]
        self.end    = dims[1]
        self.nchar  = dims[2]
        self.stride = dims[3]
        self.prefix = prefix
        self.suffix = suffix

        self.make_sequence()
        self.make_files()




#------------- FileList Function chg_prefix:  Change Prefix ------------

    def chg_prefix(self, prefix):
        """Change prefix in file list.

        Replaces the attribute prefix with the argument prefix
        and re-calculates the attribute files accordingly.

        Method Arguments:
        * prefix:  Prefix to each member of the files list 
          (string).
        """
        self.prefix = prefix
        self.make_files()




#------------- FileList Function chg_suffix:  Change Suffix ------------

    def chg_suffix(self, suffix):
        """Change suffix in file list.

        Replaces the attribute suffix with the argument suffix
        and re-calculates the attribute files accordingly.

        Method Arguments:
        * suffix:  Suffix to each member of the files list 
          (string).
        """
        self.suffix = suffix
        self.make_files()




#------------- FileList Function make_files:  Create Files -------------

    def make_files(self):
        """Create files.

        Given attributes prefix, suffix, and sequence, 
        calculates and returns file list as files attribute.
        """
        self.files = [ self.prefix + i + self.suffix  \
                       for i in self.sequence ]




#---------- FileList Function make_sequence:  Create Sequence ----------

    def make_sequence(self):
        """Create sequence.

        Given attributes start, end, stride, and nchar,
        calculates and returns string list of filenumbers
        as the attribute sequence.
        """
        seq_int = range(self.start, self.end+1, self.stride)
        self.sequence = ['%0*d' % (self.nchar, i) for i in seq_int]




#-------------------------- Main:  Test Module -------------------------

if __name__ == "__main__":
    """Test the module.

    Tests the examples in all the module documentation 
    strings, plus __test__.
    """
    import doctest, sys
    doctest.testmod(sys.modules[__name__])




# ===== end file =====
