package ledger import ( "bufio" "bytes" "io" "os" "strconv" ) type BPIs map[Currency]BPI type BPI map[string]float64 func NewBPIs(p string) (BPIs, error) { f, err := os.Open(p) if os.IsNotExist(err) { return nil, nil } if err != nil { return nil, err } defer f.Close() result := make(map[Currency]BPI) r := bufio.NewReader(f) for { line, err := readTransactionLine(r) if len(line) > 0 { fields := bytes.Fields(line) if len(fields) > 3 { date := string(fields[1]) currency := Currency(fields[len(fields)-2]) value, err := strconv.ParseFloat(string(fields[len(fields)-1][1:]), 64) if err != nil { return nil, err } if _, ok := result[currency]; !ok { result[currency] = make(BPI) } result[currency][date] = value } } if err == io.EOF { return result, nil } else if err != nil { return result, err } } } func (bpi BPI) Lookup(date string) float64 { var closestWithoutGoingOver string for k := range bpi { if k <= date && k > closestWithoutGoingOver { closestWithoutGoingOver = k } } if closestWithoutGoingOver == "" { return 0 } return bpi[closestWithoutGoingOver] }