diff hexagram-6ae12361157c/hexagram/tsv.py @ 0:1407e3634bcf draft default tip

Uploaded r11 from test tool shed.
author adam-novak
date Tue, 22 Oct 2013 14:17:59 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hexagram-6ae12361157c/hexagram/tsv.py	Tue Oct 22 14:17:59 2013 -0400
@@ -0,0 +1,109 @@
+#!/usr/bin/env python2.7
+# tsv.py: a module for writing TSV (tab-separated value) files
+"""
+This module defines two classes: a TsvWriter, which can be constructed on a
+stream to allow writing TSV data lines and #-delimited comments to that stream,
+and a TsvReader, which can be constructed on a stream and iterated over to
+obtain lists of the values from each non-comment line in the stream.
+
+TSV is most useful as the basis for other, more tightly specified file formats.
+
+"""
+
+class TsvWriter(object):
+    """
+    Represents a writer for tab-separated value files containing  #-delimited
+    comments.
+    
+    """
+    def __init__(self, stream):
+        """
+        Make a new TsvWriter for writing TSV data to the given stream.
+        """
+        
+        # This holds the stream
+        self.stream = stream
+    
+    
+    def line(self, *args):
+        """
+        Write the given values to the file, as a TSV line. Args holds a list of
+        all arguments passed. Any argument that stringifies to a string legal as
+        a TSV data item can be written.
+        
+        """
+        
+        self.list_line(args)
+        
+    
+    def list_line(self, line):
+        """
+        Write the given iterable of values (line) to the file as items on the 
+        same line. Any argument that stringifies to a string legal as a TSV data
+        item can be written.
+        
+        Does not copy the line or build a big string in memory.
+        """
+        
+        if len(line) == 0:
+            return
+        
+        self.stream.write(str(line[0]))
+        
+        for item in line[1:]:
+            self.stream.write("\t")
+            self.stream.write(str(item))
+        
+        self.stream.write("\n")
+        
+    def comment(self, text):
+        """
+        Write the given text as a TSV comment. text must be a string containing
+        no newlines.
+        
+        """
+        
+        self.stream.write("# {}\n".format(text))
+        
+    def close(self):
+        """
+        Close the underlying stream.
+        """
+        
+        self.stream.close()
+        
+class TsvReader(object):
+    """
+    Represents a reader for tab-separated value files. Skips over comments 
+    starting with #. Can be iterated over.
+    
+    Field values consisting of only whitespace are not allowed.
+    """
+    
+    def __init__(self, stream):
+        """
+        Make a new TsvReader to read from the given stream.
+        """
+        
+        self.stream = stream
+        
+    def __iter__(self):
+        """
+        Yields lists of all fields on each line, as strings, until all lines are
+        exhausted. Strips whitespace around field contents. 
+        """
+        
+        for line in self.stream:
+            line = line.strip()
+            if line == "" or line[0] == "#":
+                # Skip comments and empty lines
+                continue
+            
+            yield map(str.strip, line.split("\t"))
+            
+    def close(self):
+        """
+        Close the underlying stream.
+        """
+        
+        self.stream.close()