remarkovable 0.1

Sign up to get free protection for your applications and to get access to all the features.
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