newcomb 1.0.0 → 1.1.0

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
- SHA1:
3
- metadata.gz: b718f0e37121533e31fe9c789e912422c12406f2
4
- data.tar.gz: 49c5cb53702a3f6f8db7f2cb34c0fea50d732337
2
+ SHA256:
3
+ metadata.gz: 7cd2e97fc6d20d043706a8d5957d993910cbc910d4694654f3a7a5eceec790a3
4
+ data.tar.gz: 1b177fe3f68b65f4511b275719fc8db3955824c9f9126366d79d9c9753960ac2
5
5
  SHA512:
6
- metadata.gz: 57922988b4fc725ff86fc6d591e6398c86fdfbf378ef7aa627031834d0b979c7b5ef7dbfb68303513849eb671f417867bda55d8b17e6ac056746426b3646c81f
7
- data.tar.gz: e5b2a92ddc77101a22f7899c8f1a70433cd5b16d4e991c2940da091bd510f51f2643414823737775d6733cf5512bb72ff41d25339f62d919ecc66687714988ea
6
+ metadata.gz: 872d2e86d6520395cf1941d12b132c3dd8e9f4e166cb15ee35056317e2d0e30e6fe373b51aebc3c5bf5af2687da4ddfd80330e0b5cfb653d6e66ca612edb6592
7
+ data.tar.gz: 33042d3d6bf19205385e3139fcf5b4bbf3d83dba230f005c2d125126f70fd65b3e0ca5e3fab18b850d707aed7ed4dd2ae3b26d7034d8ea3ea52d99a9101ae4bd
data/LICENSE.txt CHANGED
@@ -1,22 +1,21 @@
1
- Copyright (c) 2014 Steve Richert
1
+ The MIT License (MIT)
2
2
 
3
- MIT License
3
+ Copyright (c) 2014 Steve Richert
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
12
11
 
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
15
14
 
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -2,11 +2,8 @@
2
2
 
3
3
  Generate random numbers that adhere to [Benford's Law](http://en.wikipedia.org/wiki/Benford's_law)
4
4
 
5
- [![Gem Version](https://img.shields.io/gem/v/newcomb.svg?style=flat)](http://rubygems.org/gems/newcomb)
6
- [![Build Status](https://img.shields.io/travis/laserlemon/newcomb/master.svg?style=flat)](https://travis-ci.org/laserlemon/newcomb)
7
- [![Code Climate](https://img.shields.io/codeclimate/github/laserlemon/newcomb.svg?style=flat)](https://codeclimate.com/github/laserlemon/newcomb)
8
- [![Code Coverage](http://img.shields.io/codeclimate/coverage/github/laserlemon/newcomb.svg?style=flat)](https://codeclimate.com/github/laserlemon/newcomb)
9
- [![Dependency Status](https://img.shields.io/gemnasium/laserlemon/newcomb.svg?style=flat)](https://gemnasium.com/laserlemon/newcomb)
5
+ [![Gem Version](https://img.shields.io/gem/v/newcomb)](http://rubygems.org/gems/newcomb)
6
+ [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/laserlemon/newcomb/rake.yml)](https://github.com/laserlemon/newcomb/actions/workflows/rake.yml)
10
7
 
11
8
  ## Usage
12
9
 
@@ -23,6 +20,26 @@ To fetch a random positive integer, provide the upper (exclusive) limit:
23
20
  Newcomb.random_number(100) # => 16
24
21
  ```
25
22
 
23
+ To fetch a random positive float, provide the upper (exclusive) limit as a float:
24
+
25
+ ```ruby
26
+ Newcomb.random_number(100.0) # => 21.895884449446473
27
+ ```
28
+
29
+ To fetch a random integer within a range, provide a range with integer endpoints:
30
+
31
+ ```ruby
32
+ Newcomb.random_number(100..1000) # => 141
33
+ ```
34
+
35
+ To fetch a random float within a range, provide a range with float (or mixed) endpoints:
36
+
37
+ ```ruby
38
+ Newcomb.random_number(100.0..1000.0) # => 203.90587157406662
39
+ Newcomb.random_number(100..1000.0) # => 424.9768102233391
40
+ Newcomb.random_number(100.0..1000) # => 628.7978615329862
41
+ ```
42
+
26
43
  Over a sufficiently large sample size, the distribution of Newcomb's random
27
44
  numbers will demonstrate Benford's Law.
28
45
 
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newcomb
4
+ VERSION = Gem::Version.new("1.1.0")
5
+ end
data/lib/newcomb.rb CHANGED
@@ -1,11 +1,68 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "securerandom"
2
4
 
5
+ # The Newcomb module is the interface to its random_number function which is
6
+ # designed to behave identically to SecureRandom.random_number except for the
7
+ # distribution of its return values. Like SecureRandom, the
8
+ # Newcomb.random_number function can be given a single argument in one of the
9
+ # following forms:
10
+ #
11
+ # Integer - The random number returned will be an Integer between 0 and the
12
+ # given maximum, exclusive.
13
+ # Float - The random number returned will be a Float between 0.0 and the
14
+ # given maximum, exclusive.
15
+ # Range - The random number returned will be either an Integer or Float,
16
+ # depending on the endpoints of the range, and within the range.
3
17
  module Newcomb
4
- def self.random_number(n = 0)
5
- if n > 0
6
- (random_number * n).floor
18
+ # The 3-element "constraints" array represents the minimum allowed value,
19
+ # the maximum allowed value, and whether the final value should be rounded
20
+ # down to the nearest integer.
21
+ DEFAULT_CONTRAINTS = [0, 1, false].freeze
22
+
23
+ def self.random_number(arg = nil)
24
+ random_factor = ((10 ** SecureRandom.random_number) - 1) / 9
25
+ min, max, round = generate_constraints(arg)
26
+ float_value = (random_factor * (max - min)) + min
27
+ round ? float_value.floor : float_value
28
+ end
29
+
30
+ def self.generate_constraints(arg)
31
+ case arg
32
+ when nil then DEFAULT_CONTRAINTS
33
+ when Range then generate_constraints_from_range(arg)
34
+ when Integer, Float then generate_constraints_from_max(arg)
35
+ else invalid_argument!(arg)
36
+ end
37
+ end
38
+
39
+ def self.generate_constraints_from_range(range)
40
+ first = range.first
41
+ last = range.last
42
+
43
+ # The given range must have integer/float endpoints.
44
+ unless (first.is_a?(Integer) || first.is_a?(Float)) && (last.is_a?(Integer) || last.is_a?(Float))
45
+ invalid_argument!(range)
46
+ end
47
+
48
+ if first < last
49
+ # We only round the final value down if both endpoints of the range
50
+ # are integers, mirroring the behavior of SecureRandom.random_number.
51
+ [first, last, first.is_a?(Integer) && last.is_a?(Integer)]
52
+ else
53
+ DEFAULT_CONTRAINTS
54
+ end
55
+ end
56
+
57
+ def self.generate_constraints_from_max(max)
58
+ if max.positive?
59
+ [0, max, max.is_a?(Integer)]
7
60
  else
8
- (10 ** SecureRandom.random_number - 1) / 9
61
+ DEFAULT_CONTRAINTS
9
62
  end
10
63
  end
64
+
65
+ def self.invalid_argument!(arg)
66
+ raise ArgumentError, "invalid argument - #{arg}"
67
+ end
11
68
  end
data/newcomb.gemspec CHANGED
@@ -1,19 +1,37 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- Gem::Specification.new do |spec|
4
- spec.name = "newcomb"
5
- spec.version = "1.0.0"
3
+ require_relative "lib/newcomb/version"
6
4
 
7
- spec.author = "Steve Richert"
8
- spec.email = "steve.richert@gmail.com"
9
- spec.summary = "Generate natural random numbers"
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "newcomb"
7
+ spec.summary = "Generate natural random numbers"
10
8
  spec.description = "Generate random numbers that adhere to Benford's Law"
11
- spec.homepage = "https://github.com/laserlemon/newcomb"
12
- spec.license = "MIT"
9
+ spec.version = Newcomb::VERSION
10
+
11
+ spec.author = "Steve Richert"
12
+ spec.email = "steve.richert@hey.com"
13
+ spec.license = "MIT"
14
+ spec.homepage = "https://github.com/laserlemon/newcomb"
15
+
16
+ spec.metadata = {
17
+ "allowed_push_host" => "https://rubygems.org",
18
+ "bug_tracker_uri" => "https://github.com/laserlemon/newcomb/issues",
19
+ "funding_uri" => "https://github.com/sponsors/laserlemon",
20
+ "homepage_uri" => "https://github.com/laserlemon/newcomb",
21
+ "rubygems_mfa_required" => "true",
22
+ "source_code_uri" => "https://github.com/laserlemon/newcomb",
23
+ }
24
+
25
+ spec.required_ruby_version = ">= 3.0.0"
26
+ spec.add_development_dependency "bundler", ">= 2"
27
+ spec.add_development_dependency "rake", ">= 13"
13
28
 
14
- spec.files = `git ls-files -z`.split("\x0")
15
- spec.test_files = spec.files.grep(/^spec/)
29
+ spec.files = [
30
+ "lib/newcomb.rb",
31
+ "lib/newcomb/version.rb",
32
+ "LICENSE.txt",
33
+ "newcomb.gemspec",
34
+ ]
16
35
 
17
- spec.add_development_dependency "bundler", "~> 1.6"
18
- spec.add_development_dependency "rake", "~> 10.3"
36
+ spec.extra_rdoc_files = ["README.md"]
19
37
  end
metadata CHANGED
@@ -1,64 +1,65 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newcomb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Richert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-15 00:00:00.000000000 Z
11
+ date: 2024-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.6'
19
+ version: '2'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.6'
26
+ version: '2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.3'
33
+ version: '13'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.3'
40
+ version: '13'
41
41
  description: Generate random numbers that adhere to Benford's Law
42
- email: steve.richert@gmail.com
42
+ email: steve.richert@hey.com
43
43
  executables: []
44
44
  extensions: []
45
- extra_rdoc_files: []
45
+ extra_rdoc_files:
46
+ - README.md
46
47
  files:
47
- - ".gitignore"
48
- - ".rspec"
49
- - ".travis.yml"
50
- - Gemfile
51
48
  - LICENSE.txt
52
49
  - README.md
53
- - Rakefile
54
50
  - lib/newcomb.rb
51
+ - lib/newcomb/version.rb
55
52
  - newcomb.gemspec
56
- - spec/newcomb_spec.rb
57
- - spec/spec_helper.rb
58
53
  homepage: https://github.com/laserlemon/newcomb
59
54
  licenses:
60
55
  - MIT
61
- metadata: {}
56
+ metadata:
57
+ allowed_push_host: https://rubygems.org
58
+ bug_tracker_uri: https://github.com/laserlemon/newcomb/issues
59
+ funding_uri: https://github.com/sponsors/laserlemon
60
+ homepage_uri: https://github.com/laserlemon/newcomb
61
+ rubygems_mfa_required: 'true'
62
+ source_code_uri: https://github.com/laserlemon/newcomb
62
63
  post_install_message:
63
64
  rdoc_options: []
64
65
  require_paths:
@@ -67,18 +68,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
67
68
  requirements:
68
69
  - - ">="
69
70
  - !ruby/object:Gem::Version
70
- version: '0'
71
+ version: 3.0.0
71
72
  required_rubygems_version: !ruby/object:Gem::Requirement
72
73
  requirements:
73
74
  - - ">="
74
75
  - !ruby/object:Gem::Version
75
76
  version: '0'
76
77
  requirements: []
77
- rubyforge_project:
78
- rubygems_version: 2.2.2
78
+ rubygems_version: 3.5.7
79
79
  signing_key:
80
80
  specification_version: 4
81
81
  summary: Generate natural random numbers
82
- test_files:
83
- - spec/newcomb_spec.rb
84
- - spec/spec_helper.rb
82
+ test_files: []
data/.gitignore DELETED
@@ -1,22 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- *.bundle
19
- *.so
20
- *.o
21
- *.a
22
- mkmf.log
data/.rspec DELETED
@@ -1,4 +0,0 @@
1
- --color
2
- --format documentation
3
- --order random
4
- --require spec_helper
data/.travis.yml DELETED
@@ -1,19 +0,0 @@
1
- branches:
2
- only:
3
- - master
4
- env:
5
- global:
6
- secure: | # CODECLIMATE_REPO_TOKEN
7
- XnaAxp9pN9OR+jSyLUXQwKkMVcUfNy+7muWXKLQRi/zIh2ObGBCEXTww/8mP
8
- hwv4Rf8a4n7+gpQhmv6MEx3xwdArkxLChs1EX79XGNN9/g/DBPtfoiKB3FLd
9
- UUJTuPurAlOklt/s+XvJTV5h50ThpvutSqkSenO5me8v/ODO6hw=
10
- language: ruby
11
- matrix:
12
- allow_failures:
13
- - rvm: ruby-head
14
- rvm:
15
- - 1.9.3
16
- - "2.0"
17
- - "2.1"
18
- - ruby-head
19
- script: bundle exec rspec
data/Gemfile DELETED
@@ -1,8 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- group :test do
6
- gem "codeclimate-test-reporter", require: false
7
- gem "rspec", "~> 3.0"
8
- end
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task default: :spec
data/spec/newcomb_spec.rb DELETED
@@ -1,68 +0,0 @@
1
- describe Newcomb do
2
- describe ".random_number" do
3
- let(:sample_size) { 1_000_000 }
4
-
5
- def assert_benford(&block)
6
- distribution = build_distribution(&block)
7
-
8
- expect(distribution.keys).to match_array([1, 2, 3, 4, 5, 6, 7, 8, 9])
9
-
10
- distribution.sort.each do |i, count|
11
- expect(distribution[i]).to be_within(tolerance(i)).of(expected_count(i))
12
- end
13
- end
14
-
15
- def build_distribution(&block)
16
- sample_size.times.with_object({}) do |_, memo|
17
- digit = block.call
18
- memo[digit] ||= 0
19
- memo[digit] += 1
20
- end
21
- end
22
-
23
- def build_sample(&block)
24
- sample_size.times.map(&block)
25
- end
26
-
27
- # TODO: Update to assert adherence to within one standard deviation
28
- def tolerance(digit)
29
- (expected_count(digit) * 0.01).round
30
- end
31
-
32
- def expected_count(digit)
33
- (((Math.log(digit + 1) - Math.log(digit)) / Math.log(10)) * sample_size).round
34
- end
35
-
36
- context "when given no arguments" do
37
- it "falls between zero (inclusive) and one (exclusive)" do
38
- sample = build_sample { Newcomb.random_number }
39
-
40
- expect(sample.map(&:class).uniq).to eq([Float])
41
- expect(sample.map(&:floor).uniq).to eq([0])
42
- end
43
-
44
- it "is distributed according to Benford's law" do
45
- assert_benford do
46
- (Newcomb.random_number * 9).floor + 1
47
- end
48
- end
49
- end
50
-
51
- context "when given an argument" do
52
- it "falls between zero (inclusive) and the given number (exclusive)" do
53
- sample = sample_size.times.map { Newcomb.random_number(13) }
54
-
55
- expect(sample.map(&:class).uniq).to eq([Fixnum])
56
- floors = sample.map(&:floor)
57
- expect(floors.min).to be >= 0
58
- expect(floors.max).to be < 13
59
- end
60
-
61
- it "is distributed according to Benford's law" do
62
- assert_benford do
63
- Newcomb.random_number(9) + 1
64
- end
65
- end
66
- end
67
- end
68
- end
data/spec/spec_helper.rb DELETED
@@ -1,6 +0,0 @@
1
- if ENV["CODECLIMATE_REPO_TOKEN"]
2
- require "codeclimate-test-reporter"
3
- CodeClimate::TestReporter.start
4
- end
5
-
6
- require "newcomb"