marky_markov 0.1.1 → 0.1.2
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 +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>
|