toxic thought waste site

Theological whimsy, metaphysical larks, and other spiritually radioactive waste products.

Saturday, June 14, 2008

Make Your Own Bible Verses

I was reading this article on the unholy union of Garfield and Markov models and it reminded me that I'd never gotten around to trying out markov modelling first hand.

Over my lunch hour I cranked out the code at the bottom of this entry. And yes I write code over my lunch hour as a form of relaxation. What do you do?

In any case, the previous blog entry was the result of running this script on the book of Mark. Mark, Markov, get it?

Any way if you've ever wanted to generate your own biblical sounding text, here's your chance. Just download some scripture and crank up your python interpreter and away you go!

BTW, I'm really curious if Mark(ov) Chapter 1 get's any hits from people seeking Biblical inspiration. I know it inspired me.


import sys
import random
import itertools

#http://www.o-bible.org/download/kjv.txt

def make_frequencies(words):
result = {}

for i in range(2, len(words)):
w1, w2, w3 = words[i-2:i+1]
if (w1,w2) not in result:
result[(w1,w2)] = {}
if w3 not in result[(w1,w2)]:
result[(w1,w2)][w3] = 0
result[(w1,w2)][w3] += 1

return result

def find_first_random(freqs):
return get_random_ith_item(list(set([x[0] for x in freqs])))

def find_second_random(first, freqs):
pair = get_random_ith_item(list(set(x for x in freqs if x[0] == first)))
if not pair:
return find_first_random(freqs)
return pair[1]

def find_markov_random(first, second, freqs):
markov_words = freqs.get((first,second), {})
word = get_random_ith_item(itertools.chain(*[[x]*count for (x,count) in markov_words.items()]))
if not word:
return find_second_random(second, freqs)

return word

def get_random_ith_item(stream):
item = None
for i,x in enumerate(stream):
if random.randint(0,i) == 0:
item = x

return item

def markovize(freqs, output_length):
result = [find_first_random(freqs)]
result.append(find_second_random(result[0], freqs))
output_length -= 2

while output_length > 0:
w1, w2 = result[-2:]
result.append(find_markov_random(w1,w2,freqs))
output_length -= 1

return result

def main():
output_length = 500

words = ' '.join(sys.stdin.readlines())

word_frequencies = make_frequencies(words.split())
print ' '.join(markovize(word_frequencies, output_length))

if __name__ == '__main__':
main()

Labels: ,

[digg]

1 Comments:

Blogger Paxtonite said...

I stumbled upon this post and was thrilled to see that you had written code to produce a random output. I have been wanting to do this again. The last time I did this was in 1983 in basic language on a Texas Instruments TI99/4A "computer" saving my code using a connected cassette tape recorder because there was no hard drive.

Do you think this is all possible using a SQL database?

Mon Oct 21, 02:29:00 PM  

Post a Comment

<< Home