Chatbot v1
This commit is contained in:
@@ -6,3 +6,4 @@ test.png
|
|||||||
password.txt
|
password.txt
|
||||||
stroopwafel.token
|
stroopwafel.token
|
||||||
UpgradeLog\.htm
|
UpgradeLog\.htm
|
||||||
|
markov_dict.npy
|
||||||
|
|||||||
+126
@@ -0,0 +1,126 @@
|
|||||||
|
import asyncio
|
||||||
|
import discord
|
||||||
|
from discord.ext import commands
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class Chatbot(object):
|
||||||
|
"""Een heuse chatbot. Under construction..."""
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
self.voice_states = {}
|
||||||
|
self.END_OF_MESSAGE = "<EOM>"
|
||||||
|
try:
|
||||||
|
np.load('markov_dict.npy')
|
||||||
|
except FileNotFoundError:
|
||||||
|
#If there's no initial file, make a new one:
|
||||||
|
initFile = {'Hoi':{self.END_OF_MESSAGE : 1}}
|
||||||
|
np.save("markov_dict.npy", initFile)
|
||||||
|
except:
|
||||||
|
print("ERROR! - Could not open or create Markov chat file")
|
||||||
|
def __check(self, ctx):
|
||||||
|
return True
|
||||||
|
|
||||||
|
#TODO laat Stroop reageren op persoonlijke berichten
|
||||||
|
|
||||||
|
#Make word pairs:
|
||||||
|
def makePairs(self, corpus):
|
||||||
|
for i in range(len(corpus)-1):
|
||||||
|
yield (corpus[i], corpus[i+1])
|
||||||
|
|
||||||
|
#Learn from a human message
|
||||||
|
#Returns an updated dict
|
||||||
|
def learnFrom(self, initialWordDict, message: str):
|
||||||
|
newWordDict = initialWordDict
|
||||||
|
|
||||||
|
message = message + " " + self.END_OF_MESSAGE
|
||||||
|
corpus = message.split()
|
||||||
|
pairs = self.makePairs(corpus)
|
||||||
|
|
||||||
|
#Add wordcounts to dict
|
||||||
|
for word_1, word_2 in pairs:
|
||||||
|
if word_1 in newWordDict.keys():
|
||||||
|
if word_2 in newWordDict[word_1].keys():
|
||||||
|
newWordDict[word_1][word_2] += 1
|
||||||
|
else:
|
||||||
|
newWordDict[word_1][word_2] = 1
|
||||||
|
else:
|
||||||
|
newWordDict[word_1] = {word_2 : 1}
|
||||||
|
return newWordDict;
|
||||||
|
|
||||||
|
@commands.command(pass_context=True, hidden=True)
|
||||||
|
@asyncio.coroutine
|
||||||
|
def trainmarkovchat(self, ctx, channelId=409751773595566081, nrOfMessages=50):
|
||||||
|
"""Train that chain, jermaine
|
||||||
|
param channelId: use this channel to train
|
||||||
|
param nrOfMessages: use the x most recent messages
|
||||||
|
"""
|
||||||
|
|
||||||
|
channel=self.bot.get_channel(channelId)
|
||||||
|
#Open current chain:
|
||||||
|
wordDict = np.load('markov_dict.npy').item()
|
||||||
|
|
||||||
|
#Iterate through the last x messages from the channel:
|
||||||
|
iterator = channel.history(limit=nrOfMessages, before=None, after=None, reverse=False, around=None)
|
||||||
|
for i in range(nrOfMessages):
|
||||||
|
msg = yield from iterator.next()
|
||||||
|
messageContent = msg.content.strip()
|
||||||
|
if messageContent == "":
|
||||||
|
pass #print("-- Bericht is leeg. Negeer.")
|
||||||
|
elif msg.author.bot:
|
||||||
|
pass #print("-- Dit is een bot chat. Negeer.")
|
||||||
|
elif messageContent[0] == "!":
|
||||||
|
pass #print("-- Dit is een commando. Negeer.")
|
||||||
|
elif "```" in messageContent:
|
||||||
|
pass #print("-- Daar zit een codeblok in. Negeer.")
|
||||||
|
else:
|
||||||
|
wordDict = self.learnFrom(wordDict, messageContent)
|
||||||
|
|
||||||
|
np.save("markov_dict.npy", wordDict)
|
||||||
|
yield from ctx.channel.send("Ik heb weer wat nieuwe woordjes geleerd. :slight_smile:")
|
||||||
|
|
||||||
|
|
||||||
|
@commands.command(pass_context=True, hidden=False)
|
||||||
|
@asyncio.coroutine
|
||||||
|
def reageer(self, ctx):
|
||||||
|
"""UNDER CONSTRUCTION. Laat Stroop iets willekeurigs zeggen.
|
||||||
|
Stroop leert van onze gesprekken. Hij kan zich nu voordoen als een van ons. Soort van.
|
||||||
|
"""
|
||||||
|
|
||||||
|
MAX_N_WORDS = 100 #Don't use more words than this
|
||||||
|
|
||||||
|
#Get dictionary/Markov chain
|
||||||
|
wordDict = np.load('markov_dict.npy').item()
|
||||||
|
#TODO store in global variable to minimise IO?
|
||||||
|
|
||||||
|
#Delete command
|
||||||
|
try:
|
||||||
|
yield from ctx.message.delete()
|
||||||
|
except:
|
||||||
|
print("No permission to delete message")
|
||||||
|
|
||||||
|
#print(wordDict)
|
||||||
|
|
||||||
|
#Pick a random first word (Which is not an end-of-message)
|
||||||
|
#TODO pick a word which responds to the previous message in the channel
|
||||||
|
first_word = np.random.choice(list(wordDict.keys()))
|
||||||
|
while first_word == self.END_OF_MESSAGE: #or first_word.islower() ???
|
||||||
|
first_word = np.random.choice(list(wordDict.keys()))
|
||||||
|
chain = [first_word]
|
||||||
|
|
||||||
|
#Go through the chain:
|
||||||
|
for i in range(MAX_N_WORDS):
|
||||||
|
if chain[-1] == self.END_OF_MESSAGE:
|
||||||
|
break
|
||||||
|
#Calculate probabilities and pick a next word:
|
||||||
|
#https://stackoverflow.com/questions/835092/python-dictionary-are-keys-and-values-always-the-same-order
|
||||||
|
possible_words = list(wordDict[chain[-1]].keys())
|
||||||
|
weights = np.array(list(wordDict[chain[-1]].values()))
|
||||||
|
probs = weights / weights.sum()
|
||||||
|
chain.append(np.random.choice(possible_words, p=probs))
|
||||||
|
|
||||||
|
chain = chain[:-1] #remove <EOM>
|
||||||
|
|
||||||
|
#print(' '.join(chain))
|
||||||
|
yield from ctx.channel.send(' '.join(chain))
|
||||||
|
|
||||||
@@ -25,3 +25,4 @@ Verder zoek je het maar lekker zelf uit. Of installeer deze requirements:
|
|||||||
* `oauth2`
|
* `oauth2`
|
||||||
* `sympy`
|
* `sympy`
|
||||||
* `asyncio`
|
* `asyncio`
|
||||||
|
* `numpy`
|
||||||
@@ -5,6 +5,7 @@ import Porno
|
|||||||
import Shitpost
|
import Shitpost
|
||||||
import General
|
import General
|
||||||
import Cryptocoin
|
import Cryptocoin
|
||||||
|
import Chatbot
|
||||||
import logging
|
import logging
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@ bot.add_cog(Shitpost.Shitpost(bot))
|
|||||||
bot.add_cog(Porno.Porno(bot))
|
bot.add_cog(Porno.Porno(bot))
|
||||||
bot.add_cog(General.General(bot))
|
bot.add_cog(General.General(bot))
|
||||||
bot.add_cog(Cryptocoin.Cryptocoin(bot))
|
bot.add_cog(Cryptocoin.Cryptocoin(bot))
|
||||||
|
bot.add_cog(Chatbot.Chatbot(bot))
|
||||||
|
|
||||||
tokenfile = open("stroopwafel.token","r")
|
tokenfile = open("stroopwafel.token","r")
|
||||||
token = tokenfile.readline()
|
token = tokenfile.readline()
|
||||||
|
|||||||
Reference in New Issue
Block a user