__author__ = 'stubbfel'
import csv
def readCSV(fileName):
    with open(fileName, newline='\n') as csvFile:
        reader = csv.reader(csvFile)
        csvTable = []
        for row in reader:
            csvTable.append(row)
        return csvTable

def writeCSV (fileName,table):
    with open(fileName, 'w', newline='\n') as csvFile:
        writer = csv.writer(csvFile)
        writer.writerows(table)

def aggrateRow(row,discardIndex):
    colCount = 0
    colSum = 0
    workcopy = row[:]
    if discardIndex >= 0:
        del workcopy[discardIndex]

    for col in workcopy:
        colCount += 1
        if is_number(col):
            colSum += float(col)
    return colSum / colCount

def aggrateCol(colIndex, table):
    rowCount = 0
    rowSum = 0

    for row in table:
        if colIndex < len(row):
            str = row[colIndex]
            if is_number(str):
                rowSum += float(str)
                rowCount += 1

    mean = rowSum / rowCount
    tmVar = 0
    for row in table:
        if colIndex < len(row):
            str = row[colIndex]
            if is_number(str):
                tmVar += (float(str)-mean)**2

    var = (tmVar / rowCount)**.5
    return mean, var

def aggrateCSVFile(files):
    for fileName in files:
        csvTable = readCSV(fileName)
        firstRow = False
        for row in csvTable:
            if firstRow:
                row.append(str(int(aggrateRow(row, 0))))
            else:
                row.append('Aggreate('+fileName+')')
                firstRow = True
        writeCSV('AG'+fileName,csvTable)

def mergeCSV(files, colIndex, outPutName):
    newTable = []
    for file in files:
        cvsTable = readCSV(file)
        newRow = []

        for row in cvsTable:
            newRow.append(row[colIndex])
        newTable.append(newRow)

    maxLen = 0
    for row in newTable:
        tmpLen = len(row)
        if tmpLen > maxLen:
            maxLen = tmpLen

    for row in newTable:
        diff = maxLen - len(row)
        for i in range(0, diff):
            row.append('0')

    zipNewTable  = []
    xindex = 0
    for x in zip(*newTable):
        if xindex == 0:
            zipNewTable.append(['time'])
        else:
            zipNewTable.append([str(xindex-1)])
        xindex += 1
        for y in x:
            zipNewTable[-1].append(y)

    for row in zipNewTable:
        print(row)
    writeCSV(outPutName,zipNewTable)

def calcNormRuntime(files, timecolIndex,outPutName, outPutName2):
    resultTable = [[]]
    scalTable = [[]]
    init = False
    tabledim = 0
    for file in files:
        inputTable = readCSV(file)

        if not init:
            timeheader = inputTable[0][timecolIndex]
            init = True
            tabledim = len(inputTable[0])-1
            for head in inputTable[0]:
                if timeheader != head:
                    resultTable[0].append("Norm"+head)
                    scalTable[0].append("Mean:"+head)
                    scalTable[0].append("Var:"+head)

        maxTime = int(inputTable[-1][timecolIndex])
        resultTable.append(['0']*tabledim)
        for row in inputTable:
            tmplist = all_indices('0',row)
            for index in tmplist:
                if resultTable[-1][index-1] == '0' or resultTable[-1][index-1] == '0.0':
                    resultTable[-1][index-1] = str(int(row[0])/maxTime)

        for index in range(0, len(resultTable[-1])):
            if not(float(resultTable[-1][index]) > 0):
                resultTable[-1][index] = '1'

    for row in resultTable:
            print(row)

    scalTable.append([])
    for colindex in range(0,tabledim):
        meanVar = aggrateCol(colindex, resultTable)
        scalTable[-1].append(str(meanVar[0]))
        scalTable[-1].append(str(meanVar[1]))

    for row in scalTable:
        print(row)

    writeCSV(outPutName,resultTable)
    writeCSV(outPutName2,scalTable)

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False
