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 +4 -4
- data/.rubocop.yml +0 -0
- data/CHANGELOG.md +9 -1
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +0 -0
- data/Gemfile.lock +26 -24
- data/LICENSE.txt +0 -0
- data/README.md +72 -0
- data/Rakefile +1 -0
- data/lib/weighted_list_rank/context.rb +0 -0
- data/lib/weighted_list_rank/item.rb +6 -0
- data/lib/weighted_list_rank/list.rb +0 -0
- data/lib/weighted_list_rank/strategies/exponential.rb +28 -11
- data/lib/weighted_list_rank/strategy.rb +0 -0
- data/lib/weighted_list_rank/version.rb +1 -1
- data/lib/weighted_list_rank.rb +0 -0
- data/sig/weighted_list_rank.rbs +0 -0
- data/weighted_list_rank.gemspec +0 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9afa895dc286e9cc5dd2370376b965eda825669debad06e21c232b996e2cab6
|
4
|
+
data.tar.gz: 6116b3e97dc978a0ca8021f683ff7d5b31b1ebd1e0e3f07fc10c7a266b34659e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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.
|
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.
|
10
|
+
json (2.7.2)
|
11
11
|
language_server-protocol (3.17.0.3)
|
12
12
|
lint_roller (1.1.0)
|
13
|
-
minitest (5.
|
14
|
-
parallel (1.
|
15
|
-
parser (3.3.0
|
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.
|
18
|
+
racc (1.8.0)
|
19
19
|
rainbow (3.1.1)
|
20
|
-
rake (13.1
|
21
|
-
regexp_parser (2.9.
|
22
|
-
rexml (3.
|
23
|
-
|
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.
|
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.
|
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.
|
35
|
-
parser (>= 3.
|
36
|
-
rubocop-minitest (0.
|
37
|
-
rubocop (>= 1.
|
38
|
-
rubocop-ast (>= 1.
|
39
|
-
rubocop-performance (1.
|
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.
|
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.
|
46
|
+
standard (1.39.0)
|
46
47
|
language_server-protocol (~> 3.17.0.2)
|
47
48
|
lint_roller (~> 1.0)
|
48
|
-
rubocop (~> 1.
|
49
|
+
rubocop (~> 1.64.0)
|
49
50
|
standard-custom (~> 1.0.0)
|
50
|
-
standard-performance (~> 1.
|
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.
|
55
|
+
standard-performance (1.4.0)
|
55
56
|
lint_roller (~> 1.1)
|
56
|
-
rubocop-performance (~> 1.
|
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
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
|
-
#
|
46
|
-
|
45
|
+
# Default score to the list's weight
|
46
|
+
score = list.weight
|
47
47
|
|
48
|
-
|
49
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
56
|
-
|
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
|
-
|
59
|
-
|
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
|
data/lib/weighted_list_rank.rb
CHANGED
File without changes
|
data/sig/weighted_list_rank.rbs
CHANGED
File without changes
|
data/weighted_list_rank.gemspec
CHANGED
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.
|
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-
|
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.
|
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
|