From acb285acb6a0d89392ce5813737b2e5b4d15fb0e Mon Sep 17 00:00:00 2001 From: Mart Lubbers Date: Thu, 7 Aug 2014 22:04:08 +0200 Subject: [PATCH] another update --- program/everything/data_processing.py | 94 ++++++- program/everything/dawg.py | 71 +++++ program/everything/pydawg.py | 289 ++++++++++++++++++++ program/everything/pydawg.pyc | Bin 0 -> 8491 bytes program/everything/t.dot | Bin 0 -> 20528 bytes program/everything/webdata/contextmenu_o.js | 22 -- 6 files changed, 449 insertions(+), 27 deletions(-) create mode 100644 program/everything/dawg.py create mode 100644 program/everything/pydawg.py create mode 100644 program/everything/pydawg.pyc create mode 100644 program/everything/t.dot diff --git a/program/everything/data_processing.py b/program/everything/data_processing.py index 08d7d0f..fffcc98 100644 --- a/program/everything/data_processing.py +++ b/program/everything/data_processing.py @@ -4,6 +4,7 @@ import ast import logging import re +import pydawg def structure_data(d): @@ -27,8 +28,8 @@ def structure_data(d): def parse_line(line): - re_spa = re.compile('(?P.*?);.*?>)(?P.*?)(?P)') + re_spa = re.compile('(?P.*?);.*?>)(?P' + '.*?)(?P)') results = [] for column in line: results.append([]) @@ -39,7 +40,86 @@ def parse_line(line): def create_nodes(d): - print d + color_dict = { + 'rgb(139, 0, 0)': '\x01', # 'datum', + 'red': '\x02', # 'tijd', + 'green': '\x03', # 'wat', + 'blue': '\x04' # 'wanneer' + } + line_w_match = [] + d['content'] = d['content'][1:] + for i, m in enumerate(d['matchdata']): + if filter(None, m): + line_w_match.append((d['content'][i], m)) + nodelists = {'Title': [], 'Summary': []} + for (title_l, summary_l), (title_m, summary_m) in line_w_match: + # Title + if title_m: + title = title_m[0] + matches = reversed(sorted(title, key=lambda x: x.end('e'))) + for match in matches: + title_l = title_l[:match.start('e')] + title_l[match.end('e'):] + title_l = title_l[:match.start('content')] +\ + color_dict[match.group('c').strip()] +\ + title_l[match.end('content'):] + title_l = title_l[:match.start('b')] + title_l[match.end('b'):] + nodelists['Title'].append(title_l) + if summary_m: + summary = summary_m[0] + matches = reversed(sorted(summary, key=lambda x: x.end('e'))) + for match in matches: + summary_l = summary_l[:match.start('e')] +\ + summary_l[match.end('e'):] + summary_l = summary_l[:match.start('content')] +\ + color_dict[match.group('c').strip()] +\ + summary_l[match.end('content'):] + summary_l = summary_l[:match.start('b')] +\ + summary_l[match.end('b'):] + nodelists['Summary'].append(summary_l) + return nodelists + + +def to_dot(q0): + nodenum = 0 + final_nodes = [] + nodes = [] + edges = [] + to_visit = [(0, q0)] + visited = set() + translation = [] + if q0.final: + final_nodes.append(nodenum) + else: + nodes.append(nodenum) + + nodenum += 1 + while to_visit: + current = to_visit.pop() + if not current[0] in visited: + visited.add(current[0]) + for char, child in current[1].children.iteritems(): + matches = [c for c in translation if c[0] == child] + curnum = -1 + if matches: + curnum = matches[-1][1] + else: + translation.append((child, nodenum)) + curnum = nodenum + nodenum += 1 + if child.final: + final_nodes.append(curnum) + else: + nodes.append(curnum) + edges.append((current[0], char, curnum)) + to_visit.append((curnum, child)) + print 'digraph dawg {' + print '\tnode [shape = doublecircle]; {}'.format( + ' '.join(str(n) for n in final_nodes)) + print '\tnode [shape = circle]; {}'.format( + ' '.join(str(n) for n in nodes)) + for fr, ch, to in edges: + print '\t{} -> {} [label = "{}"];'.format(fr, to, ch) + print '}' def main(): @@ -57,9 +137,13 @@ def main(): d['matchdata'] = [] for line in filter(None, d['content']): d['matchdata'].append(parse_line(line)) - create_nodes(d) + nodelists = create_nodes(d) + titledawg = pydawg.DAWG() + for n in sorted(nodelists['Title']): + titledawg.add_word(n) + to_dot(titledawg.q0) if __name__ == '__main__': - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(level=logging.WARNING) main() diff --git a/program/everything/dawg.py b/program/everything/dawg.py new file mode 100644 index 0000000..be0757b --- /dev/null +++ b/program/everything/dawg.py @@ -0,0 +1,71 @@ +#!/bin/env python +# -*- coding: utf-8 -*- + +import pydawg + + +def to_dot(filepath, q0): + nodenum = 0 + final_nodes = [] + nodes = [] + edges = [] + to_visit = [(0, q0)] + visited = set() + translation = [] + if q0.final: + final_nodes.append(nodenum) + else: + nodes.append(nodenum) + + nodenum += 1 + while to_visit: + current = to_visit.pop() + if not current[0] in visited: + visited.add(current[0]) + for char, child in current[1].children.iteritems(): + matches = [c for c in translation if c[0] == child] + curnum = -1 + if matches: + curnum = matches[-1][1] + else: + translation.append((child, nodenum)) + curnum = nodenum + nodenum += 1 + if child.final: + final_nodes.append(curnum) + else: + nodes.append(curnum) + edges.append((current[0], char, curnum)) + to_visit.append((curnum, child)) + print 'digraph dawg {' + print '\tnode [shape = doublecircle]; {}'.format( + ' '.join(str(n) for n in final_nodes)) + print '\tnode [shape = circle]; {}'.format( + ' '.join(str(n) for n in nodes)) + for fr, ch, to in edges: + print '\t{} -> {} [label = "{}"];'.format(fr, to, ch) + print '}' + + +d = pydawg.DAWG() + +regs = [ + 'wdag dag maand jaar tijd - wat', + 'dag maand jaar tijd - wat', + 'wdag dag maand jaar tijd - wat', + 'wdag dag maand jaar tijd - wat - Locatie: waar', + 'wdag dag maand jaar tijd - wat - Locatie: waar'] + +#regs = [ +# 'maandag 11 augustus 2014 19:30 - Neutral Milk Hotel', +# 'dinsdag 19 augustus 2014 22:00 - Arkells', +# 'maandag 24 november 2014 20:30 - Fink', +# 'woensdag 19 november 2014 20:00 - Michael Schulte', +# 'zondag 26 oktober 2014 21:00 - The Majority Says - Locatie: Bitterzoet', +# 'maandag 15 september 2014 20:30 - Ani DiFranco', +# 'maandag 13 oktober 2014 20:30 - Tarrus Riley', +# 'maandag 29 december 2014 20:30 - Alain Clark - Locatie: De Duif'] +for w in sorted(set(regs)): + d.add_word(w) + +to_dot('t.dot', d.q0) diff --git a/program/everything/pydawg.py b/program/everything/pydawg.py new file mode 100644 index 0000000..18475c1 --- /dev/null +++ b/program/everything/pydawg.py @@ -0,0 +1,289 @@ +# -*- coding: utf-8 -*- +""" + This is part of pydawg Python module. + + Pure python implementation. + + Author : Wojciech Muła, wojciech_mula@poczta.onet.pl + WWW : http://0x80.pl/proj/pydawg/ + License : Public domain + Date : $Date$ + + $Id$ +""" + + +class DAWGNode: + __slots__ = ["children", "final", "number"] + + def __init__(self, char): + self.children = {} + self.final = False + self.number = None + + def get_next(self, char): + try: + return self.children[char] + except KeyError: + return None + + def set_next(self, char, child): + self.children[char] = child + + def has_transition(self, char): + return char in self.children + + def __str__(self): + return "<" + "".join(self.children.keys()) + ">" + + +def equivalence(p, q): + "check if states p and q are equivalent" + + if p.final != q.final: + return False + + if len(p.children) != len(q.children): + return False + + s = set(p.children) + if s != set(q.children): + return False + + """ + # exact definition of equivalence + for c in s: + if not equivalence(p.children[c], q.children[c]): + return False + """ + # pratical implementation - constraints make + # this much simpler and faster + for c in s: + if p.children[c] != q.children[c]: + return False + + return True + + +class DAWG: + def __init__(self): + self._numbers_valid = False + self.register = set() + self.q0 = DAWGNode(None); + self.wp = '' + + + def add_word(self, word): + assert word > self.wp + return self.add_word_unchecked(word) + + + def add_word_unchecked(self, word): + # 1. skip existing + i = 0; + s = self.q0 + while i < len(word) and s.has_transition(word[i]): + s = s.get_next(word[i]) + i = i + 1 + + assert s != None + + # 2. minimize + if i < len(self.wp): + self._replace_or_register(s, self.wp[i:]) + + + # 3. add suffix + while i < len(word): + n = DAWGNode(word[i]) + s.set_next(word[i], n) + assert n == s.get_next(word[i]) + s = n + i = i + 1 + + s.final = True + self.wp = word + self._numbers_valid = False + + + def _replace_or_register(self, state, suffix): + stack = [] + while suffix: + letter = suffix[0] + next = state.get_next(letter) + stack.append((state, letter, next)) + + state = next + suffix = suffix[1:] + + while stack: + parent, letter, state = stack.pop() + + found = False + for r in self.register: + if equivalence(state, r): + assert(parent.children[letter] == state) + parent.children[letter] = r + + found = True + break + + if not found: + self.register.add(state) + + + def freeze(self): + self._replace_or_register(self.q0, self.wp) + self._numbers_valid = False + + close = freeze + + + def _num_nodes(self): + def clear_aux(node): + node.number = None + for child in node.children.values(): + clear_aux(child) + + def num_aux(node): + if node.number is None: + n = int(node.final) + for child in node.children.values(): + n += num_aux(child) + + node.number = n + + return node.number + + if not self._numbers_valid: + clear_aux(self.q0) + num_aux(self.q0) + self._numbers_valid = True + + + def word2index(self, word): + self._num_nodes() + + state = self.q0 + index = 0 + for c in word: + try: + next = state.children[c] + except KeyError: + return None + + for C in sorted(state.children): + if C < c: + index += state.children[C].number + else: + break + + state = next + if state.final: + index = index + 1 + #for + + return index + + + def index2word(self, index): + self._num_nodes() + + state = self.q0 + count = index + output_word = "" + while True: + for c in sorted(state.children): + tmp = state.get_next(c) + if tmp.number < count: + count -= tmp.number + else: + output_word += c + state = tmp + if state.final: + count -= 1 + + break + #for + if count <= 0: + break + + return output_word + + + def as_dot(self, file): + nodes = set() + edges = [] + tmp = set() + + def aux(node): + nodes.add((id(node), node.final)) + tmp.add(node) + + for letter, child in node.children.items(): + aux(child) + + aux(self.q0) + + for node in tmp: + for letter, child in node.children.items(): + edges.append((id(node), letter, id(child))) + + import dump2dot + dump2dot.dumpdata2dot(nodes, edges, file) + + + def words(self): + L = [] + def aux(node, word): + if node.final: + L.append(word) + + for letter, child in node.children.items(): + aux(child, word + letter) + + aux(self.q0, '') + return L + + + def __iter__(self): + return iter(self.words()) + + +import os + +def main(): + words = "aimaient aimais aimait aime aiment".split() + words = "cat rat attribute tribute".split() + + def dump(name): + with open(name, 'wt') as f: + D.as_dot(f) + + + D = DAWG() + for word in sorted(words): + print(word) + D.add_word(word) + + D.freeze() + + # MPH test + for word in words: + print(word, "=>", D.word2index(word)) + + for index in range(1, len(words) + 1): + print(index, "=>", D.index2word(index)) + + + if 1: + # show image of graph + name = "dawg.dot" + dump(name) + os.system("dotty %s" % name) + + print(D.words(), set(D.words()) == set(words)) + + +if __name__ == '__main__': + main() diff --git a/program/everything/pydawg.pyc b/program/everything/pydawg.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6507eebc4e209bb59ae7c11d95d3e699e10d2af GIT binary patch literal 8491 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 N{CUvUwy>he{ugVxh}!@F literal 0 HcmV?d00001 diff --git a/program/everything/webdata/contextmenu_o.js b/program/everything/webdata/contextmenu_o.js index 8b0cc05..5311a67 100644 --- a/program/everything/webdata/contextmenu_o.js +++ b/program/everything/webdata/contextmenu_o.js @@ -20,28 +20,6 @@ function RightMouseDown() { return false } -function init(a, w) { - console.log(a) - var b = document.createElement("DIV"); - b.id = "contextmenu"; - if (!w) var w = 120; - b.style.width = w + "px"; - var c = '
'; - c += a; - c += '
'; - b.innerHTML = c; - b.style.position = "absolute"; - b.style.left = "0px"; - b.style.top = "0px"; - b.style.visibility = "hidden"; - b.style.overflow = "hidden"; - b.style.padding = "4px"; - b.style.backgroundColor = "#ffffff"; - b.style.border = "1px solid #6a6868"; - document.body.appendChild(b); - delete b -} - function mouseUp(e) { var curselection = window.getSelection().getRangeAt(0); if (curselection.endOffset - curselection.startOffset > 0) -- 2.20.1