marky_markov 0.1.2 → 0.1.3
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.
- data/README.md +13 -1
- data/bin/marky_markov +10 -5
- data/lib/marky_markov/{one_word_dictionary.rb → markov_dictionary.rb} +7 -7
- data/lib/marky_markov/{one_word_sentence_generator.rb → markov_sentence_generator.rb} +19 -3
- data/lib/marky_markov/persistent_dictionary.rb +18 -9
- data/lib/marky_markov.rb +21 -12
- data/spec/marky_markov/markov_dictionary_spec.rb +76 -0
- data/spec/marky_markov/{one_word_sentence_spec.rb → markov_sentence_generator_spec.rb} +3 -3
- data/spec/textdictcompare.mmd +1 -1
- metadata +8 -12
- data/lib/marky_markov/two_word_dictionary.rb +0 -19
- data/lib/marky_markov/two_word_sentence_generator.rb +0 -14
- data/spec/marky_markov/one_word_dictionary_spec.rb +0 -45
- data/spec/marky_markov/two_word_dict_spec.rb +0 -31
- data/spec/marky_markov/two_word_sentence_spec.rb +0 -13
data/README.md
CHANGED
@@ -33,11 +33,23 @@ of the dictionary name.
|
|
33
33
|
puts markov.generate_n_words 10
|
34
34
|
markov.save_dictionary! # Saves the modified dictionary/creates one if it didn't exist.
|
35
35
|
|
36
|
-
If you keep
|
36
|
+
If you keep looking at generate_n_words and wonder why you can't put a
|
37
37
|
number in there, well, you can!
|
38
38
|
|
39
39
|
markov.generate_20_words
|
40
40
|
|
41
|
+
The default dictionary depth is two words.
|
42
|
+
`{"I hope" => {"this" => 1},
|
43
|
+
"hope this" => {"makes" => 1},
|
44
|
+
"this makes" => {"sense" => 1}}`
|
45
|
+
but it can be set to a depth between 1 and 9 upon dictionary creation
|
46
|
+
|
47
|
+
markov = MarkyMarkov::Dictionary.new('dictionary', 3)
|
48
|
+
|
49
|
+
creates a dictionary with a depth of three words.
|
50
|
+
`{"I hope this" => {"makes" => 1},
|
51
|
+
"hope this makes" => {"sense" => 1}`
|
52
|
+
|
41
53
|
If you want to delete a dictionary you call it upon the Dictionary class itself while
|
42
54
|
passing in the filename/location.
|
43
55
|
|
data/bin/marky_markov
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
require 'optparse'
|
5
5
|
require 'marky_markov'
|
6
6
|
|
7
|
-
#if __FILE__ == $0
|
8
7
|
options = {}
|
9
8
|
opt_parser = OptionParser.new do |opts|
|
10
9
|
opts.banner = "Usage: marky-markov COMMAND [OPTIONS]"
|
@@ -17,7 +16,7 @@ opt_parser = OptionParser.new do |opts|
|
|
17
16
|
opts.separator "Options"
|
18
17
|
|
19
18
|
options[:dictionary] = "#{ENV["HOME"]}/.marky_markov_dictionary"
|
20
|
-
opts.on('-
|
19
|
+
opts.on('-l', '--location DICTIONARY', 'Use custom dictionary location') do |file|
|
21
20
|
options[:dictionary] = file
|
22
21
|
end
|
23
22
|
|
@@ -32,6 +31,12 @@ opt_parser = OptionParser.new do |opts|
|
|
32
31
|
options[:source] = file
|
33
32
|
end
|
34
33
|
|
34
|
+
options[:depth] = 2
|
35
|
+
opts.on('-d', '--depth 1-9', 'Set dictionary depth. The higher the number
|
36
|
+
, the less random the sentence will be. Must be between 1 and 9.') do |number|
|
37
|
+
options[:depth] = number.to_i
|
38
|
+
end
|
39
|
+
|
35
40
|
options[:resetdictionary] = false
|
36
41
|
opts.on('--reset', "WARNING: Deletes default dictionary." ) do
|
37
42
|
options[:resetdictionary] = true
|
@@ -53,7 +58,7 @@ end
|
|
53
58
|
case ARGV[0]
|
54
59
|
when "speak"
|
55
60
|
if options[:source]
|
56
|
-
markov = MarkyMarkov::TemporaryDictionary.new
|
61
|
+
markov = MarkyMarkov::TemporaryDictionary.new(options[:depth])
|
57
62
|
markov.parse_file(options[:source])
|
58
63
|
else
|
59
64
|
unless File.exists?("#{options[:dictionary]}.mmd")
|
@@ -66,7 +71,7 @@ when "speak"
|
|
66
71
|
STDOUT.puts markov.generate_n_words(options[:wordcount])
|
67
72
|
when "read"
|
68
73
|
source = ARGV[1] || options[:source]
|
69
|
-
markov = MarkyMarkov::Dictionary.new(options[:dictionary])
|
74
|
+
markov = MarkyMarkov::Dictionary.new(options[:dictionary], options[:depth])
|
70
75
|
markov.parse_file(source)
|
71
76
|
markov.save_dictionary!
|
72
77
|
STDOUT.puts "Added #{source} to dictionary."
|
@@ -76,7 +81,7 @@ when "listen"
|
|
76
81
|
STDOUT.puts markov.generate_n_words(options[:wordcount])
|
77
82
|
else
|
78
83
|
unless STDIN.tty?
|
79
|
-
markov = MarkyMarkov::TemporaryDictionary.new
|
84
|
+
markov = MarkyMarkov::TemporaryDictionary.new(options[:depth])
|
80
85
|
markov.parse_string(STDIN.read)
|
81
86
|
STDOUT.puts markov.generate_n_words(options[:wordcount])
|
82
87
|
else
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# @private
|
2
|
-
class
|
3
|
-
attr_accessor :dictionary
|
4
|
-
def initialize
|
2
|
+
class MarkovDictionary
|
3
|
+
attr_accessor :dictionary, :depth
|
4
|
+
def initialize(depth=2)
|
5
5
|
@dictionary = {}
|
6
|
+
@depth = depth
|
6
7
|
end
|
7
8
|
|
8
9
|
# If File does not exist.
|
@@ -36,11 +37,10 @@ class OneWordDictionary
|
|
36
37
|
# @example Add a string
|
37
38
|
# parse_source("Hi, how are you doing?", false)
|
38
39
|
def parse_source(source, file=true)
|
39
|
-
# Special case for last word in source file as it has no words following it.
|
40
40
|
contents = file ? open_source(source) : contents = source.split
|
41
|
-
contents.each_cons(
|
42
|
-
|
41
|
+
contents.each_cons(@depth+1) do |words|
|
42
|
+
self.add_word(words[0..-2].join(' '), words[-1])
|
43
43
|
end
|
44
|
-
@dictionary[
|
44
|
+
@dictionary[contents.last(@depth).join(' ')] ||= Hash.new(0)
|
45
45
|
end
|
46
46
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# @private
|
2
|
-
class
|
2
|
+
class MarkovSentenceGenerator
|
3
3
|
def initialize(dictionary)
|
4
4
|
@dictionary = dictionary
|
5
|
+
@depth = @dictionary.depth
|
5
6
|
end
|
6
7
|
|
7
8
|
# Returns a random word via picking a random key from the dictionary.
|
@@ -15,6 +16,20 @@ class OneWordSentenceGenerator
|
|
15
16
|
keys[rand(keys.length)]
|
16
17
|
end
|
17
18
|
|
19
|
+
# Generates a random capitalized word via picking a random key from the
|
20
|
+
# dictionary and recurring if the word is lowercase.
|
21
|
+
#
|
22
|
+
# (see #random_word)
|
23
|
+
def random_capitalized_word
|
24
|
+
keys = @dictionary.dictionary.keys
|
25
|
+
x = keys[rand(keys.length)]
|
26
|
+
if /[A-Z]/ =~ x[0]
|
27
|
+
return x
|
28
|
+
else
|
29
|
+
random_capitalized_word
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
18
33
|
# Returns a word based upon the likelyhood of it appearing after the supplied word.
|
19
34
|
#
|
20
35
|
def weighted_random(lastword)
|
@@ -36,10 +51,11 @@ class OneWordSentenceGenerator
|
|
36
51
|
#
|
37
52
|
def generate(wordcount)
|
38
53
|
sentence = []
|
39
|
-
sentence
|
54
|
+
sentence.concat(random_capitalized_word.split)
|
40
55
|
(wordcount-1).times do
|
41
|
-
sentence
|
56
|
+
sentence.concat(weighted_random(sentence.last(@depth).join(' ')).split)
|
42
57
|
end
|
58
|
+
sentence.pop(sentence.length-wordcount)
|
43
59
|
sentence.join(' ')
|
44
60
|
end
|
45
61
|
end
|
@@ -1,27 +1,36 @@
|
|
1
1
|
require 'yajl'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'markov_dictionary'
|
3
3
|
|
4
4
|
# @private
|
5
|
-
class PersistentDictionary <
|
5
|
+
class PersistentDictionary < MarkovDictionary
|
6
|
+
|
7
|
+
class DepthNotInRangeError < Exception
|
8
|
+
end
|
9
|
+
|
6
10
|
# Creates a PersistentDictionary object using the supplied dictionary file.
|
7
11
|
#
|
8
|
-
# @note Do not include the .mmd file extension in the name of the dictionary.
|
9
|
-
# It will be automatically appended.
|
10
12
|
# @param [File] dictionary Name of dictionary file to create/open.
|
13
|
+
# @param [Int] depth The dictionary depth. 2 word dictionary default.
|
11
14
|
# @return [Object] PersistentDictionary object.
|
12
|
-
attr_reader :dictionarylocation
|
13
|
-
def initialize(dictionary)
|
15
|
+
attr_reader :dictionarylocation, :depth
|
16
|
+
def initialize(dictionary, depth=2)
|
17
|
+
@depth = depth
|
18
|
+
unless (1..9).include?(depth)
|
19
|
+
raise DepthNotInRangeError.new("Depth must be between 1 and 9")
|
20
|
+
end
|
14
21
|
@dictionarylocation = dictionary
|
15
22
|
self.open_dictionary
|
16
23
|
end
|
17
24
|
|
25
|
+
|
18
26
|
# Opens the dictionary objects dictionary file.
|
19
27
|
# If the file exists it assigns the contents to a hash,
|
20
28
|
# otherwise it creates an empty hash.
|
21
29
|
def open_dictionary
|
22
30
|
if File.exists?(@dictionarylocation)
|
23
|
-
File.open(@dictionarylocation,'r') do |f|
|
24
|
-
@
|
31
|
+
File.open(@dictionarylocation,'r').each do |f|
|
32
|
+
@depth = f[0].to_i
|
33
|
+
@dictionary = Yajl::Parser.parse(f[1..-1])
|
25
34
|
end
|
26
35
|
else
|
27
36
|
@dictionary = {}
|
@@ -33,7 +42,7 @@ class PersistentDictionary < TwoWordDictionary
|
|
33
42
|
def save_dictionary!
|
34
43
|
json = Yajl::Encoder.encode(@dictionary)
|
35
44
|
File.open(@dictionarylocation, 'w') do |f|
|
36
|
-
f.puts json
|
45
|
+
f.puts @depth.to_s + json
|
37
46
|
end
|
38
47
|
true
|
39
48
|
end
|
data/lib/marky_markov.rb
CHANGED
@@ -2,24 +2,28 @@
|
|
2
2
|
#A Markov Chain generator.
|
3
3
|
|
4
4
|
require_relative 'marky_markov/persistent_dictionary'
|
5
|
-
require_relative 'marky_markov/
|
5
|
+
require_relative 'marky_markov/markov_sentence_generator'
|
6
6
|
|
7
|
-
# @version = 0.1.
|
7
|
+
# @version = 0.1.3
|
8
8
|
# @author Matt Furden
|
9
9
|
# Module containing TemporaryDictionary and Dictionary for creation of
|
10
10
|
# Markov Chain Dictionaries and generating sentences from those dictionaries.
|
11
11
|
module MarkyMarkov
|
12
|
-
VERSION = '0.1.
|
12
|
+
VERSION = '0.1.3'
|
13
13
|
|
14
14
|
class TemporaryDictionary
|
15
15
|
# Create a new Temporary Markov Chain Dictionary and sentence generator for use.
|
16
|
+
# Depth defaults to two words but can be set to any number between 1 and 9.
|
16
17
|
#
|
17
18
|
# @example Create a new Temporary Dictionary.
|
18
19
|
# markov = MarkyMarkov::TemporaryDictionary.new
|
19
|
-
# @
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# @example Create a three word Temporary Dictionary.
|
21
|
+
# markov = MarkyMarkov::TemporaryDictionary.new(3)
|
22
|
+
# @param [Int] depth Optional dictionary depth. Defaults to 2.
|
23
|
+
# @return [Object] a MarkyMarkov::TemporaryDictionary object`.
|
24
|
+
def initialize(depth=2)
|
25
|
+
@dictionary = MarkovDictionary.new(depth)
|
26
|
+
@sentence = MarkovSentenceGenerator.new(@dictionary)
|
23
27
|
end
|
24
28
|
|
25
29
|
# Parses a given file and adds the sentences it contains to the current dictionary.
|
@@ -67,6 +71,7 @@ module MarkyMarkov
|
|
67
71
|
end
|
68
72
|
end
|
69
73
|
|
74
|
+
# @since 0.1.2
|
70
75
|
# Modify respond_to? to include generate_n_words method_missing implementation.
|
71
76
|
def respond_to?(method_sym, include_private = false)
|
72
77
|
if method_sym.to_s =~ /^generate_(\d*)_word[s]*$/
|
@@ -89,15 +94,19 @@ module MarkyMarkov
|
|
89
94
|
|
90
95
|
class Dictionary < TemporaryDictionary
|
91
96
|
# Open (or create if it doesn't exist) a Persistent Markov Chain Dictionary
|
92
|
-
# and sentence generator for use.
|
97
|
+
# and sentence generator for use. Optional dictionary depth may be supplied.
|
93
98
|
#
|
94
99
|
# @example Create a new Persistent Dictionary object.
|
95
100
|
# markov = MarkyMarkov::Dictionary.new("#{ENV["HOME"]}/markov_dictionary")
|
101
|
+
# @example Create a new Persistent Dictionary object with a depth of 4.
|
102
|
+
# markov = MarkyMarkov::Dictionary.new('mmdict.mmd'. 4)
|
103
|
+
# @param [File] location The location the dictionary file is/will be stored.
|
104
|
+
# @param [Int] depth The depth of the dictionary. Defaults to 2.
|
96
105
|
attr_reader :dictionarylocation
|
97
|
-
def initialize(location)
|
106
|
+
def initialize(location, depth=2)
|
98
107
|
@dictionarylocation = "#{location}.mmd"
|
99
|
-
@dictionary = PersistentDictionary.new(@dictionarylocation)
|
100
|
-
@sentence =
|
108
|
+
@dictionary = PersistentDictionary.new(@dictionarylocation, depth)
|
109
|
+
@sentence = MarkovSentenceGenerator.new(@dictionary)
|
101
110
|
end
|
102
111
|
|
103
112
|
# Save the Persistent Dictionary file into JSON format for later use.
|
@@ -120,7 +129,7 @@ module MarkyMarkov
|
|
120
129
|
# MarkyMarkov::Dictionary.delete_dictionary!("#{ENV["HOME"]}/markov_dictionary")
|
121
130
|
# @example Delete the dictionary of the object 'markov'
|
122
131
|
# MarkyMarkov::Dictionary.delete_dictionary!(markov)
|
123
|
-
# @param [String] location location/name of the dictionary file to be deleted.
|
132
|
+
# @param [String/Object] location location/name of the dictionary file to be deleted.
|
124
133
|
def self.delete_dictionary!(location)
|
125
134
|
location += ".mmd" if location.class == String
|
126
135
|
PersistentDictionary.delete_dictionary!(location)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe MarkovDictionary do
|
4
|
+
context "One Word Depth Dictionary" do
|
5
|
+
before(:each) do
|
6
|
+
@onetextsource = "spec/test.txt"
|
7
|
+
@onedict = MarkovDictionary.new(1)
|
8
|
+
@onedict.parse_source("Hello how are you doing today", false)
|
9
|
+
@onestringdict = {"Hello" => {"how" => 1},
|
10
|
+
"how" => {"are" => 1},
|
11
|
+
"are" => {"you" => 1},
|
12
|
+
"you" => {"doing" => 1},
|
13
|
+
"doing" => {"today" => 1},
|
14
|
+
"today" => {} }
|
15
|
+
@onetextdict = {"The" => {"cat"=>1},
|
16
|
+
"and" => {"chainsaws"=>1},
|
17
|
+
"cat" => {"likes"=>1},
|
18
|
+
"chainsaws" => {},
|
19
|
+
"likes" => {"pie"=>1},
|
20
|
+
"pie" => {"and"=>1} }
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can open a file" do
|
24
|
+
@onedict.open_source(@onetextsource).should_not be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should give a FileNotFoundError if the file doesn't exist" do
|
28
|
+
expect { @onedict.open_source("thisisntreal") }.to
|
29
|
+
raise_error(MarkovDictionary::FileNotFoundError,"thisisntreal does not exist!")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can add a word to the dictionary" do
|
33
|
+
@onedict.add_word("to", "be")
|
34
|
+
@onedict.dictionary.should include("to" => {"be" => 1})
|
35
|
+
end
|
36
|
+
|
37
|
+
it "create a dictionary via parsing a text file" do
|
38
|
+
@onedict.dictionary = {}
|
39
|
+
@onedict.parse_source(@onetextsource)
|
40
|
+
@onedict.dictionary.should eql(@onetextdict)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "builds a one word dictionary properly" do
|
44
|
+
@onedict.dictionary.should eql(@onestringdict)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "Two Word Dictionary" do
|
49
|
+
before(:each) do
|
50
|
+
@twodict = MarkovDictionary.new
|
51
|
+
@twodict.parse_source("The cat likes pie and chainsaws", false)
|
52
|
+
@twotextsource = "spec/test.txt"
|
53
|
+
@twostringdict = { "The cat" => { "likes" => 1},
|
54
|
+
"cat likes" => { "pie" => 1 },
|
55
|
+
"likes pie" => {"and" => 1 },
|
56
|
+
"pie and" => { "chainsaws" => 1 },
|
57
|
+
"and chainsaws" => {} }
|
58
|
+
@twotextdict = {"The cat" => {"likes" => 1},
|
59
|
+
"cat likes" => {"pie" => 1},
|
60
|
+
"likes pie" => {"and" => 1},
|
61
|
+
"pie and" => {"chainsaws" => 1},
|
62
|
+
"and chainsaws" => {}}
|
63
|
+
end
|
64
|
+
|
65
|
+
it "can add a word to the two-word dictionary" do
|
66
|
+
@twodict.add_word("Zebras like", "kung-fu")
|
67
|
+
@twodict.dictionary.should eql(@twostringdict.merge( {"Zebras like" => {"kung-fu" => 1}} ))
|
68
|
+
end
|
69
|
+
|
70
|
+
it "create a two-word dictionary via parsing a text file" do
|
71
|
+
@twodict.dictionary = {}
|
72
|
+
@twodict.parse_source(@twotextsource)
|
73
|
+
@twodict.dictionary.should eql(@twotextdict)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe MarkovSentenceGenerator do
|
4
4
|
before(:each) do
|
5
|
-
@dict =
|
5
|
+
@dict = MarkovDictionary.new
|
6
6
|
@dict.parse_source("Hello man how are you today", false)
|
7
|
-
@sentence =
|
7
|
+
@sentence = MarkovSentenceGenerator.new(@dict)
|
8
8
|
end
|
9
9
|
|
10
10
|
it "can pick a random word" do
|
data/spec/textdictcompare.mmd
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"The cat":{"likes":1},"cat likes":{"pie":1},"likes pie":{"and":1},"pie and":{"chainsaws":1},"and chainsaws":{}}
|
1
|
+
2{"The cat":{"likes":1},"cat likes":{"pie":1},"likes pie":{"and":1},"pie and":{"chainsaws":1},"and chainsaws":{}}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marky_markov
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yajl-ruby
|
16
|
-
requirement: &
|
16
|
+
requirement: &70361383496140 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
version: 2.0.0
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
27
|
+
version_requirements: *70361383496140
|
28
28
|
description: ! "MarkyMarkov makes it easy to generate simply Markov Chains based upon
|
29
29
|
input from\n either a source file or a string. While usable as a module in your
|
30
30
|
code it can also be called on\n from the command line and piped into like a standard
|
@@ -39,16 +39,12 @@ files:
|
|
39
39
|
- README.md
|
40
40
|
- bin/marky_markov
|
41
41
|
- lib/marky_markov.rb
|
42
|
-
- lib/marky_markov/
|
43
|
-
- lib/marky_markov/
|
42
|
+
- lib/marky_markov/markov_dictionary.rb
|
43
|
+
- lib/marky_markov/markov_sentence_generator.rb
|
44
44
|
- lib/marky_markov/persistent_dictionary.rb
|
45
|
-
-
|
46
|
-
-
|
47
|
-
- spec/marky_markov/one_word_dictionary_spec.rb
|
48
|
-
- spec/marky_markov/one_word_sentence_spec.rb
|
45
|
+
- spec/marky_markov/markov_dictionary_spec.rb
|
46
|
+
- spec/marky_markov/markov_sentence_generator_spec.rb
|
49
47
|
- spec/marky_markov/persistent_dictionary_spec.rb
|
50
|
-
- spec/marky_markov/two_word_dict_spec.rb
|
51
|
-
- spec/marky_markov/two_word_sentence_spec.rb
|
52
48
|
- spec/spec_helper.rb
|
53
49
|
- spec/textdictcompare.mmd
|
54
50
|
homepage: http://www.thefurd.com
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require_relative 'one_word_dictionary'
|
2
|
-
|
3
|
-
# @private
|
4
|
-
class TwoWordDictionary < OneWordDictionary
|
5
|
-
# Given a source of text, be it a text file (file=true) or a string (file=false)
|
6
|
-
# it will add all the words within the source to the markov dictionary.
|
7
|
-
#
|
8
|
-
# @example Add a text file
|
9
|
-
# parse_source("text.txt")
|
10
|
-
# @example Add a string
|
11
|
-
# parse_source("Hi, how are you doing?", false)
|
12
|
-
def parse_source(source, file=true)
|
13
|
-
contents = file ? open_source(source) : contents = source.split
|
14
|
-
contents.each_cons(3) do |first, second, third|
|
15
|
-
self.add_word("#{first} #{second}", third)
|
16
|
-
end
|
17
|
-
@dictionary[contents.last(2).join(' ')] ||= Hash.new(0)
|
18
|
-
end
|
19
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require_relative 'one_word_sentence_generator'
|
2
|
-
|
3
|
-
# @private
|
4
|
-
class TwoWordSentenceGenerator < OneWordSentenceGenerator
|
5
|
-
def generate(wordcount)
|
6
|
-
sentence = []
|
7
|
-
sentence.concat(random_word.split)
|
8
|
-
(wordcount-1).times do
|
9
|
-
sentence.concat(weighted_random(sentence.last(2).join(' ')).split)
|
10
|
-
end
|
11
|
-
sentence.pop(sentence.length-wordcount)
|
12
|
-
sentence.join(' ')
|
13
|
-
end
|
14
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'spec_helper.rb'
|
2
|
-
|
3
|
-
describe OneWordDictionary do
|
4
|
-
before(:each) do
|
5
|
-
@textsource = "spec/test.txt"
|
6
|
-
@dict = OneWordDictionary.new
|
7
|
-
@dict.parse_source("Hello how are you doing today", false)
|
8
|
-
@stringdict = {"Hello" => {"how" => 1},
|
9
|
-
"how" => {"are" => 1},
|
10
|
-
"are" => {"you" => 1},
|
11
|
-
"you" => {"doing" => 1},
|
12
|
-
"doing" => {"today" => 1},
|
13
|
-
"today" => {} }
|
14
|
-
@textdict = {"The" => {"cat"=>1},
|
15
|
-
"and" => {"chainsaws"=>1},
|
16
|
-
"cat" => {"likes"=>1},
|
17
|
-
"chainsaws" => {},
|
18
|
-
"likes" => {"pie"=>1},
|
19
|
-
"pie" => {"and"=>1} }
|
20
|
-
end
|
21
|
-
|
22
|
-
it "can open a file" do
|
23
|
-
@dict.open_source(@textsource).should_not be_nil
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should give a FileNotFoundError if the file doesn't exist" do
|
27
|
-
expect { @dict.open_source("thisisntreal") }.to
|
28
|
-
raise_error(OneWordDictionary::FileNotFoundError,"thisisntreal does not exist!")
|
29
|
-
end
|
30
|
-
|
31
|
-
it "can add a word to the dictionary" do
|
32
|
-
@dict.add_word("to", "be")
|
33
|
-
@dict.dictionary.should include("to" => {"be" => 1})
|
34
|
-
end
|
35
|
-
|
36
|
-
it "create a dictionary via parsing a text file" do
|
37
|
-
@dict.dictionary = {}
|
38
|
-
@dict.parse_source(@textsource)
|
39
|
-
@dict.dictionary.should eql(@textdict)
|
40
|
-
end
|
41
|
-
|
42
|
-
it "builds a one word dictionary properly" do
|
43
|
-
@dict.dictionary.should eql(@stringdict)
|
44
|
-
end
|
45
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe TwoWordDictionary do
|
4
|
-
before(:each) do
|
5
|
-
@dict = TwoWordDictionary.new
|
6
|
-
@dict.parse_source("The cat likes pie and chainsaws", false)
|
7
|
-
@textsource = "spec/test.txt"
|
8
|
-
@stringdict = { "The cat" => { "likes" => 1},
|
9
|
-
"cat likes" => { "pie" => 1 },
|
10
|
-
"likes pie" => {"and" => 1 },
|
11
|
-
"pie and" => { "chainsaws" => 1 },
|
12
|
-
"and chainsaws" => {} }
|
13
|
-
@textdict = {"The cat" => {"likes" => 1},
|
14
|
-
"cat likes" => {"pie" => 1},
|
15
|
-
"likes pie" => {"and" => 1},
|
16
|
-
"pie and" => {"chainsaws" => 1},
|
17
|
-
"and chainsaws" => {}}
|
18
|
-
end
|
19
|
-
|
20
|
-
it "can add a word to the two-word dictionary" do
|
21
|
-
@dict.add_word("Zebras like", "kung-fu")
|
22
|
-
@dict.dictionary.should eql(@stringdict.merge( {"Zebras like" => {"kung-fu" => 1}} ))
|
23
|
-
end
|
24
|
-
|
25
|
-
it "create a two-word dictionary via parsing a text file" do
|
26
|
-
@dict.dictionary = {}
|
27
|
-
@dict.parse_source(@textsource)
|
28
|
-
@dict.dictionary.should eql(@textdict)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe TwoWordSentenceGenerator do
|
4
|
-
before(:each) do
|
5
|
-
@dict = TwoWordDictionary.new
|
6
|
-
@dict.parse_source("Hello man how are you today", false)
|
7
|
-
@sentence = TwoWordSentenceGenerator.new(@dict)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "generates a sentence of the appropriate length" do
|
11
|
-
@sentence.generate(20).split.count.should eql(20)
|
12
|
-
end
|
13
|
-
end
|