pick_me_too 1.0.0 → 1.1.0
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/CHANGES.md +2 -0
- data/README.md +14 -2
- data/lib/pick_me_too.rb +20 -7
- data/pick_me_too.gemspec +1 -1
- data/test/basic_test.rb +16 -1
- metadata +13 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52db253007776ea2ede6caa43361e3e260660accdd4a0b1eb1439532f1ef92d3
|
4
|
+
data.tar.gz: 7f370bb747440c33062b8193a3edffb2fe0ac752493735366ea4d7161ded0c4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f70d7864e25ca65ea5ca660c1964f0e79229da429e2414539ffaf3a65da50b2a30f70f186266532adbf6115b4e7e7a9bbd7b0b8727994c690876e9648ff0ab7
|
7
|
+
data.tar.gz: bcf37dedb54b3304367799a16c3521541fa57c0db4dd4e819220dcb9ca85ff804c37e1b026e7867cf90a8990575d10e2b7ac0b452433d74760a358301b1eec8f
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -47,7 +47,7 @@ of frequencies:
|
|
47
47
|
|
48
48
|
What you need is something that will randomly pick these things for you with the frequencies you specify.
|
49
49
|
|
50
|
-
One way to do this would be to make an array,
|
50
|
+
One way to do this would be to make an array, fill it with the items according to the frequencies specified,
|
51
51
|
and then pick randomly from the array:
|
52
52
|
|
53
53
|
```ruby
|
@@ -72,7 +72,7 @@ This is the "[urn](https://en.wikipedia.org/wiki/Urn_problem)" containing the it
|
|
72
72
|
|
73
73
|
"Fill" the urn.
|
74
74
|
|
75
|
-
The required `frequencies` parameter must be something that is
|
75
|
+
The required `frequencies` parameter must be something that is effectively a list of pairs:
|
76
76
|
things to pick paired with their frequency. The "frequency" is just any positive number.
|
77
77
|
|
78
78
|
The optional `rnd` parameter is a `Proc` that when called returns a number, ideally in the interval
|
@@ -88,6 +88,18 @@ This constructor method will raise a `PickMeToo::Error` if
|
|
88
88
|
|
89
89
|
Draw an item from the urn.
|
90
90
|
|
91
|
+
## `PickMeToo#randomize!([rnd])`
|
92
|
+
|
93
|
+
Replace the random number generator.
|
94
|
+
If the optional argument is omitted, the replacement is just
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
-> { rand }
|
98
|
+
```
|
99
|
+
|
100
|
+
This is useful if you want to switch from a seeded random number generator
|
101
|
+
to something more truly random.
|
102
|
+
|
91
103
|
# Installation
|
92
104
|
|
93
105
|
`pick_me_too` is available as a gem, so one installs it as one does gems.
|
data/lib/pick_me_too.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
##
|
4
4
|
# An "urn" from which you can pick things with specified frequencies.
|
5
|
-
#
|
5
|
+
#
|
6
6
|
# require 'pick_me_too'
|
7
7
|
#
|
8
8
|
# wandering_monsters = PickMeToo.new({goblin: 10, bugbear: 2, orc: 5, spider: 3, troll: 1})
|
@@ -17,14 +17,14 @@
|
|
17
17
|
# probability the next thing you pick is also a cat, and the urn will never be picked empty. (And of course
|
18
18
|
# this is all a metaphor.)
|
19
19
|
class PickMeToo
|
20
|
-
VERSION = '1.
|
20
|
+
VERSION = '1.1.0'
|
21
21
|
|
22
22
|
class Error < StandardError; end
|
23
23
|
|
24
24
|
##
|
25
25
|
# "Fill" the urn.
|
26
26
|
#
|
27
|
-
# The required frequencies parameter must be something that is
|
27
|
+
# The required frequencies parameter must be something that is effectively a list of pairs:
|
28
28
|
# things to pick paired with their frequency. The "frequency" is just any positive number.
|
29
29
|
#
|
30
30
|
# The optional rnd parameter is a Proc that when called returns a number, ideally in the interval
|
@@ -46,7 +46,7 @@ class PickMeToo
|
|
46
46
|
balanced_binary_tree = bifurcate(frequencies.dup)
|
47
47
|
probability_tree = probabilities(frequencies, balanced_binary_tree)
|
48
48
|
# compile everything into a nested ternary expression
|
49
|
-
@picker = eval "->(p) { #{
|
49
|
+
@picker = eval "->(p) { #{ternarize(probability_tree)} }"
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -56,6 +56,19 @@ class PickMeToo
|
|
56
56
|
@objects[@picker.call(@rnd.call)]
|
57
57
|
end
|
58
58
|
|
59
|
+
##
|
60
|
+
# Replace the random number generator.
|
61
|
+
#
|
62
|
+
# If the optional argument is omitted, the replacement is just
|
63
|
+
#
|
64
|
+
# -> { rand }
|
65
|
+
#
|
66
|
+
# This is useful if you want to switch from a seeded random number generator
|
67
|
+
# to something more truly random.
|
68
|
+
def randomize!(rnd = -> { rand })
|
69
|
+
@rnd = rnd
|
70
|
+
end
|
71
|
+
|
59
72
|
private
|
60
73
|
|
61
74
|
# sanity check and normalization of frequencies
|
@@ -73,10 +86,10 @@ class PickMeToo
|
|
73
86
|
end
|
74
87
|
|
75
88
|
# reduce the probability tree to nested ternary expressions
|
76
|
-
def
|
89
|
+
def ternarize(ptree)
|
77
90
|
p, left, right = ptree.values_at :p, :left, :right
|
78
|
-
left = left.is_a?(Numeric) ? left :
|
79
|
-
right = right.is_a?(Numeric) ? right :
|
91
|
+
left = left.is_a?(Numeric) ? left : ternarize(left)
|
92
|
+
right = right.is_a?(Numeric) ? right : ternarize(right)
|
80
93
|
"(p > #{p} ? #{right} : #{left})"
|
81
94
|
end
|
82
95
|
|
data/pick_me_too.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.require_paths = ['lib']
|
26
26
|
|
27
27
|
s.add_development_dependency 'bundler', '~> 1.7'
|
28
|
-
s.add_development_dependency 'byebug', '~> 9.1.0'
|
28
|
+
s.add_development_dependency 'byebug', '~> 9.1', '>= 9.1.0'
|
29
29
|
s.add_development_dependency 'json', '~> 2'
|
30
30
|
s.add_development_dependency 'minitest', '~> 5'
|
31
31
|
s.add_development_dependency 'rake', '~> 10.0'
|
data/test/basic_test.rb
CHANGED
@@ -19,7 +19,7 @@ class BasicTest < Minitest::Test
|
|
19
19
|
|
20
20
|
def test_hash
|
21
21
|
rnd = Random.new 1
|
22
|
-
picker = PickMeToo.new({'cat' => 2, 'dog' => 1}, -> { rnd.rand })
|
22
|
+
picker = PickMeToo.new({ 'cat' => 2, 'dog' => 1 }, -> { rnd.rand })
|
23
23
|
counter = Hash.new(0)
|
24
24
|
3000.times { counter[picker.pick] += 1 }
|
25
25
|
assert_equal 2, (counter['cat'] / 1000.0).round, 'right number of cats'
|
@@ -70,4 +70,19 @@ class BasicTest < Minitest::Test
|
|
70
70
|
PickMeToo.new([['foo', nil]])
|
71
71
|
end
|
72
72
|
end
|
73
|
+
|
74
|
+
def test_randomize
|
75
|
+
rnd1 = Random.new 1
|
76
|
+
rnd2 = Random.new 1
|
77
|
+
rnd3 = Random.new 2
|
78
|
+
picker1 = PickMeToo.new({ foo: 1, bar: 2, baz: 3 }, -> { rnd1.rand })
|
79
|
+
picker2 = PickMeToo.new({ foo: 1, bar: 2, baz: 3 }, -> { rnd2.rand })
|
80
|
+
ar1 = Array.new(100) { picker1.pick }
|
81
|
+
ar2 = Array.new(100) { picker2.pick }
|
82
|
+
assert_equal ar1, ar2, 'with the same seeds we get the same sequences'
|
83
|
+
picker2.randomize! -> { rnd3.rand }
|
84
|
+
ar1 = Array.new(100) { picker1.pick }
|
85
|
+
ar2 = Array.new(100) { picker2.pick }
|
86
|
+
refute_equal ar1, ar2, 'if we randomize a picker, we get a new sequence'
|
87
|
+
end
|
73
88
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pick_me_too
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David F. Houghton
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -29,6 +29,9 @@ dependencies:
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '9.1'
|
34
|
+
- - ">="
|
32
35
|
- !ruby/object:Gem::Version
|
33
36
|
version: 9.1.0
|
34
37
|
type: :development
|
@@ -36,6 +39,9 @@ dependencies:
|
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
41
|
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '9.1'
|
44
|
+
- - ">="
|
39
45
|
- !ruby/object:Gem::Version
|
40
46
|
version: 9.1.0
|
41
47
|
- !ruby/object:Gem::Dependency
|
@@ -101,7 +107,7 @@ homepage: https://github.com/dfhoughton/pick_me_too
|
|
101
107
|
licenses:
|
102
108
|
- MIT
|
103
109
|
metadata: {}
|
104
|
-
post_install_message:
|
110
|
+
post_install_message:
|
105
111
|
rdoc_options: []
|
106
112
|
require_paths:
|
107
113
|
- lib
|
@@ -116,8 +122,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
122
|
- !ruby/object:Gem::Version
|
117
123
|
version: '0'
|
118
124
|
requirements: []
|
119
|
-
|
120
|
-
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.7.6
|
127
|
+
signing_key:
|
121
128
|
specification_version: 4
|
122
129
|
summary: Randomly select items from a list with specified frequencies
|
123
130
|
test_files:
|