Skip to content

Commit c89ca02

Browse files
authored
Add Duels and Result's Strength and Advantage (#3)
1 parent d97d6cf commit c89ca02

File tree

4 files changed

+269
-107
lines changed

4 files changed

+269
-107
lines changed

.github/workflows/go.yml

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
name: Go
22
on: [push, pull_request]
33
jobs:
4-
54
build:
65
name: Build
76
runs-on: ${{ matrix.os }}
@@ -10,43 +9,40 @@ jobs:
109
os: [ubuntu-latest, macos-latest, windows-latest]
1110

1211
steps:
13-
14-
- name: Set up Go
15-
uses: actions/setup-go@v3
16-
with:
17-
go-version: 1.20.0-rc.1
18-
check-latest: true
19-
20-
- name: Checkout
21-
uses: actions/checkout@v1
22-
with:
23-
fetch-depth: 1
24-
25-
- name: Cache Go modules
26-
uses: actions/cache@v1
27-
with:
28-
path: ~/go/pkg/mod
29-
key: ${{ runner.os }}-build-${{ hashFiles('**/go.sum') }}
30-
restore-keys: |
31-
${{ runner.OS }}-build-${{ env.cache-name }}-
32-
${{ runner.OS }}-build-
33-
${{ runner.OS }}-
34-
35-
# TODO: Enable linter when Go 1.20 is supported
36-
# - name: Lint
37-
# uses: golangci/golangci-lint-action@v2
38-
# with:
39-
# version: v1.50.1
40-
# args: --timeout 10m
41-
42-
- name: Vet
43-
if: matrix.os == 'ubuntu-latest'
44-
run: go vet -v ./...
45-
46-
- name: Build
47-
env:
48-
CGO_ENABLED: 0
49-
run: go build -ldflags "-s -w" ./...
50-
51-
- name: Test
52-
run: go test -v -race ./...
12+
- name: Set up Go
13+
uses: actions/setup-go@v4
14+
with:
15+
go-version: "1.21"
16+
17+
- name: Checkout
18+
uses: actions/checkout@v1
19+
with:
20+
fetch-depth: 1
21+
22+
- name: Cache Go modules
23+
uses: actions/cache@v1
24+
with:
25+
path: ~/go/pkg/mod
26+
key: ${{ runner.os }}-build-${{ hashFiles('**/go.sum') }}
27+
restore-keys: |
28+
${{ runner.OS }}-build-${{ env.cache-name }}-
29+
${{ runner.OS }}-build-
30+
${{ runner.OS }}-
31+
32+
- name: Lint
33+
uses: golangci/golangci-lint-action@v2
34+
with:
35+
version: v1.54.2
36+
args: --timeout 10m
37+
38+
- name: Vet
39+
if: matrix.os == 'ubuntu-latest'
40+
run: go vet -v ./...
41+
42+
- name: Build
43+
env:
44+
CGO_ENABLED: 0
45+
run: go build -ldflags "-s -w" ./...
46+
47+
- name: Test
48+
run: go test -v -race ./...

README.md

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ This client implements all Direct API features.
3636
- Unvote
3737
- Get submitted ballot
3838
- Calculate results
39+
- Get voting choices' duels (pairwise comparisons)
3940

4041
## Examples
4142

@@ -52,48 +53,48 @@ import (
5253
)
5354

5455
func main() {
55-
client := directdecisions.NewClient("my-api-key", nil)
56+
client := directdecisions.NewClient("my-api-key", nil)
5657

57-
ctx := context.Background()
58+
ctx := context.Background()
5859

59-
v, err := client.Votings.Create(ctx, []string{"Margarita", "Pepperoni", "Capricciosa"})
60-
if err != nil {
61-
log.Fatal(err)
62-
}
60+
v, err := client.Votings.Create(ctx, []string{"Margarita", "Pepperoni", "Capricciosa"})
61+
if err != nil {
62+
log.Fatal(err)
63+
}
6364

64-
log.Printf("Created voting with ID %s", v.ID)
65+
log.Printf("Created voting with ID %s", v.ID)
6566

66-
if _, err := client.Votings.Vote(ctx, v.ID, "Leonardo", map[string]int{
67-
"Pepperoni": 1,
68-
"Margarita": 2,
69-
}); err != nil {
70-
log.Fatal(err)
71-
}
67+
if _, err := client.Votings.Vote(ctx, v.ID, "Leonardo", map[string]int{
68+
"Pepperoni": 1,
69+
"Margarita": 2,
70+
}); err != nil {
71+
log.Fatal(err)
72+
}
7273

73-
log.Printf("Leonardo Voted for Pepperoni in voting with ID %s", v.ID)
74+
log.Printf("Leonardo Voted for Pepperoni in voting with ID %s", v.ID)
7475

75-
if _, err := client.Votings.Vote(ctx, v.ID, "Michelangelo", map[string]int{
76-
"Capricciosa": 1,
77-
"Margarita": 2,
78-
"Pepperoni": 2,
79-
}); err != nil {
80-
log.Fatal(err)
81-
}
76+
if _, err := client.Votings.Vote(ctx, v.ID, "Michelangelo", map[string]int{
77+
"Capricciosa": 1,
78+
"Margarita": 2,
79+
"Pepperoni": 2,
80+
}); err != nil {
81+
log.Fatal(err)
82+
}
8283

83-
log.Printf("Michelangelo Voted for Capricciosa in voting with ID %s", v.ID)
84+
log.Printf("Michelangelo Voted for Capricciosa in voting with ID %s", v.ID)
8485

85-
results, tie, err := client.Votings.Results(ctx, v.ID)
86-
if err != nil {
87-
log.Fatal(err)
88-
}
86+
results, tie, err := client.Votings.Results(ctx, v.ID)
87+
if err != nil {
88+
log.Fatal(err)
89+
}
8990

90-
if tie {
91-
log.Printf("Voting with ID %s is tied", v.ID)
92-
} else {
93-
log.Printf("Voting with ID %s is not tied", v.ID)
94-
}
91+
if tie {
92+
log.Printf("Voting with ID %s is tied", v.ID)
93+
} else {
94+
log.Printf("Voting with ID %s is not tied", v.ID)
95+
}
9596

96-
log.Printf("Results for voting with ID %s: %v", v.ID, results)
97+
log.Printf("Results for voting with ID %s: %v", v.ID, results)
9798
}
9899
```
99100

@@ -110,21 +111,21 @@ import (
110111
)
111112

112113
func main() {
113-
client := directdecisions.NewClient("my-api-key", nil)
114-
115-
ctx := context.Background()
116-
117-
_, err := client.Votings.Create(ctx, []string{"Margarita", "Pepperoni", "Capricciosa"})
118-
if err != nil {
119-
if errors.Is(err, directdecisions.ErrHTTPStatusUnauthorized) {
120-
log.Fatal("Invalid API key")
121-
}
122-
if errors.Is(err, directdecisions.ErrChoiceTooLong) {
123-
log.Fatal("Some of the choices are too long")
124-
}
125-
// ...
126-
log.Fatal(err)
127-
}
114+
client := directdecisions.NewClient("my-api-key", nil)
115+
116+
ctx := context.Background()
117+
118+
_, err := client.Votings.Create(ctx, []string{"Margarita", "Pepperoni", "Capricciosa"})
119+
if err != nil {
120+
if errors.Is(err, directdecisions.ErrHTTPStatusUnauthorized) {
121+
log.Fatal("Invalid API key")
122+
}
123+
if errors.Is(err, directdecisions.ErrChoiceTooLong) {
124+
log.Fatal("Some of the choices are too long")
125+
}
126+
// ...
127+
log.Fatal(err)
128+
}
128129
}
129130
```
130131

votings.go

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,31 +107,43 @@ type Result struct {
107107
Index int
108108
Wins int
109109
Percentage float64
110+
Strength int
111+
Advantage int
110112
}
111113

112-
func (s *VotingsService) Results(ctx context.Context, votingID string) (results []Result, tie bool, err error) {
113-
114-
type votingResultAPIResponse struct {
115-
Choice string `json:"choice"`
116-
Index int `json:"index"`
117-
Wins int `json:"wins"`
118-
Percentage float64 `json:"percentage"`
119-
}
114+
type computeResultsAPIResponse struct {
115+
Results []Result `json:"results"`
116+
Tie bool `json:"tie"`
117+
Duels []Duel `json:"duels"`
118+
}
120119

121-
type computeResultsAPIResponse struct {
122-
Results []votingResultAPIResponse `json:"results"`
123-
Tie bool `json:"tie"`
124-
}
120+
func (s *VotingsService) Results(ctx context.Context, votingID string) (results []Result, tie bool, err error) {
125121

126122
var response *computeResultsAPIResponse
127123
if err = s.client.request(ctx, http.MethodGet, "v1/votings/"+url.PathEscape(votingID)+"/results", nil, &response); err != nil {
128124
return nil, false, err
129125
}
130126

131-
results = make([]Result, len(response.Results))
132-
for i, r := range response.Results {
133-
results[i] = Result(r)
127+
return response.Results, response.Tie, nil
128+
}
129+
130+
type Duel struct {
131+
Left ChoiceStrength
132+
Right ChoiceStrength
133+
}
134+
135+
type ChoiceStrength struct {
136+
Choice string
137+
Index int
138+
Strength int
139+
}
140+
141+
func (s *VotingsService) Duels(ctx context.Context, votingID string) (results []Result, duels []Duel, tie bool, err error) {
142+
143+
var response *computeResultsAPIResponse
144+
if err = s.client.request(ctx, http.MethodGet, "v1/votings/"+url.PathEscape(votingID)+"/results/duels", nil, &response); err != nil {
145+
return nil, nil, false, err
134146
}
135147

136-
return results, response.Tie, nil
148+
return response.Results, response.Duels, response.Tie, nil
137149
}

0 commit comments

Comments
 (0)