From 037d0a5efc8e13c3cfdc7fdae5275149b3b38f4d Mon Sep 17 00:00:00 2001 From: bel Date: Fri, 27 Oct 2023 08:55:45 -0600 Subject: [PATCH] fixed get contributions --- ana/prediction_test.go | 6 ++--- ana/predictor.go | 59 +++++++++++++++++++++++------------------- ana/predictor_test.go | 24 ++++++----------- 3 files changed, 43 insertions(+), 46 deletions(-) diff --git a/ana/prediction_test.go b/ana/prediction_test.go index 61a9db7..014792e 100644 --- a/ana/prediction_test.go +++ b/ana/prediction_test.go @@ -72,7 +72,7 @@ func TestPredictionPredict(t *testing.T) { "2001-01": ledger.Balances{"X": ledger.Balance{"X": 100}}, // too old "2001-02": ledger.Balances{"X": ledger.Balance{"X": 10000}}, // too old monthsAgo2: ledger.Balances{"X": ledger.Balance{"X": 100}}, - monthsAgo1: ledger.Balances{"X": ledger.Balance{"X": 600}}, // +500 once in 6 months + monthsAgo1: ledger.Balances{"X": ledger.Balance{"X": 700}}, // +600 once in 6 months }), }, given: ledger.Balances{"X": ledger.Balance{"X": 5}}, @@ -90,7 +90,7 @@ func TestPredictionPredict(t *testing.T) { NewInterestPredictor("X", "X", 12), NewContributionPredictor(ledger.Register{ monthsAgo2: ledger.Balances{"X": ledger.Balance{"X": 100}}, - monthsAgo1: ledger.Balances{"X": ledger.Balance{"X": 600}}, + monthsAgo1: ledger.Balances{"X": ledger.Balance{"X": 700}}, }), }, given: ledger.Balances{"X": ledger.Balance{"X": 5}}, @@ -100,7 +100,7 @@ func TestPredictionPredict(t *testing.T) { prediction: Prediction{ NewContributionPredictor(ledger.Register{ monthsAgo2: ledger.Balances{"X": ledger.Balance{"X": 100}}, - monthsAgo1: ledger.Balances{"X": ledger.Balance{"X": 600}}, + monthsAgo1: ledger.Balances{"X": ledger.Balance{"X": 700}}, }), NewInterestPredictor("X", "X", 12), }, diff --git a/ana/predictor.go b/ana/predictor.go index 34617a8..e744222 100644 --- a/ana/predictor.go +++ b/ana/predictor.go @@ -1,7 +1,6 @@ package ana import ( - "log" "maps" "math" "regexp" @@ -44,11 +43,6 @@ func NewContributionPredictor(reg ledger.Register) Predictor { } func newContributionPredictor(monthlyRate map[string]ledger.Balance) Predictor { - for name, balance := range monthlyRate { - for curr, v := range balance { - log.Printf("%s/%s gains %.2f per month", name, curr, v) - } - } return func(given ledger.Balances, delta time.Duration) ledger.Balances { month := time.Hour * 24 * 365 / 12 months := float64(delta) / float64(month) @@ -73,13 +67,13 @@ func getMonthlyContributionRates(reg ledger.Register) map[string]ledger.Balance contributions := getRecentContributions(reg, window) result := make(map[string]ledger.Balance) for name := range contributions { - result[name] = getMonthlyContributionRate(contributions[name], window) + result[name] = getMonthlyContributionRate(contributions[name], window, name) } return result } // TODO better than average -func getMonthlyContributionRate(contributions []ledger.Balance, window time.Duration) ledger.Balance { +func getMonthlyContributionRate(contributions []ledger.Balance, window time.Duration, name string) ledger.Balance { sumPerCurrency := map[ledger.Currency]float64{} for _, balance := range contributions { for currency, v := range balance { @@ -99,25 +93,36 @@ func getRecentContributions(reg ledger.Register, window time.Duration) map[strin func getContributions(reg ledger.Register) map[string][]ledger.Balance { contributions := make(map[string][]ledger.Balance) - for _, date := range reg.Dates() { - for name := range reg[date] { - contributions[name] = append(contributions[name], make(ledger.Balance)) - if len(contributions[name]) > 1 { - for k := range contributions[name][len(contributions[name])-2] { - contributions[name][len(contributions[name])-1][k] = 0 - } - } - balance := contributions[name][len(contributions[name])-1] - for currency, value := range reg[date][name] { - balance[currency] = value - } - if forName := contributions[name]; len(forName) > 1 { - lastBalance := forName[len(forName)-2] - for currency := range lastBalance { - balance[currency] -= lastBalance[currency] - } - } - } + for _, name := range reg.Names() { + contributions[name] = getContributionsFor(reg, name) } return contributions } + +func getContributionsFor(reg ledger.Register, name string) []ledger.Balance { + result := make([]ledger.Balance, 0) + var last ledger.Balance + for _, date := range reg.Dates() { + if _, ok := reg[date][name]; !ok { + continue + } + + if last == nil { + last = reg[date][name] + continue + } + + result = append(result, make(ledger.Balance)) + this := result[len(result)-1] + + for k, v := range last { + this[k] = -1 * v + } + for k, v := range reg[date][name] { + this[k] += v + } + + last = reg[date][name] + } + return result +} diff --git a/ana/predictor_test.go b/ana/predictor_test.go index bc5d66a..edd14a9 100644 --- a/ana/predictor_test.go +++ b/ana/predictor_test.go @@ -61,30 +61,22 @@ func TestGetContributions(t *testing.T) { if len(got) != 2 { t.Error(len(got)) } - if len(got["a"]) != 2 { + if len(got["a"]) != 1 { t.Error(len(got["a"])) - } else if len(got["a"][0]) != 1 { + } else if len(got["a"][0]) != 2 { t.Error(got["a"]) - } else if got["a"][0]["x"] != 1 { + } else if got["a"][0]["x"] != -1 { + t.Error(got["a"][0]) + } else if got["a"][0]["y"] != 1 { t.Error(got["a"][0]) - } else if len(got["a"][1]) != 2 { - t.Error(got["a"][1]) - } else if got["a"][1]["x"] != -1 { - t.Error(got["a"][1]) - } else if got["a"][1]["y"] != 1 { - t.Error(got["a"][1]) } - if len(got["b"]) != 2 { + if len(got["b"]) != 1 { t.Error(len(got["b"])) } else if len(got["b"][0]) != 1 { t.Error(got["b"]) - } else if got["b"][0]["z"] != 1 { + } else if got["b"][0]["z"] != 3 { t.Error(got["b"][0]) - } else if len(got["b"][1]) != 1 { - t.Error(got["b"]) - } else if got["b"][1]["z"] != 3 { - t.Error(got["b"][1]) } } @@ -94,7 +86,7 @@ func TestGetMonthlyContributionRate(t *testing.T) { ledger.Balance{"x": 4}, ledger.Balance{"y": 3}, } - got := getMonthlyContributionRate(input, time.Hour*24*365/4) + got := getMonthlyContributionRate(input, time.Hour*24*365/4, "") if len(got) != 2 { t.Error(got) }