pcbr 0.3.0 → 0.5.0

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.
Files changed (10) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -0
  3. data/lib/pcbr.rb +16 -31
  4. data/pcbr.gemspec +11 -12
  5. metadata +16 -46
  6. data/.rspec +0 -1
  7. data/Gemfile +0 -3
  8. data/README.md +0 -29
  9. data/Rakefile +0 -8
  10. data/spec/_spec.rb +0 -172
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ce39501eee28e4881d896c138a0049899912b8a
4
- data.tar.gz: 68060e95d3921de4b105fd48227fc776d93ff744
3
+ metadata.gz: 479e8f9785c73a1569d807a1f311599f1285df24
4
+ data.tar.gz: 59569e2a2ac7eeeed617655e351fd3ea07743908
5
5
  SHA512:
6
- metadata.gz: b7c3edd47fd4012722dffd750833187b5951943543aca19b3b507409f787f5ec60ea1e08adb337967770a9d4494ec8e0cc7d18337a0ae68230f0b42f226101be
7
- data.tar.gz: 93051d2392065a23d4cb2918c79771e11cb08a1c6df7a13489f6bc58fe2284beb5410b850eec86251f94eed3f28e015664c3bf9d93ea1e073965fcafd160003a
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
@@ -1,8 +1,4 @@
1
- require "deep_dup"
2
-
3
1
  module PCBR
4
- VERSION = "0.3.0"
5
-
6
2
  class Error < RuntimeError
7
3
  # def initialize body
8
4
  # super "#{Module.nesting[1]} error: #{body}"
@@ -13,37 +9,35 @@ module PCBR
13
9
  Storage.new &block
14
10
  end
15
11
 
16
- ARRAY_101 = [0, 0, 0]
17
12
  class Storage
18
13
  attr_reader :table
14
+ attr_reader :set
15
+ @@default_lambda = lambda do |a_, b_|
16
+ raise Error.new "comparison vectors are of the different length" unless a_.size == b_.size
17
+ tt = [0, 0, 0]
18
+ [*a_].zip([*b_]) do |a, b|
19
+ t = a <=> b and tt[t] = t
20
+ end
21
+ tt[0] + tt[1] + tt[2]
22
+ end
19
23
 
20
24
  def initialize &block
25
+ require "set"
26
+ @set = ::Set.new
21
27
  @table = []
22
- @callback = block || lambda{ |a_, b_|
23
- ARRAY_101.dup.tap do |array|
24
- [*a_].zip([*b_]) do |a, b|
25
- t = a <=> b and array[t] = t
26
- end
27
- end.inject :+
28
- }
28
+ @callback = block || @@default_lambda
29
29
  end
30
30
 
31
31
  def store key, vector = nil
32
- raise Error.new "duplicating key" if @table.assoc key
33
- key = DeepDup.deep_dup key
34
- vector = if vector
35
- DeepDup.deep_dup vector
36
- else
37
- Array key
38
- end
32
+ raise Error.new "duplicating key" if @set.include? key
33
+ vector = Array key if vector.nil?
39
34
  score = 0
40
35
  @table.each do |item|
41
- # TODO test of this exception
42
- raise Error.new "comparison vectors are of the different length" unless vector.size == item[1].size
43
36
  point = @callback.call vector, item[1]
44
- score += point
45
37
  item[2] -= point
38
+ score += point
46
39
  end
40
+ @set.add key
47
41
  @table.push [key, vector, score]
48
42
  end
49
43
 
@@ -56,14 +50,5 @@ module PCBR
56
50
  @table.sort_by.with_index{ |item, i| [-item[2], i] }.map(&:first)
57
51
  end
58
52
 
59
- # def quality
60
- # factorial = ->x{ (1..x).inject(:*) }
61
- # (2...@table.size).each do |sublength|
62
- # combinations = factorial[@table.size] / factorial[sublength] / factorial[@table.size - sublength]
63
- # comparisons = sublength * (sublength - 1) / 2
64
- # p [sublength, combinations, comparisons, combinations * comparisons]
65
- # end
66
- # end
67
-
68
53
  end
69
54
  end
data/pcbr.gemspec CHANGED
@@ -1,20 +1,19 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "pcbr"
3
- spec.version = (require_relative "lib/pcbr"; PCBR::VERSION)
3
+ spec.version = "0.5.0"
4
+ spec.summary = "Pair Comparison Based Rating"
5
+
4
6
  spec.author = "Victor Maslov"
5
7
  spec.email = "nakilon@gmail.com"
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
- spec.homepage = "https://github.com/Nakilon/pcbr"
9
8
  spec.license = "MIT"
9
+ spec.metadata = {"source_code_uri" => "https://github.com/nakilon/pcbr"}
10
+ spec.description = <<-EOF
11
+ Making ratings is fun. After applying my method several times I've decided to gemify it.
12
+ This is one of the first gems I made so it's far for being nicely done.
13
+ EOF
10
14
 
11
- spec.files = `git ls-files -z`.split("\x0")
12
- spec.test_files = ["spec/"]
13
-
14
- spec.add_dependency "deep_dup"
15
-
16
- spec.add_development_dependency "bundler"
17
- spec.add_development_dependency "rspec", "~> 3.3.0"
15
+ spec.required_ruby_version = ">=2"
16
+ spec.add_development_dependency "minitest"
18
17
 
19
- spec.required_ruby_version = ">= 2.0.0"
18
+ spec.files = %w{ LICENSE pcbr.gemspec lib/pcbr.rb }
20
19
  end
metadata CHANGED
@@ -1,92 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pcbr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
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: 2017-12-06 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: deep_dup
14
+ name: minitest
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
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: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '>='
17
+ - - ">="
32
18
  - !ruby/object:Gem::Version
33
19
  version: '0'
34
20
  type: :development
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
- - - '>='
24
+ - - ">="
39
25
  - !ruby/object:Gem::Version
40
26
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ~>
46
- - !ruby/object:Gem::Version
47
- version: 3.3.0
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ~>
53
- - !ruby/object:Gem::Version
54
- version: 3.3.0
55
- description: Making ratings is fun. After applying my method several times I've decided
56
- to gemify it.
27
+ description: |2
28
+ Making ratings is fun. After applying my method several times I've decided to gemify it.
29
+ This is one of the first gems I made so it's far for being nicely done.
57
30
  email: nakilon@gmail.com
58
31
  executables: []
59
32
  extensions: []
60
33
  extra_rdoc_files: []
61
34
  files:
62
- - .rspec
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:
76
46
  - lib
77
47
  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
+ - - ">="
85
55
  - !ruby/object:Gem::Version
86
56
  version: '0'
87
57
  requirements: []
88
58
  rubyforge_project:
89
- rubygems_version: 2.0.14.1
59
+ rubygems_version: 2.5.2.3
90
60
  signing_key:
91
61
  specification_version: 4
92
62
  summary: Pair Comparison Based Rating
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --color
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
data/README.md DELETED
@@ -1,29 +0,0 @@
1
- # PCBR (Pairs Comparison Based Rating)
2
-
3
- Making ratings is fun. After applying my method several times I've decided to gemify it.
4
-
5
- ### Examples
6
-
7
- See [`describe "examples" do` in specs](spec/_spec.rb).
8
-
9
- ### How it works
10
-
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
-
13
- TODO: describe/illustrate algorithm?
14
-
15
- ~~At the moment it's a "proof of concept" -- it needs huge optimisations for lookups, maybe using trees.~~
16
-
17
- It worked fine in production for a project with huge computations where you can't find the best solution but have to find anything good in adequate time. Traversing the tree using this with a vector of `[leaf's quality, depth]` made things better than depth-first search with lots of ueristics.
18
-
19
- ### Installation
20
-
21
- $ gem install pcbr
22
-
23
- ### Testing with RSpec before contributing
24
-
25
- rspec
26
-
27
- or
28
-
29
- rake spec
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,172 +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 "#size" do
17
- # rating = PCBR.new
18
- # rating.store 1
19
- # rating.store 2
20
- # expect(rating.size).to eq(2)
21
- # end
22
-
23
- example "Nil elements in vector are ignored" do
24
- rating = PCBR.new
25
- rating.store 1, [1, nil]
26
- rating.store 2, [2, nil]
27
- rating.store 3, [nil, 3]
28
- rating.store 4, [nil, 4]
29
- expect(rating.sorted).to eq([2, 4, 1, 3])
30
- end
31
-
32
- example "&block" do
33
- n = 0
34
- rating = PCBR.new do |a, b|
35
- n += 1
36
- a <=> b
37
- end
38
- rating.store 1
39
- rating.store 2
40
- rating.store 3
41
- rating.store 4
42
- expect(rating.sorted).to eq([4, 3, 2, 1])
43
- expect(n).to eq(6)
44
- end
45
-
46
- example "#sorted and #score[key]" do
47
- rating = PCBR.new
48
- table = [
49
- [1, [1, 1], -1],
50
- [2, [2, 2], 5],
51
- [3, [0, 0], -5],
52
- [4, [1, 2], 3],
53
- [6, [1, 1], -1],
54
- [5, [0, 2], -1],
55
- ].each do |key, vector, |
56
- rating.store key, vector
57
- end
58
- expect(rating.sorted).to eq([2, 4, 1, 6, 5, 3])
59
- expect(rating.table.map{ |i| i[2] }.inject(:+)).to be_zero
60
- table.each do |key, _, score|
61
- expect(rating.score(key)).to eq(score)
62
- end
63
- expect(rating.table).to eq(table)
64
- end
65
-
66
- # example "quality estimation" do
67
- # rating = PCBR.new
68
- # table = [
69
- # [1, [1, 1]],
70
- # [2, [2, 2]],
71
- # [3, [0, 0]],
72
- # [4, [1, 2]],
73
- # [6, [1, 1]],
74
- # [5, [0, 2]],
75
- # ].each do |key, vector, |
76
- # rating.store key, vector
77
- # end
78
- # end
79
-
80
- example "duplicating keys are forbidden" do
81
- rating = PCBR.new
82
- rating.store 0
83
- expect{ rating.store 0 }.to raise_error PCBR::Error
84
- end
85
-
86
- example "keys and vectors are dupped" do
87
- rating = PCBR.new
88
- a = [[1]]
89
- v = [0]
90
- rating.store a, v
91
- a[0][0] = 2
92
- rating.store [[2]], [1] # expect no PCBR::Error
93
- v[0] = 3
94
- rating.store [[3]], [2]
95
- expect(rating.sorted).to eq [[[3]], [[2]], [[1]]]
96
- end
97
-
98
- end
99
-
100
-
101
- describe "examples" do
102
-
103
- example "github repos" do
104
- repos = {
105
- # Image Processing Library
106
- "IPL: ImageMagick/ImageMagick" => {issue: 36, pr: 0, watch: 29, star: 375, fork: 89},
107
- "IPL: jcupitt/libvips" => {issue: 32, pr: 1, watch: 43, star: 753, fork: 72},
108
- # Packet Manager
109
- "PM: Homebrew/brew" => {issue: 14, pr: 13, watch: 61, star: 1207, fork: 345},
110
- "PM: Linuxbrew/brew" => {issue: 21, pr: 2, watch: 5, star: 52, fork: 345},
111
- # one gem depending on another one
112
- "gem: dblock/slack-ruby-bot" => {issue: 15, pr: 0, watch: 13, star: 251, fork: 55},
113
- "gem: dblock/slack-ruby-client" => {issue: 22, pr: 2, watch: 4, star: 206, fork: 37},
114
- # Programming Language
115
- "PL: crystal-lang/crystal" => {issue: 267, pr: 44, watch: 255, star: 4952, fork: 412},
116
- "PL: elixir-lang/elixir" => {issue: 21, pr: 1, watch: 518, star: 7029, fork: 975},
117
- "PL: golang/go" => {issue: 2293, pr: 1, watch: 1521, star: 17067, fork: 2147},
118
- "PL: racket/racket" => {issue: 33, pr: 53, watch: 124, star: 1455, fork: 301},
119
- "PL: rust-lang/rust" => {issue: 2411, pr: 119, watch: 1012, star: 16790, fork: 3200},
120
- # Ruby Web Framework
121
- "RWF: padrino/padrino-framework" => {issue: 44, pr: 2, watch: 137, star: 2782, fork: 454},
122
- "RWF: sinatra/sinatra" => {issue: 12, pr: 11, watch: 377, star: 7892, fork: 1467},
123
- # Ruby Version Manager
124
- "RVM: rbenv/rbenv" => {issue: 24, pr: 12, watch: 301, star: 8257, fork: 769},
125
- "RVM: rvm/rvm" => {issue: 160, pr: 5, watch: 154, star: 3328, fork: 793},
126
- # DevOps Tool
127
- "DOT: ansible/ansible" => {issue: 1074, pr: 322, watch: 1339, star: 16926, fork: 5075},
128
- "DOT: chef/chef" => {issue: 422, pr: 52, watch: 387, star: 4265, fork: 1774},
129
- "DOT: capistrano/capistrano" => {issue: 38, pr: 6, watch: 339, star: 8392, fork: 1365},
130
- }
131
-
132
- create_rating = lambda do |&callback|
133
- PCBR.new.tap do |rating|
134
- repos.each do |repo_name, repo_stats|
135
- rating.store repo_name, callback[repo_stats, repo_name]
136
- end
137
- end
138
- end
139
-
140
- contribution_intensivity_rating = create_rating.call do |repo_stats| [
141
- repo_stats[:pr],
142
- -repo_stats[:fork],
143
- ] end
144
-
145
- quality_rating = create_rating.call do |repo_stats| [
146
- repo_stats[:star],
147
- -repo_stats[:issue],
148
- ] end
149
-
150
- resulting_rating = create_rating.call do |repo_stats, repo_name| [
151
- contribution_intensivity_rating.score(repo_name),
152
- quality_rating.score(repo_name),
153
- ] end
154
-
155
- aggregate_failures do
156
- expect(
157
- resulting_rating.sorted.map(&:split).group_by(&:first).each do |category, group|
158
- group.map! &:last
159
- end.to_a
160
- ).to eq( [
161
- ["PM:", %w{ Homebrew/brew Linuxbrew/brew }],
162
- ["RVM:", %w{ rbenv/rbenv rvm/rvm }],
163
- ["PL:", %w{ racket/racket crystal-lang/crystal elixir-lang/elixir rust-lang/rust golang/go }],
164
- ["DOT:", %w{ ansible/ansible capistrano/capistrano chef/chef }],
165
- ["RWF:", %w{ sinatra/sinatra padrino/padrino-framework }],
166
- ["gem:", %w{ dblock/slack-ruby-bot dblock/slack-ruby-client }],
167
- ["IPL:", %w{ jcupitt/libvips ImageMagick/ImageMagick }],
168
- ] )
169
- end
170
- end
171
-
172
- end