pcbr 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|