Merge branch 'feature-gui' into develop

This commit is contained in:
LSaldyt
2017-11-01 11:06:21 -07:00
7 changed files with 163000 additions and 108 deletions

View File

@ -24,25 +24,22 @@ class Reporter(object):
class Copycat(object):
def __init__(self, rng_seed=None, reporter=None, showgui=True):
def __init__(self, rng_seed=None, reporter=None, gui=False):
self.coderack = Coderack(self)
self.random = Randomness(rng_seed)
self.slipnet = Slipnet()
self.temperature = Temperature() # TODO: use entropy
self.workspace = Workspace(self)
self.reporter = reporter or Reporter()
self.showgui = showgui
self.gui = GUI('Copycat')
if gui:
self.gui = GUI('Copycat')
self.lastUpdate = float('-inf')
def step(self):
if (not self.showgui) or (self.showgui and (not self.gui.app.primary.control.paused or self.gui.app.primary.control.has_step())):
self.coderack.chooseAndRunCodelet()
self.reporter.report_coderack(self.coderack)
self.reporter.report_temperature(self.temperature)
self.reporter.report_workspace(self.workspace)
if (self.showgui):
self.gui.update(self)
self.coderack.chooseAndRunCodelet()
self.reporter.report_coderack(self.coderack)
self.reporter.report_temperature(self.temperature)
self.reporter.report_workspace(self.workspace)
def update_workspace(self, currentTime):
self.workspace.updateEverything()
@ -55,15 +52,12 @@ class Copycat(object):
def check_reset(self):
if self.gui.app.primary.control.go:
initial, modified, target = self.gui.app.primary.control.get_vars()
self.reset_with_strings(initial, modified, target)
self.gui.app.reset_with_strings(initial, modified, target)
self.workspace.resetWithStrings(initial, modified, target)
return True
else:
return False
def reset_with_strings(self, initial, modified, target):
self.workspace.resetWithStrings(initial, modified, target)
self.gui.app.reset_with_strings(initial, modified, target)
def mainLoop(self):
currentTime = self.coderack.codeletsRun
self.temperature.tryUnclamp(currentTime) # TODO: use entropy
@ -72,8 +66,6 @@ class Copycat(object):
self.update_workspace(currentTime)
self.step()
if self.showgui:
self.gui.refresh()
def runTrial(self):
"""Run a trial of the copycat algorithm"""
@ -99,18 +91,18 @@ class Copycat(object):
while True:
if self.check_reset():
answers = {}
answer = self.runTrial()
if self.showgui:
self.gui.app.log('Answered: {}'.format(answer['answer']))
d = answers.setdefault(answer['answer'], {
'count': 0,
'sumtemp': 0,
'sumtime': 0
})
d['count'] += 1
d['sumtemp'] += answer['temp']
d['sumtime'] += answer['time']
if self.showgui:
self.gui.refresh()
if not self.gui.paused():
answer = self.runTrial()
self.gui.update(self)
d = answers.setdefault(answer['answer'], {
'count': 0,
'sumtemp': 0,
'sumtime': 0
})
d['count'] += 1
d['sumtemp'] += answer['temp']
d['sumtime'] += answer['time']
self.gui.add_answers(answers)
for answer, d in answers.items():
@ -118,16 +110,12 @@ class Copycat(object):
d['avgtime'] = d.pop('sumtime') / d['count']
def run(self, initial, modified, target, iterations):
self.reset_with_strings(initial, modified, target)
self.temperature.useAdj('best')
self.gui.app.reset_with_strings(initial, modified, target)
self.workspace.resetWithStrings(initial, modified, target)
answers = {}
for i in range(iterations):
if self.check_reset():
answers = {}
answer = self.runTrial()
if self.showgui:
self.gui.app.log('Answered: {}'.format(answer['answer']))
d = answers.setdefault(answer['answer'], {
'count': 0,
'sumtemp': 0, # TODO: use entropy
@ -136,8 +124,6 @@ class Copycat(object):
d['count'] += 1
d['sumtemp'] += answer['temp'] # TODO: use entropy
d['sumtime'] += answer['time']
if self.showgui:
self.gui.add_answers(answers)
for answer, d in answers.items():
d['avgtemp'] = d.pop('sumtemp') / d['count']
@ -145,7 +131,6 @@ class Copycat(object):
return answers
def run_forever(self, initial, modified, target):
self.reset_with_strings(initial, modified, target)
self.workspace.resetWithStrings(initial, modified, target)
while True:
self.check_reset()
self.runTrial()

39
copycat/gui/gui.py Executable file → Normal file
View File

@ -30,25 +30,18 @@ class MainApplication(GridFrame):
self.add(self.primary, 0, 0, xspan=2)
self.create_widgets()
GridFrame.configure(self)
#self.messages = []
#def log(self, message):
# self.messages.append(message)
def create_widgets(self):
self.slipList = List(self, 10)
columns = 20
self.slipList = List(self, columns)
self.add(self.slipList, 0, 1)
self.codeletList = List(self, 10)
self.codeletList = List(self, columns)
self.add(self.codeletList, 1, 1)
self.objectList = List(self, 10)
self.objectList = List(self, columns)
self.add(self.objectList, 2, 1)
#self.logBox = List(self, 10)
#self.add(self.logBox, 1, 0)
self.graph2 = Plot(self, 'Answer Distribution')
self.add(self.graph2, 2, 0)
@ -62,14 +55,24 @@ class MainApplication(GridFrame):
self.slipList.update(slipnodes, key=lambda s:s.activation,
formatter=lambda s : '{}: {}'.format(s.name, round(s.activation, 2)))
self.codeletList.update(codelets, key=lambda c:c.urgency, formatter= lambda s : '{}: {}'.format(s.name, round(s.urgency, 2)))
self.objectList.update(objects, formatter=lambda s : '{}'.format(str(s.descriptions)))
#self.logBox.update(list(reversed(self.messages))[:10])
get_descriptors = lambda s : ', '.join('({}={})'.format(d.descriptionType.name, d.descriptor.name) for d in s.descriptions)
self.objectList.update(objects, formatter=lambda s : '{}: {}'.format(s, get_descriptors(s)))
'''
if len(objects) > 0:
print('Descriptions:')
for obj in objects:
print(obj)
for description in obj.descriptions:
print(' {}:'.format(description))
print(' {}'.format(description.descriptionType.name))
print(' {}'.format(description.descriptor.name))
'''
def reset_with_strings(self, initial, modified, target):
self.primary.reset_with_strings(initial, modified, target)
class GUI(object):
def __init__(self, title, updateInterval=.1):
def __init__(self, title):
self.root = tk.Tk()
self.root.title(title)
tk.Grid.rowconfigure(self.root, 0, weight=1)
@ -79,9 +82,6 @@ class GUI(object):
configure_style(ttk.Style())
self.lastUpdated = time.time()
self.updateInterval = updateInterval
def add_answers(self, answers):
def modifier(status):
with plt.style.context(('dark_background')):
@ -92,7 +92,8 @@ class GUI(object):
self.root.update_idletasks()
self.root.update()
def paused(self):
return self.app.primary.control.paused
def update(self, copycat):
current = time.time()
self.app.update(copycat)
self.lastUpdated = current

View File

@ -7,66 +7,23 @@ from tkinter import filedialog
from .control import Control
from .gridframe import GridFrame
font1Size = 32
font2Size = 16
font1 = ('Helvetica', str(font1Size))
font2 = ('Helvetica', str(font2Size))
style = dict(background='black',
foreground='white',
font=font2)
def create_main_canvas(root, initial, final, new, guess):
padding = 100
canvas = tk.Canvas(root, background='black')
def add_sequences(sequences, x, y):
for sequence in sequences:
x += padding
if sequence is None:
sequence = ''
for char in sequence:
canvas.create_text(x, y, text=char, anchor=tk.NW, font=font1, fill='white')
x += font1Size
return x, y
x = 0
y = padding
add_sequences([initial, final], x, y)
x = 0
y += padding
add_sequences([new, guess], x, y)
#canvas['height'] = str(int(canvas['height']) + padding)
#canvas['width'] = str(int(canvas['width']) + padding)
return canvas
from .workspacecanvas import WorkspaceCanvas
class Primary(GridFrame):
def __init__(self, parent, *args, **kwargs):
GridFrame.__init__(self, parent, *args, **kwargs)
self.initial = ''
self.modified = ''
self.target = ''
self.canvas = create_main_canvas(self, self.initial, self.modified, self.target, '')
self.canvas = WorkspaceCanvas(self)
self.add(self.canvas, 0, 0, xspan=2)
self.control = Control(self)
self.add(self.control, 0, 2)
GridFrame.configure(self)
def update(self, copycat):
answer = '' if copycat.workspace.rule is None else copycat.workspace.rule.buildTranslatedRule()
#self.canvas = create_main_canvas(self, self.initial, self.modified, self.target, answer)
#self.add(self.canvas, 0, 0, xspan=2)
self.canvas.update(copycat)
def reset_with_strings(self, initial, modified, target):
self.initial = initial
self.modified = modified
self.target = target
self.canvas.reset_with_strings(initial, modified, target)

159787
copycat/gui/sys Normal file

File diff suppressed because it is too large Load Diff

3093
copycat/gui/time Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
import tkinter as tk
import tkinter.ttk as ttk
from .gridframe import GridFrame
font1Size = 32
font1 = ('Helvetica', font1Size)
class WorkspaceCanvas(GridFrame):
def __init__(self, parent, *args, **kwargs):
GridFrame.__init__(self, parent, *args, **kwargs)
self.chars = []
self.initial = ''
self.modified = ''
self.target = ''
self.answer = ''
self.changed = False
self.canvas = tk.Canvas(self, background='black')
self.add(self.canvas, 0, 0)
GridFrame.configure(self)
def update(self, copycat):
answer = '' if copycat.workspace.rule is None else copycat.workspace.rule.buildTranslatedRule()
if answer != self.answer:
self.changed = True
if self.changed:
self.canvas.delete('all')
del self.chars[:]
self.add_text()
def add_text(self):
padding = 100
def add_sequences(sequences, x, y):
for sequence in sequences:
x += padding
if sequence is None:
sequence = ''
for char in sequence:
self.chars.append((char, (x, y)))
self.canvas.create_text(x, y, text=char, anchor=tk.NW, font=font1, fill='white')
x += font1Size
return x, y
x = 0
y = padding
add_sequences([self.initial, self.modified], x, y)
x = 0
y += padding
add_sequences([self.target, self.answer], x, y)
def reset_with_strings(self, initial, modified, target):
if initial != self.initial or \
modified != self.modified or \
target != self.target:
self.changed = True
self.initial = initial
self.modified = modified
self.target = target

2
gui.py
View File

@ -17,7 +17,7 @@ def main():
parser.add_argument('--seed', type=int, default=None, help='Provide a deterministic seed for the RNG.')
options = parser.parse_args()
copycat = Copycat(reporter=SimpleReporter(), rng_seed=options.seed)
copycat = Copycat(reporter=SimpleReporter(), rng_seed=options.seed, gui=True)
copycat.runGUI()
if __name__ == '__main__':