# Part of DML (Digital Music Laboratory)
# Copyright 2014-2015 Samer Abdallah, University College London
 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

# -*- coding: utf-8 -*-
__author__="samer"

import csv
from warnings import warn

import sys
import time
def print_status(msg): sys.stderr.write(msg+'\n')

# call function for each row of a CSV that has ncols columns.
# A warning is printed if any rows have the wrong number of columns.
#
# csv_for_each : string, integer, (list(string) -> void) -> void
def csv_for_each(filename,ncols,f):
    badcount=0
    with open(filename,'rb') as csvfile:
        contents=csv.reader(csvfile, delimiter=',',quotechar='"')
        for row in contents:
            if len(row)==ncols: f(row)
            else: badcount += 1
    # if badcount>0: warn("Ignoring %d malformed rows in CSV file %s" % (badcount,filename))

# map f over list of rows from CSV to list of values
#
# csv_map_rows : string, integer, (list(string) -> A) -> list(A)
def csv_map_rows(filename,ncols,f):
    good=[]
    def append_row(row): good.append(f(row))
    csv_for_each(filename,ncols,append_row)
    return good

def id(x): return x


# returns selected columns of CSV, one list per column
#
# csv_columns : string, integer, list(integer) -> list(list(string))
def csv_columns(filename,ncols,columns):
    def getter(i): return lambda r:r[i]
    return csv_map_columns(filename,ncols,map(getter,columns))

# returns selected columns of CSV, one list per column, with
# a function supplied for converting one row of strings to a row of data
#
# csv_map_columns : string, integer, list(list(string)->A) -> list(list(A))
def csv_map_columns(filename,ncols,sels):
    ii=range(0,len(sels))
    data=[[] for i in ii]
    def append_columns(row):
        for i in ii: data[i].append(sels[i](row))
    csv_for_each(filename,ncols,append_columns)

    return data
