Merge branch 'feature-gui' into develop
This commit is contained in:
@ -22,7 +22,6 @@ def codelet(name):
|
||||
return f
|
||||
return wrap
|
||||
|
||||
|
||||
# some methods common to the codelets
|
||||
def __showWhichStringObjectIsFrom(structure):
|
||||
if not structure:
|
||||
|
||||
@ -3,6 +3,7 @@ from .randomness import Randomness
|
||||
from .slipnet import Slipnet
|
||||
from .temperature import Temperature
|
||||
from .workspace import Workspace
|
||||
from .gui import GUI
|
||||
|
||||
class Reporter(object):
|
||||
"""Do-nothing base class for defining new reporter types"""
|
||||
@ -23,30 +24,56 @@ class Reporter(object):
|
||||
|
||||
|
||||
class Copycat(object):
|
||||
def __init__(self, rng_seed=None, reporter=None):
|
||||
def __init__(self, rng_seed=None, reporter=None, showgui=True):
|
||||
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')
|
||||
self.lastUpdate = float('-inf')
|
||||
|
||||
def mainLoop(self, lastUpdate):
|
||||
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)
|
||||
|
||||
def update_workspace(self, currentTime):
|
||||
self.workspace.updateEverything()
|
||||
self.coderack.updateCodelets()
|
||||
self.slipnet.update(self.random)
|
||||
self.temperature.update(self.workspace.getUpdatedTemperature())
|
||||
self.lastUpdate = currentTime
|
||||
self.reporter.report_slipnet(self.slipnet)
|
||||
|
||||
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)
|
||||
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
|
||||
# Every 15 codelets, we update the workspace.
|
||||
if currentTime >= lastUpdate + 15:
|
||||
self.workspace.updateEverything()
|
||||
self.coderack.updateCodelets()
|
||||
self.slipnet.update(self.random)
|
||||
self.temperature.update(self.workspace.getUpdatedTemperature()) # TODO: use entropy
|
||||
lastUpdate = currentTime
|
||||
self.reporter.report_slipnet(self.slipnet)
|
||||
self.coderack.chooseAndRunCodelet()
|
||||
self.reporter.report_coderack(self.coderack)
|
||||
self.reporter.report_temperature(self.temperature)
|
||||
self.reporter.report_workspace(self.workspace)
|
||||
return lastUpdate
|
||||
if currentTime >= self.lastUpdate + 15:
|
||||
self.update_workspace(currentTime)
|
||||
self.step()
|
||||
|
||||
if self.showgui:
|
||||
self.gui.refresh()
|
||||
|
||||
def runTrial(self):
|
||||
"""Run a trial of the copycat algorithm"""
|
||||
@ -54,9 +81,8 @@ class Copycat(object):
|
||||
self.slipnet.reset()
|
||||
self.temperature.reset() # TODO: use entropy
|
||||
self.workspace.reset()
|
||||
lastUpdate = float('-inf')
|
||||
while self.workspace.finalAnswer is None:
|
||||
lastUpdate = self.mainLoop(lastUpdate)
|
||||
self.mainLoop()
|
||||
answer = {
|
||||
'answer': self.workspace.finalAnswer,
|
||||
'temp': self.temperature.last_unclamped_value, # TODO: use entropy
|
||||
@ -65,22 +91,43 @@ class Copycat(object):
|
||||
self.reporter.report_answer(answer)
|
||||
return answer
|
||||
|
||||
def run(self, initial, modified, target, iterations):
|
||||
self.workspace.resetWithStrings(initial, modified, target)
|
||||
def runGUI(self):
|
||||
while not self.check_reset():
|
||||
self.gui.update(self)
|
||||
self.gui.refresh()
|
||||
answers = {}
|
||||
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.add_answers(answers)
|
||||
|
||||
self.temperature.useAdj('original')
|
||||
#self.temperature.useAdj('entropy')
|
||||
#self.temperature.useAdj('inverse') # 100 weight
|
||||
#self.temperature.useAdj('fifty_converge')
|
||||
#self.temperature.useAdj('soft')
|
||||
#self.temperature.useAdj('weighted_soft')
|
||||
#self.temperature.useAdj('alt_fifty')
|
||||
#self.temperature.useAdj('average_alt')
|
||||
for answer, d in answers.items():
|
||||
d['avgtemp'] = d.pop('sumtemp') / d['count']
|
||||
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')
|
||||
|
||||
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
|
||||
@ -89,6 +136,8 @@ 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']
|
||||
@ -96,6 +145,7 @@ class Copycat(object):
|
||||
return answers
|
||||
|
||||
def run_forever(self, initial, modified, target):
|
||||
self.workspace.resetWithStrings(initial, modified, target)
|
||||
self.reset_with_strings(initial, modified, target)
|
||||
while True:
|
||||
self.check_reset()
|
||||
self.runTrial()
|
||||
|
||||
1
copycat/gui/__init__.py
Normal file
1
copycat/gui/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .gui import GUI
|
||||
56
copycat/gui/control.py
Normal file
56
copycat/gui/control.py
Normal file
@ -0,0 +1,56 @@
|
||||
import tkinter as tk
|
||||
import tkinter.ttk as ttk
|
||||
|
||||
from .gridframe import GridFrame
|
||||
from .entry import Entry
|
||||
|
||||
class Control(GridFrame):
|
||||
def __init__(self, parent, *args, **kwargs):
|
||||
GridFrame.__init__(self, parent, *args, **kwargs)
|
||||
|
||||
self.paused = True
|
||||
self.steps = 0
|
||||
self.go = False
|
||||
|
||||
self.playbutton = ttk.Button(self, text='Play', command=lambda : self.toggle())
|
||||
self.add(self.playbutton, 0, 0)
|
||||
|
||||
self.stepbutton = ttk.Button(self, text='Step', command=lambda : self.step())
|
||||
self.add(self.stepbutton, 1, 0)
|
||||
|
||||
self.entry = Entry(self)
|
||||
self.add(self.entry, 0, 1, xspan=2)
|
||||
|
||||
self.gobutton = ttk.Button(self, text='Go', command=lambda : self.set_go())
|
||||
self.add(self.gobutton, 0, 2, xspan=2)
|
||||
|
||||
def play(self):
|
||||
self.paused = False
|
||||
self.playbutton['text'] = 'Pause'
|
||||
|
||||
def pause(self):
|
||||
self.paused = True
|
||||
self.playbutton['text'] = 'Play'
|
||||
|
||||
def toggle(self):
|
||||
if self.paused:
|
||||
self.play()
|
||||
else:
|
||||
self.pause()
|
||||
|
||||
def step(self):
|
||||
self.steps += 1
|
||||
|
||||
def has_step(self):
|
||||
if self.steps > 0:
|
||||
self.steps -= 1
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def set_go(self):
|
||||
self.go = True
|
||||
self.play()
|
||||
|
||||
def get_vars(self):
|
||||
return self.entry.a.get(), self.entry.b.get(), self.entry.c.get()
|
||||
27
copycat/gui/entry.py
Normal file
27
copycat/gui/entry.py
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
import tkinter as tk
|
||||
import tkinter.ttk as ttk
|
||||
|
||||
from .gridframe import GridFrame
|
||||
|
||||
class Entry(GridFrame):
|
||||
def __init__(self, parent, *args, **kwargs):
|
||||
GridFrame.__init__(self, parent, *args, **kwargs)
|
||||
self.aLabel = ttk.Label(self, text='Initial:')
|
||||
self.a = ttk.Entry(self, style='EntryStyle.TEntry')
|
||||
|
||||
self.add(self.aLabel, 0, 0)
|
||||
self.add(self.a, 0, 1)
|
||||
|
||||
self.bLabel = ttk.Label(self, text='Final:')
|
||||
self.b = ttk.Entry(self, style='EntryStyle.TEntry')
|
||||
|
||||
self.add(self.bLabel, 1, 0)
|
||||
self.add(self.b, 1, 1)
|
||||
|
||||
self.cLabel = ttk.Label(self, text='Next:')
|
||||
self.c = ttk.Entry(self, style='EntryStyle.TEntry')
|
||||
|
||||
self.add(self.cLabel, 2, 0)
|
||||
self.add(self.c, 2, 1)
|
||||
GridFrame.configure(self)
|
||||
11
copycat/gui/gridframe.py
Normal file
11
copycat/gui/gridframe.py
Normal file
@ -0,0 +1,11 @@
|
||||
import tkinter as tk
|
||||
import tkinter.ttk as ttk
|
||||
|
||||
class GridFrame(tk.Frame):
|
||||
def __init__(self, parent, *args, **kwargs):
|
||||
ttk.Frame.__init__(self, parent, *args, **kwargs)
|
||||
|
||||
def add(self, element, x, y, xspan=1, yspan=1):
|
||||
element.grid(column=x, row=y, columnspan=xspan, rowspan=yspan, sticky=tk.N+tk.E+tk.S+tk.W)
|
||||
tk.Grid.rowconfigure(self, x, weight=1)
|
||||
tk.Grid.columnconfigure(self, y, weight=1)
|
||||
98
copycat/gui/gui.py
Executable file
98
copycat/gui/gui.py
Executable file
@ -0,0 +1,98 @@
|
||||
import sys
|
||||
import time
|
||||
|
||||
import tkinter as tk
|
||||
import tkinter.ttk as ttk
|
||||
|
||||
from tkinter import scrolledtext
|
||||
from tkinter import filedialog
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from .status import Status, StatusFrame
|
||||
from .status import Plot
|
||||
from .gridframe import GridFrame
|
||||
from .primary import Primary
|
||||
from .list import List
|
||||
from .style import configure_style
|
||||
|
||||
from .plot import plot_imbedded
|
||||
|
||||
plt.style.use('dark_background')
|
||||
|
||||
class MainApplication(GridFrame):
|
||||
|
||||
def __init__(self, parent, *args, **kwargs):
|
||||
GridFrame.__init__(self, parent, *args, **kwargs)
|
||||
|
||||
self.parent = parent
|
||||
self.primary = Primary(self, *args, **kwargs)
|
||||
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)
|
||||
self.add(self.slipList, 0, 1)
|
||||
|
||||
self.codeletList = List(self, 10)
|
||||
self.add(self.codeletList, 1, 1)
|
||||
|
||||
self.objectList = List(self, 10)
|
||||
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)
|
||||
|
||||
def update(self, copycat):
|
||||
self.primary.update(copycat)
|
||||
|
||||
slipnodes = copycat.slipnet.slipnodes
|
||||
codelets = copycat.coderack.codelets
|
||||
objects = copycat.workspace.objects
|
||||
|
||||
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])
|
||||
|
||||
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):
|
||||
self.root = tk.Tk()
|
||||
self.root.title(title)
|
||||
tk.Grid.rowconfigure(self.root, 0, weight=1)
|
||||
tk.Grid.columnconfigure(self.root, 0, weight=1)
|
||||
self.app = MainApplication(self.root)
|
||||
self.app.grid(row=0, column=0, sticky=tk.N+tk.S+tk.E+tk.W)
|
||||
|
||||
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')):
|
||||
plot_imbedded(answers, status)
|
||||
self.app.graph2.status.modifier = modifier
|
||||
|
||||
def refresh(self):
|
||||
self.root.update_idletasks()
|
||||
self.root.update()
|
||||
|
||||
def update(self, copycat):
|
||||
current = time.time()
|
||||
self.app.update(copycat)
|
||||
self.lastUpdated = current
|
||||
26
copycat/gui/list.py
Normal file
26
copycat/gui/list.py
Normal file
@ -0,0 +1,26 @@
|
||||
import tkinter as tk
|
||||
import tkinter.ttk as ttk
|
||||
|
||||
import time
|
||||
|
||||
from .gridframe import GridFrame
|
||||
|
||||
class List(GridFrame):
|
||||
|
||||
def __init__(self, parent, columns, updateInterval=.1):
|
||||
GridFrame.__init__(self, parent)
|
||||
self.text = ttk.Label(self, anchor='w', justify=tk.LEFT, width=30)
|
||||
self.add(self.text, 0, 0)
|
||||
|
||||
self.columns = columns
|
||||
|
||||
self.lastUpdated = time.time()
|
||||
self.updateInterval = updateInterval
|
||||
|
||||
def update(self, l, key=None, reverse=False, formatter=lambda s : str(s)):
|
||||
current = time.time()
|
||||
if current - self.lastUpdated > self.updateInterval:
|
||||
l = l[:self.columns]
|
||||
if key is not None:
|
||||
l = sorted(l, key=key, reverse=False)
|
||||
self.text['text'] = '\n'.join(map(formatter, l))
|
||||
17
copycat/gui/plot.py
Normal file
17
copycat/gui/plot.py
Normal file
@ -0,0 +1,17 @@
|
||||
import matplotlib.pyplot as plt; plt.rcdefaults()
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def plot_imbedded(answers, status):
|
||||
answers = sorted(answers.items(), key=lambda kv : kv[1]['count'])
|
||||
objects = [t[0] for t in answers]
|
||||
yvalues = [t[1]['count'] for t in answers]
|
||||
|
||||
y_pos = np.arange(len(objects))
|
||||
|
||||
status.subplot.clear()
|
||||
status.subplot.bar(y_pos, yvalues, align='center', alpha=0.5)
|
||||
status.subplot.set_xticks(y_pos)
|
||||
status.subplot.set_xticklabels(tuple(objects))
|
||||
status.subplot.set_ylabel('Count')
|
||||
status.subplot.set_title('Answers')
|
||||
72
copycat/gui/primary.py
Normal file
72
copycat/gui/primary.py
Normal file
@ -0,0 +1,72 @@
|
||||
import tkinter as tk
|
||||
import tkinter.ttk as ttk
|
||||
|
||||
from tkinter import scrolledtext
|
||||
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
|
||||
|
||||
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.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)
|
||||
|
||||
def reset_with_strings(self, initial, modified, target):
|
||||
self.initial = initial
|
||||
self.modified = modified
|
||||
self.target = target
|
||||
66
copycat/gui/status.py
Normal file
66
copycat/gui/status.py
Normal file
@ -0,0 +1,66 @@
|
||||
import matplotlib
|
||||
matplotlib.use("TkAgg")
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
import tkinter as tk
|
||||
import tkinter.ttk as ttk
|
||||
|
||||
import time
|
||||
import matplotlib.animation as animation
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
plt.style.use('dark_background')
|
||||
|
||||
from .gridframe import GridFrame
|
||||
|
||||
class Plot(GridFrame):
|
||||
def __init__(self, parent, title):
|
||||
GridFrame.__init__(self, parent)
|
||||
self.status = Status()
|
||||
self.sframe = StatusFrame(self, self.status, title)
|
||||
self.add(self.sframe, 0, 0, xspan=2)
|
||||
|
||||
self.savebutton = ttk.Button(self, text='Save to path:', command=lambda : self.save())
|
||||
self.add(self.savebutton, 0, 1)
|
||||
|
||||
self.pathentry = ttk.Entry(self, style='EntryStyle.TEntry', textvariable='output/dist.png')
|
||||
self.add(self.pathentry, 1, 1)
|
||||
|
||||
def save(self):
|
||||
path = self.pathentry.get()
|
||||
if len(path) > 0:
|
||||
try:
|
||||
self.status.figure.savefig(path)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
class StatusFrame(ttk.Frame):
|
||||
def __init__(self, parent, status, title):
|
||||
ttk.Frame.__init__(self, parent)
|
||||
self.status = status
|
||||
|
||||
self.canvas = FigureCanvasTkAgg(status.figure, self)
|
||||
self.canvas.show()
|
||||
self.canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
|
||||
|
||||
self.animation = animation.FuncAnimation(status.figure, lambda i : status.update_plots(i), interval=1000)
|
||||
|
||||
class Status(object):
|
||||
def __init__(self):
|
||||
self.figure = Figure(figsize=(5,5), dpi=100)
|
||||
self.subplot = self.figure.add_subplot(111)
|
||||
self.x = []
|
||||
self.y = []
|
||||
|
||||
def modifier(status):
|
||||
with plt.style.context(('dark_background')):
|
||||
status.subplot.plot(status.x, status.y)
|
||||
|
||||
self.modifier = modifier
|
||||
self.update_plots(0)
|
||||
|
||||
def update_plots(self, i):
|
||||
self.subplot.clear()
|
||||
self.modifier(self)
|
||||
33
copycat/gui/style.py
Normal file
33
copycat/gui/style.py
Normal file
@ -0,0 +1,33 @@
|
||||
style_dict = dict(foreground='white',
|
||||
background='black')
|
||||
|
||||
map_options = dict(
|
||||
foreground=[('disabled', 'black'),
|
||||
('pressed', 'white'),
|
||||
('active', 'white')],
|
||||
background=[('disabled', 'black'),
|
||||
('pressed', '!focus', 'black'),
|
||||
('active', 'black')],
|
||||
highlightcolor=[('focus', 'black'),
|
||||
('!focus', 'black')])
|
||||
|
||||
def configure_style(style):
|
||||
style.configure('TButton', **style_dict)
|
||||
style.map('TButton', **map_options)
|
||||
style.configure('TLabel', **style_dict)
|
||||
#style.configure('TEntry', **style_dict)
|
||||
#style.map('TEntry', **map_options)
|
||||
|
||||
# A hack to change entry style
|
||||
style.element_create("plain.field", "from", "clam")
|
||||
style.layout("EntryStyle.TEntry",
|
||||
[('Entry.plain.field', {'children': [(
|
||||
'Entry.background', {'children': [(
|
||||
'Entry.padding', {'children': [(
|
||||
'Entry.textarea', {'sticky': 'nswe'})],
|
||||
'sticky': 'nswe'})], 'sticky': 'nswe'})],
|
||||
'border':'2', 'sticky': 'nswe'})])
|
||||
style.configure("EntryStyle.TEntry",
|
||||
background="black",
|
||||
foreground="white",
|
||||
fieldbackground="black")
|
||||
4
copycat/sampleText.txt
Normal file
4
copycat/sampleText.txt
Normal file
@ -0,0 +1,4 @@
|
||||
1,2
|
||||
3,4
|
||||
7,7
|
||||
100,100
|
||||
@ -23,6 +23,16 @@ class Workspace(object):
|
||||
self.intraStringUnhappiness = 0.0
|
||||
self.interStringUnhappiness = 0.0
|
||||
|
||||
# LSaldyt: default initializations for GUI entry
|
||||
self.targetString = ''
|
||||
self.initialString = ''
|
||||
self.modifiedString = ''
|
||||
self.finalAnswer = None
|
||||
self.changedObject = None
|
||||
self.objects = []
|
||||
self.structures = []
|
||||
self.rule = None
|
||||
|
||||
def __repr__(self):
|
||||
return '<Workspace trying %s:%s::%s:?>' % (
|
||||
self.initialString, self.modifiedString, self.targetString,
|
||||
|
||||
24
gui.py
Executable file
24
gui.py
Executable file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
from copycat import Copycat, Reporter
|
||||
|
||||
class SimpleReporter(Reporter):
|
||||
def report_answer(self, answer):
|
||||
print('Answered %s (time %d, final temperature %.1f)' % (
|
||||
answer['answer'], answer['time'], answer['temp'],
|
||||
))
|
||||
|
||||
def main():
|
||||
logging.basicConfig(level=logging.INFO, format='%(message)s', filename='./output/copycat.log', filemode='w')
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
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.runGUI()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user