class MorseNode:
def __init__(self,
char:str=None,
prob:float=0,
dit:'MorseNode'=None,
dah:'MorseNode'=None
):
self.char = char
self.prob = prob
self.dit = dit
self.dah = dah
def subtree_prob(self):
prob = self.prob
for d in (self.dit, self.dah):
if d is not None:
prob += d.subtree_prob()
return prob
def children_prob(self):
return self.subtree_prob() - self.prob
def is_leaf(self):
return self.dit is None and self.dah is None
def nodes(self):
nodes = [self]
for d in (self.dit, self.dah):
if d is not None:
nodes.extend(d.nodes())
return nodes
def chars(self):
return ''.join(
MorseNode.char for MorseNode in self.nodes() if MorseNode.char is not None)
def children_chars(self):
chars = ''
for d in (self.dit, self.dah):
if d is not None:
chars += d.chars()
return chars
def traverse(self, *seq):
if not len(seq):
return self
b, *seq = seq
d = self.dit if b else self.dah
# print(b, seq, d)
return MorseNode() if d is None else d.traverse(*seq)
def __repr__(self):
s = f'{self.char} {self.prob}'
for d in (self.dit, self.dah):
if d is not None:
s += f' {d.char}'
return s
def make_code(self, path=None):
"""return a mapping from characters to morse"""
code = {}
if path is None: path = tuple()
if self.char is not None:
code[self.char] = path
for d,b in ((self.dit, True), (self.dah, False)):
if d is not None:
code.update(d.make_code(path+(b,)))
return code
@classmethod
def make_tree(cls):
return MorseNode(
dit=MorseNode('e', 12.7,
dit=MorseNode('i', 7.0,
dit=MorseNode('s', 6.3,
dit=MorseNode('h', 6.1,
dit=MorseNode('5'),
dah=MorseNode('4'),
),
dah=MorseNode('v', 1.0,
# dit=MorseNode('ŝ'),
dah=MorseNode('3'),
),
),
dah=MorseNode('u', 2.8,
dit=MorseNode('f', 2.2,
dit=MorseNode('é'),
dah=MorseNode('4'),
),
dah=MorseNode(#'ü',
dit=MorseNode('ð',
dit=MorseNode('?')
),
dah=MorseNode('2'),
),
),
),
dah=MorseNode('a', 8.2,
dit=MorseNode('r', 6.0,
dit=MorseNode('l', 4.0,
# dit=MorseNode(),
dah=MorseNode(#'è',
dit=MorseNode('"')
),
),
dah=MorseNode('æ',
dit=MorseNode('+',
dah=MorseNode('.')
)
),
),
dah=MorseNode('w', 2.4,
dit=MorseNode('p', 1.9,
dit=MorseNode('þ'),
dah=MorseNode(#'à',
dit=MorseNode('@'),
),
),
dah=MorseNode('j', 0.2,
# dit=MorseNode('ĵ'),
dah=MorseNode('1',
dit=MorseNode("'")
),
),
),
),
),
dah=MorseNode('t', 9.1,
dit=MorseNode('n', 6.7,
dit=MorseNode('d', 4.3,
dit=MorseNode('b', 1.5,
dit=MorseNode('6',
dah=MorseNode('-')
),
dah=MorseNode('='),
),
dah=MorseNode('x', 0.2,
dit=MorseNode('/')
),
),
dah=MorseNode('k', 0.8,
dit=MorseNode('c', 2.8,
# dit=MorseNode('ç'),
dah=MorseNode(#empty MorseNode
dit=MorseNode(';'),
dah=MorseNode('!')
),
),
dah=MorseNode('y', 2.0,
dit=MorseNode('(',
dah=MorseNode(')')
)
),
),
),
dah=MorseNode('m', 2.4,
dit=MorseNode('g', 2.0,
dit=MorseNode('z', 0.1,
dit=MorseNode('7'),
dah=MorseNode(
dah=MorseNode(',')
),
),
dah=MorseNode('q', 0.1),
),
dah=MorseNode('o', 7.5,
dit=MorseNode('ö',
dit=MorseNode('8',
dit=MorseNode(':')
),
),
dah=MorseNode(
dit=MorseNode('9'),
dah=MorseNode('0')
),
),
),
)
)