Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
yuya-takeyama committed Aug 7, 2015
0 parents commit 52e9bb9
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/build
/percentile
/pkg
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# percentile

Show percentile of input numbers.

## Installation

```
$ go get github.com/yuya-takeyama/percentile
```

## Usage

```
$ seq 100 | percentile
50%: 50
66%: 66
75%: 75
80%: 80
90%: 90
95%: 95
98%: 98
99%: 99
100%: 100
```

## License

The MIT License

## Author

Yuya Takeyama
97 changes: 97 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package main

import (
"bufio"
"fmt"
"io"
"os"
"sort"
"strconv"

flags "github.com/jessevdk/go-flags"
"github.com/yuya-takeyama/argf"
)

const AppName = "numstat"

type Options struct {
ShowVersion bool `short:"v" long:"version" description:"Show version"`
}

var opts Options

var numbers sort.Float64Slice

func main() {
parser := flags.NewParser(&opts, flags.Default^flags.PrintErrors)
parser.Name = AppName
parser.Usage = "[OPTIONS] FILES..."

args, err := parser.Parse()
if err != nil {
fmt.Fprint(os.Stderr, err)
return
}

r, err := argf.From(args)
if err != nil {
panic(err)
}

err = percentile(r, os.Stdout, os.Stderr, opts)
if err != nil {
panic(err)
}
}

func percentile(r io.Reader, stdout io.Writer, stderr io.Writer, opts Options) error {
if opts.ShowVersion {
io.WriteString(stdout, fmt.Sprintf("%s v%s, build %s\n", AppName, Version, GitCommit))
return nil
}

reader := bufio.NewReader(r)
var line []byte
var err error
for {
if line, _, err = reader.ReadLine(); err == io.EOF {
break
} else if err != nil {
panic(err)
}

f, convErr := strconv.ParseFloat(string(line), 64)
if convErr != nil {
fmt.Fprintf(stderr, "number conversion error: %s\n", convErr)
continue
}

numbers = append(numbers, f)
}

sort.Sort(numbers)
l := len(numbers)

printPercentileN(stdout, &numbers, l, 50)
printPercentileN(stdout, &numbers, l, 66)
printPercentileN(stdout, &numbers, l, 75)
printPercentileN(stdout, &numbers, l, 80)
printPercentileN(stdout, &numbers, l, 90)
printPercentileN(stdout, &numbers, l, 95)
printPercentileN(stdout, &numbers, l, 98)
printPercentileN(stdout, &numbers, l, 99)
printPercentileN(stdout, &numbers, l, 100)

return nil
}

func percentileN(numbers *sort.Float64Slice, l, n int) float64 {
i := l*n/100 - 1
ns := *numbers

return ns[i]
}

func printPercentileN(w io.Writer, numbers *sort.Float64Slice, l, n int) {
fmt.Fprintf(w, "%d%%:\t%s\n", n, strconv.FormatFloat(percentileN(numbers, l, n), 'g', 16, 64))
}
1 change: 1 addition & 0 deletions release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ggallin release --os="linux darwin" --username=yuya-takeyama
5 changes: 5 additions & 0 deletions version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

const Version string = "0.0.1"

var GitCommit = ""

0 comments on commit 52e9bb9

Please sign in to comment.