Template class and class design on concrete example xl2csv writer

Discussion in 'Python' started by Karim, Nov 23, 2011.

  1. Karim

    Karim Guest

    Hello All,

    I have the following code and I am quite satisfied with its design BUT I
    have the feeling I can do better.
    Basically the, main() execute the program (I did not put the parsing of
    arguments function). I am opening
    an Excel document and writing content in a CSV one w/ different format.
    The design is an abstract template
    class XLWriter, and derived 'Xl2Csv', 'Xl2Scsv', 'Xl2text' classes to
    write the correct ASCII DOCUMENT to correct format.
    The property hook method file_format is implement in these classes and
    return an object of type 'XlCsvFileFormat' or 'XlTabFileFormat'.
    It allows to put the right file extension and delimiter. These class are
    derived from standard csv.excel and csv.excel_tab.
    At last a Factory class MakeXlWriter has the job to create the correct
    writer.

    For now I did not add a strategy pattern which usually goes with the
    Template pattern.

    Except from that all better design or others critics will be welcome.


    Regards
    karim

    _______________________________________________________________________________________________________________________________________

    from __future__ import print_function

    import sys, os, argparse, csv, xlrd

    __all__ = ['main', 'Xl2CsvError', 'XLWriter', 'XlCsvFileFormat',
    'XlTabFileFormat', 'Xl2Csv', 'Xl2Scsv', 'Xl2text', 'MakeXlWriter']


    class Xl2CsvError(Exception):
    """The exception class to manage the internal program errors."""
    pass

    class XlWriter(object):
    """Abstract template class."""
    def __init__(self, xlfilename=None, sheets=None):
    """Initializer."""
    if self.__class__.__name__ == 'XlWriter':
    raise TypeError('Abstract template Class XlWriter could not
    be instanciated directly!')

    if not xlfilename:
    raise Xl2CsvError('Please provide a non empty file name!')
    else:
    self._source_name = xlfilename

    self._book = xlrd.open_workbook(xlfilename)

    if sheets is not None:
    if isinstance(sheets[0], int):
    self._selected_sheets =
    [self._book.sheet_by_index(sheetnum-1) for sheetnum in sheets]
    elif isinstance(sheets[0], str):
    try:
    self._selected_sheets =
    [self._book.sheet_by_name(sheetname) for sheetname in sheets]
    except xlrd.biffh.XLRDError, e:
    print('{0} in file document {1}'.format(e, xlfilename))
    sys.exit(1)
    else:
    raise Xl2CsvError('Sheets element type not recognized!')
    else:
    self._selected_sheets = self._book.sheets()

    def write(self):
    """The file extraction public method."""

    for sheet in self._selected_sheets:
    xlfilename = '{sheet}{ext}'.format(sheet=sheet.name,
    ext='.'+self.file_format.extension.lower())
    try:
    writer = csv.writer(open(xlfilename, 'wb'),
    delimiter=self.file_format.delimiter)
    print("Creating csv file '{file}' for sheet '{sheet}'
    contained in document {src} ...".format(
    sheet=sheet.name, file=xlfilename,
    src=self._source_name), end=' ')
    for row in xrange(sheet.nrows):
    writer.writerow(sheet.row_values(row))
    print('Done.')
    except csv.Error, e:
    print(e)
    return 1

    return 0

    @property
    def file_format(self):
    """Hook method. Need to implement in derived classes.

    Should return an XLAsciiFileFormat object to get file extension
    and inner delimiter.
    """
    pass

    class XlCsvFileFormat(csv.excel):
    """Add file extension to the usual properties of Excel-generated
    CSV files."""
    extension = 'CSV'

    class XlTabFileFormat(csv.excel_tab):
    """Add file extension to the usual properties of Excel-generated
    <TAB> delimited files."""
    extension = 'TXT'

    class Xl2Csv(XlWriter):
    @property
    def file_format(self):
    """Hook factory method"""
    return XlCsvFileFormat()

    class Xl2Scsv(XlWriter):
    @property
    def file_format(self):
    """Hook factory method"""
    _format = XlCsvFileFormat()
    _format.extension = 'SCSV'
    _format.delimiter = ';'
    return _format

    class Xl2Text(XlWriter):
    @property
    def file_format(self):
    """Hook factory method"""
    return XlTabFileFormat()

    class MakeXlWriter(object):
    """Factory class for XLWriter objects.
    """
    @staticmethod
    def make(xlfilename=None, sheets=None, extension='CSV'):
    if extension == "TXT":
    return Xl2Text(xlfilename=xlfilename, sheets=sheets)
    elif extension == "SCSV":
    return Xl2Scsv(xlfilename=xlfilename, sheets=sheets)
    elif extension == "CSV":
    return Xl2Csv(xlfilename=xlfilename, sheets=sheets)

    def main():
    """Main of this application"""
    args = _process_command_line()
    args.xl.close()
    writer = MakeXlWriter.make(xlfilename=args.xl.name,
    sheets=args.sheets, extension=args.ext)
    return writer.write()

    ___________________________________________________________________________________________________________________________
    Karim, Nov 23, 2011
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter the Swede

    JDOM simple concrete example

    Peter the Swede, Nov 12, 2003, in forum: Java
    Replies:
    1
    Views:
    497
    Christophe Vanfleteren
    Nov 12, 2003
  2. WideBoy
    Replies:
    0
    Views:
    471
    WideBoy
    Jan 4, 2006
  3. Wat
    Replies:
    2
    Views:
    593
    Cy Edmunds
    Dec 4, 2004
  4. DaVinci
    Replies:
    1
    Views:
    558
    Piotr Kobzda
    Oct 5, 2006
  5. Henri
    Replies:
    1
    Views:
    366
    Henri
    Jul 13, 2004
Loading...

Share This Page