pcbr 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (9) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -0
  3. data/lib/pcbr.rb +2 -11
  4. data/pcbr.gemspec +5 -9
  5. metadata +8 -38
  6. data/Gemfile +0 -3
  7. data/README.md +0 -27
  8. data/Rakefile +0 -8
  9. data/spec/_spec.rb +0 -199
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c14c95b38050d0a74a838c101e6321886aa7ac9
4
- data.tar.gz: 4059ab70af92b3cad59bbc3199d29f948477d525
3
+ metadata.gz: 479e8f9785c73a1569d807a1f311599f1285df24
4
+ data.tar.gz: 59569e2a2ac7eeeed617655e351fd3ea07743908
5
5
  SHA512:
6
- metadata.gz: '097ea8ee69316361d9124ca139757ddb8b0ef4e54ca4a5c91ca33f91cb80c9a06b8225d8cbaa608b0929c922c429c4b295af712d634983f4e9da997c47c05a8f'
7
- data.tar.gz: d6be5246bf91af6e918583c98d25ffc96e48f7d7af5e6e647f66665c2c6f87db599ccdd77edcbd14204eadae9a96da1b387c3589c9074464f45f428be9c52d01
6
+ metadata.gz: 280c5a469bb446ec87f1fbc47e47cf77f4325e9c1162b6d4836c79f370d472dc99c71169fd0c58cecffbcf302cc583c8605dc163088b383f19b826bd0c33b62e
7
+ data.tar.gz: 5a8b362448c8d3276ea54257ead0c2fbdd8337c0ae3e1a48e5bc78acae17002f479ba63db68d025749bdad4f51c402f3401e71dfdc5bb74617be724b61f100cb
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Victor Maslov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/lib/pcbr.rb CHANGED
@@ -22,14 +22,14 @@ module PCBR
22
22
  end
23
23
 
24
24
  def initialize &block
25
+ require "set"
26
+ @set = ::Set.new
25
27
  @table = []
26
- @set = Set.new
27
28
  @callback = block || @@default_lambda
28
29
  end
29
30
 
30
31
  def store key, vector = nil
31
32
  raise Error.new "duplicating key" if @set.include? key
32
- key = [NilClass, FalseClass, TrueClass, Numeric, Symbol, Method].any?{ |c| key.is_a? c } ? key : key.dup
33
33
  vector = Array key if vector.nil?
34
34
  score = 0
35
35
  @table.each do |item|
@@ -50,14 +50,5 @@ module PCBR
50
50
  @table.sort_by.with_index{ |item, i| [-item[2], i] }.map(&:first)
51
51
  end
52
52
 
53
- # def quality
54
- # factorial = ->x{ (1..x).inject(:*) }
55
- # (2...@table.size).each do |sublength|
56
- # combinations = factorial[@table.size] / factorial[sublength] / factorial[@table.size - sublength]
57
- # comparisons = sublength * (sublength - 1) / 2
58
- # p [sublength, combinations, comparisons, combinations * comparisons]
59
- # end
60
- # end
61
-
62
53
  end
63
54
  end
data/pcbr.gemspec CHANGED
@@ -1,23 +1,19 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "pcbr"
3
- spec.version = "0.4.2"
3
+ spec.version = "0.5.0"
4
4
  spec.summary = "Pair Comparison Based Rating"
5
5
 
6
6
  spec.author = "Victor Maslov"
7
7
  spec.email = "nakilon@gmail.com"
8
8
  spec.license = "MIT"
9
- spec.homepage = "https://github.com/Nakilon/pcbr"
9
+ spec.metadata = {"source_code_uri" => "https://github.com/nakilon/pcbr"}
10
10
  spec.description = <<-EOF
11
11
  Making ratings is fun. After applying my method several times I've decided to gemify it.
12
12
  This is one of the first gems I made so it's far for being nicely done.
13
13
  EOF
14
14
 
15
- spec.test_files = ["spec/"]
16
- spec.files = `git ls-files -z`.split(?\0) - spec.test_files
15
+ spec.required_ruby_version = ">=2"
16
+ spec.add_development_dependency "minitest"
17
17
 
18
- spec.add_development_dependency "bundler"
19
- spec.add_development_dependency "rspec", "~> 3.3.0"
20
- spec.add_development_dependency "ruby-prof"
21
-
22
- spec.required_ruby_version = ">= 2.0.0"
18
+ spec.files = %w{ LICENSE pcbr.gemspec lib/pcbr.rb }
23
19
  end
metadata CHANGED
@@ -1,45 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pcbr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Maslov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-29 00:00:00.000000000 Z
11
+ date: 2021-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: rspec
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 3.3.0
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 3.3.0
41
- - !ruby/object:Gem::Dependency
42
- name: ruby-prof
14
+ name: minitest
43
15
  requirement: !ruby/object:Gem::Requirement
44
16
  requirements:
45
17
  - - ">="
@@ -60,16 +32,14 @@ executables: []
60
32
  extensions: []
61
33
  extra_rdoc_files: []
62
34
  files:
63
- - Gemfile
64
- - README.md
65
- - Rakefile
35
+ - LICENSE
66
36
  - lib/pcbr.rb
67
37
  - pcbr.gemspec
68
- - spec/_spec.rb
69
- homepage: https://github.com/Nakilon/pcbr
38
+ homepage:
70
39
  licenses:
71
40
  - MIT
72
- metadata: {}
41
+ metadata:
42
+ source_code_uri: https://github.com/nakilon/pcbr
73
43
  post_install_message:
74
44
  rdoc_options: []
75
45
  require_paths:
@@ -78,7 +48,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
78
48
  requirements:
79
49
  - - ">="
80
50
  - !ruby/object:Gem::Version
81
- version: 2.0.0
51
+ version: '2'
82
52
  required_rubygems_version: !ruby/object:Gem::Requirement
83
53
  requirements:
84
54
  - - ">="
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
data/README.md DELETED
@@ -1,27 +0,0 @@
1
- # PCBR (Pairs Comparison Based Rating)
2
-
3
- You often need to sort an array of vectors. This allows you to do it without knowing the optimal ranking function and with some pairs of vectors that are not even comparable.
4
-
5
- ### Examples
6
-
7
- See [`describe "examples" do` in specs](spec/_spec.rb).
8
-
9
- ### How it works
10
-
11
- The first idea was in 2013 -- at that time I was imagining it as a tree data structure. Later in May 2015 I've realised that it's really about dots in n-dimensional space and sectors, and round-robin. Applying it to Reddit RSS feed made it 50% more interesting. It also applied well to boost tree search process in the [bad Facebook advertisment classifier](https://drive.google.com/file/d/0B3BLwu7Vb2U-SVhKYWVMR2JvOFk/view?usp=sharing) production project. Since then I mostly use it to oprimize tree searches, it's basically an automated replacement for euristics.
12
-
13
- ### Installation
14
-
15
- $ gem install pcbr
16
-
17
- ### Testing
18
-
19
- rspec
20
-
21
- or
22
-
23
- rake spec
24
-
25
- ### TODO
26
-
27
- Illustrate this README, replace rspec with minitest.
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- require "bundler/gem_tasks"
2
-
3
- task :default => %w{ spec }
4
-
5
- require "rspec/core/rake_task"
6
- RSpec::Core::RakeTask.new(:spec) do |t|
7
- t.verbose = false
8
- end
data/spec/_spec.rb DELETED
@@ -1,199 +0,0 @@
1
- require_relative "../lib/pcbr"
2
-
3
-
4
- require "pp"
5
-
6
-
7
- describe "basic specs" do
8
-
9
- example "scalar key without vector and without &block" do
10
- rating = PCBR.new
11
- rating.store 1
12
- rating.store 2
13
- expect(rating.sorted).to eq([2, 1])
14
- end
15
-
16
- example "raises if vectors are of the different length" do
17
- rating = PCBR.new
18
- rating.store 1, [2]
19
- expect{ rating.store 3, [4, 5] }.to raise_error PCBR::Error
20
- end
21
-
22
- # example "#size" do
23
- # rating = PCBR.new
24
- # rating.store 1
25
- # rating.store 2
26
- # expect(rating.size).to eq(2)
27
- # end
28
-
29
- example "Nil elements in vector are ignored" do
30
- rating = PCBR.new
31
- rating.store 1, [1, nil]
32
- rating.store 2, [2, nil]
33
- rating.store 3, [nil, 3]
34
- rating.store 4, [nil, 4]
35
- expect(rating.sorted).to eq([2, 4, 1, 3])
36
- end
37
-
38
- example "&block" do
39
- n = 0
40
- rating = PCBR.new do |a, b|
41
- n += 1
42
- a <=> b
43
- end
44
- rating.store 1
45
- rating.store 2
46
- rating.store 3
47
- rating.store 4
48
- expect(rating.sorted).to eq([4, 3, 2, 1])
49
- expect(n).to eq(6)
50
- end
51
-
52
- example "the vector is not neccessary an Array" do
53
- rating = PCBR.new do |a, b|
54
- a <=> b
55
- end
56
- 0.class.class_eval do
57
- def size
58
- fail
59
- end
60
- end
61
- rating.store 1, 2
62
- rating.store 2, 1
63
- expect(rating.sorted).to eq([1, 2])
64
- end
65
-
66
- example "#sorted and #score[key]" do
67
- rating = PCBR.new
68
- table = [
69
- [1, [1, 1], -1],
70
- [2, [2, 2], 5],
71
- [3, [0, 0], -5],
72
- [4, [1, 2], 3],
73
- [6, [1, 1], -1],
74
- [5, [0, 2], -1],
75
- ].each do |key, vector, |
76
- rating.store key, vector
77
- end
78
- expect(rating.sorted).to eq([2, 4, 1, 6, 5, 3])
79
- expect(rating.table.map{ |i| i[2] }.inject(:+)).to be_zero
80
- table.each do |key, _, score|
81
- expect(rating.score(key)).to eq(score)
82
- end
83
- expect(rating.table).to eq(table)
84
- end
85
-
86
- # example "quality estimation" do
87
- # rating = PCBR.new
88
- # table = [
89
- # [1, [1, 1]],
90
- # [2, [2, 2]],
91
- # [3, [0, 0]],
92
- # [4, [1, 2]],
93
- # [6, [1, 1]],
94
- # [5, [0, 2]],
95
- # ].each do |key, vector, |
96
- # rating.store key, vector
97
- # end
98
- # end
99
-
100
- example "duplicating keys are forbidden" do
101
- rating = PCBR.new
102
- rating.store 0
103
- expect{ rating.store 0 }.to raise_error PCBR::Error
104
- end
105
-
106
- example "keys are dupped" do
107
- rating = PCBR.new
108
- a = [[1]]
109
- v = [0]
110
- rating.store a, v
111
- a[0][0] = 2
112
- rating.store [[1]], [1]
113
- expect(rating.sorted).to eq [[[1]], [[2]]]
114
- end
115
-
116
- example "keys are dupped but not deeply" do
117
- rating = PCBR.new
118
- a = [[1]]
119
- v = [0]
120
- rating.store a, v
121
- a[0][0] = 2
122
- expect{ rating.store [[2]], [1] }.to raise_error PCBR::Error
123
- end
124
-
125
- end
126
-
127
-
128
- describe "examples" do
129
-
130
- example "github repos" do
131
- repos = {
132
- # Image Processing Library
133
- "IPL: ImageMagick/ImageMagick" => {issue: 36, pr: 0, watch: 29, star: 375, fork: 89},
134
- "IPL: jcupitt/libvips" => {issue: 32, pr: 1, watch: 43, star: 753, fork: 72},
135
- # Packet Manager
136
- "PM: Homebrew/brew" => {issue: 14, pr: 13, watch: 61, star: 1207, fork: 345},
137
- "PM: Linuxbrew/brew" => {issue: 21, pr: 2, watch: 5, star: 52, fork: 345},
138
- # one gem depending on another one
139
- "gem: dblock/slack-ruby-bot" => {issue: 15, pr: 0, watch: 13, star: 251, fork: 55},
140
- "gem: dblock/slack-ruby-client" => {issue: 22, pr: 2, watch: 4, star: 206, fork: 37},
141
- # Programming Language
142
- "PL: crystal-lang/crystal" => {issue: 267, pr: 44, watch: 255, star: 4952, fork: 412},
143
- "PL: elixir-lang/elixir" => {issue: 21, pr: 1, watch: 518, star: 7029, fork: 975},
144
- "PL: golang/go" => {issue: 2293, pr: 1, watch: 1521, star: 17067, fork: 2147},
145
- "PL: racket/racket" => {issue: 33, pr: 53, watch: 124, star: 1455, fork: 301},
146
- "PL: rust-lang/rust" => {issue: 2411, pr: 119, watch: 1012, star: 16790, fork: 3200},
147
- # Ruby Web Framework
148
- "RWF: padrino/padrino-framework" => {issue: 44, pr: 2, watch: 137, star: 2782, fork: 454},
149
- "RWF: sinatra/sinatra" => {issue: 12, pr: 11, watch: 377, star: 7892, fork: 1467},
150
- # Ruby Version Manager
151
- "RVM: rbenv/rbenv" => {issue: 24, pr: 12, watch: 301, star: 8257, fork: 769},
152
- "RVM: rvm/rvm" => {issue: 160, pr: 5, watch: 154, star: 3328, fork: 793},
153
- # DevOps Tool
154
- "DOT: ansible/ansible" => {issue: 1074, pr: 322, watch: 1339, star: 16926, fork: 5075},
155
- "DOT: chef/chef" => {issue: 422, pr: 52, watch: 387, star: 4265, fork: 1774},
156
- "DOT: capistrano/capistrano" => {issue: 38, pr: 6, watch: 339, star: 8392, fork: 1365},
157
- }
158
-
159
- create_rating = lambda do |&callback|
160
- PCBR.new.tap do |rating|
161
- repos.each do |repo_name, repo_stats|
162
- rating.store repo_name, callback[repo_stats, repo_name]
163
- end
164
- end
165
- end
166
-
167
- contribution_intensivity_rating = create_rating.call do |repo_stats| [
168
- repo_stats[:pr],
169
- -repo_stats[:fork],
170
- ] end
171
-
172
- quality_rating = create_rating.call do |repo_stats| [
173
- repo_stats[:star],
174
- -repo_stats[:issue],
175
- ] end
176
-
177
- resulting_rating = create_rating.call do |repo_stats, repo_name| [
178
- contribution_intensivity_rating.score(repo_name),
179
- quality_rating.score(repo_name),
180
- ] end
181
-
182
- aggregate_failures do
183
- expect(
184
- resulting_rating.sorted.map(&:split).group_by(&:first).each do |category, group|
185
- group.map! &:last
186
- end.to_a
187
- ).to eq( [
188
- ["PM:", %w{ Homebrew/brew Linuxbrew/brew }],
189
- ["RVM:", %w{ rbenv/rbenv rvm/rvm }],
190
- ["PL:", %w{ racket/racket crystal-lang/crystal elixir-lang/elixir rust-lang/rust golang/go }],
191
- ["DOT:", %w{ ansible/ansible capistrano/capistrano chef/chef }],
192
- ["RWF:", %w{ sinatra/sinatra padrino/padrino-framework }],
193
- ["gem:", %w{ dblock/slack-ruby-bot dblock/slack-ruby-client }],
194
- ["IPL:", %w{ jcupitt/libvips ImageMagick/ImageMagick }],
195
- ] )
196
- end
197
- end
198
-
199
- end