spicy-proton 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 +4 -4
- data/README.md +16 -9
- data/lib/corpus/adjectives.bin +0 -0
- data/lib/corpus/adjectives.yaml +5178 -5138
- data/lib/corpus/colors.bin +0 -0
- data/lib/corpus/colors.yaml +156 -136
- data/lib/corpus/nouns.bin +0 -0
- data/lib/corpus/nouns.yaml +11074 -11036
- data/lib/disk-corpus.rb +103 -0
- data/lib/memory-corpus.rb +71 -0
- data/lib/seek.rb +30 -0
- data/lib/spicy-proton.rb +26 -40
- metadata +23 -6
- data/lib/binary.rb +0 -102
- data/lib/corpus/combined.bin +0 -0
- data/lib/files.rb +0 -23
data/lib/disk-corpus.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'bindata'
|
3
|
+
require 'seek'
|
4
|
+
|
5
|
+
module Spicy
|
6
|
+
end
|
7
|
+
|
8
|
+
module Spicy::Disk
|
9
|
+
module Files
|
10
|
+
def self.dir
|
11
|
+
@@dir ||= File.join(File.dirname(__FILE__), 'corpus')
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.adjectives
|
15
|
+
@@adjectives ||= File.join(dir, 'adjectives.bin')
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.nouns
|
19
|
+
@@nouns ||= File.join(dir, 'nouns.bin')
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.colors
|
23
|
+
@@colors ||= File.join(dir, 'colors.bin')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Header < BinData::Record
|
28
|
+
endian :little
|
29
|
+
uint8 :width
|
30
|
+
uint8 :min_length
|
31
|
+
uint8 :group_count, :value => lambda { cumulative.length }
|
32
|
+
array :cumulative, :type => :uint32, :initial_length => :group_count
|
33
|
+
end
|
34
|
+
|
35
|
+
class WordList
|
36
|
+
include Spicy::Seek
|
37
|
+
|
38
|
+
def initialize(file_name)
|
39
|
+
@file = File.open(file_name, 'r')
|
40
|
+
header = Header.read(@file)
|
41
|
+
@origin = @file.pos
|
42
|
+
|
43
|
+
@width = header.width.to_i
|
44
|
+
@min = header.min_length.to_i
|
45
|
+
@max = @min + header.cumulative.count - 1
|
46
|
+
|
47
|
+
@cumulative = Hash[(@min..@max).zip(header.cumulative.to_a.map(&:to_i))]
|
48
|
+
end
|
49
|
+
|
50
|
+
def close
|
51
|
+
@file.close
|
52
|
+
end
|
53
|
+
|
54
|
+
def word(*args)
|
55
|
+
self.seek(*args) do |index, _|
|
56
|
+
@file.seek(@origin + index * @width, IO::SEEK_SET)
|
57
|
+
@file.read(@width).strip
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Corpus
|
63
|
+
private_class_method :new
|
64
|
+
|
65
|
+
def self.use
|
66
|
+
corpus = new
|
67
|
+
begin
|
68
|
+
yield corpus
|
69
|
+
ensure
|
70
|
+
corpus.close
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def initialize
|
75
|
+
@lists = {}
|
76
|
+
end
|
77
|
+
|
78
|
+
def close
|
79
|
+
@lists.values.each(&:close)
|
80
|
+
end
|
81
|
+
|
82
|
+
def adjective(*args)
|
83
|
+
generate(:adjectives, *args)
|
84
|
+
end
|
85
|
+
|
86
|
+
def noun(*args)
|
87
|
+
generate(:nouns, *args)
|
88
|
+
end
|
89
|
+
|
90
|
+
def color(*args)
|
91
|
+
generate(:colors, *args)
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def generate(type, *args)
|
97
|
+
@lists[type] ||= begin
|
98
|
+
WordList.new(Files.send(type))
|
99
|
+
end
|
100
|
+
@lists[type].word(*args)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'seek'
|
3
|
+
|
4
|
+
module Spicy
|
5
|
+
end
|
6
|
+
|
7
|
+
module Spicy::Memory
|
8
|
+
module Files
|
9
|
+
def self.dir
|
10
|
+
@@dir ||= File.join(File.dirname(__FILE__), 'corpus')
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.adjectives
|
14
|
+
@@adjectives ||= File.join(dir, 'adjectives.yaml')
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.nouns
|
18
|
+
@@nouns ||= File.join(dir, 'nouns.yaml')
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.colors
|
22
|
+
@@colors ||= File.join(dir, 'colors.yaml')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class WordList
|
27
|
+
include Spicy::Seek
|
28
|
+
|
29
|
+
def initialize(file_name)
|
30
|
+
dataset = YAML.load_file(file_name)
|
31
|
+
|
32
|
+
@words = dataset['words']
|
33
|
+
@cumulative = dataset['cumulative']
|
34
|
+
|
35
|
+
@min = @cumulative.keys.min
|
36
|
+
@max = @cumulative.keys.max
|
37
|
+
end
|
38
|
+
|
39
|
+
def word(*args)
|
40
|
+
self.seek(*args) do |index, length|
|
41
|
+
index -= (@cumulative[length - 1] || 0)
|
42
|
+
@words[length][index]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Corpus
|
48
|
+
def initialize
|
49
|
+
dir = File.dirname(__FILE__)
|
50
|
+
@adjectives = WordList.new(Files.adjectives)
|
51
|
+
@nouns = WordList.new(Files.nouns)
|
52
|
+
@colors = WordList.new(Files.colors)
|
53
|
+
end
|
54
|
+
|
55
|
+
def adjective(*args)
|
56
|
+
@adjectives.word(*args)
|
57
|
+
end
|
58
|
+
|
59
|
+
def noun(*args)
|
60
|
+
@nouns.word(*args)
|
61
|
+
end
|
62
|
+
|
63
|
+
def color(*args)
|
64
|
+
@colors.word(*args)
|
65
|
+
end
|
66
|
+
|
67
|
+
def pair(separator = '-')
|
68
|
+
"#{self.adjective}#{separator}#{self.noun}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/seek.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Spicy
|
4
|
+
module Seek
|
5
|
+
def seek(min: nil, max: nil, length: nil, &found)
|
6
|
+
if !length.nil? && (!min.nil? || !max.nil?)
|
7
|
+
raise ArgumentError.new('length cannot be specified if min or max are specified.')
|
8
|
+
end
|
9
|
+
|
10
|
+
if !min.nil? && !max.nil? && min > max
|
11
|
+
raise ArgumentError.new('min must be no more than max.')
|
12
|
+
end
|
13
|
+
|
14
|
+
min = [min || length || @min, @min].max
|
15
|
+
max = [max || length || @max, @max].min
|
16
|
+
|
17
|
+
rand_min = @cumulative[min - 1] || 0
|
18
|
+
rand_max = @cumulative[max] || @cumulative[@max]
|
19
|
+
index = SecureRandom.random_number(rand_min...rand_max)
|
20
|
+
|
21
|
+
min.upto(max) do |len|
|
22
|
+
if @cumulative[len] > index
|
23
|
+
return found.call(index, len)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/spicy-proton.rb
CHANGED
@@ -1,66 +1,55 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require '
|
1
|
+
require 'forwardable'
|
2
|
+
require 'disk-corpus'
|
3
|
+
require 'memory-corpus'
|
4
4
|
|
5
5
|
module Spicy
|
6
6
|
class Proton
|
7
|
+
extend Forwardable
|
8
|
+
|
7
9
|
def initialize
|
8
|
-
|
9
|
-
@adjectives = YAML.load_file(Files.adjectives)
|
10
|
-
@nouns = YAML.load_file(Files.nouns)
|
11
|
-
@colors = YAML.load_file(Files.colors)
|
10
|
+
@corpus = Memory::Corpus.new
|
12
11
|
end
|
13
12
|
|
14
|
-
def self.adjective
|
15
|
-
|
13
|
+
def self.adjective(*args)
|
14
|
+
Disk::Corpus.use do |c|
|
15
|
+
c.adjective(*args)
|
16
|
+
end
|
16
17
|
end
|
17
18
|
|
18
|
-
def self.noun
|
19
|
-
|
19
|
+
def self.noun(*args)
|
20
|
+
Disk::Corpus.use do |c|
|
21
|
+
c.noun(*args)
|
22
|
+
end
|
20
23
|
end
|
21
24
|
|
22
|
-
def self.color
|
23
|
-
|
25
|
+
def self.color(*args)
|
26
|
+
Disk::Corpus.use do |c|
|
27
|
+
c.color(*args)
|
28
|
+
end
|
24
29
|
end
|
25
30
|
|
26
31
|
def self.pair(separator = '-')
|
27
|
-
|
28
|
-
"#{
|
32
|
+
Disk::Corpus.use do |c|
|
33
|
+
"#{c.adjective}#{separator}#{c.noun}"
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
32
37
|
def self.format(format)
|
33
|
-
|
34
|
-
self.format_with(
|
38
|
+
Disk::Corpus.use do |c|
|
39
|
+
self.format_with(c, format)
|
35
40
|
end
|
36
41
|
end
|
37
42
|
|
38
|
-
def adjective
|
39
|
-
random(adjectives)
|
40
|
-
end
|
41
|
-
|
42
|
-
def noun
|
43
|
-
random(nouns)
|
44
|
-
end
|
45
|
-
|
46
|
-
def color
|
47
|
-
random(colors)
|
48
|
-
end
|
49
|
-
|
50
|
-
def pair(separator = '-')
|
51
|
-
"#{self.adjective}#{separator}#{self.noun}"
|
52
|
-
end
|
53
|
-
|
54
43
|
def format(format)
|
55
44
|
self.class.format_with(self, format)
|
56
45
|
end
|
57
46
|
|
58
|
-
|
47
|
+
def_delegators :@corpus, :adjective, :noun, :color, :pair, :adjectives, :nouns, :colors
|
59
48
|
|
60
49
|
private
|
61
50
|
|
62
51
|
def self.format_with(source, format)
|
63
|
-
format.gsub(/%([anc])/) do
|
52
|
+
format.gsub(/%([anc%])/) do
|
64
53
|
case $1
|
65
54
|
when 'a'
|
66
55
|
source.adjective
|
@@ -68,13 +57,10 @@ module Spicy
|
|
68
57
|
source.noun
|
69
58
|
when 'c'
|
70
59
|
source.color
|
60
|
+
when '%'
|
61
|
+
'%'
|
71
62
|
end
|
72
63
|
end
|
73
64
|
end
|
74
|
-
|
75
|
-
def random(set)
|
76
|
-
index = SecureRandom.random_number(set.count)
|
77
|
-
set[index]
|
78
|
-
end
|
79
65
|
end
|
80
66
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spicy-proton
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Schmich
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bindata
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.3'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: minitest
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -32,12 +46,15 @@ extra_rdoc_files: []
|
|
32
46
|
files:
|
33
47
|
- LICENSE
|
34
48
|
- README.md
|
35
|
-
- lib/
|
49
|
+
- lib/corpus/adjectives.bin
|
36
50
|
- lib/corpus/adjectives.yaml
|
51
|
+
- lib/corpus/colors.bin
|
37
52
|
- lib/corpus/colors.yaml
|
38
|
-
- lib/corpus/
|
53
|
+
- lib/corpus/nouns.bin
|
39
54
|
- lib/corpus/nouns.yaml
|
40
|
-
- lib/
|
55
|
+
- lib/disk-corpus.rb
|
56
|
+
- lib/memory-corpus.rb
|
57
|
+
- lib/seek.rb
|
41
58
|
- lib/spicy-proton.rb
|
42
59
|
homepage: https://github.com/schmich/spicy-proton
|
43
60
|
licenses:
|
@@ -51,7 +68,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
51
68
|
requirements:
|
52
69
|
- - ">="
|
53
70
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
71
|
+
version: 2.0.0
|
55
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
73
|
requirements:
|
57
74
|
- - ">="
|
data/lib/binary.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'yaml'
|
3
|
-
require 'securerandom'
|
4
|
-
require 'files'
|
5
|
-
|
6
|
-
module Spicy
|
7
|
-
class BinaryCorpus
|
8
|
-
private_class_method :new
|
9
|
-
|
10
|
-
def self.use
|
11
|
-
file = File.open(Files.combined, 'r')
|
12
|
-
begin
|
13
|
-
corpus = new(file)
|
14
|
-
yield corpus
|
15
|
-
ensure
|
16
|
-
file.close
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def initialize(file)
|
21
|
-
@file = file
|
22
|
-
@meta = {}
|
23
|
-
self.class.corpus.keys.each do |set|
|
24
|
-
bytes = @file.read(3 * 4)
|
25
|
-
start, count, size = bytes.unpack('L*')
|
26
|
-
@meta[set] = {
|
27
|
-
start: start,
|
28
|
-
count: count,
|
29
|
-
size: size
|
30
|
-
}
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.generate
|
35
|
-
dir = File.dirname(__FILE__)
|
36
|
-
sources = corpus.values
|
37
|
-
|
38
|
-
sets = sources.map do |source|
|
39
|
-
terms = YAML.load_file(source)
|
40
|
-
{
|
41
|
-
terms: terms,
|
42
|
-
start: 0,
|
43
|
-
count: terms.count,
|
44
|
-
size: terms.map(&:length).max
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
|
-
start = (3 * 4) * sets.length
|
49
|
-
sets.each do |set|
|
50
|
-
set[:start] = start
|
51
|
-
start += set[:count] * set[:size]
|
52
|
-
end
|
53
|
-
|
54
|
-
File.open(Files.combined, 'w+') do |f|
|
55
|
-
meta = []
|
56
|
-
sets.each do |set|
|
57
|
-
meta << set[:start]
|
58
|
-
meta << set[:count]
|
59
|
-
meta << set[:size]
|
60
|
-
end
|
61
|
-
|
62
|
-
f.write(meta.pack('L*'))
|
63
|
-
|
64
|
-
sets.each do |set|
|
65
|
-
set[:terms].each do |term|
|
66
|
-
padding = "\0" * (set[:size] - term.length)
|
67
|
-
f.write(term + padding)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def adjective
|
74
|
-
read_random(:adjectives)
|
75
|
-
end
|
76
|
-
|
77
|
-
def noun
|
78
|
-
read_random(:nouns)
|
79
|
-
end
|
80
|
-
|
81
|
-
def color
|
82
|
-
read_random(:colors)
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
|
87
|
-
def read_random(set)
|
88
|
-
set = @meta[set]
|
89
|
-
index = SecureRandom.random_number(set[:count])
|
90
|
-
@file.seek(set[:start] + index * set[:size], IO::SEEK_SET)
|
91
|
-
@file.read(set[:size]).strip
|
92
|
-
end
|
93
|
-
|
94
|
-
def self.corpus
|
95
|
-
{
|
96
|
-
adjectives: Files.adjectives,
|
97
|
-
nouns: Files.nouns,
|
98
|
-
colors: Files.colors
|
99
|
-
}
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|