/
rate.go
133 lines (116 loc) · 2.5 KB
/
rate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package rate
import (
"errors"
"fmt"
"github.com/coopernurse/gorp"
"math"
)
type (
Rate struct {
Id int64
ItemType int64
ItemId int64
Rate int64
Title string
Description string
Behind int64
Against int64
Abstained int64
Votes []Vote `db:"-"`
Wilson float64 `db:"-"`
}
Vote struct {
RateId int64
Value int64
UserId int64
}
)
func WilsonSum(sum, num int64) int64 {
if num == 0 {
return 0
}
Sum := float64(sum)
Num := float64(num)
behind := Num - ((Num - Sum) / 2)
z := 1.5 //1.96 = 97.50%; 3.715 = 99.99%; 2.326 = 99%;
phat := 1.0 * behind / Num
w := int64(((phat + (z * z / (2 * Num)) - z*math.Sqrt((phat*(1-phat)+z*z/(4*Num))/Num)) / (1 + z*z/Num)) * 100)
return w
}
func (r Rate) Create(Db *gorp.DbMap, itemType int64, itemId int64) Rate {
rn := r.GetRate(Db, itemType, itemId)
if rn.Id == 0 {
r.ItemId = itemId
r.ItemType = itemType
Db.Insert(&r)
}
return r
}
func (r Rate) GetRate(Db *gorp.DbMap, itemType int64, itemId int64) Rate {
if r.Id != 0 {
return r
}
Db.SelectOne(&r, "select * from Rate where ItemId = ? and ItemType = ?",
itemId, itemType)
r.Votes = r.GetVotes(Db)
return r
}
func (r Rate) GetRateById(Db *gorp.DbMap, id int64) Rate {
Db.SelectOne(&r, "select * from Rate where Id = ?", id)
if r.Id != 0 {
r.Votes = r.GetVotes(Db)
}
return r
}
func (r Rate) Vote(Db *gorp.DbMap, v string, u int64) (Rate, error) {
var el int64
if r.Id == 0 {
return Rate{}, errors.New("Rate not found")
}
r = r.GetRate(Db, r.ItemType, r.ItemId)
id, err := Db.SelectInt("select RateId from Vote where RateId = ? and"+
" UserId = ?", r.Id, u)
if err != nil {
return Rate{}, err
}
if id != 0 {
return Rate{}, errors.New("You have already voted")
}
switch v {
case "a":
el = -1
r.Against++
Db.Exec("update Rate set Against = Against+1 where Id = ?", r)
break
case "b":
el = 1
r.Behind++
Db.Exec("update Rate set Behind = Behind+1 where Id = ?", r)
break
default:
return Rate{}, errors.New("Vote election undefined")
}
r.Rate = WilsonSum(r.Behind-r.Against, r.Against+r.Behind)
vote := Vote{
RateId: r.Id,
Value: el,
UserId: u,
}
Db.Update(&r)
Db.Insert(&vote)
return r, nil
}
func (r Rate) String() string {
s := r.Behind - r.Against
if s != 0 {
return fmt.Sprintf("%+d", r.Behind-r.Against)
}
return fmt.Sprint(0)
}
func (r Rate) GetVotes(Db *gorp.DbMap) []Vote {
if r.Id == 0 {
return []Vote{}
}
Db.Select(&r.Votes, "select * from Vote where RateId = ?", r.Id)
return r.Votes
}