remarkovable 0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a17b52251e917de43adfcb8a3265137ebea1f089
4
+ data.tar.gz: 04a8d08821c42e82e3cef0caf71cc841e1161cc4
5
+ SHA512:
6
+ metadata.gz: 802a5d3df97044b11e293caa463313d14c5eb9c87b63269de627b385f27281026704da3e95c865aba6ac8d091cf0f236a72d44f9a8093dbda53b28b87a00cbef
7
+ data.tar.gz: 97f87565cd104939392b8fcc9899b419e2852818ae392888a5a0a0df2d4e31b7292d2eddf87793a8d1991b61a53333870e718c8bd132db45e2de7fec6820626f
@@ -0,0 +1,52 @@
1
+ class Remarkovable
2
+ attr_accessor :markov_model
3
+
4
+ def initialize(string: string, prefix_length: 2)
5
+ return if string.nil?
6
+ @markov_model = Hash.new { |hash, key| hash[key] = [] }
7
+
8
+ words = string.split(/([.!?])|\s+/)
9
+ words.each_with_index do |word, i|
10
+ key = [word]
11
+
12
+ (prefix_length - 1).times do |n|
13
+ next_word = i + n + 1
14
+ key << words[next_word]
15
+ end
16
+
17
+ key = key.join(' ')
18
+ match = words[i + prefix_length]
19
+ add_triad(key: key, match: match) if i < words.size - prefix_length
20
+ end
21
+ end
22
+
23
+ def speak(custom_key: nil)
24
+ return if @markov_model.nil?
25
+ key = if !custom_key.nil? && @markov_model[custom_key].any?
26
+ custom_key
27
+ else
28
+ @markov_model.keys.sample
29
+ end
30
+ output = Array(key.capitalize.split(' '))
31
+
32
+ until (output & %w(. ! ?)).any?
33
+ match = @markov_model[key].sample
34
+ if match.nil?
35
+ key = @markov_model.keys.sample
36
+ next
37
+ end
38
+ output << match
39
+ output.flatten!
40
+ key = [output[-2], output[-1]].join(' ')
41
+ end
42
+
43
+ output.join(' ').gsub(/\s+([,.!?])/, '\1')
44
+ end
45
+
46
+ private
47
+
48
+ def add_triad(key: key, match: match)
49
+ @markov_model[key] = {} unless @markov_model[key]
50
+ @markov_model[key] += [match]
51
+ end
52
+ end
@@ -0,0 +1,139 @@
1
+ require 'minitest/autorun'
2
+ require './lib/remarkovable.rb'
3
+
4
+ class RemarkovableTest < Minitest::Test
5
+ def test_add_pair_simple_case
6
+ string = 'we are walking'
7
+ mc = Remarkovable.new(string: string)
8
+ expected_output = {
9
+ 'we are' => ['walking']
10
+ }
11
+
12
+ assert_equal expected_output, mc.markov_model
13
+ end
14
+
15
+ def test_add_pair_nil
16
+ string = nil
17
+ mc = Remarkovable.new(string: string)
18
+ expected_output = nil
19
+
20
+ assert_equal nil, mc.speak
21
+ end
22
+
23
+ def test_add_pair_three_words_and_punctuation
24
+ string = 'we (are) walking.'
25
+ mc = Remarkovable.new(string: string)
26
+ expected_output = {
27
+ 'we (are)' => ['walking'],
28
+ '(are) walking' => ['.']
29
+ }
30
+
31
+ assert_equal expected_output, mc.markov_model
32
+ end
33
+
34
+ def test_add_pair_three_words_and_spaces
35
+ string = 'we are walking.'
36
+ mc = Remarkovable.new(string: string)
37
+ expected_output = {
38
+ 'we are' => ['walking'],
39
+ 'are walking' => ['.']
40
+ }
41
+
42
+ assert_equal expected_output, mc.markov_model
43
+ end
44
+
45
+ def test_add_pair_three_words_and_quotes
46
+ string = 'we are "walking".'
47
+ mc = Remarkovable.new(string: string)
48
+ expected_output = {
49
+ 'we are' => ['"walking"'],
50
+ 'are "walking"' => ['.']
51
+ }
52
+
53
+ assert_equal expected_output, mc.markov_model
54
+ end
55
+
56
+ def test_add_pair_key_duplication
57
+ string = 'we are walking we are talking we are walking.'
58
+ mc = Remarkovable.new(string: string)
59
+ expected_output = {
60
+ 'we are' => %w(walking talking walking),
61
+ 'are walking' => ['we', '.'],
62
+ 'walking we' => ['are'],
63
+ 'are talking' => ['we'],
64
+ 'talking we' => ['are']
65
+ }
66
+
67
+ assert_equal expected_output, mc.markov_model
68
+ end
69
+
70
+ def test_add_pair_with_newlines
71
+ string = "we are walking\n\rwe are talking we are walking."
72
+ mc = Remarkovable.new(string: string)
73
+ expected_output = {
74
+ 'we are' => %w(walking talking walking),
75
+ 'are walking' => ['we', '.'],
76
+ 'walking we' => ['are'],
77
+ 'are talking' => ['we'],
78
+ 'talking we' => ['are']
79
+ }
80
+
81
+ assert_equal expected_output, mc.markov_model
82
+ end
83
+
84
+ def test_custom_prefix_length_1
85
+ string = 'we are.'
86
+ mc = Remarkovable.new(string: string, prefix_length: 1)
87
+ expected_output = {
88
+ 'we' => ['are'],
89
+ 'are' => ['.']
90
+ }
91
+
92
+ assert_equal expected_output, mc.markov_model
93
+ end
94
+
95
+ def test_custom_prefix_length_3
96
+ string = 'we are walking.'
97
+ mc = Remarkovable.new(string: string, prefix_length: 3)
98
+ expected_output = {
99
+ 'we are walking' => ['.']
100
+ }
101
+
102
+ assert_equal expected_output, mc.markov_model
103
+ end
104
+
105
+ def test_custom_prefix_length_4
106
+ string = 'we are walking talking.'
107
+ mc = Remarkovable.new(string: string, prefix_length: 4)
108
+ expected_output = {
109
+ 'we are walking talking' => ['.']
110
+ }
111
+
112
+ assert_equal expected_output, mc.markov_model
113
+ end
114
+
115
+ def test_custom_prefix_length_5
116
+ string = 'we are walking talking singing.'
117
+ mc = Remarkovable.new(string: string, prefix_length: 5)
118
+ expected_output = {
119
+ 'we are walking talking singing' => ['.']
120
+ }
121
+
122
+ assert_equal expected_output, mc.markov_model
123
+ end
124
+
125
+ def test_custom_key
126
+ string = "we are walking\n\rwe are talking we are walking."
127
+ mc = Remarkovable.new(string: string)
128
+ expected_output = /^We are./
129
+
130
+ assert_match expected_output, mc.speak(custom_key: 'we are')
131
+ end
132
+
133
+ def test_custom_key_no_match
134
+ string = "we are walking\n\rwe are talking we are walking."
135
+ mc = Remarkovable.new(string: string)
136
+
137
+ assert_nil mc.speak(custom_key: 'foo bar') =~ /Foo bar/i
138
+ end
139
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remarkovable
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Jake Worth
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A gem that produces Markov chain output from any text.
14
+ email:
15
+ - jake@jakeworth.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/remarkovable.rb
21
+ - test/test_remarkovable.rb
22
+ homepage: http://github.com/jwworth/remarkovable
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.4.5
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Markov chains for all.
46
+ test_files:
47
+ - test/test_remarkovable.rb