carlos / todomvc-bakeoff Public

Clone
git clone https://amadan.net/carlos/todomvc-bakeoff

Plain git — no account needed to clone.

Download

Download this file

1package bakeoff
2
3import (
4 "encoding/json"
5 "fmt"
6 "sort"
7 "strings"
8)
9
10// MedianReadability combines several scorer replies: each score is the
11// median across replies, and the notes come from the reply whose overall
12// score is the median. Replies may wrap the JSON in a code fence.
13func MedianReadability(replies []string) (Readability, error) {
14 type reply struct {
15 Naming, Structure, Traceability, Errors, Comments, Overall float64
16 Notes string
17 }
18 var rs []reply
19 for _, s := range replies {
20 i, j := strings.Index(s, "{"), strings.LastIndex(s, "}")
21 if i < 0 || j < i {
22 return Readability{}, fmt.Errorf("no JSON object in reply %q", s)
23 }
24 var r reply
25 if err := json.Unmarshal([]byte(s[i:j+1]), &r); err != nil {
26 return Readability{}, err
27 }
28 rs = append(rs, r)
29 }
30 if len(rs) == 0 {
31 return Readability{}, fmt.Errorf("no replies")
32 }
33 med := func(get func(reply) float64) float64 {
34 v := make([]float64, len(rs))
35 for i, r := range rs {
36 v[i] = get(r)
37 }
38 return median(v)
39 }
40 out := Readability{
41 Naming: med(func(r reply) float64 { return r.Naming }),
42 Structure: med(func(r reply) float64 { return r.Structure }),
43 Traceability: med(func(r reply) float64 { return r.Traceability }),
44 Errors: med(func(r reply) float64 { return r.Errors }),
45 Comments: med(func(r reply) float64 { return r.Comments }),
46 Overall: med(func(r reply) float64 { return r.Overall }),
47 }
48 byOverall := append([]reply(nil), rs...)
49 sort.SliceStable(byOverall, func(i, j int) bool { return byOverall[i].Overall < byOverall[j].Overall })
50 out.Notes = byOverall[len(byOverall)/2].Notes
51 return out, nil
52}
53