Example #1
0
    def stringify(self, record_or_index, fields=None, exclude=[]):
        """
        Return element, passed in as a record or index, as the string that
        would be output by the output() method.
        """

        record = record_or_index
        if type(record_or_index) != numpy.void:
            record = self[record_or_index]
            
        if fields is None: fields = [s[0] for s in self.spec]
        for skip_field in exclude:
            if skip_field in fields: fields.remove(skip_field)
        
        strings = []
        for field in fields:
            strings.append(self.field_spec[field][2] % record[field])
        return ' '.join(strings)
Example #2
0
    def output(self, indices=None, fields=None, exclude=[], rename=[],
               select_values=None, skip_values=None, 
               sort=None, reverse=False, sliced=None, unique=None,
               filename=None, append=False, fh=None, stringify=False,
               print_spec=None, print_header=None, line_space=0, delimiter=' '):
        """
        Print to screen, or file filename or file handle fh, the records
        given by indices (default all).

        File format is as follows --
        
        #fields symbol average_volume liquidity days min_close min_volume
        #types |S14 <f8 <f8 <i8 <f8 <f8
        #formats %-14s %9.0f %8.2f %3d %9.4f %9.0f
        AA+                 1190     0.08  31   56.0000       100
        ABL                 6415     0.09  48   12.8750       200

        fields:
        list of fields, to selectively print, in that order.

        exclude:
        list of fields to exclude from printing.

        rename:
        list of (field, new_name) pairs to rename fields in header of output

        sort:
        sort records by this field before printing.

        reverse:
        reverse records to be printed.

        sliced:
        select records based on this slice tuple.
        
        unique:
        print only the first occurrence for each unique value for this field.

        filename:
        print to this file.

        fh:
        print to this filehandle.

        stringify:
        return output as string.
        
        append:
        append to file if file already exists.
        
        print_spec:
        Whether to print a three-line header or not. Defaults to true if writing
        to a new file, false otherwise.

        print_header:
        Whether to print a one-line header or not. Defaults to true if printing
        to standard output, false otherwise.

        select_values:
        (<field>, set([str1, str2, ...])) where rows are to be printed only if
        the value for <field> is in [str1, str2, ...]
        
        skip_values:
        (<field>, set([str1, str2, ...])) where rows are to be printed only if
        the value for <field> is not in [str1, str2, ...]

        line_space:
        Print an empty line every these many lines.
        """

        if filename:
            mode = 'w'
            if append and os.path.exists(filename):
                mode = 'a'
            elif print_spec is None and print_header is None: print_spec = True
            if filename[-3:] == '.gz':
                if mode == 'a': raise AssertionError('Can not append to .gz file ' + filename)
                fh = gzip.open(filename, 'wb')
            else: fh = open(filename, mode)
        elif fh is None and print_header is None and print_spec is None:
            print_header = True

        if stringify:
            assert filename is None and fh is None, 'Too many output options.'
            fh = cStringIO.StringIO()
            
        field_format = dict([(field, spec[2]) \
                             for field, spec in self.field_spec.items()])
        if fields is None: fields = [s[0] for s in self.spec]
        elif numpy.isscalar(fields): fields = [fields]

        if exclude is not None:
            if numpy.isscalar(exclude): exclude = [exclude]
            for skip_field in exclude:
                if skip_field in fields: fields.remove(skip_field)

        if print_spec or print_header:
            print >>fh, self.header(fields=fields, spec=print_spec, rename=rename, delimiter=delimiter)

        if indices is None: records = self
        else: records = self[indices]        
        if sort is not None:
            srt_idx = arrays.argsort(records, order=sort, reverse=reverse)
            records = records[srt_idx]
        elif reverse: records = records[::-1]

        if sliced is not None:
            if numpy.isscalar(sliced): sliced = [sliced]
            records = records[slice(*sliced)]
            
        uniques = {}
        line_count = 0
        for record in records:
            if select_values and record[select_values[0]] not in select_values[1]: continue
            if skip_values and record[skip_values[0]] in skip_values[1]: continue
            if unique:
                if record[unique] in uniques: continue
                uniques[record[unique]] = True
                
            strings = []
            for field in fields:
                if record[field] == '': record[field] = '#NA'
                strings.append(field_format[field] % record[field])
            if line_space and line_count and line_count % line_space == 0: print ''
            print >>fh, delimiter.join(strings)
            line_count += 1

        if stringify: return fh.getvalue()
        if fh is not None: fh.flush()
        if filename: fh.close()