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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 01e2c317e998efe31d72e1a399d1d8eb677854a7
4
- data.tar.gz: fad0b2a2c09333ef31eff3f3aaaf91c7b3d1862f
3
+ metadata.gz: 6882c6ed2001ecae7be9eae066e3f534beeb1559
4
+ data.tar.gz: 0a0982ccc0a17285537b1adfc12bfe854da6c10f
5
5
  SHA512:
6
- metadata.gz: 8d0563d3909815866885f6f654c172f39675c442fb24a7306162090f848e2e50f4161aabf0fcc4f4779e474ff3b5c9902ec8d5c7cdc66db69cd7a3886f17a9bc
7
- data.tar.gz: f05702dd19c5be8b6480ef4a513294c493f7138a2bb2d3c5f329fc6a734a9060660ab168f4d987f830c188142fc6bd5334c0a903b0f45024d7810ba7cb02e284
6
+ metadata.gz: 834aeca013589496b5e6b95a0d5ec7e327fc6192ba57e7dab7c2d8507055013058a96b354b13bb2422c21caa7cce92c0fd5f0011c60d3cb5c202b723eb94dbf4
7
+ data.tar.gz: d773e4c3776f66ba003cf7b7c1327a376e439f8f72480b903d1512db906c27aa55c9f01a052c11a24fbde4f4e90d7bb50b13d6494fbd963ea407d0d4807eb5fd
@@ -1,3 +1,6 @@
1
+ # 0.0.3 / 2014-03-31
2
+ * [FEATURE] Filtering of recommendations based on tags
3
+
1
4
  # 0.0.2 / 2014-03-31
2
5
  * [FEATURE] Weighted groups. Incremental additions. Deletions.
3
6
 
@@ -1,8 +1,9 @@
1
1
  require 'redis'
2
2
  require 'commendo/version'
3
3
  require 'commendo/content_set'
4
+ require 'commendo/tag_set'
4
5
  require 'commendo/weighted_group'
5
6
 
6
7
  module Commendo
7
- # Your code goes here...
8
+
8
9
  end
@@ -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
+
@@ -1,3 +1,3 @@
1
1
  module Commendo
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -66,12 +66,12 @@ module Commendo
66
66
  end
67
67
  cs.calculate_similarity
68
68
  expected = [
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 }
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
- { resource: '9', similarity: 0.5 },
92
- { resource: '6', similarity: 0.5 },
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 test_accepts_tag_collection
148
- skip
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 test_filters_by_tag_collection
152
- skip
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).select { |sim| sim[:resource] == "#{similar}" }.length > 0
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.2
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: