weighted_list_rank 0.3.0 → 0.4.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.
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