marky_markov 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +9 -0
- data/lib/marky_markov.rb +50 -13
- data/lib/marky_markov/one_word_dictionary.rb +11 -0
- data/lib/marky_markov/one_word_sentence_generator.rb +10 -1
- data/lib/marky_markov/persistent_dictionary.rb +25 -7
- data/lib/marky_markov/two_word_dictionary.rb +7 -0
- data/spec/marky_markov/persistent_dictionary_spec.rb +3 -3
- metadata +5 -22
- data/doc/MarkyMarkov.html +0 -120
- data/doc/MarkyMarkov/Dictionary.html +0 -415
- data/doc/MarkyMarkov/TemporaryDictionary.html +0 -588
- data/doc/_index.html +0 -136
- data/doc/class_list.html +0 -47
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -55
- data/doc/css/style.css +0 -322
- data/doc/file.README.html +0 -162
- data/doc/file_list.html +0 -49
- data/doc/frames.html +0 -13
- data/doc/index.html +0 -162
- data/doc/js/app.js +0 -205
- data/doc/js/full_list.js +0 -173
- data/doc/js/jquery.js +0 -16
- data/doc/method_list.html +0 -110
- data/doc/top-level-namespace.html +0 -105
data/README.md
CHANGED
@@ -33,11 +33,20 @@ 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 look at generate_n_words and wonder why you can't put a
|
37
|
+
number in there, well, you can!
|
38
|
+
|
39
|
+
markov.generate_20_words
|
40
|
+
|
36
41
|
If you want to delete a dictionary you call it upon the Dictionary class itself while
|
37
42
|
passing in the filename/location.
|
38
43
|
|
39
44
|
MarkyMarkov::Dictionary.delete_dictionary!('dictionary')
|
40
45
|
|
46
|
+
OR you can pass in a MarkyMarkov::Dictionary object directly.
|
47
|
+
|
48
|
+
MarkyMarkov::Dictionary.delete_dictionary!(markov)
|
49
|
+
|
41
50
|
|
42
51
|
# Command-Line Usage
|
43
52
|
|
data/lib/marky_markov.rb
CHANGED
@@ -4,8 +4,12 @@
|
|
4
4
|
require_relative 'marky_markov/persistent_dictionary'
|
5
5
|
require_relative 'marky_markov/two_word_sentence_generator'
|
6
6
|
|
7
|
+
# @version = 0.1.2
|
8
|
+
# @author Matt Furden
|
9
|
+
# Module containing TemporaryDictionary and Dictionary for creation of
|
10
|
+
# Markov Chain Dictionaries and generating sentences from those dictionaries.
|
7
11
|
module MarkyMarkov
|
8
|
-
VERSION = '0.1.
|
12
|
+
VERSION = '0.1.2'
|
9
13
|
|
10
14
|
class TemporaryDictionary
|
11
15
|
# Create a new Temporary Markov Chain Dictionary and sentence generator for use.
|
@@ -17,7 +21,7 @@ module MarkyMarkov
|
|
17
21
|
@dictionary = TwoWordDictionary.new
|
18
22
|
@sentence = TwoWordSentenceGenerator.new(@dictionary)
|
19
23
|
end
|
20
|
-
|
24
|
+
|
21
25
|
# Parses a given file and adds the sentences it contains to the current dictionary.
|
22
26
|
#
|
23
27
|
# @example Open a text file and add its contents to the dictionary.
|
@@ -26,16 +30,16 @@ module MarkyMarkov
|
|
26
30
|
def parse_file(location)
|
27
31
|
@dictionary.parse_source(location, true)
|
28
32
|
end
|
29
|
-
|
33
|
+
|
30
34
|
# Parses a given string and adds them to the current dictionary.
|
31
35
|
#
|
32
36
|
# @example Add a string to the dictionary.
|
33
37
|
# markov.parse_string "I could really go for some Chicken Makhani."
|
34
|
-
# @param [String]
|
38
|
+
# @param [String] string the sentence you want to add to the dictionary.
|
35
39
|
def parse_string(string)
|
36
40
|
@dictionary.parse_source(string, false)
|
37
41
|
end
|
38
|
-
|
42
|
+
|
39
43
|
# Generates a sentence/sentences of n words using the dictionary generated via
|
40
44
|
# parse_string or parse_file.
|
41
45
|
#
|
@@ -46,7 +50,33 @@ module MarkyMarkov
|
|
46
50
|
def generate_n_words(wordcount)
|
47
51
|
@sentence.generate(wordcount)
|
48
52
|
end
|
49
|
-
|
53
|
+
|
54
|
+
# Dynamically call generate_n_words if an Int is substituted for
|
55
|
+
# the n in the method call.
|
56
|
+
#
|
57
|
+
# @since 0.1.2
|
58
|
+
# @example Generate a 40 and a 1 word long string of words.
|
59
|
+
# markov.generate_40_words
|
60
|
+
# markov.generate_1_word
|
61
|
+
# @return [String] the sentence generated by the dictionary.
|
62
|
+
def method_missing(method_sym, *args, &block)
|
63
|
+
if method_sym.to_s =~ /^generate_(\d*)_word[s]*$/
|
64
|
+
generate_n_words($1.to_i)
|
65
|
+
else
|
66
|
+
super
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Modify respond_to? to include generate_n_words method_missing implementation.
|
71
|
+
def respond_to?(method_sym, include_private = false)
|
72
|
+
if method_sym.to_s =~ /^generate_(\d*)_word[s]*$/
|
73
|
+
true
|
74
|
+
else
|
75
|
+
super
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
|
50
80
|
# Clears the temporary dictionary's hash, useful for keeping
|
51
81
|
# the same dictionary object but removing the words it has learned.
|
52
82
|
#
|
@@ -63,11 +93,13 @@ module MarkyMarkov
|
|
63
93
|
#
|
64
94
|
# @example Create a new Persistent Dictionary object.
|
65
95
|
# markov = MarkyMarkov::Dictionary.new("#{ENV["HOME"]}/markov_dictionary")
|
96
|
+
attr_reader :dictionarylocation
|
66
97
|
def initialize(location)
|
67
|
-
@
|
98
|
+
@dictionarylocation = "#{location}.mmd"
|
99
|
+
@dictionary = PersistentDictionary.new(@dictionarylocation)
|
68
100
|
@sentence = TwoWordSentenceGenerator.new(@dictionary)
|
69
101
|
end
|
70
|
-
|
102
|
+
|
71
103
|
# Save the Persistent Dictionary file into JSON format for later use.
|
72
104
|
#
|
73
105
|
# @example Save the dictionary to disk.
|
@@ -75,17 +107,22 @@ module MarkyMarkov
|
|
75
107
|
def save_dictionary!
|
76
108
|
@dictionary.save_dictionary!
|
77
109
|
end
|
78
|
-
|
79
|
-
#
|
110
|
+
|
111
|
+
# Takes a dictionary location/name and deletes it from the file-system.
|
112
|
+
# Alternatively, pass in a MarkyMarkov::Dictionary object in
|
113
|
+
# directly and it will delete that objects dictionary from disk.
|
80
114
|
#
|
81
|
-
# @note To ensure that someone doesn't pass in something that shouldn't
|
82
|
-
#
|
83
|
-
#
|
115
|
+
# @note To ensure that someone doesn't pass in something that shouldn't
|
116
|
+
# be deleted by accident, the filetype .mmd is added to the end of the
|
117
|
+
# supplied argument, so do not include the extension when calling the method.
|
84
118
|
#
|
85
119
|
# @example Delete the dictionary located at '~/markov_dictionary.mmd'
|
86
120
|
# MarkyMarkov::Dictionary.delete_dictionary!("#{ENV["HOME"]}/markov_dictionary")
|
121
|
+
# @example Delete the dictionary of the object 'markov'
|
122
|
+
# MarkyMarkov::Dictionary.delete_dictionary!(markov)
|
87
123
|
# @param [String] location location/name of the dictionary file to be deleted.
|
88
124
|
def self.delete_dictionary!(location)
|
125
|
+
location += ".mmd" if location.class == String
|
89
126
|
PersistentDictionary.delete_dictionary!(location)
|
90
127
|
end
|
91
128
|
end
|
@@ -18,12 +18,23 @@ class OneWordDictionary
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
# Given root word and what it is followed by, it adds them to the dictionary.
|
22
|
+
#
|
23
|
+
# @example Adding a word
|
24
|
+
# add_word("Hello", "world")
|
21
25
|
def add_word(rootword, followedby)
|
22
26
|
@dictionary[rootword] ||= Hash.new(0)
|
23
27
|
@dictionary[rootword][followedby] ||= 0
|
24
28
|
@dictionary[rootword][followedby] += 1
|
25
29
|
end
|
26
30
|
|
31
|
+
# Given a source of text, be it a text file (file=true) or a string (file=false)
|
32
|
+
# it will add all the words within the source to the markov dictionary.
|
33
|
+
#
|
34
|
+
# @example Add a text file
|
35
|
+
# parse_source("text.txt")
|
36
|
+
# @example Add a string
|
37
|
+
# parse_source("Hi, how are you doing?", false)
|
27
38
|
def parse_source(source, file=true)
|
28
39
|
# Special case for last word in source file as it has no words following it.
|
29
40
|
contents = file ? open_source(source) : contents = source.split
|
@@ -4,18 +4,25 @@ class OneWordSentenceGenerator
|
|
4
4
|
@dictionary = dictionary
|
5
5
|
end
|
6
6
|
|
7
|
+
# Returns a random word via picking a random key from the dictionary.
|
8
|
+
# In the case of the TwoWordDictionary, it returns two words to ensure
|
9
|
+
# that the sentence will have a valid two word string to pick the next
|
10
|
+
# word from.
|
11
|
+
#
|
12
|
+
# @return [String] a string containing a random dictionary key.
|
7
13
|
def random_word
|
8
14
|
keys = @dictionary.dictionary.keys
|
9
15
|
keys[rand(keys.length)]
|
10
16
|
end
|
11
17
|
|
18
|
+
# Returns a word based upon the likelyhood of it appearing after the supplied word.
|
19
|
+
#
|
12
20
|
def weighted_random(lastword)
|
13
21
|
# If word has no words in its dictionary (last word in source text file)
|
14
22
|
# have it pick a random word to display instead.
|
15
23
|
@dictionary.dictionary.fetch(lastword, random_word)
|
16
24
|
total = @dictionary.dictionary[lastword].values.inject(:+)
|
17
25
|
return random_word if total.nil?
|
18
|
-
|
19
26
|
random = rand(total)+1
|
20
27
|
@dictionary.dictionary[lastword].each do |word, occurs|
|
21
28
|
random -= occurs
|
@@ -25,6 +32,8 @@ class OneWordSentenceGenerator
|
|
25
32
|
end
|
26
33
|
end
|
27
34
|
|
35
|
+
# Generates a sentence of (wordcount) length using the weighted_random function.
|
36
|
+
#
|
28
37
|
def generate(wordcount)
|
29
38
|
sentence = []
|
30
39
|
sentence << random_word
|
@@ -3,11 +3,21 @@ require_relative 'two_word_dictionary'
|
|
3
3
|
|
4
4
|
# @private
|
5
5
|
class PersistentDictionary < TwoWordDictionary
|
6
|
+
# Creates a PersistentDictionary object using the supplied dictionary file.
|
7
|
+
#
|
8
|
+
# @note Do not include the .mmd file extension in the name of the dictionary.
|
9
|
+
# It will be automatically appended.
|
10
|
+
# @param [File] dictionary Name of dictionary file to create/open.
|
11
|
+
# @return [Object] PersistentDictionary object.
|
12
|
+
attr_reader :dictionarylocation
|
6
13
|
def initialize(dictionary)
|
7
|
-
@dictionarylocation =
|
14
|
+
@dictionarylocation = dictionary
|
8
15
|
self.open_dictionary
|
9
16
|
end
|
10
17
|
|
18
|
+
# Opens the dictionary objects dictionary file.
|
19
|
+
# If the file exists it assigns the contents to a hash,
|
20
|
+
# otherwise it creates an empty hash.
|
11
21
|
def open_dictionary
|
12
22
|
if File.exists?(@dictionarylocation)
|
13
23
|
File.open(@dictionarylocation,'r') do |f|
|
@@ -18,6 +28,8 @@ class PersistentDictionary < TwoWordDictionary
|
|
18
28
|
end
|
19
29
|
end
|
20
30
|
|
31
|
+
# Saves the PersistentDictionary objects @dictionary hash
|
32
|
+
# to disk in JSON format.
|
21
33
|
def save_dictionary!
|
22
34
|
json = Yajl::Encoder.encode(@dictionary)
|
23
35
|
File.open(@dictionarylocation, 'w') do |f|
|
@@ -26,12 +38,18 @@ class PersistentDictionary < TwoWordDictionary
|
|
26
38
|
true
|
27
39
|
end
|
28
40
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
41
|
+
# Deletes the supplied dictionary file.
|
42
|
+
# Can either be passed the dictionary location and name, or a
|
43
|
+
# PersistentDictionary object.
|
44
|
+
def self.delete_dictionary!(dictionary)
|
45
|
+
if dictionary.respond_to?(:dictionarylocation)
|
46
|
+
dictionary = dictionary.dictionarylocation
|
47
|
+
end
|
48
|
+
if File.exists?(dictionary)
|
49
|
+
File.delete(dictionary)
|
50
|
+
"Deleted #{dictionary}"
|
51
|
+
else
|
52
|
+
"#{dictionary} does not exist."
|
34
53
|
end
|
35
|
-
false
|
36
54
|
end
|
37
55
|
end
|
@@ -2,6 +2,13 @@ require_relative 'one_word_dictionary'
|
|
2
2
|
|
3
3
|
# @private
|
4
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)
|
5
12
|
def parse_source(source, file=true)
|
6
13
|
contents = file ? open_source(source) : contents = source.split
|
7
14
|
contents.each_cons(3) do |first, second, third|
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe PersistentDictionary do
|
4
4
|
before do
|
5
|
-
@dict = PersistentDictionary.new("spec/textdict")
|
5
|
+
@dict = PersistentDictionary.new("spec/textdict.mmd")
|
6
6
|
@dict.parse_source("spec/test.txt")
|
7
7
|
end
|
8
8
|
|
@@ -11,12 +11,12 @@ describe PersistentDictionary do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should be able to load an existing dictionary" do
|
14
|
-
otherdict = PersistentDictionary.new("spec/textdictcompare")
|
14
|
+
otherdict = PersistentDictionary.new("spec/textdictcompare.mmd")
|
15
15
|
@dict.dictionary.should eql(otherdict.dictionary)
|
16
16
|
end
|
17
17
|
|
18
18
|
after do
|
19
|
-
PersistentDictionary.delete_dictionary!("spec/textdict")
|
19
|
+
PersistentDictionary.delete_dictionary!("spec/textdict.mmd")
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
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.2
|
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-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yajl-ruby
|
16
|
-
requirement: &
|
16
|
+
requirement: &70118059271520 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -24,10 +24,10 @@ dependencies:
|
|
24
24
|
version: 2.0.0
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
27
|
+
version_requirements: *70118059271520
|
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
|
-
code it can also be called on\n from the command line and piped into like a
|
30
|
+
code it can also be called on\n from the command line and piped into like a standard
|
31
31
|
UNIX application."
|
32
32
|
email: mfurden@gmail.com
|
33
33
|
executables:
|
@@ -38,23 +38,6 @@ extra_rdoc_files:
|
|
38
38
|
files:
|
39
39
|
- README.md
|
40
40
|
- bin/marky_markov
|
41
|
-
- doc/MarkyMarkov.html
|
42
|
-
- doc/MarkyMarkov/Dictionary.html
|
43
|
-
- doc/MarkyMarkov/TemporaryDictionary.html
|
44
|
-
- doc/_index.html
|
45
|
-
- doc/class_list.html
|
46
|
-
- doc/css/common.css
|
47
|
-
- doc/css/full_list.css
|
48
|
-
- doc/css/style.css
|
49
|
-
- doc/file.README.html
|
50
|
-
- doc/file_list.html
|
51
|
-
- doc/frames.html
|
52
|
-
- doc/index.html
|
53
|
-
- doc/js/app.js
|
54
|
-
- doc/js/full_list.js
|
55
|
-
- doc/js/jquery.js
|
56
|
-
- doc/method_list.html
|
57
|
-
- doc/top-level-namespace.html
|
58
41
|
- lib/marky_markov.rb
|
59
42
|
- lib/marky_markov/one_word_dictionary.rb
|
60
43
|
- lib/marky_markov/one_word_sentence_generator.rb
|
data/doc/MarkyMarkov.html
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
-
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
-
<head>
|
5
|
-
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
6
|
-
<title>
|
7
|
-
Module: MarkyMarkov
|
8
|
-
|
9
|
-
— Documentation by YARD 0.7.5
|
10
|
-
|
11
|
-
</title>
|
12
|
-
|
13
|
-
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />
|
14
|
-
|
15
|
-
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
|
16
|
-
|
17
|
-
<script type="text/javascript" charset="utf-8">
|
18
|
-
relpath = '';
|
19
|
-
if (relpath != '') relpath += '/';
|
20
|
-
</script>
|
21
|
-
|
22
|
-
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
23
|
-
|
24
|
-
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
25
|
-
|
26
|
-
|
27
|
-
</head>
|
28
|
-
<body>
|
29
|
-
<script type="text/javascript" charset="utf-8">
|
30
|
-
if (window.top.frames.main) document.body.className = 'frames';
|
31
|
-
</script>
|
32
|
-
|
33
|
-
<div id="header">
|
34
|
-
<div id="menu">
|
35
|
-
|
36
|
-
<a href="_index.html">Index (M)</a> »
|
37
|
-
|
38
|
-
|
39
|
-
<span class="title">MarkyMarkov</span>
|
40
|
-
|
41
|
-
|
42
|
-
<div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
|
43
|
-
</div>
|
44
|
-
|
45
|
-
<div id="search">
|
46
|
-
|
47
|
-
<a id="class_list_link" href="#">Class List</a>
|
48
|
-
|
49
|
-
<a id="method_list_link" href="#">Method List</a>
|
50
|
-
|
51
|
-
<a id="file_list_link" href="#">File List</a>
|
52
|
-
|
53
|
-
</div>
|
54
|
-
<div class="clear"></div>
|
55
|
-
</div>
|
56
|
-
|
57
|
-
<iframe id="search_frame"></iframe>
|
58
|
-
|
59
|
-
<div id="content"><h1>Module: MarkyMarkov
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
</h1>
|
64
|
-
|
65
|
-
<dl class="box">
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
<dt class="r1 last">Defined in:</dt>
|
75
|
-
<dd class="r1 last">lib/marky_markov.rb</dd>
|
76
|
-
|
77
|
-
</dl>
|
78
|
-
<div class="clear"></div>
|
79
|
-
|
80
|
-
<h2>Defined Under Namespace</h2>
|
81
|
-
<p class="children">
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
<strong class="classes">Classes:</strong> <span class='object_link'><a href="MarkyMarkov/Dictionary.html" title="MarkyMarkov::Dictionary (class)">Dictionary</a></span>, <span class='object_link'><a href="MarkyMarkov/TemporaryDictionary.html" title="MarkyMarkov::TemporaryDictionary (class)">TemporaryDictionary</a></span>
|
87
|
-
|
88
|
-
|
89
|
-
</p>
|
90
|
-
|
91
|
-
<h2>Constant Summary</h2>
|
92
|
-
|
93
|
-
<dl class="constants">
|
94
|
-
|
95
|
-
<dt id="VERSION-constant" class="">VERSION =
|
96
|
-
|
97
|
-
</dt>
|
98
|
-
<dd><pre class="code"><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>0.1.0</span><span class='tstring_end'>'</span></span></pre></dd>
|
99
|
-
|
100
|
-
</dl>
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
</div>
|
112
|
-
|
113
|
-
<div id="footer">
|
114
|
-
Generated on Mon Feb 6 22:18:54 2012 by
|
115
|
-
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
116
|
-
0.7.5 (ruby-1.9.3).
|
117
|
-
</div>
|
118
|
-
|
119
|
-
</body>
|
120
|
-
</html>
|