def lex_search(self): """ Update the viewer after lexicalization """ words = self._e.get().split() if len(words) == 0: return self.clean_anchor() self._tagset = TAGTreeSet() self._treeview.clear() for word in words: self._tagset[word] = TAGTreeSet() fset = self._tagset[word] lex_list = word_to_features(word) self.lexicalize_tagset(lex_list, fset) for morph in lex_list: if len(morph[0]) > 1: phrases = [v[0] for v in morph[0]] if words == phrases: index = '' for i in phrases: index = index + i + ' ' if not isinstance(self._tagset[index], TAGTreeSet): self._tagset[index] = TAGTreeSet() fset = self._tagset[index] self.lexicalize_tagset([morph], fset) self._tagset.set_start_fs(self._alltrees.start_fs) self._treeview.update(self._tagset) self._count = {}
def update_lex_tree(self): """ Update the viewer with selected words """ words = self.phrases.get().split() if len(words) == 0: return self._tagset = TAGTreeSet() self._e.delete(0, END) self._treeview.clear() for word in words: self._tagset[word] = TAGTreeSet() fset = self._tagset[word] self.lexicalize_tagset(lex_list, fset) for morph in lex_list: if len(morph[0]) > 1: phrases = [v[0] for v in morph[0]] if phrases == words: index = '' for i in phrases: index = index + i + ' ' if not index in self._tagset: self._tagset[index] = TAGTreeSet() fset = self._tagset[index] self.lexicalize_tagset([morph], fset) self._tagset.set_start_fs(self._alltrees.start_fs) self._treeview.update(self._tagset) self._count = {}
def clear(self): """ Empty the treeview and TAG tree set. """ self._sfs_button['text'] = 'Add Start Features' self._add_fs = True x = self._tagview.get_children() for item in x: self._tagview.delete(item) self._trees = TAGTreeSet()
class TAGTreeSetView(object): """ A window that displays a TAG Tree set. TAG Tree Set contains a group of TAG trees, when clicking the tree name on the tree list, the tree will be displayed on the canvas. """ def __init__(self, tagtrees, parent=None): self._trees = tagtrees if parent is None: self._top = Tk() self._top.title('NLTK') self._top.bind('<Control-p>', lambda e: self.print_to_file()) self._top.bind('<Control-x>', self.destroy) self._top.bind('<Control-q>', self.destroy) self._top.geometry("1400x800") else: self._top = parent[0] frame = Frame(self._top) v = StringVar() self.w = Label(frame, text='Regexp:') self._e = Entry(frame, textvariable=v) self._e.bind("<Return>", self.return_pressed) self._show_fs = True self._show_fs_button = Button(frame, text="Hide Features", command=self.show_fs) self._sfs_button = Button(frame, text="Add Start Features", command=self.start_feat) self.highlight_button = Button(frame, text="Highlight", command=self.highlight) self.remove_button = Button(frame, text="Remove", command=self.remove) self.keep_button = Button(frame, text="Keep", command=self.keep) self._sfs_button.pack(side=LEFT) self._show_fs_button.pack(side=LEFT) self.w.pack(side=LEFT) self._e.pack(expand=1, fill='both', side = LEFT) self.highlight_button.pack(side=RIGHT) self.keep_button.pack(side=RIGHT) self.remove_button.pack(side=RIGHT) statframe = Frame(self._top) self.notfl = Label(statframe, text='Tree Framilies:') self.notf = StringVar() self.nott = StringVar() self.tfcl = Label(statframe, textvariable=self.notf) self.nottl = Label(statframe, text='Trees:') self.tcl = Label(statframe, textvariable=self.nott) self.notf.set(str(self._trees.tree_family_count())) self.nott.set(str(self._trees.tree_count())) statframe.pack(side = BOTTOM, fill='both') self.notfl.pack(side = LEFT) self.tfcl.pack(side = LEFT) self.nottl.pack(side = LEFT) self.tcl.pack(side = LEFT) frame.pack(side = BOTTOM, fill='both') self._frame = Frame(self._top) self._frame.pack(fill='both', side = LEFT) self.cols = ('fullpath', 'type') self._add_fs = True self._tagview = ttk.Treeview(self._frame, columns=self.cols, displaycolumns='', yscrollcommand=lambda f, l:autoscroll(vsb, f, l), xscrollcommand=lambda f, l:autoscroll(hsb, f, l)) ysb = ttk.Scrollbar(self._frame, orient=VERTICAL, command=self._tagview.yview) xsb = ttk.Scrollbar(self._frame, orient=HORIZONTAL, command=self._tagview.xview) self._tagview['yscroll'] = ysb.set self._tagview['xscroll'] = xsb.set if parent: self._tagview.bind('<<TreeviewSelect>>', parent[1]) else: self._tagview.bind('<<TreeviewSelect>>', self.display) self.populate_tree('', self._trees) self._tagview.configure(xscrollcommand=xsb.set, yscrollcommand=ysb.set) ysb.pack(fill='y', side='right') xsb.pack(fill='x', side='bottom') self._tagview.heading('#0', text='Trees', anchor=W) self._tagview.column('#0', stretch=1, width=220) self._tagview.pack(expand=1, fill='both') self._tw = TAGTreeView(None, parent=self._top) self._tw.pack(expand=1, fill='both', side = LEFT) self.sfs_tree ={} def return_pressed(self, event): """ Short-cut for pressing return to show feature structures """ words = self._e.get().split() if len(words) == 0: self._show_fs = False self.show_fs() return def start_feat(self): """ Add or Remove start feature structure of TAG tree set """ if self._trees.start_fs is None: raise TypeError("Should set start feature for TAG Trees First") node = self._tagview.focus() path = self._tagview.set(node, "fullpath").split('/') tree = self._trees for subpath in path[1:]: if subpath in tree: tree = tree[subpath] else: raise TypeError("%s: tree does not match" % type(self).__name__) if isinstance(tree, type(self._trees)): return if not tree.start_feat: self._sfs_button['text'] = 'Delete Start Features' self.add_start_fs(tree, self._trees.start_fs) tree.start_feat = True else: self._sfs_button['text'] = 'Add Start Features' self.del_start_fs(tree) tree.start_feat = False self._add_fs = not self._add_fs def add_start_fs(self, tree, start_fs): """ Add start feature structure. :param tree: display tree :type: TAGTree :param start_fs: start feature structure :type: FeatStruct """ root = tree.get_node_name() + '.t' all_fs = tree.get_all_fs() self._old_sfs = copy.deepcopy(all_fs[root]) for i in start_fs: all_fs[root][i] = start_fs[i] tree.set_all_fs(all_fs) self._tw.redraw(self._show_fs, tree) def del_start_fs(self, tree): """ Remove start feature structure. :param tree: display tree :type: TAGTree """ root = tree.get_node_name() + '.t' all_fs = tree.get_all_fs() all_fs[root] = self._old_sfs tree.set_all_fs(all_fs) self._old_sfs = None self._tw.redraw(self._show_fs, tree) def pack(self): """ Pack the canvas frame of ``TAGTreeView``. """ self._tagview.pack(expand=1, fill='both') self._frame.pack(fill='both', side = LEFT) self._tw.pack(expand=1, fill='both', side = LEFT) def focus(self): """ Get selected TAGTree :return: selected treeview :rtype: TAGTree """ node = self._tagview.focus() path = self._tagview.set(node, "fullpath").split('/') tree = self._trees for subpath in path[1:]: if subpath in tree: if not isinstance(tree, type(self._trees)): if tree._lex: tree[subpath] = tree[subpath].copy(True) tree = tree[subpath] else: raise TypeError("%s: tree does not match" % type(self).__name__) if not isinstance(tree, type(self._trees)): if tree._lex: tree.lexicalize() tree._lex = False return (tree, subpath) def display(self, event=None): """ Display the tag tree on the canvas when the tree is selected. """ node = self._tagview.focus() path = self._tagview.set(node, "fullpath").split('/') tree = self._trees for subpath in path[1:]: if subpath in tree: if not isinstance(tree, type(self._trees)): if tree._lex: tree[subpath] = tree[subpath].copy(True) tree = tree[subpath] else: raise TypeError("%s: tree does not match" % type(self).__name__) if not isinstance(tree, type(self._trees)): if tree.start_feat: self._sfs_button['text'] = 'Delete Start Features' else: self._sfs_button['text'] = 'Add Start Features' if tree._lex: tree.lexicalize() tree._lex = False self._tw.redraw(self._show_fs, tree) else: self._tw.redraw(self._show_fs, tree) def populate_tree(self, parent, trees): """ Popluate the trees on the treeview. """ if not trees: return for t in sorted(trees.keys()): node = parent parent_path = self._tagview.set(parent, "fullpath") path = parent_path + '/' + t if ord(t[0]) < 10: f_chr = self.greek(t[0]) else: f_chr = t[0] if isinstance(trees[t], type(trees)): node = self._tagview.insert(parent, END, text=f_chr+t[1:], values=[path, 'directory']) self.populate_tree(node, trees[t]) else: self._tagview.insert(parent, END, text=f_chr+t[1:], values=[path, 'file']) def clear(self): """ Empty the treeview and TAG tree set. """ self._sfs_button['text'] = 'Add Start Features' self._add_fs = True x = self._tagview.get_children() for item in x: self._tagview.delete(item) self._trees = TAGTreeSet() def update(self, trees): """ Update the window when the change the TAG tree set. """ self._tw.clear() self._trees = trees self.populate_tree('', trees) self.notf.set(str(self._trees.tree_family_count())) self.nott.set(str(self._trees.tree_count())) def greek(self, ascii): """ Translate ASCII to greek letter """ i = ord(u'\u03af') + ord(ascii) return chr(i) def destroy(self, *e): if self._top is None: return self._top.destroy() self._top = None def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs) def show_fs(self): """ Display or hide the feature structure on the canvas. """ if self._show_fs: self._show_fs_button['text'] = 'Show Feature' else: self._show_fs_button['text'] = 'Hide Feature' self._e.delete(0, END) self._show_fs = not self._show_fs node = self._tagview.focus() path = self._tagview.set(node, "fullpath").split('/') tree = self._trees for subpath in path[1:]: if subpath in tree: tree = tree[subpath] else: raise TypeError("%s: tree does not match" % type(self).__name__) if not isinstance(tree, type(self._trees)): self._tw.redraw(self._show_fs, tree) def keep(self): """ Display the feature structures which match the input regular expression. """ node = self._tagview.focus() path = self._tagview.set(node, "fullpath").split('/') tree = self._trees for subpath in path[1:]: if subpath in tree: tree = tree[subpath] else: raise TypeError("%s: tree does not match" % type(self).__name__) if not isinstance(tree, type(self._trees)): self._tw.redraw(self._show_fs, tree, keep=True, reg=self._e.get()) self._show_fs_button['text'] = 'Show ALL Features' self._show_fs = False #return def highlight(self): """ Remove the feature structures which match the input regular expression from the canvas. """ node = self._tagview.focus() path = self._tagview.set(node, "fullpath").split('/') tree = self._trees for subpath in path[1:]: if subpath in tree: tree = tree[subpath] else: raise TypeError("%s: tree does not match" % type(self).__name__) if not isinstance(tree, type(self._trees)): self._tw.redraw(self._show_fs, tree, highlight=True, reg=self._e.get()) def remove(self): """ Highlight the feature structures which match the input regular expression. """ node = self._tagview.focus() path = self._tagview.set(node, "fullpath").split('/') tree = self._trees for subpath in path[1:]: if subpath in tree: tree = tree[subpath] else: raise TypeError("%s: tree does not match" % type(self).__name__) if not isinstance(tree, type(self._trees)): self._tw.redraw(self._show_fs, tree, remove=True, reg=self._e.get()) self._show_fs_button['text'] = 'Show ALL Features' self._show_fs = False
class LexView(object): """ A window that lexicalize a TAG Tree set. When type in word in the text entry, the TAG Tree Set will be lexicalized. Only TAG Trees that can be lexicalized with that word remain in the window. The word will be attached to the substitution node of the tree, and feature structure will be updated to make the tree consistent with the word. """ def __init__(self, grammar): self._top = Tk() self._top.title('NLTK') self._top.bind('<Control-x>', self.destroy) self._top.bind('<Control-q>', self.destroy) self._top.geometry("1400x800") self.frame = Frame(self._top) v = StringVar() self._e = Entry(self.frame, textvariable=v) self._e.bind("<Return>", self.return_pressed) all_button = Button(self.frame, text='Show All', command=self.show_all) button = Button(self.frame, text="Search", command=self.lex_search) self._e.pack(expand=1, fill='both', side=LEFT) self.phrases = StringVar() self.phrases.set("") update_button = Button(self.frame, text="Select", command=self.update_lex_tree) self._w = OptionMenu(self.frame, self.phrases, []) update_button.pack(side=RIGHT) self._w.pack(side=RIGHT) wl = Label(self.frame, text='Anchors:') wl.pack(side=RIGHT) all_button.pack(side=RIGHT) button.pack(side=RIGHT) self.frame.pack(fill='both') self.grammar = grammar self._tagset = grammar.trees self._treeview = TAGTreeSetView(self._tagset, (self._top, self.display)) self._treeview.pack() self._dicword = {} self._count = {} def display(self, event=None): """ Display the tag tree on the canvas when the tree is selected. """ node = self._treeview._tagview.focus() path = self._treeview._tagview.set(node, "fullpath").split('/') tree = self._treeview._trees for subpath in path[1:]: if subpath in tree: if not isinstance(tree, type(self._treeview._trees)): if tree._lex: tree[subpath] = tree[subpath].copy(True) tree = tree[subpath] else: raise TypeError("%s: tree does not match" % type(self).__name__) if not isinstance(tree, type(self._treeview._trees)): # Words is supposed to be all words with associated with a tree words = [] if len(words) > 0: self.update_anchor(words) if tree.start_feat: self._treeview._sfs_button['text'] = 'Delete Start Features' else: self._treeview._sfs_button['text'] = 'Add Start Features' if tree._lex: tree.lexicalize() tree._lex = False self._treeview._tw.redraw(self._treeview._show_fs, tree) else: self._treeview._tw.redraw(self._treeview._show_fs, tree) else: for path in tree: if isinstance(tree[path], type(self._treeview._trees)): return self.phrases.set("") if isinstance(tree, type(self._treeview._trees)) and subpath[-6:] == '.trees': tree_fam = tree[subpath] treename = subpath[:-6] else: treename = subpath def update_anchor(self, words): """ Update anchors with selected words :param: selected words :type: basestring """ self.clean_anchor() for choice in words: phrase = '' for term in choice: phrase = phrase + term[0] + ' ' if not phrase in self._dicword: self._dicword[phrase] = choice else: continue import tkinter as tk self._w['menu'].add_command(label=phrase, command=tk._setit(self.phrases, phrase)) def clean_anchor(self): """ Clean anchors of this viewer """ self._dicword = {} self._w['menu'].delete(0, 'end') def update_lex_tree(self): """ Update the viewer with selected words """ words = self.phrases.get().split() if len(words) == 0: return self._tagset = TAGTreeSet() self._e.delete(0, END) self._treeview.clear() for word in words: self._tagset[word] = TAGTreeSet() fset = self._tagset[word] self.lexicalize_tagset(lex_list, fset) for morph in lex_list: if len(morph[0]) > 1: phrases = [v[0] for v in morph[0]] if phrases == words: index = '' for i in phrases: index = index + i + ' ' if not index in self._tagset: self._tagset[index] = TAGTreeSet() fset = self._tagset[index] self.lexicalize_tagset([morph], fset) self._tagset.set_start_fs(self._alltrees.start_fs) self._treeview.update(self._tagset) self._count = {} def return_pressed(self, event): """ Short-cut for pressing return to show feature structures """ self.clean_anchor() words = self._e.get().split() if len(words) == 0: self.show_all() return self.lex_search() def resize(self, *e): """ Resize the window """ self._treeview(e) def show_all(self): """ Show all the TAG Tree in window """ self.clean_anchor() self._e.delete(0, END) self._tagset = self._alltrees self._treeview.clear() self._treeview.update(self._tagset) return def lex_search(self): """ Update the viewer after lexicalization """ words = self._e.get().split() if len(words) == 0: return self.clean_anchor() self._tagset = TAGTreeSet() self._treeview.clear() for word in words: self._tagset[word] = TAGTreeSet() fset = self._tagset[word] lex_list = word_to_features(word) self.lexicalize_tagset(lex_list, fset) for morph in lex_list: if len(morph[0]) > 1: phrases = [v[0] for v in morph[0]] if words == phrases: index = '' for i in phrases: index = index + i + ' ' if not isinstance(self._tagset[index], TAGTreeSet): self._tagset[index] = TAGTreeSet() fset = self._tagset[index] self.lexicalize_tagset([morph], fset) self._tagset.set_start_fs(self._alltrees.start_fs) self._treeview.update(self._tagset) self._count = {} def lexicalize_tagset(self, lex_list, fset): """ Lexicalize all TAG tree set :param lex_list: a list of lexicalized node :type: list :alltrees: TAG tree set to be lexicalized :type: TAGTreeSet """ for morph in lex_list: index = '' for i in morph[0]: index = index + i[0] + '.' + i[1] + ' ' for i in morph[5][1]: index = index + i + '_' index = index[:-1] if index not in fset: fset[index] = TAGTreeSet() sset = fset[index] if len(morph[2]) > 0: for tf in morph[2]: ckey = index+tf tf = tf + '.trees' if tf not in sset: key = tf self._count[ckey] = 0 else: key = tf[:-5] + '_' + str(self._count[ckey]) + '.trees' sset[key] = TAGTreeSet() index = None for sub in self._alltrees: if tf in self._alltrees[sub]: index = sub if not index: raise NameError('No tree family') sset[key] += self._alltrees[index][tf].copy(True) for t in sset[key]: if sset[key][t]._lex: sset[key][t]._lex_fs sset[key][t].init_lex(morph[0], morph[3], morph[4]) self._count[ckey] += 1 else: for t in morph[1]: ckey = index+t if t not in sset: key = t self._count[ckey] = 0 else: key = t + '_' + str(self._count[ckey]) for sub in self._alltrees: for tr in self._alltrees[sub]: if t in self._alltrees[sub][tr]: sset[key] = self._alltrees[sub][tr][t].copy(True) self._count[ckey] += 1 if not isinstance(sset[key], TAGTree): raise TypeError('Not TAGTree') sset[key].init_lex(morph[0], morph[3], morph[4]) def destroy(self, *e): if self._top is None: return self._top.destroy() self._top = None def mainloop(self, *args, **kwargs): if in_idle(): return self._top.mainloop(*args, **kwargs)