package ana import ( "regexp" "slices" "strings" "gogs.inhome.blapointe.com/ana-ledger/src/ledger" ) type Normalizer struct { m map[string][]normalize } type normalize struct { startDate string factor float64 } func NewDefaultNormalizer() Normalizer { return NewNormalizer(). With("^Zach", "2025-09-01", 151). // turtle up With("^Zach", "2023-10-05", 139). // to turtle With("^Zach", "2021-12-30", 135). // at pluralsight With("^Zach", "2020-07-30", 120). // to pluralsight With("^Zach", "2019-07-16", 77). // at fedex With("^Zach", "2017-02-16", 49). // to fedex With("^Bel", "2025-10-01", 225). // render up With("^Bel", "2025-04-01", 214). // lc4 at render With("^Bel", "2023-12-05", 190). // to render With("^Bel", "2022-12-31", 154). // at q With("^Bel", "2022-06-30", 148). // at q With("^Bel", "2021-12-31", 122). // at q With("^Bel", "2020-12-31", 118). // at q With("^Bel", "2019-12-31", 111). // at q With("^Bel", "2018-12-31", 92). // at q With("^Bel", "2018-02-16", 86) // to q } func NewNormalizer() Normalizer { return Normalizer{ m: make(map[string][]normalize), } } func (n Normalizer) With(pattern, startDate string, factor float64) Normalizer { n.m[pattern] = append(n.m[pattern], normalize{startDate: startDate, factor: factor}) slices.SortFunc(n.m[pattern], func(a, b normalize) int { return -1 * strings.Compare(a.startDate, b.startDate) }) return n } func (n Normalizer) Normalize(deltas ledger.Deltas) ledger.Deltas { deltas = slices.Clone(deltas) patterns := []string{} for pattern := range n.m { patterns = append(patterns, pattern) } like := ledger.LikeName(strings.Join(patterns, "|")) for i, delta := range deltas { if !like(delta) { continue } deltas[i] = n.NormalizeDelta(delta) } return deltas } func (n Normalizer) NormalizeDelta(delta ledger.Delta) ledger.Delta { delta.Value /= n.NormalizeFactor(delta.Name, delta.Date) return delta } func (n Normalizer) NormalizeFactor(name, date string) float64 { for pattern := range n.m { if regexp.MustCompile(pattern).MatchString(name) { for _, normalize := range n.m[pattern] { if normalize.startDate < date { return normalize.factor } } } } return 1.0 }