ads2_2022/code/python/src/hirschberg/types.py

113 lines
3.6 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import annotations;
from src.thirdparty.types import *;
from src.thirdparty.maths import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'Alignment',
'AlignmentBasic',
'AlignmentPair',
];
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Class Alignments
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Alignment():
@property
def parts1(self) -> List[str]:
if isinstance(self, AlignmentBasic):
return [self.word1];
elif isinstance(self, AlignmentPair):
return self.left.parts1 + self.right.parts1;
return [];
@property
def parts2(self) -> List[str]:
if isinstance(self, AlignmentBasic):
return [self.word2];
elif isinstance(self, AlignmentPair):
return self.left.parts2 + self.right.parts2;
return [];
def astree(
self,
indent: str = ' ',
prefix: str = '',
braces: bool = False,
branch: str = ' └──── ',
) -> str:
return '\n'.join(list(self._astree_recursion(indent=indent, prefix=prefix, braces=braces, branch=branch)));
def _astree_recursion(
self,
depth: int = 0,
indent: str = ' ',
prefix: str = '',
braces: bool = False,
branch: str = ' └──── ',
branch_atom: str = '˚└──── ',
) -> Generator[str, None, None]:
word1 = self.as_string1(braces=braces);
word2 = self.as_string2(braces=braces);
if isinstance(self, AlignmentBasic):
u = prefix + branch_atom if depth > 0 else prefix;
yield f'{u}{word2}';
if depth == 0:
yield f'{" "*len(u)}{"-"*len(word1)}';
yield f'{" "*len(u)}{word1}';
elif isinstance(self, AlignmentPair):
u = prefix + branch if depth > 0 else prefix;
yield f'{u}{word2}';
if depth == 0:
yield f'{" "*len(u)}{"-"*len(word1)}';
yield f'{" "*len(u)}{word1}';
yield f'{indent}{prefix}';
yield from self.left._astree_recursion(
depth = depth + 1,
indent = indent,
prefix = indent + prefix,
braces = braces,
branch = branch,
);
yield f'{indent}{prefix}';
yield from self.right._astree_recursion(
depth = depth + 1,
indent = indent,
prefix = indent + prefix,
braces = braces,
branch = branch,
);
return;
def as_string1(self, braces: bool = False) -> Tuple[str, str]:
if braces:
return f'({")(".join(self.parts1)})';
return ''.join(self.parts1);
def as_string2(self, braces: bool = False,) -> Tuple[str, str]:
if braces:
return f'({")(".join(self.parts2)})';
return ''.join(self.parts2);
@dataclass
class AlignmentBasic(Alignment):
word1: str = field();
word2: str = field();
@dataclass
class AlignmentPair(Alignment):
left: Alignment = field();
right: Alignment = field();