Advertisement
Guest User

Untitled

a guest
Feb 21st, 2020
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.69 KB | None | 0 0
  1. class MetaReplay:
  2.     def __init__(self, transitions):
  3.         cached_meta = {0: {}}
  4.  
  5.         running_state = {}
  6.         for transition_point, transition in transitions.items():
  7.             running_state[transition.metatarget] = transition.assignments
  8.             cached_meta[transition_point.start] = running_state.copy()
  9.  
  10.         self.cached_meta = sorted(cached_meta.items(), key=lambda x: x[0])
  11.         self.keys = [x[0] for x in self.cached_meta]
  12.  
  13.     def __getitem__(self, key):
  14.         if isinstance(key, int):
  15.             assert key >= 0
  16.  
  17.             relevant_meta_index = bisect.bisect_right(self.keys, key)
  18.             if relevant_meta_index:
  19.                 return self.cached_meta[relevant_meta_index - 1][1]
  20.  
  21.         raise IndexError
  22.  
  23.     def get_value(self, index, segprop, segvalue):
  24.         result = {"id": segvalue}
  25.         relevant_meta = self[index]
  26.  
  27.         meta_target = MetaTarget(segprop, segvalue)
  28.         if meta_target in relevant_meta:
  29.             for assignment in relevant_meta[meta_target]:
  30.                 result[assignment.sprop] = assignment.value
  31.  
  32.         return result
  33.  
  34.  
  35. class SegmentTopology:
  36.     OVERLAPPING = "overlapping"
  37.     COVERING = "covering"
  38.  
  39.     def __init__(self, segments, story_length):
  40.         self.by_start = sorted(segments, key=lambda x: x.start)
  41.         self.start_keys = [x.start for x in self.by_start]
  42.         self.by_end = sorted(segments, key=lambda x: x.end)
  43.         self.end_keys = [x.end for x in self.by_end]
  44.         self.story_length = story_length
  45.  
  46.     def _end_after_inclusive(self, index):
  47.         first = bisect.bisect_left(self.end_keys, index)
  48.         return self.by_end[first:]
  49.  
  50.     def _start_strictly_before(self, index):
  51.         post_last = bisect.bisect_left(self.start_keys, index)
  52.         if post_last == None:
  53.             return []
  54.         return self.by_start[:post_last]
  55.  
  56.     def _start_before_inclusive(self, index):
  57.         post_first = bisect.bisect_right(self.start_keys, index)
  58.         if post_first == None:
  59.             return []
  60.         return self.by_start[:post_first]
  61.  
  62.     def _end_strictly_after(self, index):
  63.         last = bisect.bisect_right(self.end_keys, index)
  64.         return self.by_end[last:]
  65.  
  66.     def get_overlapping(self, start, end):
  67.         # find overlapping segments that end after this one starts and start before
  68.         # this one ends
  69.  
  70.         result = set()
  71.  
  72.         for candidate in self._end_after_inclusive(start):
  73.             if candidate.start >= end:
  74.                 break
  75.             result.add(candidate)
  76.  
  77.         for candidate in self._start_strictly_before(end)[::-1]:
  78.             if candidate.end < start:
  79.                 break
  80.             result.add(candidate)
  81.  
  82.         return result
  83.  
  84.     def get_covers(self, start, end):
  85.         # TODO: use an rtree to make get_covers() more efficient
  86.  
  87.         # find covering segments that start before this one start and end after
  88.         # this one ends
  89.  
  90.         start_before = set(self._start_before_inclusive(start))
  91.         end_after = set(self._end_strictly_after(end))
  92.  
  93.         print(start_before)
  94.         print(end_after)
  95.  
  96.         return start_before.intersection(end_after)
  97.  
  98.     def __getitem__(self, key):
  99.         if isinstance(key, int):
  100.             key = slice(key, key + 1, SegmentTopology.COVERING)
  101.  
  102.         start, end, _ = slice(key.start, key.stop).indices(self.story_length)
  103.         match_type = key.step
  104.  
  105.         if match_type == SegmentTopology.OVERLAPPING:
  106.             return self.get_overlapping(start, end)
  107.         elif match_type == SegmentTopology.COVERING:
  108.             return self.get_covers(start, end)
  109.  
  110.         raise TypeError(
  111.             'match type ("stride" value) must be one of OVERLAPPING or COVERING'
  112.         )
  113.  
  114.  
  115. class SegmentDict:
  116.     def __init__(self, items_by_seg, story_length):
  117.         self._dict = items_by_seg.copy()
  118.         self.segment_db = SegmentTopology(self._dict.keys(), story_length)
  119.  
  120.     def __getitem__(self, key):
  121.         result = []
  122.         for matching_segment in self.segment_db[key]:
  123.             result.append((matching_segment, self._dict[matching_segment]))
  124.  
  125.         return result
  126.  
  127. class MetaSegmentDict:
  128.     # TODO: finish this next
  129.  
  130. class CookieSynthNavigator:
  131.     def __init__(self, marked_story):
  132.         tokenizer = CookieSynthTokenizer()
  133.         parse_tree = COOKIESYNTH_PARSER.parse(marked_story)
  134.         tokenizer.visit(parse_tree)
  135.  
  136.         self.story = ''.join(tokenizer.story_pieces)
  137.         self.story_length = len(self.story)
  138.         self.meta = MetaReplay(tokenizer.meta_transitions)
  139.         self.types = SegmentDict(tokenizer.stypes, self.story_length)
  140.         self.assignments = SegmentDict(tokenizer.assignments, self.story_length)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement