https://github.com/takecy/grouping
simple id grouping package in golang. Useful for AB testing.
https://github.com/takecy/grouping
abtesting golang
Last synced: about 2 months ago
JSON representation
simple id grouping package in golang. Useful for AB testing.
- Host: GitHub
- URL: https://github.com/takecy/grouping
- Owner: takecy
- License: mit
- Created: 2018-03-03T07:04:24.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-09-17T15:38:18.000Z (over 7 years ago)
- Last Synced: 2025-08-15T06:45:52.076Z (7 months ago)
- Topics: abtesting, golang
- Language: Go
- Homepage:
- Size: 16.6 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# grouping
`grouping` is simple id grouping package in golang. Useful for AB testing.

[](https://godoc.org/github.com/takecy/grouping)
[](https://goreportcard.com/report/github.com/takecy/grouping)
[](https://travis-ci.org/takecy/grouping)
## Overview
There are several elements to conduct the AB testing.
### Prepare
1. Define AB testing (Name, Rate etc...)
1. Grouping for IDs (e.g. Users)
### Per Request
1. Decide group of requested id
1. Separate out
1. Logging of result
1. Verification
1. Return to 1...
This package provides simple way of `Prepare` and `1. Decide group of id` (e.g. user) based on unique id in server-side.
### Non Goal
* Feature flag management
* Branch processing for groups
## Usage
### Basic usage
see [example](./example/simple/main.go)
```
package main
import (
"fmt"
"github.com/takecy/grouping"
)
// SimpleElem implements `grouping.Elementer`
type SimpleElem struct {
name string
ratio int
}
func (e *SimpleElem) GetName() string { return e.name }
func (e *SimpleElem) GetRatio() int { return e.ratio }
func (e *SimpleElem) SetRatio(r int) { e.ratio = r }
func main() {
group := grouping.GroupDefinition{
// case: A+B+C=100
Elems: []grouping.Elementer{
&SimpleElem{name: "group-A", ratio: 10},
&SimpleElem{name: "group-B", ratio: 20},
&SimpleElem{name: "group-C", ratio: 70},
},
}
g, err := grouping.New(group)
if err != nil {
panic(err)
}
//
// The same result will be obtained no matter how many times it is executed.
//
testName := "welcome_content_test"
userID1 := "user-001"
elem1, err := g.GetGroup(userID1, testName)
if err != nil {
panic(err)
}
fmt.Printf("elem1: %v\n", elem1.GetName()) // group-A
userID2 := "user-002"
elem2, err := g.GetGroup(userID2, testName)
if err != nil {
panic(err)
}
fmt.Printf("elem2: %v\n", elem2.GetName()) // group-C
}
```
### Advanced usage
#### Default specification
You can define groups with a total ratio less than 100.
In this case, You can specify `default` for cases not matches any group.
see [example](./example/default_elem/main.go)
```
group := grouping.GroupDefinition{
// this means 20% of all
Elems: []grouping.Elementer{
&SimpleElem{name: "group-A", ratio: 20},
},
// not match
DefaultElem: &SimpleElem{name: "group-default"},
}
g, err := grouping.New(group)
if err != nil {
panic(err)
}
```
#### Customize hash function
You can customize function for generate hash.
see [example](./example/hash_func/main.go)
```
group := grouping.GroupDefinition{
// case: A+B=100
Elems: []grouping.Elementer{
&SimpleElem{name: "group-A", ratio: 30},
&SimpleElem{name: "group-B", ratio: 70},
},
}
// replace hash function
hashFunc := func(seed string) uint32 {
return uint32(len(seed))
}
g, err := grouping.NewWithHashFunc(group, hashFunc)
if err != nil {
panic(err)
}
```
## LICENSE
[MIT](./LICENSE)