src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

report.go (1837B)


      1 package report
      2 
      3 import (
      4 	"sort"
      5 
      6 	"code.dwrz.net/src/pkg/dqs/entry"
      7 	"code.dwrz.net/src/pkg/dqs/stats"
      8 )
      9 
     10 type Recommendation struct {
     11 	Name   string
     12 	Points int
     13 }
     14 
     15 type Report struct {
     16 	BodyFat stats.Stats
     17 	DQS     stats.Stats
     18 	Entries []*entry.Entry
     19 	Weight  stats.Stats
     20 
     21 	Less []*Recommendation
     22 	More []*Recommendation
     23 }
     24 
     25 func New(entries []*entry.Entry) *Report {
     26 	var (
     27 		bf  = []stats.DateValue{}
     28 		dqs = []stats.DateValue{}
     29 		w   = []stats.DateValue{}
     30 
     31 		unclaimed = map[string]int{}
     32 		negative  = map[string]int{}
     33 	)
     34 	for _, e := range entries {
     35 		bf = append(bf, stats.DateValue{
     36 			Date:  e.Date,
     37 			Value: e.BodyFat,
     38 		})
     39 		dqs = append(dqs, stats.DateValue{
     40 			Date:  e.Date,
     41 			Value: e.Score(),
     42 		})
     43 		w = append(w, stats.DateValue{
     44 			Date:  e.Date,
     45 			Value: e.Weight,
     46 		})
     47 
     48 		// Iterate through high quality categories.
     49 		// Collect all unclaimed positive points.
     50 		// Collect all claimed negative points.
     51 		for _, c := range e.Categories {
     52 			for _, p := range c.Portions {
     53 				if p.Points > 0 && !p.Amount.Claimed() {
     54 					unclaimed[c.Name] += p.Points
     55 				}
     56 				if p.Points < 0 && p.Amount.Claimed() {
     57 					negative[c.Name] += p.Points
     58 				}
     59 			}
     60 		}
     61 	}
     62 
     63 	// Assemble the recommendations.
     64 	var more = []*Recommendation{}
     65 	var less = []*Recommendation{}
     66 	for name, points := range unclaimed {
     67 		more = append(more, &Recommendation{
     68 			Name:   name,
     69 			Points: points,
     70 		})
     71 	}
     72 	for name, points := range negative {
     73 		less = append(less, &Recommendation{
     74 			Name:   name,
     75 			Points: points,
     76 		})
     77 	}
     78 	sort.Slice(more, func(i, j int) bool {
     79 		return more[i].Points > more[j].Points
     80 	})
     81 	sort.Slice(less, func(i, j int) bool {
     82 		return less[i].Points < less[j].Points
     83 	})
     84 
     85 	return &Report{
     86 		BodyFat: stats.New(bf),
     87 		DQS:     stats.New(dqs),
     88 		Weight:  stats.New(w),
     89 		Entries: entries,
     90 
     91 		More: more,
     92 		Less: less,
     93 	}
     94 }