1
# This module is part of the Divmod project and is Copyright 2003 Amir Bakhtiar:
2
# amir@divmod.org. This is free software; you can redistribute it and/or
3
# modify it under the terms of version 2.1 of the GNU Lesser General Public
4
# License as published by the Free Software Foundation.
14
from util import Command, StatusBar, Notebook
15
from tester import TestView
17
class PoolView(Frame):
18
def __init__(self, master=None, guesser=None, app=None):
19
Frame.__init__(self, master, bg='lightblue3')
21
self.listView = Frame(self)
23
bp = Button(self, text="New Pool", command=self.newPool)
24
bp.pack(side=LEFT, anchor=SE)
28
self.guesser = guesser
33
self.listView.destroy()
34
self.listView = Frame(self)
36
for pool in self.guesser.poolNames():
37
self.addPool(self.guesser.pools[pool])
38
self.addPool(self.guesser.corpus, 'Total')
43
def addLoadSave(self):
45
frame.pack(side=RIGHT)
46
bp = Button(frame, text="Upload", command=self.upload, state=DISABLED)
47
bp.pack(side=BOTTOM, fill=X)
48
bp = Button(frame, text="Save", command=self.save)
49
bp.pack(side=BOTTOM, fill=X)
50
bp = Button(frame, text="Load", command=self.load)
51
bp.pack(side=BOTTOM, fill=X)
53
def addPool(self, pool, name=None):
57
line = Frame(self.listView)
61
idx = self.guesser.poolNames().index(name)
62
col = self.defaultColours()[idx]
63
l = Label(line, text=name, anchor=W, width=10)
64
l.grid(row=0, column=0)
65
colourStripe = Label(line, text=' ', width=1, bg=col, anchor=W, relief=GROOVE)
66
colourStripe.grid(row=0, column=1)
68
train.set(pool.trainCount)
69
l = Label(line, textvariable=train, anchor=E, width=10, relief=SUNKEN)
70
l.grid(row=0, column=2)
73
l = Label(line, textvariable=uTok, anchor=E, width=12, relief=SUNKEN)
74
l.grid(row=0, column=3)
76
tTok.set(pool.tokenCount)
77
l = Label(line, textvariable=tTok, anchor=E, width=10, relief=SUNKEN)
78
l.grid(row=0, column=4)
79
self.model[name]=(pool, uTok, tTok, train)
82
for pool, ut, tt, train in self.model.values():
84
tt.set(pool.tokenCount)
85
train.set(pool.trainCount)
88
path = tkFileDialog.asksaveasfilename()
91
self.guesser.save(path)
92
self.app.dirty = False
95
path = tkFileDialog.askopenfilename()
98
self.guesser.load(path)
100
self.app.dirty = False
103
p = tkSimpleDialog.askstring('Create Pool', 'Name for new pool?')
106
if p in self.guesser.pools:
107
tkMessageBox.showwarning('Bad pool name!', 'Pool %s already exists.' % p)
108
self.guesser.newPool(p)
111
self.app.status.log('New pool created: %s.' % p, clear=3)
113
def defaultColours(self):
114
return ['green', 'yellow', 'lightblue', 'red', 'blue', 'orange', 'purple', 'pink']
116
def columnHeadings(self):
117
# FIXME factor out and generalize
118
title = Label(self, text='Pools', relief=RAISED, borderwidth=1)
119
title.pack(side=TOP, fill=X)
120
msgLine = Frame(self, relief=RAISED, borderwidth=1)
121
msgLine.pack(side=TOP)
123
colHeadings = [('Name', 10), ('', 1), ('Trained', 10), ('Unique Tokens', 12), ('Tokens', 10)]
124
for cHdr, width in colHeadings:
125
l = Label(msgLine, text=cHdr, width=width, bg='lightblue')
126
l.grid(row=0, column=currCol)
130
class Trainer(Frame):
131
def __init__(self, parent, guesser=None, itemClass=None):
132
self.status = StatusBar(parent)
133
self.status.pack(side=BOTTOM, fill=X)
134
Frame.__init__(self, parent)
135
self.pack(side=TOP, fill=BOTH)
136
self.itemsPerPage = 20
138
for i in range(self.itemsPerPage):
139
self.rows.append(ItemRow())
145
from reverend.thomas import Bayes
146
self.guesser = Bayes()
148
self.guesser = guesser
149
if itemClass is None:
150
self.itemClass = TextItem
152
self.itemClass = itemClass
153
for row in self.rows:
154
row.summary.set('foo')
158
self.nb = Notebook(self)
159
## frame1 = Frame(self.nb())
160
## self.poolView = PoolView(frame1, guesser=self.guesser, app=self)
161
## self.poolView.pack(side=TOP)
162
frame2 = Frame(self.nb())
163
self.poolView = PoolView(frame2, guesser=self.guesser, app=self)
164
self.poolView.pack(side=TOP)
165
self.listView = Canvas(frame2, relief=GROOVE)
166
self.listView.pack(padx=3)
167
bn = Button(self.listView, text="Load training", command=self.loadCorpus)
168
bn.pack(side=RIGHT, anchor=NE, fill=X)
169
self.columnHeadings()
172
frame3 = Frame(self.nb())
173
self.testView = TestView(frame3, guesser=self.guesser, app=self)
176
frame4 = Frame(self.nb())
177
bp = Button(frame4, text="Quit", command=self.quitNow)
180
#self.nb.add_screen(frame1, 'Reverend')
181
self.nb.add_screen(frame2, 'Training')
182
self.nb.add_screen(frame3, 'Testing')
183
self.nb.add_screen(frame4, 'Quit')
186
def addNextPrev(self):
187
npFrame = Frame(self.listView)
188
npFrame.pack(side=BOTTOM, fill=X)
189
bn = Button(npFrame, text="Prev Page", command=self.prevPage)
190
bn.grid(row=0, column=0)
191
bn = Button(npFrame, text="Next Page", command=self.nextPage)
192
bn.grid(row=0, column=1)
195
def loadCorpus(self):
196
path = tkFileDialog.askdirectory()
199
self.loadFileList(path)
205
for pool in self.guesser.poolNames():
206
path = tkFileDialog.askdirectory()
207
dirs.append((pool, path))
208
for pool, path in dirs:
212
def displayList(self):
213
for item in self.items:
216
def displayRows(self):
217
for row in self.rows:
220
def loadFileList(self, path):
221
listing = os.listdir(path)
222
self.files = [os.path.join(path, file) for file in listing]
226
self.cursor = max(0, self.cursor - self.itemsPerPage)
230
self.cursor = min(len(self.files), self.cursor + self.itemsPerPage)
233
def displayItems(self):
234
theseFiles = self.files[self.cursor:self.cursor + self.itemsPerPage]
236
for file, row in zip(theseFiles, self.rows):
237
fp = open(file, 'rb')
239
item = self.itemClass.fromFile(fp)
245
guesses = self.guesser.guess(item)
246
summary = item.summary()
247
cols = item.columnDefs()
249
for c, ignore in cols:
250
s += summary[c] + ' '
251
row.initialize(item, s, guesses, self.guesser.poolNames())
256
if tkMessageBox.askyesno("You have unsaved changes!", "Quit without saving?"):
260
def columnHeadings(self):
261
# FIXME - Something better for columns and rows in general
262
line = Frame(self.listView, relief=RAISED, borderwidth=1)
263
line.pack(side=TOP, padx=2, pady=1)
264
colHeadings = self.itemClass.columnDefs()
266
for cHdr, width in colHeadings:
267
l = Label(line, text=cHdr, width=width, bg='lightblue')
268
l.grid(row=0, column=currCol)
273
def training(self, row):
274
sel = row.selection.get()
275
self.guesser.train(sel, row.original)
280
self.poolView.refresh()
281
pools = self.guesser.poolNames()
282
for row in self.rows:
283
row.setGuess(self.guesser.guess(row.original), pools)
285
def displayRow(self, row, bgc=None):
287
line = Frame(self.listView, bg=bgc)
290
self.insertRadios(row)
291
Label(line, text=row.summary.get(), textvariable=row.summary, width=60, bg=bgc,
292
anchor=W).grid(row=0, column=2)
293
#Label(line, text=row.guess, width=7, bg=bgc, anchor=W).grid(row=0, column=1)
294
colourStripe = Label(line, text=' ', width=1, bg=bgc, anchor=W, relief=GROOVE)
295
colourStripe.grid(row=0, column=1)
296
line.colourStripe = colourStripe
297
pools = self.guesser.poolNames()
298
row.refreshColour(pools)
303
pools = self.guesser.poolNames()
304
for row in self.rows:
307
self.insertRadios(row)
308
row.refreshColour(pools)
311
def insertRadios(self, row):
312
radioFrame = Frame(row.line)
313
radioFrame.grid(row=0, column=0)
318
colours = row.defaultColours()
319
pools = self.guesser.poolNames()
321
rb = Radiobutton(radioFrame, text=pool, variable=v, value=pool, command=Command(self.training, row), bg=None)
322
rb.grid(row=0, column=currCol)
329
class TextItem(object):
330
def __init__(self, text):
334
return {'Text': self.text}
336
def columnNames(self):
340
return self.text.lower()
342
def fromFile(self, fp):
343
"""Return the first line of the file.
345
ti = self(fp.readline())
347
fromFile = classmethod(fromFile)
350
class ItemRow(object):
351
def __init__(self, orig=None):
357
self.summary = StringVar()
358
self.selection = StringVar()
360
def initialize(self, item=None, summary='', guess=None, pools=[]):
361
self.selection.set('')
363
self.summary.set(summary)
364
self.setGuess(guess, pools)
366
def setGuess(self, guess, pools):
370
self.selection.set(self.bestGuess())
371
self.current = self.bestGuess()
372
self.refreshColour(pools)
374
def refreshColour(self, pools):
376
if self.guess[0][0] in pools:
377
idx = pools.index(self.guess[0][0])
378
col = self.defaultColours()[idx]
380
self.line.colourStripe.config(bg=col)
383
return self.original.__repr__()
385
def defaultColours(self):
386
return ['green', 'yellow', 'lightblue', 'red', 'blue', 'orange', 'purple', 'pink']
390
return self.guess[0][0]
397
if __name__ == "__main__":
399
root.title('Reverend Trainer')
400
root.minsize(width=300, height=300)
401
#root.maxsize(width=600, height=600)
402
display = Trainer(root)