InnominateOne

SGDQ 2015 Markov Chain Chat Simulator

Aug 3rd, 2015
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.83 KB | None | 0 0
  1. import os
  2. import sys
  3. import time
  4. from datetime import datetime, timezone
  5.  
  6. def parse_ts(ts_str):
  7.     return datetime.strptime(ts_str, "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=timezone.utc).timestamp()
  8.  
  9. def read_chatlog(chatlog_line):
  10.     try:
  11.         line_split = chatlog_line.split(' ', 1)
  12.         timestamp = parse_ts(line_split[0])
  13.         message = line_split[1].split(": ", 1)
  14.         user = message[0].lower()
  15.         comment = message[1].rstrip("\n")
  16.     except Exception as e:
  17.         return '','',''
  18.     return timestamp, user, comment
  19.  
  20. class Markov(object):
  21.     def __init__(self, length):
  22.         from collections import defaultdict
  23.         self.length = length
  24.         self._states = defaultdict(set)
  25.  
  26.     def makeQueue(self):
  27.         from collections import deque
  28.         return deque((None for i in range(self.length)), maxlen = self.length)
  29.        
  30.     def updateWithMessage(self, message):
  31.         queue = self.makeQueue()
  32.        
  33.         for token in message:
  34.             self.registerChain(queue, token)
  35.             queue.append(token)
  36.  
  37.     def registerChain(self, state, token):
  38.         self._states[tuple(state)].add(token)
  39.         #could count occurrences of token to do weighting
  40.  
  41.     def generateToken(self, state):
  42.         from random import choice
  43.         outputs = self._states[tuple(state)]
  44.         if len(outputs) == 0:
  45.             return None #equates to "end message"
  46.         else:
  47.             return choice(tuple(outputs))
  48.  
  49.     def generateAllTokens(self):
  50.         queue = self.makeQueue()
  51.  
  52.         while True:
  53.             token = self.generateToken(queue)
  54.            
  55.             if token is None:
  56.                 return
  57.             else:
  58.                 queue.append(token)
  59.                 yield token
  60.  
  61.     def generateMessage(self):
  62.         return "".join(self.generateAllTokens())
  63.  
  64. def tokenise(message):
  65.     import re
  66.     tokens = re.findall(r"(?:\w+)|(?:\W+)", message)
  67.     tokens.append(None) #denotes the end of the string
  68.     return tokens
  69.  
  70. def generateMarkov(file, length = 2):
  71.     markov = Markov(length)
  72.     for index, line in enumerate(file):
  73.         timestamp, username, message = read_chatlog(line)
  74.         if username == "":
  75.             continue
  76.        
  77.         markov.updateWithMessage(tokenise(message))
  78.  
  79.     return markov
  80.  
  81. if __name__ == "__main__":
  82.     MARKOV_LENGTH = 4 #take last N tokens into account when generating
  83.     #note that spaces and other punctuation are considered tokens
  84.     CHAT_LINES_TO_GENERATE = 1000
  85.    
  86.     input_file = open("gamesdonequick.txt", 'r', encoding = "utf-8")
  87.     output_file = open("gdq_markov.txt", "w", encoding = "utf-8")
  88.     markov = generateMarkov(input_file)
  89.     for count in range(CHAT_LINES_TO_GENERATE):
  90.         output_file.write(markov.generateMessage())
  91.         output_file.write("\n")
  92.     output_file.flush()
Advertisement
Add Comment
Please, Sign In to add comment