weighted_list_rank 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02c97cc567dfd099a6f65066c534b3780d1a8ca7f8b6a2148d6410c348ed6db9
4
- data.tar.gz: 235f31a73f88b44485d5c5a0fae360d6f4fe2a417e380ddaccadfa214af4d5d6
3
+ metadata.gz: f9afa895dc286e9cc5dd2370376b965eda825669debad06e21c232b996e2cab6
4
+ data.tar.gz: 6116b3e97dc978a0ca8021f683ff7d5b31b1ebd1e0e3f07fc10c7a266b34659e
5
5
  SHA512:
6
- metadata.gz: e908050bff4073ce084cc6b20a30992a52a08d93dc2732ae4e891605d2dc3c761166a79e90093ddb5b345ebe9da344c4ebe430fd9d9e1b780bccced0d4ee97fb
7
- data.tar.gz: 67fa8168ec949cbdcb3c1dc728d8461ae0a4bf51234cef9d251eaf10b63eb8ca617d55945a719ea297cfe24c42a1ab89c871f8f090af601c97ec21f22b0c2b6f
6
+ metadata.gz: 71656bad8660b6ae1455afc06a406dddf69f688feb22b690b6dcef57b39aa2ba60df1fe14be91aa22af957b71960b7fe856a980b1769090ea039149fcb005abe
7
+ data.tar.gz: cb30e3d19ed531e74ff7d665c92029a105c83a6d18e3ce98671c3471218c1c5fa6fc39672394161444b38cc2a97d0dfc2aeab60cfaedefde2664f246cd9ac5c6
data/.rubocop.yml CHANGED
File without changes
data/CHANGELOG.md CHANGED
@@ -1,8 +1,16 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2024-06-26
4
+ - Added score_penalty feature to allow percentage-based penalties on item scores.
5
+ - Updated all dependencies to their latest versions.
6
+
7
+ ## [0.3.1] - 2024-05-026
8
+
9
+ - Fixed issue with lists with only a single item getting bonus points
10
+
3
11
  ## [0.3.0] - 2024-02-03
4
12
 
5
- - added bonus_pool_percentage feature to expoential
13
+ - added bonus_pool_percentage feature to exponential
6
14
 
7
15
  ## [0.2.0] - 2024-02-03
8
16
 
data/CODE_OF_CONDUCT.md CHANGED
File without changes
data/Gemfile CHANGED
File without changes
data/Gemfile.lock CHANGED
@@ -1,59 +1,61 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- weighted_list_rank (0.1.1)
4
+ weighted_list_rank (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.2)
10
- json (2.7.1)
10
+ json (2.7.2)
11
11
  language_server-protocol (3.17.0.3)
12
12
  lint_roller (1.1.0)
13
- minitest (5.21.2)
14
- parallel (1.24.0)
15
- parser (3.3.0.5)
13
+ minitest (5.24.0)
14
+ parallel (1.25.1)
15
+ parser (3.3.3.0)
16
16
  ast (~> 2.4.1)
17
17
  racc
18
- racc (1.7.3)
18
+ racc (1.8.0)
19
19
  rainbow (3.1.1)
20
- rake (13.1.0)
21
- regexp_parser (2.9.0)
22
- rexml (3.2.6)
23
- rubocop (1.59.0)
20
+ rake (13.2.1)
21
+ regexp_parser (2.9.2)
22
+ rexml (3.3.1)
23
+ strscan
24
+ rubocop (1.64.1)
24
25
  json (~> 2.3)
25
26
  language_server-protocol (>= 3.17.0)
26
27
  parallel (~> 1.10)
27
- parser (>= 3.2.2.4)
28
+ parser (>= 3.3.0.2)
28
29
  rainbow (>= 2.2.2, < 4.0)
29
30
  regexp_parser (>= 1.8, < 3.0)
30
31
  rexml (>= 3.2.5, < 4.0)
31
- rubocop-ast (>= 1.30.0, < 2.0)
32
+ rubocop-ast (>= 1.31.1, < 2.0)
32
33
  ruby-progressbar (~> 1.7)
33
34
  unicode-display_width (>= 2.4.0, < 3.0)
34
- rubocop-ast (1.30.0)
35
- parser (>= 3.2.1.0)
36
- rubocop-minitest (0.34.5)
37
- rubocop (>= 1.39, < 2.0)
38
- rubocop-ast (>= 1.30.0, < 2.0)
39
- rubocop-performance (1.20.2)
35
+ rubocop-ast (1.31.3)
36
+ parser (>= 3.3.1.0)
37
+ rubocop-minitest (0.35.0)
38
+ rubocop (>= 1.61, < 2.0)
39
+ rubocop-ast (>= 1.31.1, < 2.0)
40
+ rubocop-performance (1.21.1)
40
41
  rubocop (>= 1.48.1, < 2.0)
41
- rubocop-ast (>= 1.30.0, < 2.0)
42
+ rubocop-ast (>= 1.31.1, < 2.0)
42
43
  rubocop-rake (0.6.0)
43
44
  rubocop (~> 1.0)
44
45
  ruby-progressbar (1.13.0)
45
- standard (1.33.0)
46
+ standard (1.39.0)
46
47
  language_server-protocol (~> 3.17.0.2)
47
48
  lint_roller (~> 1.0)
48
- rubocop (~> 1.59.0)
49
+ rubocop (~> 1.64.0)
49
50
  standard-custom (~> 1.0.0)
50
- standard-performance (~> 1.3)
51
+ standard-performance (~> 1.4)
51
52
  standard-custom (1.0.2)
52
53
  lint_roller (~> 1.0)
53
54
  rubocop (~> 1.50)
54
- standard-performance (1.3.1)
55
+ standard-performance (1.4.0)
55
56
  lint_roller (~> 1.1)
56
- rubocop-performance (~> 1.20.2)
57
+ rubocop-performance (~> 1.21.0)
58
+ strscan (3.1.0)
57
59
  unicode-display_width (2.5.0)
58
60
 
59
61
  PLATFORMS
data/LICENSE.txt CHANGED
File without changes
data/README.md CHANGED
@@ -92,6 +92,78 @@ custom_ranked_items.each do |item|
92
92
  end
93
93
  ```
94
94
 
95
+ ### Using Item Penalties
96
+ The WeightedListRank system also supports applying penalties to individual items. A penalty is defined as a percentage reduction in the item's score. This feature can be used to de-emphasize certain items based on specific criteria.
97
+
98
+ To use the penalty feature, include the score_penalty attribute when defining your items:
99
+
100
+ ```ruby
101
+ class MyItem
102
+ include WeightedListRank::Item
103
+ attr_reader :id, :position, :score_penalty
104
+
105
+ def initialize(id, position, score_penalty = nil)
106
+ @id = id
107
+ @position = position
108
+ @score_penalty = score_penalty
109
+ end
110
+ end
111
+ ```
112
+
113
+ You can then apply the penalties when calculating the scores:
114
+
115
+ ```ruby
116
+ require 'weighted_list_rank'
117
+
118
+ # Initialize items and list with text identifiers and penalties
119
+ items = [
120
+ MyItem.new("Item 1", 1, 0.20), # 20% penalty
121
+ MyItem.new("Item 2", 2, 0.10), # 10% penalty
122
+ MyItem.new("Item 3", 3, nil) # No penalty
123
+ ]
124
+ list = MyList.new("List 1", 10, items)
125
+
126
+ # Initialize the Exponential strategy with an optional exponent
127
+ exponential_strategy = WeightedListRank::Strategies::Exponential.new(exponent: 1.5)
128
+
129
+ # Create a RankingContext using the Exponential strategy
130
+ ranking_context = WeightedListRank::RankingContext.new(exponential_strategy)
131
+
132
+ # Rank the items
133
+ ranked_items = ranking_context.rank([list])
134
+
135
+ # Display the ranked items
136
+ ranked_items.each do |item|
137
+ puts "Item: #{item[:id]}, Total Score: #{item[:total_score]}"
138
+ end
139
+ ```
140
+
141
+ ### Customizing Penalties Example
142
+ You can customize the penalty values to see how they affect the final scores of the items.
143
+
144
+ ```ruby
145
+ # Customizing penalties for different items
146
+ items = [
147
+ MyItem.new("Item 1", 1, 0.30), # 30% penalty
148
+ MyItem.new("Item 2", 2, 0.15), # 15% penalty
149
+ MyItem.new("Item 3", 3, nil) # No penalty
150
+ ]
151
+ list = MyList.new("List 1", 10, items)
152
+
153
+ # Initialize the Exponential strategy with an optional exponent
154
+ exponential_strategy = WeightedListRank::Strategies::Exponential.new(exponent: 2.0)
155
+
156
+ # Create a RankingContext using the Exponential strategy
157
+ ranking_context = WeightedListRank::RankingContext.new(exponential_strategy)
158
+
159
+ # Rank the items
160
+ ranked_items = ranking_context.rank([list])
161
+
162
+ # Output the results
163
+ ranked_items.each do |item|
164
+ puts "Item: #{item[:id]}, Total Score: #{item[:total_score]}"
165
+ end
166
+ ```
95
167
 
96
168
  ## Development
97
169
 
data/Rakefile CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "rake/testtask"
5
+ require "standard/rake"
5
6
 
6
7
  Rake::TestTask.new(:test) do |t|
7
8
  t.libs << "test"
File without changes
@@ -11,5 +11,11 @@ module WeightedListRank
11
11
  def id
12
12
  raise NotImplementedError, "Implement this method to return the item's unique identifier"
13
13
  end
14
+
15
+ # Returns the score penalty of the item. Can be overridden by the including class.
16
+ # @return [Float, NilClass] the score penalty of the item as a percentage (e.g., 0.20 for 20%) or nil if no penalty
17
+ def score_penalty
18
+ nil
19
+ end
14
20
  end
15
21
  end
File without changes
@@ -42,21 +42,38 @@ module WeightedListRank
42
42
  # @return [Float] the calculated score for the item, adjusted by the list's weight, the specified exponent,
43
43
  # and the bonus pool percentage.
44
44
  def calculate_score(list, item)
45
- # Return the list weight if there are no positions
46
- return list.weight if item.position.nil?
45
+ # Default score to the list's weight
46
+ score = list.weight
47
47
 
48
- num_items = list.items.count
49
- total_bonus_pool = list.weight * bonus_pool_percentage
48
+ unless item.position.nil? || list.items.count == 1
49
+ num_items = list.items.count
50
+ total_bonus_pool = list.weight * bonus_pool_percentage
50
51
 
51
- # Calculate the exponential factor for the item's rank position
52
- exponential_factor = (num_items + 1 - item.position)**exponent
53
- total_exponential_factor = (1..num_items).sum { |pos| (num_items + 1 - pos)**exponent }
52
+ # Calculate the exponential factor for the item's rank position
53
+ exponential_factor = (num_items + 1 - item.position)**exponent
54
+ total_exponential_factor = (1..num_items).sum { |pos| (num_items + 1 - pos)**exponent }
54
55
 
55
- # Allocate a portion of the total bonus pool based on the item's exponential factor
56
- item_bonus = (exponential_factor / total_exponential_factor) * total_bonus_pool
56
+ # Allocate a portion of the total bonus pool based on the item's exponential factor
57
+ item_bonus = (exponential_factor / total_exponential_factor) * total_bonus_pool
57
58
 
58
- # The final score is the list's weight plus the item's allocated bonus
59
- list.weight + item_bonus
59
+ # Add the item's allocated bonus to the default score
60
+ score += item_bonus
61
+ end
62
+
63
+ # Apply score penalty if it exists
64
+ apply_penalty(score, item.score_penalty)
65
+ end
66
+
67
+ private
68
+
69
+ # Applies the score penalty if it exists
70
+ #
71
+ # @param score [Float] the original score of the item
72
+ # @param penalty [Float, NilClass] the score penalty of the item as a percentage (e.g., 0.20 for 20%) or nil if no penalty
73
+ #
74
+ # @return [Float] the score after applying the penalty
75
+ def apply_penalty(score, penalty)
76
+ penalty ? score * (1 - penalty) : score
60
77
  end
61
78
  end
62
79
  end
File without changes
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WeightedListRank
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
File without changes
File without changes
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weighted_list_rank
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Sherman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-04 00:00:00.000000000 Z
11
+ date: 2024-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -112,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
112
  - !ruby/object:Gem::Version
113
113
  version: '0'
114
114
  requirements: []
115
- rubygems_version: 3.3.7
115
+ rubygems_version: 3.5.11
116
116
  signing_key:
117
117
  specification_version: 4
118
118
  summary: generate ranks of items from weighted lists