Source code for cnt.rulebase.rules.interval_based_operations.basic_operation
"""
Collect the unicode codepoint specified by intervals.
"""
from typing import Type, Generator, Tuple, List
from cnt.rulebase import workflow
[docs]class IntervalBasedOperationLabelProcessor(workflow.BasicLabelProcessor):
[docs] def result(self) -> Generator[Tuple[int, bool], None, None]:
while True:
try:
index, labels = next(self.index_labels_generator)
except StopIteration:
return
# workflow.labelType -> bool
marked = False
for label in labels.values():
if label:
marked = True
break
yield index, marked
IntervalWithLabelType = Tuple[workflow.IntervalType, bool]
IntervalWithLabelGeneratorType = Generator[IntervalWithLabelType, None, None]
#pylint: disable=W0223
[docs]class IntervalBasedOperationOutputGenerator(workflow.BasicOutputGenerator):
[docs] def continuous_intervals(self) -> IntervalWithLabelGeneratorType:
cur_start = -1
cur_label = False
# Init.
try:
index, label = next(self.label_processor_result)
cur_start = index
cur_label = label
except StopIteration:
return
while True:
try:
index, label = next(self.label_processor_result)
except StopIteration:
break
if label == cur_label:
continue
else:
yield (cur_start, index), cur_label
cur_label = label
cur_start = index
yield (cur_start, len(self.input_sequence)), cur_label
def _generate_interval_labeler_class() -> Type[workflow.IntervalLabeler]:
class DerivedIntervalLabeler(workflow.IntervalLabeler):
pass
return DerivedIntervalLabeler
[docs]class BasicIntervalBasedOperation:
def __init__(self, intervals: workflow.IntervalListType):
# Labeler.
self.sequential_labeler_class = _generate_interval_labeler_class()
self.sequential_labeler_class.initialize_by_intervals(intervals)
# OutputGenerator.
self._output_generator_class = workflow.BasicOutputGenerator
self.initialize_output_generator_class()
# Workflow.
self.interval_based_workflow = self._generate_workflow()
[docs] def initialize_output_generator_class(self) -> None:
"""
Derived class should override this method by initializing ``self._output_generator_class``.
"""
raise NotImplementedError()
def _generate_workflow(self) -> workflow.BasicWorkflow:
return workflow.BasicWorkflow(
sequential_labeler_classes=[self.sequential_labeler_class],
label_processor_class=IntervalBasedOperationLabelProcessor,
output_generator_class=self._output_generator_class,
)
[docs]class IntervalsCollectionBasedOperation:
def __init__(self, intervals_collection: List[workflow.IntervalListType]):
# Labelers.
self.sequential_labeler_classes: List[Type[workflow.IntervalLabeler]] = []
for intervals in intervals_collection:
self.sequential_labeler_classes.append(_generate_interval_labeler_class())
self.sequential_labeler_classes[-1].initialize_by_intervals(intervals)
# OutputGenerator.
self._output_generator_class = workflow.BasicOutputGenerator
self.initialize_output_generator_class()
self._label_processor_class = workflow.BasicLabelProcessor
self.initialize_label_processor_class()
# Workflow.
self.interval_based_workflow = self._generate_workflow()
[docs] def initialize_label_processor_class(self) -> None:
"""
Derived class should override this method by initializing ``self._label_processor_class``.
"""
raise NotImplementedError()
[docs] def initialize_output_generator_class(self) -> None:
"""
Derived class should override this method by initializing ``self._output_generator_class``.
"""
raise NotImplementedError()
def _generate_workflow(self) -> workflow.BasicWorkflow:
return workflow.BasicWorkflow(
sequential_labeler_classes=self.sequential_labeler_classes,
label_processor_class=self._label_processor_class,
output_generator_class=self._output_generator_class,
)