Update markov demo.

This commit is contained in:
Georg Brandl 2009-10-11 08:39:16 +00:00
parent 30fd2bb884
commit 86d38e9ecc
2 changed files with 35 additions and 31 deletions

View File

@ -5,11 +5,10 @@ def __init__(self, histsize, choice):
self.histsize = histsize self.histsize = histsize
self.choice = choice self.choice = choice
self.trans = {} self.trans = {}
def add(self, state, next): def add(self, state, next):
if not self.trans.has_key(state): self.trans.setdefault(state, []).append(next)
self.trans[state] = [next]
else:
self.trans[state].append(next)
def put(self, seq): def put(self, seq):
n = self.histsize n = self.histsize
add = self.add add = self.add
@ -17,26 +16,29 @@ def put(self, seq):
for i in range(len(seq)): for i in range(len(seq)):
add(seq[max(0, i-n):i], seq[i:i+1]) add(seq[max(0, i-n):i], seq[i:i+1])
add(seq[len(seq)-n:], None) add(seq[len(seq)-n:], None)
def get(self): def get(self):
choice = self.choice choice = self.choice
trans = self.trans trans = self.trans
n = self.histsize n = self.histsize
seq = choice(trans[None]) seq = choice(trans[None])
while 1: while True:
subseq = seq[max(0, len(seq)-n):] subseq = seq[max(0, len(seq)-n):]
options = trans[subseq] options = trans[subseq]
next = choice(options) next = choice(options)
if not next: break if not next:
seq = seq + next break
seq += next
return seq return seq
def test(): def test():
import sys, string, random, getopt import sys, random, getopt
args = sys.argv[1:] args = sys.argv[1:]
try: try:
opts, args = getopt.getopt(args, '0123456789cdw') opts, args = getopt.getopt(args, '0123456789cdwq')
except getopt.error: except getopt.error:
print 'Usage: markov [-#] [-cddqw] [file] ...' print 'Usage: %s [-#] [-cddqw] [file] ...' % sys.argv[0]
print 'Options:' print 'Options:'
print '-#: 1-digit history size (default 2)' print '-#: 1-digit history size (default 2)'
print '-c: characters (default)' print '-c: characters (default)'
@ -49,16 +51,19 @@ def test():
print 'exactly one space separating words.' print 'exactly one space separating words.'
print 'Output consists of paragraphs separated by blank' print 'Output consists of paragraphs separated by blank'
print 'lines, where lines are no longer than 72 characters.' print 'lines, where lines are no longer than 72 characters.'
sys.exit(2)
histsize = 2 histsize = 2
do_words = 0 do_words = False
debug = 1 debug = 1
for o, a in opts: for o, a in opts:
if '-0' <= o <= '-9': histsize = eval(o[1:]) if '-0' <= o <= '-9': histsize = int(o[1:])
if o == '-c': do_words = 0 if o == '-c': do_words = False
if o == '-d': debug = debug + 1 if o == '-d': debug += 1
if o == '-q': debug = 0 if o == '-q': debug = 0
if o == '-w': do_words = 1 if o == '-w': do_words = True
if not args: args = ['-'] if not args:
args = ['-']
m = Markov(histsize, random.choice) m = Markov(histsize, random.choice)
try: try:
for filename in args: for filename in args:
@ -72,13 +77,15 @@ def test():
if debug: print 'processing', filename, '...' if debug: print 'processing', filename, '...'
text = f.read() text = f.read()
f.close() f.close()
paralist = string.splitfields(text, '\n\n') paralist = text.split('\n\n')
for para in paralist: for para in paralist:
if debug > 1: print 'feeding ...' if debug > 1: print 'feeding ...'
words = string.split(para) words = para.split()
if words: if words:
if do_words: data = tuple(words) if do_words:
else: data = string.joinfields(words, ' ') data = tuple(words)
else:
data = ' '.join(words)
m.put(data) m.put(data)
except KeyboardInterrupt: except KeyboardInterrupt:
print 'Interrupted -- continue with data read so far' print 'Interrupted -- continue with data read so far'
@ -86,16 +93,19 @@ def test():
print 'No valid input files' print 'No valid input files'
return return
if debug: print 'done.' if debug: print 'done.'
if debug > 1: if debug > 1:
for key in m.trans.keys(): for key in m.trans.keys():
if key is None or len(key) < histsize: if key is None or len(key) < histsize:
print repr(key), m.trans[key] print repr(key), m.trans[key]
if histsize == 0: print repr(''), m.trans[''] if histsize == 0: print repr(''), m.trans['']
print print
while 1: while True:
data = m.get() data = m.get()
if do_words: words = data if do_words:
else: words = string.split(data) words = data
else:
words = data.split()
n = 0 n = 0
limit = 72 limit = 72
for w in words: for w in words:
@ -103,15 +113,9 @@ def test():
print print
n = 0 n = 0
print w, print w,
n = n + len(w) + 1 n += len(w) + 1
print print
print print
def tuple(list):
if len(list) == 0: return ()
if len(list) == 1: return (list[0],)
i = len(list)//2
return tuple(list[:i]) + tuple(list[i:])
if __name__ == "__main__": if __name__ == "__main__":
test() test()

View File

@ -61,7 +61,7 @@ def mkwave(octave):
sinewave = '' sinewave = ''
for i in range(100): for i in range(100):
val = int(math.sin(math.pi * i * octave / 50.0) * 30000) val = int(math.sin(math.pi * i * octave / 50.0) * 30000)
sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255) sinewave += chr((val >> 8) & 255) + chr(val & 255)
return sinewave return sinewave
defaultwave = mkwave(OCTAVE) defaultwave = mkwave(OCTAVE)