67 lines
1.3 KiB
Go
67 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"fmt"
|
|
"io"
|
|
"sort"
|
|
"strconv"
|
|
)
|
|
|
|
type statsFunc func(data []float64) float64
|
|
|
|
func sum(data []float64) float64 {
|
|
sum := 0.0
|
|
for _, v := range data {
|
|
sum += v
|
|
}
|
|
return sum
|
|
}
|
|
|
|
func avg(data []float64) float64 {
|
|
return sum(data) / float64(len(data))
|
|
}
|
|
|
|
func min(data []float64) float64 {
|
|
sort.Float64s(data)
|
|
return data[0]
|
|
}
|
|
|
|
func max(data []float64) float64 {
|
|
sort.Float64s(data)
|
|
return data[len(data)-1]
|
|
}
|
|
|
|
func csv2float(r io.Reader, column int) ([]float64, error) {
|
|
cr := csv.NewReader(r)
|
|
// set this to reuse the same slice for each read
|
|
// operation to reduce the memory allocation
|
|
cr.ReuseRecord = true
|
|
if column < 1 {
|
|
return nil, fmt.Errorf("%w: please provide a valid column number", ErrInvalidColumn)
|
|
}
|
|
column--
|
|
var data []float64
|
|
for i := 0; ; i++ {
|
|
row, err := cr.Read()
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot read data from file: %w", err)
|
|
}
|
|
if i == 0 {
|
|
continue
|
|
}
|
|
if len(row) <= column {
|
|
return nil, fmt.Errorf("%w: File has only %d columns", ErrInvalidColumn, len(row))
|
|
}
|
|
v, err := strconv.ParseFloat(row[column], 64)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("%w: %s", ErrNotNumber, err)
|
|
}
|
|
data = append(data, v)
|
|
}
|
|
return data, nil
|
|
}
|