splashy 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -41,20 +41,24 @@ buckets.select
41
41
  # :b => ["20", "21"],
42
42
  # :c => ["30", "31", "32", "33", "34", "35", "36", "37"]
43
43
  # }
44
+
45
+ # Or even grab randomly:
46
+
47
+ buckets.select( :random => true )
44
48
  ```
45
49
 
46
50
  Changelog
47
51
  =========
48
52
 
49
- * 0.1.0 - Several bug fixes, add "neediest_buckets" method to Buckets to allow
50
- you to choose which buckets to add to first if an element can be put in
53
+ * *0.1.1* - Add support for random selection from buckets.
54
+ * *0.1.0* - Several bug fixes, add `#neediest_buckets` method to `Buckets` to
55
+ allow you to choose which buckets to add to first if an element can be put in
51
56
  multiple buckets, final distributions can now have empty buckets if it means
52
- we meet the wanted distribution better (i.e. a 99% % 1% distribution with 5
53
- and 1 elements, respectively, which will now select 4 and 0 elements if your
54
- wanted count is 4).
55
- * 0.0.2 - Raise `ArgumentError` when trying to add to a bucket that doesn't
57
+ we meet the wanted distribution better (i.e. a 99% to 1% wanted distribution
58
+ with 5 and 1 elements, respectively, which will now select 4 and 0 elements if your wanted count is 4).
59
+ * *0.0.2* - Raise `ArgumentError` when trying to add to a bucket that doesn't
56
60
  exist, don't consider an empty bucket "satisfied".
57
- * 0.0.1 - Initial release.
61
+ * *0.0.1* - Initial release.
58
62
 
59
63
  Contributing
60
64
  ============
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -1,7 +1,7 @@
1
1
  module Splashy
2
2
  private
3
3
 
4
- # Private: Collector of elements.
4
+ # Private: Collects elements and maintains a count.
5
5
  class Bucket
6
6
  attr_reader :name
7
7
 
@@ -22,6 +22,14 @@ module Splashy
22
22
  end
23
23
  end
24
24
 
25
+ def random_elements( count = nil )
26
+ if @elements.respond_to?( :sample )
27
+ @elements.sample( count )
28
+ else
29
+ count ? @elements.sort_by{ rand }[0, count] : @elements.sort_by{ rand }
30
+ end
31
+ end
32
+
25
33
  def empty?
26
34
  self.count == 0
27
35
  end
@@ -30,4 +38,4 @@ module Splashy
30
38
  @elements.count
31
39
  end
32
40
  end
33
- end
41
+ end
@@ -69,9 +69,12 @@ module Splashy
69
69
  #
70
70
  # Returns a Hash of elements matching the desired distribution, keyed by
71
71
  # the bucket names.
72
- def select
72
+ def select( opts = {} )
73
73
  self.assert_satisfied!
74
- selected = self._select_wanted
74
+ opts = { :random => false }.merge( opts )
75
+
76
+ selected = self._select_wanted( opts[:random] )
77
+
75
78
  # Sometimes we need to fudge by a few to meet the `@wanted_count`
76
79
  selected = self.trim( selected, @wanted_count ) if @wanted_count
77
80
  selected
@@ -101,13 +104,17 @@ module Splashy
101
104
  #
102
105
  # Returns Hash of bucket elements, matching the wanted distribution as
103
106
  # closely as possible.
104
- def _select_wanted
107
+ def _select_wanted( randomly = false )
105
108
  final_count = self.estimated_final_count
106
109
 
107
110
  @buckets.values.inject({}) do |memo, bucket|
108
111
  count = ( final_count * @wanted_distribution[bucket.name] ).round
109
112
  count = [1, count].max # Ensure every bucket has at least one element
110
- memo[bucket.name] = bucket.elements( count )
113
+ if randomly
114
+ memo[bucket.name] = bucket.random_elements( count )
115
+ else
116
+ memo[bucket.name] = bucket.elements( count )
117
+ end
111
118
  memo
112
119
  end
113
120
  end
data/splashy.gemspec CHANGED
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{splashy}
8
- s.version = "0.1.0"
7
+ s.name = "splashy"
8
+ s.version = "0.1.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tyson Tate"]
12
- s.date = %q{2011-12-09}
13
- s.description = %q{Simple distribution-based sampling of arbitrary objects from any number of buckets. Splashy. Buckets. Get it!?}
14
- s.email = %q{tyson@tysontate.com}
12
+ s.date = "2011-12-13"
13
+ s.description = "Simple distribution-based sampling of arbitrary objects from any number of buckets. Splashy. Buckets. Get it!?"
14
+ s.email = "tyson@tysontate.com"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
17
  "README.markdown"
@@ -23,7 +23,6 @@ Gem::Specification.new do |s|
23
23
  "README.markdown",
24
24
  "Rakefile",
25
25
  "VERSION",
26
- "buckets.gemspec",
27
26
  "lib/splashy.rb",
28
27
  "lib/splashy/bucket.rb",
29
28
  "lib/splashy/buckets.rb",
@@ -31,11 +30,11 @@ Gem::Specification.new do |s|
31
30
  "test/helper.rb",
32
31
  "test/test_splashy_buckets.rb"
33
32
  ]
34
- s.homepage = %q{http://github.com/tysontate/splashy}
33
+ s.homepage = "http://github.com/tysontate/splashy"
35
34
  s.licenses = ["MIT"]
36
35
  s.require_paths = ["lib"]
37
- s.rubygems_version = %q{1.4.2}
38
- s.summary = %q{Simple distribution-based sampling of arbitrary objects from buckets.}
36
+ s.rubygems_version = "1.8.11"
37
+ s.summary = "Simple distribution-based sampling of arbitrary objects from buckets."
39
38
 
40
39
  if s.respond_to? :specification_version then
41
40
  s.specification_version = 3
data/test/helper.rb CHANGED
@@ -8,7 +8,6 @@ rescue Bundler::BundlerError => e
8
8
  exit e.status_code
9
9
  end
10
10
  require 'minitest/autorun'
11
- # require 'minitest/unit'
12
11
  require 'minitest/benchmark'
13
12
 
14
13
  $LOAD_PATH.unshift(File.dirname(__FILE__))
@@ -213,7 +213,7 @@ describe Splashy::Buckets do
213
213
  end
214
214
 
215
215
  it "selects from a pool with an uneven distribution" do
216
- @buckets = Splashy::Buckets.new( {:a => 0.33, :b => 0.33, :c => 0.34}, 5 )
216
+ @buckets = Splashy::Buckets.new( {:a => 0.34, :b => 0.32, :c => 0.34}, 5 )
217
217
  fill_with_counts( 10, 2, 40 )
218
218
  assert @buckets.satisfied?
219
219
  assert_equal(
@@ -241,6 +241,18 @@ describe Splashy::Buckets do
241
241
  @buckets.select
242
242
  )
243
243
  end
244
+
245
+ it "selects randomly" do
246
+ @buckets = Splashy::Buckets.new( {:a => 0.5, :b => 0.20, :c => 0.30}, 10 )
247
+ fill_with_counts( 10, 10, 10 )
248
+ assert @buckets.satisfied?
249
+ randomized = @buckets.select( :random => true )
250
+ assert_equal( 5, randomized[:a].size )
251
+ assert_equal( 2, randomized[:b].size )
252
+ assert_equal( 3, randomized[:c].size )
253
+ # Non-deterministic, obv, but whatever.
254
+ assert_equal( false, randomized[:a].sort == randomized[:a] )
255
+ end
244
256
  end
245
257
 
246
258
  describe "variances" do
@@ -263,7 +275,7 @@ describe Splashy::Buckets do
263
275
  end
264
276
 
265
277
  it "reports on a pool with a wacky distribution" do
266
- @buckets = Splashy::Buckets.new( {:a => 0.01, :b => 0.01, :c => 0.98} )
278
+ @buckets = Splashy::Buckets.new( {:a => 0.02, :b => 0.01, :c => 0.97} )
267
279
  fill_with_counts( 3, 3, 3 )
268
280
  assert_equal( [:c, :a, :b], @buckets.neediest_buckets )
269
281
  end
@@ -283,4 +295,3 @@ describe Splashy::Buckets do
283
295
  end
284
296
  end
285
297
  end
286
-
metadata CHANGED
@@ -1,125 +1,96 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: splashy
3
- version: !ruby/object:Gem::Version
4
- hash: 27
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 0
10
- version: 0.1.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Tyson Tate
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-12-09 00:00:00 -08:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- prerelease: false
12
+ date: 2011-12-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
23
15
  name: minitest
24
- type: :development
25
- version_requirements: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70277083322720 !ruby/object:Gem::Requirement
26
17
  none: false
27
- requirements:
28
- - - ">="
29
- - !ruby/object:Gem::Version
30
- hash: 3
31
- segments:
32
- - 0
33
- version: "0"
34
- requirement: *id001
35
- - !ruby/object:Gem::Dependency
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
36
23
  prerelease: false
24
+ version_requirements: *70277083322720
25
+ - !ruby/object:Gem::Dependency
37
26
  name: bundler
38
- type: :development
39
- version_requirements: &id002 !ruby/object:Gem::Requirement
27
+ requirement: &70277083321600 !ruby/object:Gem::Requirement
40
28
  none: false
41
- requirements:
29
+ requirements:
42
30
  - - ~>
43
- - !ruby/object:Gem::Version
44
- hash: 23
45
- segments:
46
- - 1
47
- - 0
48
- - 0
31
+ - !ruby/object:Gem::Version
49
32
  version: 1.0.0
50
- requirement: *id002
51
- - !ruby/object:Gem::Dependency
33
+ type: :development
52
34
  prerelease: false
35
+ version_requirements: *70277083321600
36
+ - !ruby/object:Gem::Dependency
53
37
  name: jeweler
54
- type: :development
55
- version_requirements: &id003 !ruby/object:Gem::Requirement
38
+ requirement: &70277083320380 !ruby/object:Gem::Requirement
56
39
  none: false
57
- requirements:
40
+ requirements:
58
41
  - - ~>
59
- - !ruby/object:Gem::Version
60
- hash: 7
61
- segments:
62
- - 1
63
- - 6
64
- - 4
42
+ - !ruby/object:Gem::Version
65
43
  version: 1.6.4
66
- requirement: *id003
67
- description: Simple distribution-based sampling of arbitrary objects from any number of buckets. Splashy. Buckets. Get it!?
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70277083320380
47
+ description: Simple distribution-based sampling of arbitrary objects from any number
48
+ of buckets. Splashy. Buckets. Get it!?
68
49
  email: tyson@tysontate.com
69
50
  executables: []
70
-
71
51
  extensions: []
72
-
73
- extra_rdoc_files:
52
+ extra_rdoc_files:
74
53
  - LICENSE.txt
75
54
  - README.markdown
76
- files:
55
+ files:
77
56
  - Gemfile
78
57
  - Gemfile.lock
79
58
  - LICENSE.txt
80
59
  - README.markdown
81
60
  - Rakefile
82
61
  - VERSION
83
- - buckets.gemspec
84
62
  - lib/splashy.rb
85
63
  - lib/splashy/bucket.rb
86
64
  - lib/splashy/buckets.rb
87
65
  - splashy.gemspec
88
66
  - test/helper.rb
89
67
  - test/test_splashy_buckets.rb
90
- has_rdoc: true
91
68
  homepage: http://github.com/tysontate/splashy
92
- licenses:
69
+ licenses:
93
70
  - MIT
94
71
  post_install_message:
95
72
  rdoc_options: []
96
-
97
- require_paths:
73
+ require_paths:
98
74
  - lib
99
- required_ruby_version: !ruby/object:Gem::Requirement
75
+ required_ruby_version: !ruby/object:Gem::Requirement
100
76
  none: false
101
- requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- hash: 3
105
- segments:
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ segments:
106
82
  - 0
107
- version: "0"
108
- required_rubygems_version: !ruby/object:Gem::Requirement
83
+ hash: 4086114583339023412
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
85
  none: false
110
- requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- hash: 3
114
- segments:
115
- - 0
116
- version: "0"
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
117
90
  requirements: []
118
-
119
91
  rubyforge_project:
120
- rubygems_version: 1.4.2
92
+ rubygems_version: 1.8.11
121
93
  signing_key:
122
94
  specification_version: 3
123
95
  summary: Simple distribution-based sampling of arbitrary objects from buckets.
124
96
  test_files: []
125
-
data/buckets.gemspec DELETED
@@ -1,57 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{buckets}
8
- s.version = "0.0.1"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Tyson Tate"]
12
- s.date = %q{2011-12-08}
13
- s.description = %q{Simple distribution-based sampling of arbitrary objects via the use of, well, buckets.}
14
- s.email = %q{tyson@tysontate.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE.txt",
17
- "README.markdown"
18
- ]
19
- s.files = [
20
- "Gemfile",
21
- "Gemfile.lock",
22
- "LICENSE.txt",
23
- "README.markdown",
24
- "Rakefile",
25
- "VERSION",
26
- "buckets.gemspec",
27
- "lib/splashy.rb",
28
- "lib/splashy/bucket.rb",
29
- "lib/splashy/buckets.rb",
30
- "test/helper.rb",
31
- "test/test_splashy_buckets.rb"
32
- ]
33
- s.homepage = %q{http://github.com/tysontate/buckets}
34
- s.licenses = ["MIT"]
35
- s.require_paths = ["lib"]
36
- s.rubygems_version = %q{1.4.2}
37
- s.summary = %q{Simple distribution-based sampling of arbitrary objects.}
38
-
39
- if s.respond_to? :specification_version then
40
- s.specification_version = 3
41
-
42
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
- s.add_development_dependency(%q<minitest>, [">= 0"])
44
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
45
- s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
46
- else
47
- s.add_dependency(%q<minitest>, [">= 0"])
48
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
49
- s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
50
- end
51
- else
52
- s.add_dependency(%q<minitest>, [">= 0"])
53
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
54
- s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
55
- end
56
- end
57
-