Skip to content

Commit

Permalink
Try out NullObject pattern.
Browse files Browse the repository at this point in the history
  • Loading branch information
zolrath committed Feb 10, 2012
1 parent 2add063 commit 2b9a5a9
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 31 deletions.
4 changes: 2 additions & 2 deletions lib/marky_markov.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
require_relative 'marky_markov/persistent_dictionary'
require_relative 'marky_markov/markov_sentence_generator'

# @version = 0.3.0
# @version = 0.3.1
# @author Matt Furden
# Module containing TemporaryDictionary and Dictionary for creation of
# Markov Chain Dictionaries and generating sentences from those dictionaries.
module MarkyMarkov
VERSION = '0.3.0'
VERSION = '0.3.1'

class TemporaryDictionary
# Create a new Temporary Markov Chain Dictionary and sentence generator for use.
Expand Down
63 changes: 36 additions & 27 deletions lib/marky_markov/markov_sentence_generator.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# Messing about with the NullObject pattern, can't apply it in too many
# places in this one. Need to evaluate what else could be used in this
# aside from my first instinct of defaulting to []
class NullObject
def method_missing (*args, &block)
self
end
def nil?; true; end
def <<(*); end
end
NULL_OBJECT = NullObject.new

# @private
class MarkovSentenceGenerator
def initialize(dictionary)
Expand All @@ -12,36 +24,34 @@ def initialize(dictionary)
#
# @return [String] a string containing a random dictionary key.
def random_word
keys = @dictionary.dictionary.keys
keys[rand(keys.length)]
words = @dictionary.dictionary.keys
words[rand(words.length)]
end

# Generates a random capitalized word via picking a random key from the
# dictionary and recurring if the word is lowercase.
#
# (see #random_word)
def random_capitalized_word(attempts=0)
keys = @dictionary.dictionary.keys
x = keys[rand(keys.length)]
if /[A-Z]/ =~ x[0]
return x
elsif attempts < 30
# If you don't find a capitalized word after 30 attempts, just use
# a lowercase word as there may be no capitals in the dicationary.
random_capitalized_word(attempts+1)
else
random_word
def random_capitalized_word
attempts = 0
# If you don't find a capitalized word after 30 attempts, just use
# a lowercase word as there may be no capitals in the dicationary.
until attempts > 30
words = @dictionary.dictionary.keys
random_choice = words[rand(words.length)]
if /[A-Z]/ =~ random_choice[0]
return random_choice
end
end
random_word
end

# Returns a word based upon the likelyhood of it appearing after the supplied word.
#
#
def weighted_random(lastword)
# If word has no words in its dictionary (last word in source text file)
# have it pick a random word to display instead.
if word = @dictionary.dictionary[lastword]
word.sample
end
@dictionary.dictionary.fetch(lastword) {NULL_OBJECT}.sample
end

# Generates a sentence of (wordcount) length using the weighted_random function.
Expand All @@ -68,19 +78,18 @@ def generate(wordcount)
# @return [String] the sentence(s) generated.
def generate_sentence(sentencecount)
sentence = []
# Find out how many actual keys are in the dictionary.
key_count = @dictionary.dictionary.keys.length
# If less than 30 keys, use that plus five as your maximum sentence length.
maximum_length = key_count < 30 ? key_count + 5 : 30
sentencecount.times do
# Find out how many actual keys are in the dictionary.
key_count = @dictionary.dictionary.keys.length
# If less than 30 keys, use that plus five as your maximum sentence length.
maximum_length = key_count < 30 ? key_count + 5 : 30
stop_at_index = sentence.count + maximum_length
wordcount = 0
sentence.concat(random_capitalized_word)
until (/[.!?]/ =~ sentence.last[-1])
until (/[.!?]/ =~ sentence.last[-1]) || wordcount > 30
wordcount += 1
word = weighted_random(sentence.last(@depth))
sentence << word unless word.nil?
# If a word ending with a . ! or ? isn't found after 30 words,
# just add a period as there may be none in the dictionary.
sentence[-1] << "." if word.nil? || sentence.count > stop_at_index
sentence << word
sentence[-1] << "." if wordcount == 30
end
end
sentence.join(' ')
Expand Down
4 changes: 2 additions & 2 deletions marky_markov.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ Gem::Specification.new do |s|
## If your rubyforge_project name is different, then edit it and comment out
## the sub! line in the Rakefile
s.name = 'marky_markov'
s.version = '0.3.0'
s.date = '2012-02-09'
s.version = '0.3.1'
s.date = '2012-02-10'
s.rubyforge_project = 'marky_markov'

## Make sure your summary is short. The description may be as long
Expand Down

0 comments on commit 2b9a5a9

Please sign in to comment.