1111
1212from __future__ import print_function , division
1313
14-
1514import sys
15+ import string
1616import random
1717
18- from markov import skip_gutenberg_header , shift
18+ # global variables
19+ suffix_map = {} # map from prefixes to a list of suffixes
20+ prefix = () # current tuple of words
1921
2022
21- class Markov :
22- """Encapsulates the statistical summary of a text."""
23+ def process_file ( filename , order = 2 ) :
24+ """Reads a file and performs Markov analysis.
2325
24- def __init__ (self ):
25- self .suffix_map = {} # map from prefixes to a list of suffixes
26- self .prefix = () # current tuple of words
26+ filename: string
27+ order: integer number of words in the prefix
2728
28- def process_file (self , filename , order = 2 ):
29- """Reads a file and performs Markov analysis.
29+ returns: map from prefix to list of possible suffixes.
30+ """
31+ fp = open (filename )
32+ skip_gutenberg_header (fp )
3033
31- filename: string
32- order: integer number of words in the prefix
34+ for line in fp :
35+ for word in line .rstrip ().split ():
36+ process_word (word , order )
3337
34- Returns: map from prefix to list of possible suffixes.
35- """
36- fp = open (filename )
37- skip_gutenberg_header (fp )
3838
39- for line in fp :
40- for word in line .rstrip ().split ():
41- self .process_word (word , order )
39+ def skip_gutenberg_header (fp ):
40+ """Reads from fp until it finds the line that ends the header.
4241
43- def process_word (self , word , order = 2 ):
44- """Processes each word.
42+ fp: open file object
43+ """
44+ for line in fp :
45+ if line .startswith ('*END*THE SMALL PRINT!' ):
46+ break
4547
46- word: string
47- order: integer
4848
49- During the first few iterations, all we do is store up the words;
50- after that we start adding entries to the dictionary.
51- """
52- if len (self .prefix ) < order :
53- self .prefix += (word ,)
54- return
49+ def process_word (word , order = 2 ):
50+ """Processes each word.
51+
52+ word: string
53+ order: integer
5554
56- try :
57- self .suffix_map [self .prefix ].append (word )
58- except KeyError :
59- # if there is no entry for this prefix, make one
60- self .suffix_map [self .prefix ] = [word ]
55+ During the first few iterations, all we do is store up the words;
56+ after that we start adding entries to the dictionary.
57+ """
58+ global prefix
59+ if len (prefix ) < order :
60+ prefix += (word ,)
61+ return
6162
62- self .prefix = shift (self .prefix , word )
63+ try :
64+ suffix_map [prefix ].append (word )
65+ except KeyError :
66+ # if there is no entry for this prefix, make one
67+ suffix_map [prefix ] = [word ]
68+
69+ prefix = shift (prefix , word )
70+
71+
72+ def random_text (n = 100 ):
73+ """Generates random wordsfrom the analyzed text.
74+
75+ Starts with a random prefix from the dictionary.
76+
77+ n: number of words to generate
78+ """
79+ # choose a random prefix (not weighted by frequency)
80+ start = random .choice (list (suffix_map .keys ()))
81+
82+ for i in range (n ):
83+ suffixes = suffix_map .get (start , None )
84+ if suffixes == None :
85+ # if the start isn't in map, we got to the end of the
86+ # original text, so we have to start again.
87+ random_text (n - i )
88+ return
6389
64- def random_text (self , n = 100 ):
65- """Generates random wordsfrom the analyzed text.
90+ # choose a random suffix
91+ word = random .choice (suffixes )
92+ print (word , end = ' ' )
93+ start = shift (start , word )
6694
67- Starts with a random prefix from the dictionary.
6895
69- n: number of words to generate
70- """
71- # choose a random prefix (not weighted by frequency)
72- start = random .choice (list (self .suffix_map .keys ()))
96+ def shift (t , word ):
97+ """Forms a new tuple by removing the head and adding word to the tail.
7398
74- for i in range (n ):
75- suffixes = self .suffix_map .get (start , None )
76- if suffixes == None :
77- # if the prefix isn't in map, we got to the end of the
78- # original text, so we have to start again.
79- self .random_text (n - i )
80- return
99+ t: tuple of strings
100+ word: string
81101
82- # choose a random suffix
83- word = random .choice (suffixes )
84- print (word , end = ' ' )
85- start = shift (start , word )
102+ Returns: tuple of strings
103+ """
104+ return t [1 :] + (word ,)
86105
87106
88107def main (script , filename = 'emma.txt' , n = 100 , order = 2 ):
@@ -92,11 +111,10 @@ def main(script, filename='emma.txt', n=100, order=2):
92111 except ValueError :
93112 print ('Usage: %d filename [# of words] [prefix length]' % script )
94113 else :
95- markov = Markov ( )
96- markov . process_file ( filename , order )
97- markov . random_text ( n )
114+ process_file ( filename , order )
115+ random_text ( n )
116+ print ( )
98117
99118
100119if __name__ == '__main__' :
101120 main (* sys .argv )
102-
0 commit comments