package main import ( "encoding/csv" "errors" "io" "io/fs" "io/ioutil" "log" "os" "regexp" "strconv" ) func readData(f *os.File) ([][]float64, error) { records := make([][]string, 0, 251) r := csv.NewReader(f) for { record, err := r.Read() if err == io.EOF { break } if err != nil { return nil, err } records = append(records, record) } data, err := parseRecords(records) if err != nil { return nil, err } return data, nil } func parseRecords(r [][]string) ([][]float64, error) { if len(r) == 0 { return nil, errors.New("ErrNoRecords") } // remove the header. r = r[1:] u := 0 y := 1 data := [][]float64{make([]float64, 0, len(r)), make([]float64, 0, len(r))} for _, uy := range r { fu, err := strconv.ParseFloat(uy[u], 64) if err != nil { return nil, err } fy, err := strconv.ParseFloat(uy[y], 64) if err != nil { return nil, err } data[u] = append(data[u], fu) data[y] = append(data[y], fy) } return data, nil } func readFile(s *string) ([][]float64, error) { f, err := os.Open(*s) if err != nil { return nil, err } defer f.Close() data, err := readData(f) if err != nil { return nil, err } return data, nil } // nolint: gocognit func saveStuff( meanU, meanY, varianceU, varianceY, cov float64, autocorrelationU, autocorrelationY, mutCorrelationUY, mutCorrelationYU, errVals []float64, theta, thetaT [][]float64, ) error { fFnames := map[string]float64{ "mean_u": meanU, "mean_y": meanY, "variance_u": varianceU, "variance_y": varianceY, "covariance_uy": cov, } sFnames := map[string][]float64{ "autocorrelation_u": autocorrelationU, "autocorrelation_y": autocorrelationY, "mutual_correlation_uy": mutCorrelationUY, "mutual_correlation_yu": mutCorrelationYU, "estimate_error": errVals, } smFnames := map[string][][]float64{ "theta": theta, "thetaT": theta, } prefix := "data/" suffix := ".txt" for k, v := range fFnames { f, err := os.Create(prefix + k + suffix) if err != nil { return err } defer f.Close() _, err = f.WriteString(strconv.FormatFloat(v, 'f', 64, 64)) if err != nil { return err } } suffix = ".csv" for k, v := range sFnames { f, err := os.Create(prefix + k + suffix) if err != nil { return err } defer f.Close() w := csv.NewWriter(f) s := recordsFromFloat64Slice(v) err = w.WriteAll(s) if err != nil { return err } } for k, v := range smFnames { if k == "thetaT" { for i := range thetaT { th := theta[i] f, err := os.Create(prefix + k + "_p" + strconv.Itoa(i) + suffix) if err != nil { return err } defer f.Close() w := csv.NewWriter(f) s := recordsFromFloat64Slice(th) err = w.WriteAll(s) if err != nil { return err } } } f, err := os.Create(prefix + k + suffix) if err != nil { return err } w := csv.NewWriter(f) s := recordsFromSliceFloat64Slice(v) err = w.WriteAll(s) if err != nil { return err } // since we need the file soon, close it now. err = f.Close() if err != nil { return err } { reread, err := ioutil.ReadFile(prefix + k + suffix) if err != nil { if errors.Is(err, fs.ErrNotExist) { log.Println("apparently this file has not been written yet") } return err } // remove double quotes. cleared := regexp.MustCompile(`("?;"|";"?)|"`).ReplaceAll(reread, []byte("${1}")) if err = ioutil.WriteFile(prefix+k+suffix, cleared, 0o600); err != nil { return err } } } return nil } func recordsFromFloat64Slice(f []float64) [][]string { s := make([][]string, 0, len(f)) for i := range f { tmp := strconv.FormatFloat(f[i], 'f', 64, 64) s = append(s, []string{tmp}) } return s } func recordsFromSliceFloat64Slice(f [][]float64) [][]string { s := make([][]string, 0, len(f)) for i := range f { row := "" for j := range f[i] { tmp := strconv.FormatFloat(f[i][j], 'f', 64, 64) if j == 0 { row += tmp } else { row += ", " + tmp } } s = append(s, []string{row}) } return s }