pcbr 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/lib/pcbr.rb +5 -4
- data/pcbr.gemspec +2 -2
- data/spec/_spec.rb +84 -11
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c9c0f6e6ebf91facae8f193b2d990e14d8ebda2
|
4
|
+
data.tar.gz: df06fdbfd408a51c0dd698c1086456fb7b39dcca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ece51e1255f4eb3e530206ec05aa9775d62853acad02179003237ea72f1905a5006f7a23195a1d43d0c0c357cd15ff8c852f2ec42168155d158a633f91a82e11
|
7
|
+
data.tar.gz: bfed2b1d0a291bdfc4e6301031f76a5182c9cf014aa58b9a4087c67f99424b89f88d61ce56431d47d6ee4950cbfbb81ec83a6853012169b448298fb49b92373d
|
data/README.md
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
# PCBR (Pairs
|
1
|
+
# PCBR (Pairs Comparison Based Rating)
|
2
2
|
|
3
3
|
Making ratings is fun. After applying my method several times I've decided to gemify it.
|
4
4
|
|
5
5
|
### Examples
|
6
6
|
|
7
|
-
|
7
|
+
See [`describe "examples" do` in specs](spec/_spec.rb).
|
8
8
|
|
9
9
|
### How it works
|
10
10
|
|
11
|
-
The first idea of rating items by one-to-one
|
11
|
+
The first idea of rating items by one-to-one comparison was about QuakeLive players in 2013 or so and it didn't work well. At that time I was thinking about tree data structure. Later in May 2015 I've realised that it's really about dots in n-dimensional space and sectors. Applying it to Reddit RSS made my feed 50% more interesting.
|
12
12
|
|
13
|
-
TODO:
|
13
|
+
TODO: describe/illustrate algorithm?
|
14
14
|
|
15
|
-
At the moment it's a "proof of concept"
|
15
|
+
At the moment it's a "proof of concept" -- it needs huge optimisations for lookups, maybe using trees.
|
16
16
|
|
17
17
|
### Installation
|
18
18
|
|
data/lib/pcbr.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
class PCBR
|
2
2
|
|
3
|
-
VERSION = "0.0.
|
3
|
+
VERSION = "0.0.2"
|
4
4
|
|
5
5
|
def initialize &block
|
6
6
|
@table = []
|
7
|
-
@callback = block ||
|
7
|
+
@callback = block || ->*_{[*_[0]]}
|
8
8
|
end
|
9
9
|
|
10
10
|
def size
|
@@ -14,7 +14,7 @@ class PCBR
|
|
14
14
|
def store key, *vector
|
15
15
|
vector = vector.empty? ? [key] : vector.first
|
16
16
|
score = @table.map do |item|
|
17
|
-
@callback[vector].zip(@callback[item[1]]).map do |a, b|
|
17
|
+
@callback[vector, key].zip(@callback[item[1], item[0]]).map do |a, b|
|
18
18
|
a <=> b
|
19
19
|
end.uniq.inject(0, :+).tap do |point|
|
20
20
|
item[2] -= point
|
@@ -28,7 +28,8 @@ class PCBR
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def sorted
|
31
|
-
|
31
|
+
# from the best to the worst
|
32
|
+
@table.sort_by.with_index{ |item, i| [-item.last, i] }.map(&:first)
|
32
33
|
end
|
33
34
|
|
34
35
|
def data
|
data/pcbr.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |spec|
|
|
3
3
|
spec.version = (require_relative "lib/pcbr"; PCBR::VERSION)
|
4
4
|
spec.author = "Victor Maslov"
|
5
5
|
spec.email = "nakilon@gmail.com"
|
6
|
-
spec.summary = "Pair
|
7
|
-
spec.description = "
|
6
|
+
spec.summary = "Pair Comparison Based Rating"
|
7
|
+
spec.description = "Making ratings is fun. After applying my method several times I've decided to gemify it."
|
8
8
|
spec.homepage = "https://github.com/Nakilon/pcbr"
|
9
9
|
spec.license = "MIT"
|
10
10
|
|
data/spec/_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative "../lib/pcbr"
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe "basic specs" do
|
4
4
|
|
5
5
|
example "#size" do
|
6
6
|
rating = PCBR.new
|
@@ -22,34 +22,107 @@ describe PCBR do
|
|
22
22
|
rating.store key, vector
|
23
23
|
end
|
24
24
|
expectation = {
|
25
|
-
|
25
|
+
2 => 5,
|
26
|
+
4 => 3,
|
26
27
|
1 => -1,
|
27
28
|
6 => -1,
|
28
29
|
5 => -1,
|
29
|
-
|
30
|
-
2 => 5,
|
30
|
+
3 => -5,
|
31
31
|
}.each do |item, score|
|
32
32
|
expect(rating.score(item)).to eq(score)
|
33
33
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
aggregate_failures do
|
35
|
+
expect(rating.sorted).to eq(expectation.keys)
|
36
|
+
expect(rating.scores).to eq(expectation )
|
37
|
+
expect(rating.data ).to eq(data )
|
38
|
+
end
|
37
39
|
end
|
38
40
|
|
39
41
|
example "&block" do
|
40
42
|
rating = PCBR.new do |item|
|
41
43
|
[item[:goodness], -item[:badness]]
|
42
44
|
end
|
43
|
-
rating.store 1, {goodness: 1, badness: 1}
|
44
45
|
rating.store 2, {goodness: 1, badness: 2}
|
45
|
-
|
46
|
+
rating.store 1, {goodness: 1, badness: 1}
|
47
|
+
expect(rating.sorted).to eq([1, 2])
|
46
48
|
end
|
47
49
|
|
48
50
|
example "scalar key without vector and without &block" do
|
49
51
|
rating = PCBR.new
|
50
|
-
rating.store 2
|
51
52
|
rating.store 1
|
52
|
-
|
53
|
+
rating.store 2
|
54
|
+
expect(rating.sorted).to eq([2, 1])
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "examples" do
|
60
|
+
|
61
|
+
example "github repos" do
|
62
|
+
repos = {
|
63
|
+
# Image Processing Library
|
64
|
+
"IPL: ImageMagick/ImageMagick" => {issue: 36, pr: 0, watch: 29, star: 375, fork: 89},
|
65
|
+
"IPL: jcupitt/libvips" => {issue: 32, pr: 1, watch: 43, star: 753, fork: 72},
|
66
|
+
# Packet Manager
|
67
|
+
"PM: Homebrew/brew" => {issue: 14, pr: 13, watch: 61, star: 1207, fork: 345},
|
68
|
+
"PM: Linuxbrew/brew" => {issue: 21, pr: 2, watch: 5, star: 52, fork: 345},
|
69
|
+
# one gem depending on another one
|
70
|
+
"gem: dblock/slack-ruby-bot" => {issue: 15, pr: 0, watch: 13, star: 251, fork: 55},
|
71
|
+
"gem: dblock/slack-ruby-client" => {issue: 22, pr: 2, watch: 4, star: 206, fork: 37},
|
72
|
+
# Programming Language
|
73
|
+
"PL: crystal-lang/crystal" => {issue: 267, pr: 44, watch: 255, star: 4952, fork: 412},
|
74
|
+
"PL: elixir-lang/elixir" => {issue: 21, pr: 1, watch: 518, star: 7029, fork: 975},
|
75
|
+
"PL: golang/go" => {issue: 2293, pr: 1, watch: 1521, star: 17067, fork: 2147},
|
76
|
+
"PL: racket/racket" => {issue: 33, pr: 53, watch: 124, star: 1455, fork: 301},
|
77
|
+
"PL: rust-lang/rust" => {issue: 2411, pr: 119, watch: 1012, star: 16790, fork: 3200},
|
78
|
+
# Ruby Web Framework
|
79
|
+
"RWF: padrino/padrino-framework" => {issue: 44, pr: 2, watch: 137, star: 2782, fork: 454},
|
80
|
+
"RWF: sinatra/sinatra" => {issue: 12, pr: 11, watch: 377, star: 7892, fork: 1467},
|
81
|
+
# Ruby Version Manager
|
82
|
+
"RVM: rbenv/rbenv" => {issue: 24, pr: 12, watch: 301, star: 8257, fork: 769},
|
83
|
+
"RVM: rvm/rvm" => {issue: 160, pr: 5, watch: 154, star: 3328, fork: 793},
|
84
|
+
# DevOps Tools
|
85
|
+
"DOT: ansible/ansible" => {issue: 1074, pr: 322, watch: 1339, star: 16926, fork: 5075},
|
86
|
+
"DOT: chef/chef" => {issue: 422, pr: 52, watch: 387, star: 4265, fork: 1774},
|
87
|
+
"DOT: capistrano/capistrano" => {issue: 38, pr: 6, watch: 339, star: 8392, fork: 1365},
|
88
|
+
}
|
89
|
+
|
90
|
+
store_repos_to_rating = lambda do |rating|
|
91
|
+
repos.each do |repo_name, repo_stats|
|
92
|
+
rating.store repo_name, repo_stats
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
contribution_intensivity_rating = PCBR.new do |repo_stats| [
|
97
|
+
repo_stats[:pr],
|
98
|
+
-repo_stats[:fork],
|
99
|
+
] end.tap &store_repos_to_rating
|
100
|
+
|
101
|
+
quality_rating = PCBR.new do |repo_stats| [
|
102
|
+
repo_stats[:star],
|
103
|
+
-repo_stats[:issue],
|
104
|
+
] end.tap &store_repos_to_rating
|
105
|
+
|
106
|
+
resulting_rating = PCBR.new do |_, repo_name| [
|
107
|
+
contribution_intensivity_rating.score(repo_name),
|
108
|
+
quality_rating.score(repo_name),
|
109
|
+
] end.tap &store_repos_to_rating
|
110
|
+
|
111
|
+
aggregate_failures do
|
112
|
+
expect(
|
113
|
+
resulting_rating.sorted.map(&:split).group_by(&:first).each do |category, group|
|
114
|
+
group.map! &:last
|
115
|
+
end.to_a
|
116
|
+
).to eq( [
|
117
|
+
["PM:", %w{ Homebrew/brew Linuxbrew/brew }],
|
118
|
+
["RVM:", %w{ rbenv/rbenv rvm/rvm }],
|
119
|
+
["PL:", %w{ racket/racket crystal-lang/crystal elixir-lang/elixir rust-lang/rust golang/go }],
|
120
|
+
["DOT:", %w{ ansible/ansible capistrano/capistrano chef/chef }],
|
121
|
+
["RWF:", %w{ sinatra/sinatra padrino/padrino-framework }],
|
122
|
+
["gem:", %w{ dblock/slack-ruby-bot dblock/slack-ruby-client }],
|
123
|
+
["IPL:", %w{ jcupitt/libvips ImageMagick/ImageMagick }],
|
124
|
+
] )
|
125
|
+
end
|
53
126
|
end
|
54
127
|
|
55
128
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pcbr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Maslov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,7 +38,8 @@ dependencies:
|
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 3.3.0
|
41
|
-
description:
|
41
|
+
description: Making ratings is fun. After applying my method several times I've decided
|
42
|
+
to gemify it.
|
42
43
|
email: nakilon@gmail.com
|
43
44
|
executables: []
|
44
45
|
extensions: []
|
@@ -74,5 +75,5 @@ rubyforge_project:
|
|
74
75
|
rubygems_version: 2.0.14
|
75
76
|
signing_key:
|
76
77
|
specification_version: 4
|
77
|
-
summary: Pair
|
78
|
+
summary: Pair Comparison Based Rating
|
78
79
|
test_files: []
|