Tons of rewriting to get right back to where we were before\!
[scrappy.git] / modules / markov / markov.py
blobe08962e49e769f19b0a74597d641d7bcb57a510e
1 #markov module for scrappy
3 #the inspiration for this code comes from
4 #"The Practice of Programming", so some of the variable
5 #names and such will be similar.
7 import random
8 import pickle
9 import re
11 nickmatch = None
12 statetab = {}
14 w1 = w2 = "\n"
16 def init(scrap):
17 global nickmatch
19 scrap.register_event("msg", markov_learn)
20 scrap.register_event("msg", markov_talk)
21 scrap.register_event("msg", markov_load)
22 scrap.register_event("msg", markov_dump)
23 scrap.register_event("msg", markov_stats)
25 nickmatch = re.compile(scrap.nickname)
27 random.seed()
29 def markov_stats(c,list,bot):
30 global statetab
32 cmd = list[4].split(" ")[0]
34 if cmd == "markov_stats":
35 c.privmsg(list[5], "words: %d" % len(statetab[("\n","\n")]))
36 c.privmsg(list[5], "chains: %d" % len(statetab.items()))
38 #loads in a previously pickled saved state
39 def markov_load(c,list,bot):
40 global statetab
42 cmd = list[4].split(" ")[0]
44 if cmd == "mkload":
45 fp = list[4].split(" ")[1]
47 try:
48 pkfile = open(fp,"r")
49 statetab = pickle.load(pkfile)
50 except IOError:
51 print "Could not load db: Doesn't exist\n"
54 #pickles out the state to a file
55 def markov_dump(c,list,bot):
56 global statetab
58 cmd = list[4].split(" ")[0]
60 if cmd == "mkdump":
61 fp = list[4].split(" ")[1]
63 pkfile = open(fp,"w+")
65 pickle.dump(statetab,pkfile)
67 def markov_learn(c,list,bot):
68 """ Should not be called directly """
70 words = [x for x in list[4].split(" ") if not x.isspace()]
72 global statetab
73 global w1
74 global w2
76 w1 = w2 = "\n"
78 #go through every word and put them in a hash table.
79 #EX the sentence "Mary had a little lamb"
80 #first iteration, w1 and w2 are both empty.
81 #statetab[w1][w2] doesn't exist, so make it and set
82 #statetab[""][""] to Mary.
84 #Then, set w1 to w2 and w2 to i, so the chain moves forward.
85 for i in words:
86 statetab.setdefault((w1,w2),[]).append(i)
87 w1,w2 = w2, i
89 statetab.setdefault((w1,w2),[]).append("\n")
91 if nickmatch.search(list[4]) and bot.autorep == 1 and random.randint(0,3) == 0:
92 tmp = emit_chain(random.choice(list[4].split(" ")))
94 if len(tmp) <= 2:
95 return
97 c.privmsg(list[5], "%s: %s" % (list[0],tmp))
98 return
100 #randomly reply
101 if random.randint(0,15) == 0 and bot.talk == 1:
102 c.privmsg(list[5], "%s" % (emit_chain(random.choice(list[4].split(" ")))))
104 def emit_chain(key):
105 global statetab
106 global w1
107 global w2
109 i = 0
111 w1 = w2 = "\n"
113 newword = ""
115 #make the first word the key if its not a space
116 # if(key != " "):
117 # retval = key + " "
118 # else:
119 retval = ""
121 if key != " ":
122 w2 = key
124 while 1:
125 try:
126 newword = random.choice(statetab[(w1,w2)])
127 except KeyError:
128 return retval
130 retval = retval + newword + " "
131 w1,w2 = w2,newword
133 i = i + 1
135 #max of rand words if we don't hit a space or other error
136 if i >= random.randint(5,50):
137 return retval
139 return retval
141 def markov_talk(c,list,bot):
142 """ Makes the markov chain talk to you """
144 cmd = list[4].split(" ")[0]
146 try:
147 key = list[4].split(" ")[1]
148 except IndexError:
149 key = " "
151 if list[3] and cmd == "talk":
152 tmp = emit_chain(key);
153 if len(tmp) <= 2:
154 return
155 c.privmsg(list[5],"%s" % tmp)