commendo 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/commendo.rb +2 -1
- data/lib/commendo/content_set.rb +15 -3
- data/lib/commendo/tag_set.rb +36 -0
- data/lib/commendo/version.rb +1 -1
- data/test/content_set_test.rb +86 -13
- data/test/tag_set_test.rb +48 -0
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6882c6ed2001ecae7be9eae066e3f534beeb1559
|
4
|
+
data.tar.gz: 0a0982ccc0a17285537b1adfc12bfe854da6c10f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 834aeca013589496b5e6b95a0d5ec7e327fc6192ba57e7dab7c2d8507055013058a96b354b13bb2422c21caa7cce92c0fd5f0011c60d3cb5c202b723eb94dbf4
|
7
|
+
data.tar.gz: d773e4c3776f66ba003cf7b7c1327a376e439f8f72480b903d1512db906c27aa55c9f01a052c11a24fbde4f4e90d7bb50b13d6494fbd963ea407d0d4807eb5fd
|
data/CHANGELOG.md
CHANGED
data/lib/commendo.rb
CHANGED
data/lib/commendo/content_set.rb
CHANGED
@@ -2,10 +2,10 @@ module Commendo
|
|
2
2
|
|
3
3
|
class ContentSet
|
4
4
|
|
5
|
-
attr_accessor :redis, :key_base
|
5
|
+
attr_accessor :redis, :key_base, :tag_set
|
6
6
|
|
7
|
-
def initialize(redis, key_base)
|
8
|
-
@redis, @key_base = redis, key_base
|
7
|
+
def initialize(redis, key_base, tag_set = nil)
|
8
|
+
@redis, @key_base, @tag_set = redis, key_base, tag_set
|
9
9
|
end
|
10
10
|
|
11
11
|
def add_by_group(group, *resources)
|
@@ -68,7 +68,19 @@ module Commendo
|
|
68
68
|
similar_resources.map do |resource|
|
69
69
|
{resource: resource[0], similarity: resource[1].to_f}
|
70
70
|
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def filtered_similar_to(resource, options = {})
|
74
|
+
similar = similar_to(resource)
|
75
|
+
return similar if options[:include].nil? && options[:exclude].nil?
|
76
|
+
similar.delete_if { |s| !options[:exclude].nil? && tags_match(s[:resource], options[:exclude]) }
|
77
|
+
similar.delete_if { |s| !options[:include].nil? && !tags_match(s[:resource], options[:include]) }
|
78
|
+
similar
|
79
|
+
end
|
71
80
|
|
81
|
+
def tags_match(resource, tags)
|
82
|
+
resource_tags = tag_set.get(resource)
|
83
|
+
(resource_tags & tags).length > 0
|
72
84
|
end
|
73
85
|
|
74
86
|
def similarity_key(resource)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Commendo
|
2
|
+
|
3
|
+
class TagSet
|
4
|
+
|
5
|
+
attr_accessor :redis, :key_base
|
6
|
+
|
7
|
+
def initialize(redis, key_base)
|
8
|
+
@redis, @key_base = redis, key_base
|
9
|
+
end
|
10
|
+
|
11
|
+
def get(resource)
|
12
|
+
redis.smembers(resource_key(resource)).sort
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(resource, *tags)
|
16
|
+
redis.sadd(resource_key(resource), tags)
|
17
|
+
end
|
18
|
+
|
19
|
+
def set(resource, *tags)
|
20
|
+
delete(resource)
|
21
|
+
add(resource, *tags)
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(resource)
|
25
|
+
redis.del(resource_key(resource))
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def resource_key(resource)
|
31
|
+
"#{key_base}:#{resource}"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
data/lib/commendo/version.rb
CHANGED
data/test/content_set_test.rb
CHANGED
@@ -66,12 +66,12 @@ module Commendo
|
|
66
66
|
end
|
67
67
|
cs.calculate_similarity
|
68
68
|
expected = [
|
69
|
-
{
|
70
|
-
{
|
71
|
-
{
|
72
|
-
{
|
73
|
-
{
|
74
|
-
{
|
69
|
+
{resource: '9', similarity: 0.5},
|
70
|
+
{resource: '6', similarity: 0.5},
|
71
|
+
{resource: '12', similarity: 0.33333333333333},
|
72
|
+
{resource: '3', similarity: 0.25},
|
73
|
+
{resource: '21', similarity: 0.16666666666667},
|
74
|
+
{resource: '15', similarity: 0.16666666666667}
|
75
75
|
]
|
76
76
|
assert_equal expected, cs.similar_to(18)
|
77
77
|
end
|
@@ -88,8 +88,8 @@ module Commendo
|
|
88
88
|
end
|
89
89
|
cs.calculate_similarity(0.4)
|
90
90
|
expected = [
|
91
|
-
{
|
92
|
-
{
|
91
|
+
{resource: '9', similarity: 0.5},
|
92
|
+
{resource: '6', similarity: 0.5},
|
93
93
|
]
|
94
94
|
assert_equal expected, cs.similar_to(18)
|
95
95
|
end
|
@@ -144,16 +144,89 @@ module Commendo
|
|
144
144
|
assert similar_to(cs, 10, 12)
|
145
145
|
end
|
146
146
|
|
147
|
-
def
|
148
|
-
|
147
|
+
def test_filters_include_by_tag_collection
|
148
|
+
redis = Redis.new(db: 15)
|
149
|
+
redis.flushdb
|
150
|
+
ts = TagSet.new(redis, 'CommendoTests:tags')
|
151
|
+
cs = ContentSet.new(redis, 'CommendoTests', ts)
|
152
|
+
(3..23).each do |group|
|
153
|
+
(3..23).each do |res|
|
154
|
+
cs.add(res, group) if res % group == 0
|
155
|
+
ts.add(res, 'mod3') if res.modulo(3).zero?
|
156
|
+
ts.add(res, 'mod4') if res.modulo(4).zero?
|
157
|
+
ts.add(res, 'mod5') if res.modulo(5).zero?
|
158
|
+
end
|
159
|
+
end
|
160
|
+
cs.calculate_similarity
|
161
|
+
|
162
|
+
actual = cs.filtered_similar_to(10, include: ['mod5'])
|
163
|
+
assert_equal 3, actual.length
|
164
|
+
assert contains_resource('5', actual)
|
165
|
+
assert contains_resource('15', actual)
|
166
|
+
assert contains_resource('20', actual)
|
167
|
+
|
149
168
|
end
|
150
169
|
|
151
|
-
def
|
152
|
-
|
170
|
+
def test_filters_exclude_by_tag_collection
|
171
|
+
redis = Redis.new(db: 15)
|
172
|
+
redis.flushdb
|
173
|
+
ts = TagSet.new(redis, 'CommendoTests:tags')
|
174
|
+
cs = ContentSet.new(redis, 'CommendoTests', ts)
|
175
|
+
(3..23).each do |group|
|
176
|
+
(3..23).each do |res|
|
177
|
+
cs.add(res, group) if res % group == 0
|
178
|
+
ts.add(res, 'mod3') if res.modulo(3).zero?
|
179
|
+
ts.add(res, 'mod4') if res.modulo(4).zero?
|
180
|
+
ts.add(res, 'mod5') if res.modulo(5).zero?
|
181
|
+
end
|
182
|
+
end
|
183
|
+
cs.calculate_similarity
|
184
|
+
|
185
|
+
actual = cs.filtered_similar_to(10, exclude: ['mod3'])
|
186
|
+
assert_equal 2, actual.length
|
187
|
+
assert contains_resource('5', actual)
|
188
|
+
assert contains_resource('20', actual)
|
189
|
+
refute contains_resource('15', actual)
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_filters_includes_and_exclude_by_tag_collection
|
194
|
+
redis = Redis.new(db: 15)
|
195
|
+
redis.flushdb
|
196
|
+
ts = TagSet.new(redis, 'CommendoTests:tags')
|
197
|
+
cs = ContentSet.new(redis, 'CommendoTests', ts)
|
198
|
+
(3..23).each do |group|
|
199
|
+
(3..23).each do |res|
|
200
|
+
cs.add(res, group) if res % group == 0
|
201
|
+
ts.add(res, 'mod3') if res.modulo(3).zero?
|
202
|
+
ts.add(res, 'mod4') if res.modulo(4).zero?
|
203
|
+
ts.add(res, 'mod5') if res.modulo(5).zero?
|
204
|
+
end
|
205
|
+
end
|
206
|
+
cs.calculate_similarity
|
207
|
+
|
208
|
+
actual = cs.filtered_similar_to(12, include: ['mod4'], exclude: ['mod3', 'mod5'])
|
209
|
+
assert_equal 3, actual.length
|
210
|
+
|
211
|
+
refute contains_resource('6', actual)
|
212
|
+
refute contains_resource('18', actual)
|
213
|
+
assert contains_resource('4', actual)
|
214
|
+
refute contains_resource('3', actual)
|
215
|
+
refute contains_resource('9', actual)
|
216
|
+
assert contains_resource('8', actual)
|
217
|
+
refute contains_resource('21', actual)
|
218
|
+
assert contains_resource('16', actual)
|
219
|
+
refute contains_resource('15', actual)
|
220
|
+
refute contains_resource('20', actual)
|
221
|
+
|
153
222
|
end
|
154
223
|
|
155
224
|
def similar_to(cs, resource, similar)
|
156
|
-
cs.similar_to(resource)
|
225
|
+
contains_resource(similar, cs.similar_to(resource))
|
226
|
+
end
|
227
|
+
|
228
|
+
def contains_resource(resource, similarities)
|
229
|
+
similarities.select { |sim| sim[:resource] == "#{resource}" }.length > 0
|
157
230
|
end
|
158
231
|
|
159
232
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
gem 'minitest'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'minitest/pride'
|
4
|
+
require 'minitest/mock'
|
5
|
+
require 'mocha/setup'
|
6
|
+
require 'commendo'
|
7
|
+
|
8
|
+
module Commendo
|
9
|
+
|
10
|
+
class TagSetTest < Minitest::Test
|
11
|
+
|
12
|
+
def test_adds_tags_for_resource
|
13
|
+
redis = Redis.new(db: 15)
|
14
|
+
redis.flushdb
|
15
|
+
ts = TagSet.new(redis, 'TagSetTest')
|
16
|
+
assert_equal [], ts.get(1)
|
17
|
+
ts.add(1, 'foo', 'bar', 'baz')
|
18
|
+
assert_equal ['bar', 'baz','foo'], ts.get(1)
|
19
|
+
ts.add(1, 'qux', 'qip')
|
20
|
+
assert_equal ['bar', 'baz', 'foo', 'qip', 'qux'], ts.get(1)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_sets_tags_for_resource
|
24
|
+
redis = Redis.new(db: 15)
|
25
|
+
redis.flushdb
|
26
|
+
ts = TagSet.new(redis, 'TagSetTest')
|
27
|
+
assert_equal [], ts.get(1)
|
28
|
+
ts.set(1, 'foo', 'bar', 'baz')
|
29
|
+
assert_equal ['bar', 'baz', 'foo'], ts.get(1)
|
30
|
+
ts.set(1, 'qux', 'qip')
|
31
|
+
assert_equal ['qip', 'qux'], ts.get(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_deletes_tags_for_resource
|
35
|
+
redis = Redis.new(db: 15)
|
36
|
+
redis.flushdb
|
37
|
+
ts = TagSet.new(redis, 'TagSetTest')
|
38
|
+
ts.set(1, 'foo', 'bar', 'baz')
|
39
|
+
ts.set(2, 'qux', 'qip')
|
40
|
+
assert_equal ['bar', 'baz', 'foo'], ts.get(1)
|
41
|
+
assert_equal ['qip', 'qux'], ts.get(2)
|
42
|
+
ts.delete(1)
|
43
|
+
assert_equal [], ts.get(1)
|
44
|
+
assert_equal ['qip', 'qux'], ts.get(2)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Styles
|
@@ -111,9 +111,11 @@ files:
|
|
111
111
|
- lib/commendo.rb
|
112
112
|
- lib/commendo/content_set.rb
|
113
113
|
- lib/commendo/similarity.lua
|
114
|
+
- lib/commendo/tag_set.rb
|
114
115
|
- lib/commendo/version.rb
|
115
116
|
- lib/commendo/weighted_group.rb
|
116
117
|
- test/content_set_test.rb
|
118
|
+
- test/tag_set_test.rb
|
117
119
|
- test/weighted_group_test.rb
|
118
120
|
homepage: ''
|
119
121
|
licenses:
|
@@ -141,5 +143,6 @@ specification_version: 4
|
|
141
143
|
summary: A Jaccard-similarity recommender using Redis sets
|
142
144
|
test_files:
|
143
145
|
- test/content_set_test.rb
|
146
|
+
- test/tag_set_test.rb
|
144
147
|
- test/weighted_group_test.rb
|
145
148
|
has_rdoc:
|