-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmarkov-bot.py
More file actions
93 lines (70 loc) · 2.28 KB
/
markov-bot.py
File metadata and controls
93 lines (70 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import random
import pickle
import sys
import irc
import os
# Ник, сервер, порт, канал
nickname = "markov"
server = "irc.quakenet.org"
port = 6667
channel = "#azaza"
# Прегенерированные цепи в формате «ключевое слово — имя файла»
files = {
'default': 'lor'
}
# Минимальный и максимальный размер (в словах) текста,
# который будет генерировать робот
size = (10, 30)
# Разделитель слов для робота
sep = ' '
def lookup(name, postfix):
filename = name + postfix
for root, dirs, files in os.walk("."):
if filename in files:
return os.path.join(root, filename)
raise FileNotFoundError(filename)
chains = {}
for keyword, name in files.items():
with open(lookup(name, ".pickle"), 'rb') as fin:
chains[keyword] = pickle.load(fin)
def select_chain(question):
question = question.lower()
for keyword, kv in chains.items():
if keyword in question:
return kv
return chains['default']
def words(question):
return question.lower().split()
def find_start(kv, question):
for word in words(question):
valid = filter(lambda key: word in key, kv.keys())
valid = list(valid)
if len(valid) > 0:
return random.choice(valid)
return random.choice(list(kv.keys()))
def gen(kv, answer):
length = random.randint(*size)
curr = find_start(kv, answer)
res = curr + sep
for idx in range(length):
if curr not in kv: break
variants = list(kv[curr].keys())
probs = list(kv[curr].values())
(curr,) = random.choices(variants, weights=probs)
res += curr + sep
return res
irc = irc.IRC(ipv6 = False)
irc.connect(server, channel, nickname, port = port)
detector = "Welcome to the QuakeNet IRC Network"
while True:
text = irc.get().strip()
if len(text) <= 0: continue
print(text)
if detector in text:
irc.join(channel)
if "PRIVMSG" in text and channel in text and nickname in text:
try:
msg = text.split("PRIVMSG " + channel)[1]
irc.send(channel, gen(select_chain(msg), msg))
except IndexError:
pass