Class: MyFirstMarkov::Chain
- Inherits:
-
Object
- Object
- MyFirstMarkov::Chain
- Defined in:
- lib/my_first_markov/chain.rb
Constant Summary collapse
- DEFAULT_COUNT =
5- DEFAULT_DEBUG =
true
Class Method Summary collapse
- .default_next_method ⇒ Object
- .default_split_on_value ⇒ Object
- .file_to_entries(file, split_on, starting_entry, next_method) ⇒ Object
- .from_downcase_file(file, split_on, starting_entry, next_method) ⇒ Object
- .from_entries(entries, starting_entry, next_method, count) ⇒ Object
- .from_file(file, split_on, starting_entry, next_method) ⇒ Object
- .next_methods ⇒ Object
- .split_on_values ⇒ Object
Instance Method Summary collapse
- #add(entry, next_entry) ⇒ Object
- #first(count = nil) ⇒ Object
-
#initialize(ordered_entries, debug = DEFAULT_DEBUG) ⇒ Chain
constructor
A new instance of Chain.
- #most_likely_next(entry, count = nil) ⇒ Object
- #random_next(entry, count = nil) ⇒ Object
Constructor Details
#initialize(ordered_entries, debug = DEFAULT_DEBUG) ⇒ Chain
Returns a new instance of Chain.
68 69 70 71 72 73 74 75 |
# File 'lib/my_first_markov/chain.rb', line 68 def initialize(ordered_entries, debug=DEFAULT_DEBUG) @debug = debug @entries = Hash.new ordered_entries.each_with_index do |entry, index| next_entry_idx = next_idx_or_nil(index, ordered_entries.size) add(entry, ordered_entries[next_entry_idx]) if next_entry_idx end end |
Class Method Details
.default_next_method ⇒ Object
14 15 16 |
# File 'lib/my_first_markov/chain.rb', line 14 def self.default_next_method next_methods.first end |
.default_split_on_value ⇒ Object
22 23 24 |
# File 'lib/my_first_markov/chain.rb', line 22 def self.default_split_on_value split_on_values.first end |
.file_to_entries(file, split_on, starting_entry, next_method) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/my_first_markov/chain.rb', line 35 def self.file_to_entries(file, split_on, starting_entry, next_method) unless split_on && MyFirstMarkov::Chain.split_on_values.include?(split_on.downcase) split_on = MyFirstMarkov::Chain.default_split_on_value end if next_method if matches = next_method.match(/^(\D+)(\d+)$/) next_method = matches[1] count = matches[2] unless MyFirstMarkov::Chain.next_methods.include?(next_method.downcase) next_method = MyFirstMarkov::Chain.default_next_method end end else next_method = MyFirstMarkov::Chain.default_next_method end unless File.exists?(file) fail("Unknown file: #{file.inspect}") end data = File.read(file) ("word" == split_on.downcase) ? entries = data.split : entries = data.split(//) entries ||= [] #puts "return [#{entries.inspect}, #{starting_entry.inspect}, #{next_method.inspect}, #{count || DEFAULT_COUNT}]" return [entries, starting_entry, next_method, count || DEFAULT_COUNT] end |
.from_downcase_file(file, split_on, starting_entry, next_method) ⇒ Object
26 27 28 29 |
# File 'lib/my_first_markov/chain.rb', line 26 def self.from_downcase_file(file, split_on, starting_entry, next_method) entries, starting_entry, next_method, count = file_to_entries(file, split_on, starting_entry, next_method) return from_entries(entries.map(&:downcase), starting_entry, next_method, count) end |
.from_entries(entries, starting_entry, next_method, count) ⇒ Object
64 65 66 |
# File 'lib/my_first_markov/chain.rb', line 64 def self.from_entries(entries, starting_entry, next_method, count) new(entries).send(next_method.downcase, starting_entry, count) end |
.from_file(file, split_on, starting_entry, next_method) ⇒ Object
31 32 33 |
# File 'lib/my_first_markov/chain.rb', line 31 def self.from_file(file, split_on, starting_entry, next_method) from_entries(*file_to_entries(file, split_on, starting_entry, next_method)) end |
.next_methods ⇒ Object
10 11 12 |
# File 'lib/my_first_markov/chain.rb', line 10 def self.next_methods ["random_next", "most_likely_next", "first"] end |
.split_on_values ⇒ Object
18 19 20 |
# File 'lib/my_first_markov/chain.rb', line 18 def self.split_on_values ["word", "character"] end |
Instance Method Details
#add(entry, next_entry) ⇒ Object
77 78 79 80 |
# File 'lib/my_first_markov/chain.rb', line 77 def add(entry, next_entry) @entries[entry] ||= Hash.new(0) @entries[entry][next_entry] += 1 end |
#first(count = nil) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/my_first_markov/chain.rb', line 82 def first(count=nil) count ||= DEFAULT_COUNT # @entries.keys.sort {|a,b| num_observations_for(b) <=> num_observations_for(a) }.take(count) results = @entries.keys.reduce({}) { |memo, key| memo[key] = num_observations_for(key); memo }.sort { |a,b| num_observations_for(b.first) <=> num_observations_for(a.first) } .take(count.to_i) if (@debug) results.reduce({}) { |memo, ary| memo[ary.first] = ary.last; memo }.to_json else #results.first results.map(&:first).to_json # the "entry" part, not the "num_observations" end end |
#most_likely_next(entry, count = nil) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/my_first_markov/chain.rb', line 98 def most_likely_next(entry, count=nil) count ||= DEFAULT_COUNT _next(entry) do |observation_total, next_entries_and_observations| results = next_entries_and_observations .sort {|a,b| b.last <=> a.last} # sort (in reverse) by observations .take(count.to_i) # choose the array(s) with the largest observation (could be many with same #) if (@debug) # debug: results.reduce({}) { |memo, ary| memo[ary.first] = ary.last; memo }.to_json else results.map(&:first).to_json # the "entry" part, not the "num_observations" end end end |
#random_next(entry, count = nil) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/my_first_markov/chain.rb', line 114 def random_next(entry, count=nil) count ||= 1 #puts "called w/ entry: #{entry.inspect}, count: #{count.inspect}" _next(entry) do |observation_total, next_entries_and_observations| random_threshold = rand(observation_total) + 1 partial_observation_sum = 0 results = next_entries_and_observations.select { |next_entry, num_observations| partial_observation_sum += num_observations partial_observation_sum >= random_threshold }.take(count.to_i) if (@debug) # debug: #{ result.first => result.last }.to_json results.reduce({}) { |memo, ary| memo[ary.first] = ary.last; memo }.to_json else #result.first # the "entry" part, not the "num_observations" results.map(&:first).to_json # the "entry" part, not the "num_observations" end end end |