weightedpicker 0.1.1 → 0.1.2

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.
data/spec/spec_helper.rb DELETED
@@ -1,12 +0,0 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- require 'rspec'
4
- require 'weightedpicker'
5
-
6
- # Requires supporting files with custom matchers and macros, etc,
7
- # in ./support/ and its subdirectories.
8
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
-
10
- RSpec.configure do |config|
11
-
12
- end
data/spec/tree_spec.rb DELETED
@@ -1,123 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require "stringio"
3
- require "fileutils"
4
-
5
- class WeightedPicker::Tree
6
- public :log2_ceil
7
- public :depth
8
- public :choose
9
- public :index
10
- public :add_ancestors
11
- attr_reader :weights
12
- end
13
-
14
- describe "Weightedpicker::Tree" do
15
- before do
16
- @tree00 = WeightedPicker::Tree.new({"A" => 2, "B" => 1, "C" => 1})
17
- @tree01 = WeightedPicker::Tree.new({"A" => 0})
18
- @tree02 = WeightedPicker::Tree.new({})
19
- end
20
-
21
- it "should do in initialize" do
22
- #@tree00
23
- end
24
-
25
- it "should return a hash of names_weights" do
26
- #@tree00 = WeightedPicker::Tree.new({"A" => 2, "B" => 1, "C" => 1})
27
- @tree00.names_weights.should == {"A" => 2, "B" => 1, "C" => 1}
28
- end
29
-
30
- it "should pick" do
31
- results = {"A" => 0, "B" => 0, "C" => 0}
32
- srand(0)
33
- 300.times do |i|
34
- results[@tree00.pick] += 1
35
- end
36
- #pp results #=> {"A"=> 52, "B"=>76, "C"=>72}
37
- results["A"].should be_within(15).of(150)
38
- results["B"].should be_within( 8).of( 75)
39
- results["C"].should be_within( 8).of( 75)
40
-
41
- lambda{ @tree01.pick}.should raise_error(WeightedPicker::Tree::NoEntryError)
42
- lambda{ @tree02.pick}.should raise_error(WeightedPicker::Tree::NoEntryError)
43
- end
44
-
45
- it "should weigh item" do
46
- @tree00.weigh "A"
47
- @tree00.weights.should == [
48
- [6],
49
- [5,1],
50
- [4,1,1,0],
51
- ]
52
- @tree00.names_weights.should == {"A" => 4, "B" => 1, "C" => 1}
53
- lambda{ @tree00.weigh("D")}.should raise_error(WeightedPicker::Tree::NoEntryError)
54
- end
55
-
56
- it "should weigh item, but be limited by MAX" do
57
- tree10 = WeightedPicker::Tree.new({"A" => 60000, "B" => 1, "C" => 1})
58
-
59
- tree10.weigh "A"
60
- tree10.weights.should == [
61
- [65538],
62
- [65537,1],
63
- [65536,1,1,0],
64
- ]
65
- tree10.names_weights.should == {"A" => 65536, "B" => 1, "C" => 1}
66
- end
67
-
68
- it "should lighten item" do
69
- @tree00.lighten "A"
70
- @tree00.weights.should == [
71
- [3],
72
- [2,1],
73
- [1,1,1,0],
74
- ]
75
- @tree00.names_weights.should == {"A" => 1, "B" => 1, "C" => 1}
76
- lambda{ @tree00.lighten("D")}.should raise_error(WeightedPicker::Tree::NoEntryError)
77
- end
78
-
79
- it "should lighten item, but be limited by MIN" do
80
- @tree00.lighten "B"
81
- @tree00.weights.should == [
82
- [4],
83
- [3,1],
84
- [2,1,1,0],
85
- ]
86
- @tree00.names_weights.should == {"A" => 2, "B" => 1, "C" => 1}
87
- end
88
-
89
-
90
- it "should add_ancestors" do
91
- @tree00.add_ancestors(1,10)
92
- @tree00.weights.should == [
93
- [14],
94
- [13,1],
95
- [2,11,1,0],
96
- ]
97
- end
98
-
99
- it "should log2_ceil" do
100
- #lambda{ @tree00.log2_ceil(0)}.should raise_error(WeightedPicker::Tree::NoEntryError)
101
- @tree00.log2_ceil( 1).should == 0
102
- @tree00.log2_ceil( 2).should == 1
103
- @tree00.log2_ceil( 3).should == 2
104
- @tree00.log2_ceil( 4).should == 2
105
- @tree00.log2_ceil( 8).should == 3
106
- @tree00.log2_ceil(16).should == 4
107
- @tree00.log2_ceil(20).should == 5
108
- end
109
-
110
- #it "should choose" do
111
- # @tree00.choose(1,2).should == 0
112
- # @tree00.choose(1,2).should == 1
113
- # @tree00.choose(1,2).should == 1
114
- #end
115
-
116
- it "should get index" do
117
- @tree00.index("A").should == 0
118
- @tree00.index("B").should == 1
119
- #lambda{ @tree00.find("C")}.should raise_error(WeightedPicker::Tree::NoEntryError)
120
- end
121
-
122
- end
123
-
@@ -1,238 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require "stringio"
3
- require "fileutils"
4
-
5
- class WeightedPicker
6
- attr_accessor :weights
7
- public :merge
8
- end
9
-
10
- AB_YAML = "spec/a256b128.yaml"
11
- NOT_EXIST_FILE = "not_exist_file"
12
-
13
-
14
-
15
- describe "Weightedpicker" do
16
- before do
17
- @wp00 = WeightedPicker.new({})
18
- @wp01 = WeightedPicker.load_file "spec/a256b128.yaml"
19
- @wp02 = WeightedPicker.load_file "spec/a512b64.yaml"
20
- end
21
-
22
- describe "initialize" do
23
- it "should create new file with data of 256 when the file not exist" do
24
- FileUtils.rm NOT_EXIST_FILE if File.exist? NOT_EXIST_FILE
25
- lambda{
26
- WeightedPicker.load_file(NOT_EXIST_FILE)
27
- }.should raise_error(Errno::ENOENT)
28
- FileUtils.rm NOT_EXIST_FILE if File.exist? NOT_EXIST_FILE
29
- end
30
-
31
- #it "should raise exception" do
32
- # # 作成できないファイル名。
33
- # lambda{WeightedPicker.load_file("")}.should raise_error(Errno::ENOENT)
34
- #end
35
-
36
- it "should read correctly" do
37
- # 正しく取り込めているか?
38
- @wp01.names_weights.should == { "A" => 256, "B" => 128, }
39
- @wp02.names_weights.should == { "A" => 512, "B" => 64, }
40
- end
41
-
42
- it "should treat as MAX_WEIGHT when the values are over the MAX_WEIGHT" do
43
- #Not write
44
- WeightedPicker.load_file("spec/a99999b64.yaml").names_weights.should == { "A" => 65536, "B" => 64, }
45
- end
46
-
47
- it "should treat as 0 when the values are negative" do
48
- #Not write
49
- WeightedPicker.load_file("spec/a-1b256.yaml").names_weights.should == { "A" => 0, "B" => 256, }
50
- end
51
-
52
- #New item is set by max values in alive entries.
53
- it "should merge when keys between weights and items" do
54
- @wp01.merge(["B","C"])
55
- @wp01.names_weights.should == { "B" => 128, "C" => 256, }
56
- @wp02.merge(["B","C"])
57
- @wp02.names_weights.should == { "B" => 64, "C" => 256, }
58
- end
59
-
60
- #New item is set by max values in alive entries.
61
- it "should merge when keys between weights and items" do
62
- @wp01.merge(["A","C"])
63
- @wp01.names_weights.should == { "A" => 256, "C" => 256, }
64
- @wp02.merge(["A","C"])
65
- @wp02.names_weights.should == { "A" => 512, "C" => 512, }
66
- end
67
-
68
- it "should raise exception if include not integer weight." do
69
- weights = { "A" => 1.0, "B" => 0.5, }
70
- lambda{
71
- WeightedPicker.load_file("spec/float.yaml")
72
- }.should raise_error(WeightedPicker::InvalidWeightError)
73
- end
74
-
75
- after do
76
- #FileUtils.rm AB_YAML if File.exist? AB_YAML
77
- FileUtils.rm NOT_EXIST_FILE if File.exist? NOT_EXIST_FILE
78
- end
79
- end
80
-
81
- #before do
82
- # @wp01 = WeightedPicker.load_file(AB_YAML)
83
- # @wp00 = WeightedPicker.new({})
84
- #end
85
-
86
- describe "pick" do
87
- srand(0)
88
- it "should pick" do
89
- lambda{@wp00.pick}.should raise_error(WeightedPicker::Tree::NoEntryError)
90
-
91
- results = {"A" => 0, "B" => 0}
92
- 300.times do |i|
93
- results[@wp01.pick] += 1
94
- end
95
- #pp @wp01.names_weights #=> {"A"=>256, "B"=>128}
96
- results["A"].should be_within(20).of(200)
97
- results["B"].should be_within(10).of(100)
98
- end
99
- end
100
-
101
- describe "weigh" do
102
- it "should weigh A" do
103
- @wp01.weigh("A")
104
- @wp01.names_weights.should == { "A" => 512, "B" => 128 }
105
- end
106
-
107
- it "should weigh B" do
108
- @wp01.weigh("B")
109
- @wp01.names_weights.should == { "A" => 256, "B" => 256 }
110
- end
111
-
112
- it "should raise error" do
113
- lambda{Marshal.load(Marshal.dump(@wp01)).weigh("C")}.should raise_error(WeightedPicker::Tree::NoEntryError)
114
- end
115
-
116
- end
117
-
118
- describe "Weightedpicker::lighten" do
119
- #before do
120
- # @wp01 = WeightedPicker.load_file(AB_YAML)
121
- #end
122
-
123
- it "should lighten A" do
124
- t = Marshal.load(Marshal.dump(@wp01))
125
- t.lighten("A")
126
- t.names_weights.should == { "A" => 128, "B" => 128 }
127
- end
128
-
129
- it "should lighten B" do
130
- t = Marshal.load(Marshal.dump(@wp01))
131
- t.lighten("B")
132
- t.names_weights.should == { "A" => 256, "B" => 64 }
133
- end
134
-
135
- it "should raise error" do
136
- t = Marshal.load(Marshal.dump(@wp01))
137
- lambda{t.lighten("C")}.should raise_error(WeightedPicker::Tree::NoEntryError)
138
- end
139
-
140
- end
141
-
142
- describe "include zero weight" do
143
- it "should not change zero weight." do
144
- wp01 = WeightedPicker.load_file("spec/a256b0.yaml")
145
- wp01.names_weights.should == { "A" => 256, "B" => 0 }
146
- wp01.lighten("A")
147
- wp01.names_weights.should == { "A" => 128, "B" => 0 }
148
- wp01.weigh("A")
149
- wp01.names_weights.should == { "A" => 256, "B" => 0 }
150
- wp01.lighten("B")
151
- wp01.names_weights.should == { "A" => 256, "B" => 0 }
152
- wp01.weigh("B")
153
- wp01.names_weights.should == { "A" => 256, "B" => 0 }
154
- end
155
-
156
- end
157
-
158
- describe "include one weight" do
159
- it "should not change zero weight." do
160
- wp01 = WeightedPicker.load_file("spec/a256b1.yaml")
161
-
162
- wp01.names_weights.should == { "A" => 256, "B" => 1 }
163
-
164
- wp01.lighten("A")
165
- wp01.names_weights.should == { "A" => 128, "B" => 1 }
166
-
167
- wp01.weigh("A")
168
- wp01.names_weights.should == { "A" => 256, "B" => 1 }
169
-
170
- wp01.lighten("B")
171
- wp01.names_weights.should == { "A" => 256, "B" => 1 }
172
-
173
- wp01.weigh("B")
174
- wp01.names_weights.should == { "A" => 256, "B" => 2 }
175
- end
176
-
177
- end
178
-
179
- describe "Weightedpicker::dump" do
180
- it "should dump yaml." do
181
- io = StringIO.new
182
- @wp01.dump(io)
183
- io.rewind
184
- results = YAML.load(io)
185
- results.should == { "A" => 256, "B" => 128, }
186
-
187
- end
188
-
189
- end
190
-
191
- describe "Weightedpicker::names" do
192
- it "should return an array of names." do
193
- @wp01.names.should == [ "A", "B"]
194
- end
195
-
196
- end
197
-
198
- describe "Weightedpicker::dump_histgram" do
199
- it "should output histgram to io." do
200
- input = {}
201
- 4.times do |power|
202
- num = 10**power
203
- num.times do |i|
204
- input["#{power}_#{i}"] = num
205
- end
206
- end
207
- #pp input
208
- wp20 = WeightedPicker.new(input)
209
- #pp wp20
210
- io = StringIO.new
211
- wp20.dump_histgram(io)
212
- io.rewind
213
- io.read.should == <<HERE
214
- 1( 1)|*
215
- 2( 0)|
216
- 4( 0)|
217
- 8( 0)|
218
- 16( 10)|*
219
- 32( 0)|
220
- 64( 0)|
221
- 128( 100)|*****
222
- 256( 0)|
223
- 512( 0)|
224
- 1024(1000)|**************************************************
225
- 2048( 0)|
226
- 4096( 0)|
227
- 8192( 0)|
228
- 16384( 0)|
229
- 32768( 0)|
230
- 65536( 0)|
231
- HERE
232
-
233
- end
234
-
235
- end
236
-
237
- end
238
-
@@ -1,74 +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 = "weightedpicker"
8
- s.version = "0.1.1"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["ippei94da"]
12
- s.date = "2013-04-18"
13
- s.description = "This library enables to pick out items at the rate of their weight.\n Weight data is storaged as a YAML file.\n You can use this library for music player, wallpaper changer, language training.\n "
14
- s.email = "ippei94da@gmail.com"
15
- s.executables = ["weight"]
16
- s.extra_rdoc_files = [
17
- "LICENSE.txt",
18
- "README.rdoc"
19
- ]
20
- s.files = [
21
- ".document",
22
- ".rspec",
23
- "CHANGES",
24
- "Gemfile",
25
- "LICENSE.txt",
26
- "README.rdoc",
27
- "Rakefile",
28
- "VERSION",
29
- "bin/weight",
30
- "lib/weightedpicker.rb",
31
- "lib/weightedpicker/tree.rb",
32
- "spec/a-1b256.yaml",
33
- "spec/a256b0.yaml",
34
- "spec/a256b1.yaml",
35
- "spec/a256b128.yaml",
36
- "spec/a512b64.yaml",
37
- "spec/a99999b64.yaml",
38
- "spec/float.yaml",
39
- "spec/spec_helper.rb",
40
- "spec/tree_spec.rb",
41
- "spec/weightedpicker_spec.rb",
42
- "weightedpicker.gemspec"
43
- ]
44
- s.homepage = "http://github.com/ippei94da/weightedpicker"
45
- s.licenses = ["MIT"]
46
- s.require_paths = ["lib"]
47
- s.rubygems_version = "1.8.11"
48
- s.summary = "Picking one item from list at the rate of its weight."
49
-
50
- if s.respond_to? :specification_version then
51
- s.specification_version = 3
52
-
53
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
- s.add_development_dependency(%q<rspec>, ["~> 2.13.0"])
55
- s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
56
- s.add_development_dependency(%q<bundler>, ["~> 1.3.4"])
57
- s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
58
- s.add_development_dependency(%q<simplecov>, [">= 0"])
59
- else
60
- s.add_dependency(%q<rspec>, ["~> 2.13.0"])
61
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
62
- s.add_dependency(%q<bundler>, ["~> 1.3.4"])
63
- s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
64
- s.add_dependency(%q<simplecov>, [">= 0"])
65
- end
66
- else
67
- s.add_dependency(%q<rspec>, ["~> 2.13.0"])
68
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
69
- s.add_dependency(%q<bundler>, ["~> 1.3.4"])
70
- s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
71
- s.add_dependency(%q<simplecov>, [">= 0"])
72
- end
73
- end
74
-