commendo 0.0.5 → 0.0.6
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/CHANGELOG.md +3 -0
- data/lib/commendo/content_set.rb +3 -9
- data/lib/commendo/tag_set.rb +5 -0
- data/lib/commendo/version.rb +1 -1
- data/lib/commendo/weighted_group.rb +17 -6
- data/test/tag_set_test.rb +21 -0
- data/test/weighted_group_test.rb +122 -12
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f16a2f22f2afbdf32e7242ee821fca56ba8c690
|
4
|
+
data.tar.gz: c77c52106e8df36b855f41eb2c6bbd0d0f82bbbe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86cd12a3d567df7dc14bc77767d4297fca094fa4d0987bd8eb6674103c77455afc383a2933a2fa947e75b2ede3b07dd244379bf1b8ce5530b6d0e662c9830868
|
7
|
+
data.tar.gz: e327b49f232971ecb94c1e8bbec2e1ebf06673cdc596e2bc1a8722238fbc0316d24d84582d30a39769224288119e764cd473252c73184ee4d1b4fe190b62aea1
|
data/CHANGELOG.md
CHANGED
data/lib/commendo/content_set.rb
CHANGED
@@ -86,17 +86,12 @@ module Commendo
|
|
86
86
|
|
87
87
|
def filtered_similar_to(resource, options = {})
|
88
88
|
similar = similar_to(resource)
|
89
|
-
return similar if options[:include].nil? && options[:exclude].nil?
|
90
|
-
similar.delete_if { |s| !options[:exclude].nil? &&
|
91
|
-
similar.delete_if { |s| !options[:include].nil? &&
|
89
|
+
return similar if @tag_set.nil? || options[:include].nil? && options[:exclude].nil?
|
90
|
+
similar.delete_if { |s| !options[:exclude].nil? && @tag_set.matches(s[:resource], *options[:exclude]) }
|
91
|
+
similar.delete_if { |s| !options[:include].nil? && !@tag_set.matches(s[:resource], *options[:include]) }
|
92
92
|
similar
|
93
93
|
end
|
94
94
|
|
95
|
-
def tags_match(resource, tags)
|
96
|
-
resource_tags = tag_set.get(resource)
|
97
|
-
(resource_tags & tags).length > 0
|
98
|
-
end
|
99
|
-
|
100
95
|
def similarity_key(resource)
|
101
96
|
"#{similar_key_base}:#{resource}"
|
102
97
|
end
|
@@ -137,7 +132,6 @@ module Commendo
|
|
137
132
|
"#{key_base}:groups"
|
138
133
|
end
|
139
134
|
|
140
|
-
|
141
135
|
def group_key(group)
|
142
136
|
"#{group_key_base}:#{group}"
|
143
137
|
end
|
data/lib/commendo/tag_set.rb
CHANGED
data/lib/commendo/version.rb
CHANGED
@@ -2,18 +2,21 @@ module Commendo
|
|
2
2
|
|
3
3
|
class WeightedGroup
|
4
4
|
|
5
|
-
attr_accessor :content_sets, :redis, :key_base
|
5
|
+
attr_accessor :content_sets, :redis, :key_base, :tag_set
|
6
6
|
|
7
7
|
def initialize(redis, key_base, *content_sets)
|
8
8
|
@content_sets, @redis, @key_base = content_sets, redis, key_base
|
9
9
|
end
|
10
10
|
|
11
11
|
def similar_to(resource)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
resources = resource.kind_of?(Array) ? resource : [resource]
|
13
|
+
keys = []
|
14
|
+
weights = []
|
15
|
+
content_sets.each do |cs|
|
16
|
+
resources.each do |resource|
|
17
|
+
keys << cs[:cs].similarity_key(resource)
|
18
|
+
weights << cs[:weight]
|
19
|
+
end
|
17
20
|
end
|
18
21
|
tmp_key = "#{key_base}:tmp:#{SecureRandom.uuid}"
|
19
22
|
redis.zunionstore(tmp_key, keys, weights: weights)
|
@@ -26,6 +29,14 @@ module Commendo
|
|
26
29
|
|
27
30
|
end
|
28
31
|
|
32
|
+
def filtered_similar_to(resource, options = {})
|
33
|
+
similar = similar_to(resource)
|
34
|
+
return similar if @tag_set.nil? || options[:include].nil? && options[:exclude].nil?
|
35
|
+
similar.delete_if { |s| !options[:exclude].nil? && @tag_set.matches(s[:resource], *options[:exclude]) }
|
36
|
+
similar.delete_if { |s| !options[:include].nil? && !@tag_set.matches(s[:resource], *options[:include]) }
|
37
|
+
similar
|
38
|
+
end
|
39
|
+
|
29
40
|
end
|
30
41
|
|
31
42
|
end
|
data/test/tag_set_test.rb
CHANGED
@@ -44,5 +44,26 @@ module Commendo
|
|
44
44
|
assert_equal ['qip', 'qux'], ts.get(2)
|
45
45
|
end
|
46
46
|
|
47
|
+
def test_matches_tags
|
48
|
+
redis = Redis.new(db: 15)
|
49
|
+
redis.flushdb
|
50
|
+
ts = TagSet.new(redis, 'TagSetTest')
|
51
|
+
ts.set(1, 'foo', 'bar', 'baz')
|
52
|
+
ts.set(2, 'qux', 'qip')
|
53
|
+
|
54
|
+
assert ts.matches(1, 'foo')
|
55
|
+
assert ts.matches(1, 'bar', 'baz')
|
56
|
+
assert ts.matches(1, 'bar', 'baz', 'foo')
|
57
|
+
refute ts.matches(1, 'qux')
|
58
|
+
refute ts.matches(1, 'qip')
|
59
|
+
|
60
|
+
refute ts.matches(2, 'foo')
|
61
|
+
refute ts.matches(2, 'bar', 'baz')
|
62
|
+
refute ts.matches(2, 'bar', 'baz', 'foo')
|
63
|
+
assert ts.matches(2, 'qux', 'qip')
|
64
|
+
assert ts.matches(2, 'qux')
|
65
|
+
assert ts.matches(2, 'qip')
|
66
|
+
end
|
67
|
+
|
47
68
|
end
|
48
69
|
end
|
data/test/weighted_group_test.rb
CHANGED
@@ -9,21 +9,36 @@ module Commendo
|
|
9
9
|
|
10
10
|
class WeightedGroupTest < Minitest::Test
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
redis.
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
def setup
|
13
|
+
super
|
14
|
+
@redis ||= Redis.new(db: 15)
|
15
|
+
@redis.flushdb
|
16
|
+
@tag_set = TagSet.new(@redis, 'CommendoTests:Tags')
|
17
|
+
@cs1 = ContentSet.new(@redis, 'CommendoTests:ContentSet1', @tag_set)
|
18
|
+
@cs2 = ContentSet.new(@redis, 'CommendoTests:ContentSet2', @tag_set)
|
19
|
+
@cs3 = ContentSet.new(@redis, 'CommendoTests:ContentSet3', @tag_set)
|
18
20
|
(3..23).each do |group|
|
19
21
|
(3..23).each do |res|
|
20
|
-
cs1.add_by_group(group, res) if (res % group == 0) && (res % 2 == 0)
|
21
|
-
cs2.add_by_group(group, res) if (res % group == 0) && (res % 3 == 0)
|
22
|
-
cs3.add_by_group(group, res) if (res % group == 0) && (res % 6 == 0)
|
22
|
+
@cs1.add_by_group(group, res) if (res % group == 0) && (res % 2 == 0)
|
23
|
+
@cs2.add_by_group(group, res) if (res % group == 0) && (res % 3 == 0)
|
24
|
+
@cs3.add_by_group(group, res) if (res % group == 0) && (res % 6 == 0)
|
25
|
+
@tag_set.add(res, 'mod3') if res.modulo(3).zero?
|
26
|
+
@tag_set.add(res, 'mod4') if res.modulo(4).zero?
|
27
|
+
@tag_set.add(res, 'mod5') if res.modulo(5).zero?
|
28
|
+
@tag_set.add(res, 'mod7') if res.modulo(7).zero?
|
23
29
|
end
|
24
30
|
end
|
25
|
-
[cs1, cs2, cs3].each { |cs| cs.calculate_similarity }
|
26
|
-
|
31
|
+
[@cs1, @cs2, @cs3].each { |cs| cs.calculate_similarity }
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_calls_each_content_set
|
35
|
+
weighted_group = WeightedGroup.new(
|
36
|
+
@redis,
|
37
|
+
'CommendoTests:WeightedGroup',
|
38
|
+
{cs: @cs1, weight: 1.0},
|
39
|
+
{cs: @cs2, weight: 10.0},
|
40
|
+
{cs: @cs3, weight: 100.0}
|
41
|
+
)
|
27
42
|
expected = [
|
28
43
|
{resource: '6', similarity: 55.5},
|
29
44
|
{resource: '12', similarity: 36.963},
|
@@ -35,12 +50,107 @@ module Commendo
|
|
35
50
|
assert_equal expected, weighted_group.similar_to(18)
|
36
51
|
end
|
37
52
|
|
53
|
+
def test_filters_include_recommendations
|
54
|
+
weighted_group = WeightedGroup.new(
|
55
|
+
@redis,
|
56
|
+
'CommendoTests:WeightedGroup',
|
57
|
+
{cs: @cs1, weight: 1.0},
|
58
|
+
{cs: @cs2, weight: 10.0},
|
59
|
+
{cs: @cs3, weight: 100.0}
|
60
|
+
)
|
61
|
+
expected = [{resource: '15', similarity: 1.67}]
|
62
|
+
weighted_group.tag_set = @tag_set
|
63
|
+
assert_equal expected, weighted_group.filtered_similar_to(18, include: ['mod5'])
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_filters_exclude_recommendations
|
67
|
+
weighted_group = WeightedGroup.new(
|
68
|
+
@redis,
|
69
|
+
'CommendoTests:WeightedGroup',
|
70
|
+
{cs: @cs1, weight: 1.0},
|
71
|
+
{cs: @cs2, weight: 10.0},
|
72
|
+
{cs: @cs3, weight: 100.0}
|
73
|
+
)
|
74
|
+
expected = [
|
75
|
+
{resource: '6', similarity: 55.5},
|
76
|
+
{resource: '12', similarity: 36.963},
|
77
|
+
{resource: '9', similarity: 5.0},
|
78
|
+
{resource: '3', similarity: 2.5}
|
79
|
+
]
|
80
|
+
weighted_group.tag_set = @tag_set
|
81
|
+
assert_equal expected, weighted_group.filtered_similar_to(18, exclude: ['mod5', 'mod7'])
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_filters_include_and_exclude_recommendations
|
85
|
+
weighted_group = WeightedGroup.new(
|
86
|
+
@redis,
|
87
|
+
'CommendoTests:WeightedGroup',
|
88
|
+
{cs: @cs1, weight: 100.0},
|
89
|
+
{cs: @cs2, weight: 10.0},
|
90
|
+
{cs: @cs3, weight: 1.0}
|
91
|
+
)
|
92
|
+
expected = [
|
93
|
+
{resource: '16', similarity: 66.7},
|
94
|
+
{resource: '4', similarity: 50.0},
|
95
|
+
{resource: '12', similarity: 20.0}
|
96
|
+
]
|
97
|
+
weighted_group.tag_set = @tag_set
|
98
|
+
assert_equal expected, weighted_group.filtered_similar_to(8, include: ['mod4'], exclude: ['mod5'])
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_similar_to_mutliple_items
|
102
|
+
weighted_group = WeightedGroup.new(
|
103
|
+
@redis,
|
104
|
+
'CommendoTests:WeightedGroup',
|
105
|
+
{cs: @cs1, weight: 100.0},
|
106
|
+
{cs: @cs2, weight: 10.0},
|
107
|
+
{cs: @cs3, weight: 1.0}
|
108
|
+
)
|
109
|
+
expected = [
|
110
|
+
{resource: '12', similarity: 83.0},
|
111
|
+
{resource: '18', similarity: 58.0},
|
112
|
+
{resource: '8', similarity: 50.0},
|
113
|
+
{resource: '16', similarity: 33.3},
|
114
|
+
{resource: '20', similarity: 25.0},
|
115
|
+
{resource: '9', similarity: 8.33},
|
116
|
+
{resource: '21', similarity: 5.83},
|
117
|
+
{resource: '15', similarity: 5.83},
|
118
|
+
{resource: '6', similarity: 5.0},
|
119
|
+
{resource: '3', similarity: 5.0}
|
120
|
+
]
|
121
|
+
weighted_group.tag_set = @tag_set
|
122
|
+
assert_equal expected, weighted_group.similar_to([3,4,5,6,7])
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_filtered_similar_to_mutliple_items
|
126
|
+
weighted_group = WeightedGroup.new(
|
127
|
+
@redis,
|
128
|
+
'CommendoTests:WeightedGroup',
|
129
|
+
{cs: @cs1, weight: 100.0},
|
130
|
+
{cs: @cs2, weight: 10.0},
|
131
|
+
{cs: @cs3, weight: 1.0}
|
132
|
+
)
|
133
|
+
expected = [
|
134
|
+
{resource: '12', similarity: 83.0},
|
135
|
+
#{resource: '18', similarity: 58.0},
|
136
|
+
{resource: '8', similarity: 50.0},
|
137
|
+
{resource: '16', similarity: 33.3},
|
138
|
+
#{resource: '20', similarity: 25.0},
|
139
|
+
#{resource: '9', similarity: 8.33},
|
140
|
+
#{resource: '21', similarity: 5.83},
|
141
|
+
#{resource: '15', similarity: 5.83},
|
142
|
+
#{resource: '6', similarity: 5.0},
|
143
|
+
#{resource: '3', similarity: 5.0}
|
144
|
+
]
|
145
|
+
weighted_group.tag_set = @tag_set
|
146
|
+
assert_equal expected, weighted_group.filtered_similar_to([3,4,5,6,7], include: ['mod4'], exclude: ['mod5'])
|
147
|
+
end
|
148
|
+
|
38
149
|
def test_precalculates
|
39
150
|
skip
|
40
151
|
end
|
41
152
|
|
42
153
|
|
43
|
-
|
44
154
|
end
|
45
155
|
|
46
156
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: commendo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Styles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|