CSV spreadsheet files are suitable for storing tabular data in a relatively portable way.

The CSV format is flexible but somewhat ill-defined.

For present purposes, authors may assume that the data fields contain no commas, backslashes, or quotation marks.



Task

Read a CSV file, change some values and save the changes back to a file.

For this task we will use the following CSV file:

C1,C2,C3,C4,C5
1,5,9,13,17
2,6,10,14,18
3,7,11,15,19
4,8,12,16,20

Suggestions


 Show how to add a column, headed 'SUM', of the sums of the rows.
 If possible, illustrate the use of built-in or standard functions, methods, or libraries, that handle generic CSV files.



import io.{lines, PrintWriter}
 
data Table( header, rows )
 
def read( file ) =
  l = lines( file )
 
  def next = vector( l.next().split(',') )
 
  if l.isEmpty() then
    return Table( vector(), [] )
 
  header = next()
  rows = seq()
 
  while l.hasNext()
    rows += next()
 
  Table( header, rows.toList() )
 
def write( table, out ) =
  w = if out is String then PrintWriter( out ) else out
 
  w.println( table.header.mkString(',') )
 
  for r <- table.rows
    w.println( r.mkString(',') )
 
  if out is String
    w.close()
 
def updateRow( header, row, updates ) =
  r = dict( (header(i), row(i)) | i <- 0:header.length() )
  updates( r )
  vector( r(f) | f <- header )
 
def update( table, updates ) =		
  Table( table.header, (updateRow(table.header, r, updates) | r <- table.rows).toList() )
 
def addColumn( table, column, updates ) =
  Table( table.header + [column], (updateRow(table.header + [column], r + [null], updates) | r <- table.rows).toList() )
 
t = addColumn( read('test.csv'), 'SUM', r -> r('SUM') = sum(int(v) | (_, v) <- r if v != null) )
write( t, 'test_out.csv' )
write( t, System.out )