Skip to content

Instantly share code, notes, and snippets.

@Spencer-Comin
Last active November 8, 2021 02:48
Show Gist options
  • Select an option

  • Save Spencer-Comin/37484a9264bb9efe5d8d4c1b8430181e to your computer and use it in GitHub Desktop.

Select an option

Save Spencer-Comin/37484a9264bb9efe5d8d4c1b8430181e to your computer and use it in GitHub Desktop.
from collections import defaultdict
from random import choices, choice
import json
import re
word_map = defaultdict(lambda: defaultdict(int))
start_map = defaultdict(lambda: defaultdict(int))
def save(filename):
with open(filename, 'w') as file:
json.dump({'word_map': word_map, 'start_map': start_map}, file,
indent=4)
def load(filename):
with open(filename, 'r') as file:
maps = json.load(file)
for first, map in maps['word_map'].items():
for second, count in map.items():
word_map[first][second] += count
for first, map in maps['start_map'].items():
for second, count in map.items():
start_map[first][second] += count
def train_set(filename):
with open(filename) as training_set:
last_word = None
for line in training_set.readlines():
line = re.findall(r"[\w']+|[.,!?;]", line)
if not line:
continue
process(last_word, line)
last_word = line[-1]
def process(my_last_word, response):
response = response + [None]
word = response[0]
start_map[my_last_word][word] += 1
for follow in response[1:]:
word_map[word][follow] += 1
word = follow
def respond(their_last_word):
if their_last_word in start_map:
response_set = start_map[their_last_word]
else:
response_set = choice(list(word_map.values()))
response = []
while True:
word = choices(list(response_set.keys()),
list(response_set.values()))[0]
if word is None:
return response
response.append(word)
response_set = word_map[word]
def merge(tokens):
if not tokens:
return ''
output = tokens[0]
for token in tokens[1:]:
if token in '.,!?;':
output += token
else:
output += ' ' + token
return output
if __name__ == "__main__":
my_last = None
print('To save: >>filename')
print('To load: <<filename')
print('To train from text file: !!filename')
while True:
raw = input('HUMAN: ').lstrip()
if raw.startswith('>>'):
save(raw[2:])
continue
elif raw.startswith('<<'):
load(raw[2:])
continue
elif raw.startswith('!!'):
train_set(raw[2:])
continue
human_says = re.findall(r"[\w']+|[.,!?;]", raw)
process(my_last, human_says)
their_last = None
if human_says:
their_last = human_says[-1]
response = respond(their_last)
my_last = None
if response:
my_last = response[-1]
print('MACHINE: ', merge(response))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment