'Tries to determine the number of columns as well as those columns that
contain numerical values in the dataset.  A skip parameter is used
because various tabular data types reuse this function, and their data
type classes are responsible to determine how many invalid comment
lines should be skipped. Using None for skip will cause skip to be
zero, but the first line will be processed as a header. A
max_data_lines parameter is used because various tabular data types
reuse this function, and their data type classes are responsible to
determine how many data lines should be processed to ensure that the
non-optional metadata parameters are properly set; if used, optional
metadata parameters will be set to None, unless the entire file has
already been read. Using None for max_data_lines will process all data
lines.
Items of interest:
1. We treat \'overwrite\' as always True (we always want to set tabular metadata when called).
2. If a tabular file has no data, it will have one column of type \'str\'.
3. We used to check only the first 100 lines when setting metadata and this class\'s
set_peek() method read the entire file to determine the number of lines in the file.
Since metadata can now be processed on cluster nodes, we\'ve merged the line count portion
of the set_peek() processing here, and we now check the entire contents of the file.'

def set_meta(self, dataset, overwrite=True, skip=None, max_data_lines=100000, max_guess_type_data_lines=None, **kwd):

    requested_skip = skip
    if (skip is None):
        skip = 0
    column_type_set_order = ['int', 'float', 'list', 'str']
    default_column_type = column_type_set_order[(-1)]
    column_type_compare_order = list(column_type_set_order)
    column_type_compare_order.reverse()
    def type_overrules_type(column_type1, column_type2):
        if ((column_type1 is None) or (column_type1 == column_type2)):
            return False
        if (column_type2 is None):
            return True
        for column_type in column_type_compare_order:
            if (column_type1 == column_type):
                return True
            if (column_type2 == column_type):
                return False
        raise ValueError(('Tried    to    compare    unknown    column    types:    %s    and    %s' % (column_type1, column_type2)))
    def is_int(column_text):
        try:
            int(column_text)
            return True
        except:
            return False
    def is_float(column_text):
        try:
            float(column_text)
            return True
        except:
            if (column_text.strip().lower() == 'na'):
                return True
            return False
    def is_list(column_text):
        return (',' in column_text)
    def is_str(column_text):
        if (column_text == ''):
            return False
        return True
    is_column_type = {}
    for column_type in column_type_set_order:
        is_column_type[column_type] = locals()[('is_%s' % column_type)]
    def guess_column_type(column_text):
        for column_type in column_type_set_order:
            if is_column_type[column_type](column_text):
                return column_type
        return None
    data_lines = 0
    comment_lines = 0
    column_types = []
    first_line_column_types = [default_column_type]
    if dataset.has_data():
        with compression_utils.get_fileobj(dataset.file_name) as dataset_fh:
            i = 0
            while True:
                line = dataset_fh.readline()
                if (not line):
                    break
                line = line.rstrip('\r\n')
                if ((i < skip) or (not line) or line.startswith('#')):
                    comment_lines += 1
                else:
                    data_lines += 1
                    if ((max_guess_type_data_lines is None) or (data_lines <= max_guess_type_data_lines)):
                        fields = line.split(' DCTB ')
                        for (field_count, field) in enumerate(fields):
                            if (field_count >= len(column_types)):
                                column_types.append(None)
                            column_type = guess_column_type(field)
                            if type_overrules_type(column_type, column_types[field_count]):
                                column_types[field_count] = column_type
                    if ((i == 0) and (requested_skip is None)):
                        first_line_column_types = column_types
                        column_types = [None for col in first_line_column_types]
                if ((max_data_lines is not None) and (data_lines >= max_data_lines)):
                    if (dataset_fh.tell() != dataset.get_size()):
                        data_lines = None
                        comment_lines = None
                    break
                i += 1
    if (len(first_line_column_types) > len(column_types)):
        for column_type in first_line_column_types[len(column_types):]:
            column_types.append(column_type)
    for i in range(len(column_types)):
        if (column_types[i] is None):
            if ((len(first_line_column_types) <= i) or (first_line_column_types[i] is None)):
                column_types[i] = default_column_type
            else:
                column_types[i] = first_line_column_types[i]
    dataset.metadata.data_lines = data_lines
    dataset.metadata.comment_lines = comment_lines
    dataset.metadata.column_types = column_types
    dataset.metadata.columns = len(column_types)
    dataset.metadata.delimiter = ' DCTB '
