801 lines
37 KiB
Python
801 lines
37 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Created on Mon Apr 24 14:26:02 2023
|
|
|
|
@author: Edward Middleton-Smith
|
|
|
|
Braille 3D Model Product Creation
|
|
|
|
Braille Dictionary Conversion / Creation
|
|
Plaintext message translation into Braille for 3D modelling
|
|
"""
|
|
|
|
# CLASSES
|
|
# ATTRIBUTE DECLARATION
|
|
# METHODS
|
|
# FUNCTION
|
|
# ARGUMENTS
|
|
# ARGUMENT VALIDATION
|
|
# ATTRIBUTE + VARIABLE INSTANTIATION
|
|
# METHODS
|
|
# RETURNS
|
|
|
|
# NORMAL METHODS
|
|
# FUNCTION
|
|
# ARGUMENTS
|
|
# ARGUMENT VALIDATION
|
|
# VARIABLE INSTANTIATION
|
|
# METHODS
|
|
# RETURNS
|
|
|
|
|
|
import pandas as pd
|
|
from typing import Optional
|
|
from enum import Enum
|
|
import argument_validation as av
|
|
import sys
|
|
|
|
class difficulty(Enum):
|
|
ALPHABETPUNCTUATION = 1
|
|
SIMPLEWORDGROUPSIGNS = 2
|
|
LOWERCONTRACTIONS = 3
|
|
def mini():
|
|
# FUNCTION
|
|
# Get minimum value in enumerator
|
|
# RETURNS
|
|
return min([e.value for e in difficulty])
|
|
def maxi():
|
|
# FUNCTION
|
|
# Get maximum value in enumerator
|
|
# RETURNS
|
|
return max([e.value for e in difficulty])
|
|
|
|
class braille_trans():
|
|
# ATTRIBUTE DECLARATION
|
|
key: str # search key in input messages for Braille translation - includes additional characters for literal processing
|
|
level: difficulty # stage of learning at which this translation is discovered
|
|
braille: list # list[list[int]] # Braille translation of plaintext
|
|
plaintext: str # English plaintext key
|
|
# METHODS
|
|
# def argvalinit(key: str, level: difficulty, braille: list, plaintext: Optional[str] = None):
|
|
# # run before instantiating braille_trans
|
|
# # av.val_list(braille, 'list')=
|
|
# # _m = 'braille_trans.argvalinit'
|
|
# # if not av.val_str(key, 'key', method, min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument')
|
|
# if not (av.val_str(key) and (str(type(level)) == "<enum 'difficulty'>" or av.val_int(level, difficulty.mini(), difficulty.maxi())) and av.val_list(braille, "<class 'list'>") and (av.val_str(plaintext, -1, -1, True) or plaintext == None)):
|
|
# print(f'Invalid braille_trans instantiation. key = {key}, level = {level}, braille = {braille}, plaintext = {plaintext}')
|
|
# return None
|
|
# return braille_trans(key, level, braille, plaintext)
|
|
|
|
def __new__(cls, key: str, level: difficulty, braille: list, plaintext: Optional[str] = None):
|
|
# FUNCTION
|
|
# Initialise class object
|
|
# ARGUMENTS
|
|
# str key
|
|
# difficulty level
|
|
# list[list[int]] braille
|
|
# optional str plaintext
|
|
# VARIABLE DECLARATION
|
|
_m = 'braille_trans.__new__'
|
|
v_arg_type = 'class attribute'
|
|
# ARGUMENT VALIDATION
|
|
av.val_str(key, 'key', _m, 1, -1, v_arg_type = v_arg_type)
|
|
av.val_type(level, "<enum 'difficulty'>", 'level', _m, v_arg_type = v_arg_type)
|
|
av.val_nested_list(braille, 0, 1, 'braille', _m, "<class 'int'>", -1, [-1, 6], -1, [-1, 6], v_arg_type = v_arg_type)
|
|
if not (av.val_str(plaintext, 'plaintext', _m, -1, -1, True, True, v_arg_type) or str(type(plaintext)) == "<class 'NoneType'>"):
|
|
raise ValueError(av.error_msg_str(_m, 'plaintext', plaintext, "<class 'str'>", v_arg_type = v_arg_type))
|
|
# if not av.val_str(key):
|
|
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'key', key, 'attribute'))
|
|
# if not av.val_type(level, "<enum 'difficulty'>"):
|
|
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'level', level, 'attribute'))
|
|
# if not av.val_nested_list(braille, 0, 2, "<class 'int'>", 6, [1, 6], 6, [-1, 6]):
|
|
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'braille', braille, 'attribute'))
|
|
# if not (av.val_str(plaintext) or str(type(plaintext)) == "<class 'NoneType'>"):
|
|
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'plaintext', plaintext, 'attribute'))
|
|
# RETURNS
|
|
return super(braille_trans, cls).__new__(cls)
|
|
|
|
def __init__(self, key: str, level: difficulty, braille: list, plaintext: Optional[str] = None):
|
|
# FUNCTION
|
|
# Construct class object
|
|
# ARGUMENTS
|
|
# str key
|
|
# difficulty level
|
|
# list[list[int]] braille
|
|
# optional str plaintext
|
|
# ARGUMENT VALIDATION
|
|
# see __new__()
|
|
# ATTRIBUTE + VARIABLE INSTANTIATION
|
|
self.key = key
|
|
self.level = level
|
|
self.braille = braille
|
|
self.plaintext = self.key if (plaintext is None) else plaintext
|
|
|
|
def __repr__(self):
|
|
return f"key = {self.key}, level = {self.level}, braille = {self.braille}, plaintext = {self.plaintext}"
|
|
|
|
# def query_lvl(self):
|
|
# return ' & '.join(["{}=='{}'".format(key, value)
|
|
# for key, value in self.__dict__.items()
|
|
# if not value is None])
|
|
|
|
def as_dict(self):
|
|
return {'key': self.key, 'level': self.level, 'braille': self.braille, 'plaintext': self.plaintext}
|
|
|
|
class product():
|
|
# ATTRIBUTE DECLARATION
|
|
name: str
|
|
line_length: int # number of Braille characters per line on keyboard
|
|
msg: str # pre-translated English (with necessary modifications for input to this programme e.g. splitting up undesired translations with hidden delimiter character @?NOTHING)
|
|
msg_prefix: str # additional pre-translated str as above to pre-append to product for adding header to creation of product messages from dictionary queries
|
|
filename: str # filename - name without spaces
|
|
# METHODS
|
|
# def argvalinit(name: str, line_length: int, msg: str, msg_prefix: Optional[str] = ''):
|
|
# # run before instantiating product
|
|
# if not (av.val_str(name) and av.val_int(line_length, 0) and av.val_str(msg) and av.val_str(msg_prefix)):
|
|
# print(f'Invalid product instantiation. name = {name}, line_length = {line_length}, msg = {msg}, msg_prefix = {msg_prefix}')
|
|
# return None
|
|
# return product(name, line_length, msg, msg_prefix)
|
|
|
|
def __new__(cls, name, line_length, msg, msg_prefix = ''):
|
|
# FUNCTION
|
|
# Initialise class object
|
|
# ARGUMENTS
|
|
# str name
|
|
# int line_length
|
|
# str msg
|
|
# str msg_prefix
|
|
# ARGUMENT VALIDATION
|
|
_m = 'product.__new__'
|
|
v_arg_type = 'class attribute'
|
|
av.val_str(name, 'name', _m, 1, -1, v_arg_type = v_arg_type)
|
|
av.val_int(line_length, 'line_length', _m, 1, v_arg_type = v_arg_type)
|
|
av.val_str(msg, 'msg', _m, -1, -1, v_arg_type = v_arg_type)
|
|
av.val_str(msg_prefix, 'msg_prefix', _m, -1, -1, v_arg_type = v_arg_type)
|
|
# if not av.val_str(name):
|
|
# raise ValueError(av.error_msg_str('product.__new__', 'name', name, 'attribute'))
|
|
# if not av.val_int(line_length, 1):
|
|
# raise ValueError(av.error_msg_str('product.__new__', 'line_length', line_length, 'attribute'))
|
|
# if not av.val_str(msg):
|
|
# raise ValueError(av.error_msg_str('product.__new__', 'msg', msg, 'attribute'))
|
|
# if not av.val_str(msg_prefix):
|
|
# raise ValueError(av.error_msg_str('product.__new__', 'msg_prefix', msg_prefix, 'attribute'))
|
|
# RETURNS
|
|
return super(product, cls).__new__(cls)
|
|
|
|
def __init__(self, name: str, line_length: int, msg: str, msg_prefix: Optional[str] = ''):
|
|
# FUNCTION
|
|
# Construct class object
|
|
# ARGUMENTS
|
|
# str name
|
|
# int line_length
|
|
# str msg
|
|
# str msg_prefix
|
|
# ARGUMENT VALIDATION
|
|
# see __new__()
|
|
# ATTRIBUTE + VARIABLE INSTANTIATION
|
|
self.name = name
|
|
self.line_length = line_length
|
|
self.msg = msg
|
|
self.msg_prefix = msg_prefix # for procedurally-generated messages from difficulty selection
|
|
self.filename = name.replace(' ', '_')
|
|
|
|
def __repr__(self):
|
|
return f"name = {self.name}, line_length = {self.line_length}, msg = {self.msg}, msg_prefix = {self.msg_prefix}, filename = {self.filename}"
|
|
|
|
def get_braille_translations():
|
|
# FUNCTION
|
|
# return list of braille translations
|
|
# longer keys get priority in translation
|
|
# VARIABLE INSTANTIATION
|
|
temp_dict = [braille_trans("A", difficulty(1), [[1, 0, 0, 0, 0, 0]]),
|
|
braille_trans("B", difficulty(1), [[1, 1, 0, 0, 0, 0]]),
|
|
braille_trans("C", difficulty(1), [[1, 0, 0, 1, 0, 0]]),
|
|
braille_trans("D", difficulty(1), [[1, 0, 0, 1, 1, 0]]),
|
|
braille_trans("E", difficulty(1), [[1, 0, 0, 0, 1, 0]]),
|
|
braille_trans("F", difficulty(1), [[1, 1, 0, 1, 0, 0]]),
|
|
braille_trans("G", difficulty(1), [[1, 1, 0, 1, 1, 0]]),
|
|
braille_trans("H", difficulty(1), [[1, 1, 0, 0, 1, 0]]),
|
|
braille_trans("I", difficulty(1), [[0, 1, 0, 1, 0, 0]]),
|
|
braille_trans("J", difficulty(1), [[0, 1, 0, 1, 1, 0]]),
|
|
braille_trans("K", difficulty(1), [[1, 0, 1, 0, 0, 0]]),
|
|
braille_trans("L", difficulty(1), [[1, 1, 1, 0, 0, 0]]),
|
|
braille_trans("M", difficulty(1), [[1, 0, 1, 1, 0, 0]]),
|
|
braille_trans("N", difficulty(1), [[1, 0, 1, 1, 1, 0]]),
|
|
braille_trans("O", difficulty(1), [[1, 0, 1, 0, 1, 0]]),
|
|
braille_trans("P", difficulty(1), [[1, 1, 1, 1, 0, 0]]),
|
|
braille_trans("Q", difficulty(1), [[1, 1, 1, 1, 1, 0]]),
|
|
braille_trans("R", difficulty(1), [[1, 1, 1, 0, 1, 0]]),
|
|
braille_trans("S", difficulty(1), [[0, 1, 1, 1, 0, 0]]),
|
|
braille_trans("T", difficulty(1), [[0, 1, 1, 1, 1, 0]]),
|
|
braille_trans("U", difficulty(1), [[1, 0, 1, 0, 0, 1]]),
|
|
braille_trans("V", difficulty(1), [[1, 1, 1, 0, 0, 1]]),
|
|
braille_trans("W", difficulty(1), [[0, 1, 0, 1, 1, 1]]),
|
|
braille_trans("X", difficulty(1), [[1, 0, 1, 1, 0, 1]]),
|
|
braille_trans("Y", difficulty(1), [[1, 0, 1, 1, 1, 1]]),
|
|
braille_trans("Z", difficulty(1), [[1, 0, 1, 0, 1, 1]]),
|
|
braille_trans("@?NUM", difficulty(1), [[0, 0, 1, 1, 1, 1]], 'NUMBER'),
|
|
#" ", difficulty(1), [[0, 0, 0, 0, 0, 0]]),
|
|
braille_trans(",", difficulty(1), [[0, 1, 0, 0, 0, 0]]),
|
|
braille_trans(";", difficulty(1), [[0, 1, 1, 0, 0, 0]]),
|
|
braille_trans(":", difficulty(1), [[0, 1, 0, 0, 1, 0]]),
|
|
braille_trans(".", difficulty(1), [[0, 1, 0, 0, 1, 1]]),
|
|
braille_trans("!", difficulty(1), [[0, 1, 1, 0, 1, 0]]),
|
|
braille_trans("(", difficulty(1), [[0, 1, 1, 0, 1, 1]]),
|
|
braille_trans(")", difficulty(1), [[0, 1, 1, 0, 1, 1]]),
|
|
braille_trans("?", difficulty(1), [[0, 1, 1, 0, 0, 1]]),
|
|
braille_trans('"@?BO', difficulty(1), [[0, 1, 1, 0, 0, 1]], '"'),
|
|
braille_trans('"@?BC', difficulty(1), [[0, 0, 1, 0, 1, 1]], '"'),
|
|
braille_trans("'", difficulty(1), [[0, 0, 1, 0, 0, 0]]),
|
|
braille_trans("@?ABBREV1", difficulty(1), [[0, 0, 0, 1, 0, 0]], "ABBREV"),
|
|
braille_trans("@?ABBREV2", difficulty(1), [[0, 0, 0, 1, 1, 0]], "ABBREV"),
|
|
braille_trans("@?ABBREV3", difficulty(1), [[0, 0, 0, 1, 1, 1]], "ABBREV"),
|
|
braille_trans("@?ABBREV4", difficulty(1), [[0, 0, 0, 0, 1, 0]], "ABBREV"),
|
|
braille_trans("...", difficulty(1), [[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0]]),
|
|
braille_trans("-", difficulty(1), [[0, 0, 1, 0, 0, 1]]),
|
|
braille_trans("-@?S", difficulty(1), [[0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1]], "-"),
|
|
braille_trans("-@?L", difficulty(1), [[0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1]], "-"),
|
|
braille_trans("/@?B", difficulty(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "/"),
|
|
braille_trans("\@?B", difficulty(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "\\"),
|
|
braille_trans("[@?BPH", difficulty(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "["),
|
|
braille_trans("]@?BPH", difficulty(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "]"),
|
|
braille_trans("<", difficulty(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]]),
|
|
braille_trans(">", difficulty(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]]),
|
|
braille_trans("/", difficulty(1), [[0, 0, 0, 1, 1, 1], [0, 0, 1, 1, 0, 0]]),
|
|
braille_trans("{", difficulty(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]]),
|
|
braille_trans("}", difficulty(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]]),
|
|
braille_trans("[@?BSQ", difficulty(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 1]], "["),
|
|
braille_trans("]@?BSQ", difficulty(1), [[0, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1]], "]"),
|
|
braille_trans("'@?BO", difficulty(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 0, 1]], "'"),
|
|
braille_trans("'@?BC", difficulty(1), [[0, 1, 1, 0, 0, 1], [0, 0, 0, 0, 0, 1]], "'"),
|
|
# oldbrailledict_2 = {
|
|
# Simple Upper Wordsigns
|
|
braille_trans("BUT", difficulty(2), [[1, 1, 0, 0, 0, 0]]),
|
|
braille_trans("CAN", difficulty(2), [[1, 0, 0, 1, 0, 0]]),
|
|
braille_trans("DO", difficulty(2), [[1, 0, 0, 1, 1, 0]]),
|
|
braille_trans("EVERY", difficulty(2), [[1, 0, 0, 0, 1, 0]]),
|
|
braille_trans("FROM", difficulty(2), [[1, 1, 0, 1, 0, 0]]),
|
|
braille_trans("GO", difficulty(2), [[1, 1, 0, 1, 1, 0]]),
|
|
braille_trans("HAVE", difficulty(2), [[1, 1, 0, 0, 1, 0]]),
|
|
braille_trans("JUST", difficulty(2), [[0, 1, 0, 1, 1, 0]]),
|
|
braille_trans("KNOWLEDGE", difficulty(2), [[1, 0, 1, 0, 0, 0]]),
|
|
braille_trans("LIKE", difficulty(2), [[1, 1, 1, 0, 0, 0]]),
|
|
braille_trans("MORE", difficulty(2), [[1, 0, 1, 1, 0, 0]]),
|
|
braille_trans("NOT", difficulty(2), [[1, 0, 1, 1, 1, 0]]),
|
|
braille_trans("PEOPLE", difficulty(2), [[1, 1, 1, 1, 0, 0]]),
|
|
braille_trans("QUITE", difficulty(2), [[1, 1, 1, 1, 1, 0]]),
|
|
braille_trans("RATHER", difficulty(2), [[1, 1, 1, 0, 1, 0]]),
|
|
braille_trans("SO", difficulty(2), [[0, 1, 1, 1, 0, 0]]),
|
|
braille_trans("THAT", difficulty(2), [[0, 1, 1, 1, 1, 0]]),
|
|
braille_trans("US", difficulty(2), [[1, 0, 1, 0, 0, 1]]),
|
|
braille_trans("VERY", difficulty(2), [[1, 1, 1, 0, 0, 1]]),
|
|
braille_trans("WILL", difficulty(2), [[0, 1, 0, 1, 1, 1]]),
|
|
braille_trans("IT", difficulty(2), [[1, 0, 1, 1, 0, 1]]),
|
|
braille_trans("YOU", difficulty(2), [[1, 0, 1, 1, 1, 1]]),
|
|
braille_trans("AS", difficulty(2), [[1, 0, 1, 0, 1, 1]]),
|
|
braille_trans("CHILD", difficulty(2), [[1, 0, 0, 0, 0, 1]]),
|
|
braille_trans("SHALL", difficulty(2), [[1, 0, 0, 1, 0, 1]]),
|
|
braille_trans("THIS", difficulty(2), [[1, 0, 0, 1, 1, 1]]),
|
|
braille_trans("WHICH", difficulty(2), [[1, 0, 0, 0, 1, 1]]),
|
|
braille_trans("OUT", difficulty(2), [[1, 1, 0, 0, 1, 1]]),
|
|
braille_trans("STILL", difficulty(2), [[0, 0, 1, 1, 0, 0]]),
|
|
# Simple Upper Groupsigns
|
|
braille_trans("AND", difficulty(2), [[1, 1, 1, 1, 0, 1]]),
|
|
braille_trans("FOR", difficulty(2), [[1, 1, 1, 1, 1, 1]]),
|
|
braille_trans("OF", difficulty(2), [[1, 1, 1, 0, 1, 1]]),
|
|
braille_trans("THE", difficulty(2), [[0, 1, 1, 1, 0, 1]]),
|
|
braille_trans("WITH", difficulty(2), [[0, 1, 1, 1, 1, 1]]),
|
|
braille_trans("CH", difficulty(2), [[1, 0, 0, 0, 0, 1]]),
|
|
braille_trans("GH", difficulty(2), [[1, 1, 0, 0, 0, 1]]),
|
|
braille_trans("SH", difficulty(2), [[1, 0, 0, 1, 0, 1]]),
|
|
braille_trans("TH", difficulty(2), [[1, 0, 0, 1, 1, 1]]),
|
|
braille_trans("WH", difficulty(2), [[1, 0, 0, 0, 1, 1]]),
|
|
braille_trans("ED", difficulty(2), [[1, 1, 0, 1, 0, 1]]),
|
|
braille_trans("ER", difficulty(2), [[1, 1, 0, 1, 1, 1]]),
|
|
braille_trans("OU", difficulty(2), [[1, 1, 0, 0, 1, 1]]),
|
|
braille_trans("OW", difficulty(2), [[0, 1, 0, 1, 0, 1]]),
|
|
braille_trans("ST", difficulty(2), [[0, 0, 1, 1, 0, 0]]),
|
|
braille_trans("AR", difficulty(2), [[0, 0, 1, 1, 1, 0]]),
|
|
braille_trans("ING", difficulty(2), [[0, 0, 1, 1, 0, 1]]),
|
|
braille_trans("BLE", difficulty(2), [[0, 0, 1, 1, 1, 1]]),
|
|
# oldbrailledict_3 = {
|
|
# Lower Contractions
|
|
# Initial Groupsigns
|
|
braille_trans("BE", difficulty(3), [[0, 1, 1, 0, 0, 0]]),
|
|
braille_trans("COM", difficulty(3), [[0, 0, 1, 0, 0, 1]]),
|
|
braille_trans("CON", difficulty(3), [[0, 1, 0, 0, 1, 0]]),
|
|
braille_trans("DIS", difficulty(3), [[0, 1, 0, 0, 1, 1]]),
|
|
# Initial-Medial-Terminal Groupsigns
|
|
braille_trans("EN", difficulty(3), [[0, 1, 0, 0, 0, 1]]),
|
|
braille_trans("IN", difficulty(3), [[0, 0, 1, 0, 1, 0]]),
|
|
# Medial Groupsigns
|
|
braille_trans("EA", difficulty(3), [[0, 1, 0, 0, 0, 0]]),
|
|
braille_trans("BB", difficulty(3), [[0, 1, 1, 0, 0, 0]]),
|
|
braille_trans("CC", difficulty(3), [[0, 1, 0, 0, 1, 0]]),
|
|
braille_trans("DD", difficulty(3), [[0, 1, 0, 0, 1, 1]]),
|
|
braille_trans("FF", difficulty(3), [[0, 1, 1, 0, 1, 0]]),
|
|
braille_trans("GG", difficulty(3), [[0, 1, 1, 0, 1, 1]]),
|
|
# Wordsigns
|
|
braille_trans("ENOUGH", difficulty(3), [[0, 1, 0, 0, 0, 1]]),
|
|
braille_trans("TO", difficulty(3), [[0, 1, 1, 0, 1, 0]]),
|
|
braille_trans("WERE", difficulty(3), [[0, 1, 1, 0 , 1, 1]]),
|
|
braille_trans("HIS", difficulty(3), [[0, 1, 1, 0, 0, 1]]),
|
|
braille_trans("INTO", difficulty(3), [[0, 0, 1, 0, 1, 0], [0, 1, 1, 0, 1, 0]]), #(sequenced)
|
|
braille_trans("BY", difficulty(3), [[0, 0, 1, 0, 1, 1]]), #(sequenced)
|
|
braille_trans("WAS", difficulty(3), [[0, 0 , 1, 0 , 1, 1]]),
|
|
|
|
# Modifiers
|
|
braille_trans("@?LET", difficulty(3), [[0, 0, 0, 0, 1, 1]], "LET"),
|
|
braille_trans("@?CAPS", difficulty(3), [[0, 0, 0, 0, 0, 1]], "CAPS"),
|
|
braille_trans("@?EMPH", difficulty(3), [[0, 0, 0, 1, 0, 1]], "EMPH"),
|
|
]
|
|
# remove None 's - rejected inputs
|
|
valid = False
|
|
while not valid:
|
|
try:
|
|
temp_dict.remove(None)
|
|
except:
|
|
valid = True
|
|
braille_dict = pd.DataFrame([x.as_dict() for x in temp_dict]) # , columns=['key', 'level', 'msg', 'msg_prefix'])
|
|
# RETURNS
|
|
# print('Braille Dictionary Creation')
|
|
# print(f"type(temp_dict) = {type(temp_dict)}")
|
|
# print("temp_dict = ")
|
|
# for i in range(len(temp_dict)):
|
|
# print(f"{temp_dict[i]}")
|
|
# print('')
|
|
# print(f"type(braille_dict) = {type(braille_dict)}")
|
|
# print(f"braille_dict = {braille_dict}")
|
|
|
|
return braille_dict # temp_dict # braille_dict
|
|
|
|
def get_delimiters():
|
|
# FUNCTION
|
|
# delimiters and special character codes for plaintext message before braille translation
|
|
# VARIABLE INSTANTIATION
|
|
txtdict = {"@?NUM" : "NUMBER",
|
|
"@?NOTHING" : "",
|
|
#" " : "",
|
|
'"@?BO' : '"',
|
|
'"@?BC' : '"',
|
|
"-@?S" : "-",
|
|
"-@?L" : "-",
|
|
"/@?B" : "/",
|
|
"[@?BPH" : "[",
|
|
"]@?BPH" : "]",
|
|
"[@?BSQ" : "[",
|
|
"]@?BSQ" : "]",
|
|
"'@?BO" : "'",
|
|
"'@?BC" : "'",
|
|
"@?LET" : "LET",
|
|
"@?CAPS" : "CAPS",
|
|
"@?EMPH" : "EMPH",
|
|
"@?ABBREV1" : "ABBREV",
|
|
"@?ABBREV2" : "ABBREV",
|
|
"@?ABBREV3" : "ABBREV",
|
|
"@?ABBREV4" : "ABBREV",
|
|
}
|
|
# RETURNS
|
|
return txtdict
|
|
|
|
def gen_difficulty_msgstr(braille_dict, level: difficulty = difficulty(1)):
|
|
# FUNCTION
|
|
# generate keyboard message for specified difficulty
|
|
# ARGUMENTS
|
|
# list[braille_trans] braille_dict
|
|
# difficulty level
|
|
# ARGUMENT VALIDATION
|
|
_m = 'gen_difficulty_msgstr'
|
|
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', _m)
|
|
av.val_type(level, "<enum 'difficulty'>", 'level', _m)
|
|
# VARIABLE INSTANTIATION
|
|
str_out = ''
|
|
# n = len(braille_dict)
|
|
# METHODS
|
|
# print(f"len(braille_dict) = {n}")
|
|
# print(f"braille_dict.columns =")
|
|
# for i in braille_dict.columns:
|
|
# print(braille_dict.columns[i])
|
|
# temp_dict = braille_dict['key']
|
|
dict_iterator = braille_dict[braille_dict['level'] == level]
|
|
print(f"dict_iterator.index = {dict_iterator.index}")
|
|
for bd_i in range(len(dict_iterator.index)):
|
|
bd_n = dict_iterator['key'][dict_iterator.index[bd_i]]
|
|
# print(f"bd_i = {bd_i}")
|
|
# print(f"bd_n = {bd_n}")
|
|
str_out += "@?NOTHING" + bd_n
|
|
# for i in range(n):
|
|
# bd_i = braille_dict.loc[i][0]
|
|
# # print(f"bd_i = {bd_i}")
|
|
# # print(f"type(bd_i) = {str(type(bd_i))}")
|
|
# if (bd_i.level == difficulty):
|
|
# str_out += "@?NOTHING" + bd_i.key
|
|
# RETURNS
|
|
return str_out
|
|
|
|
# def get_braille_by_key(braille_dict: pd.DataFrame, key: str):
|
|
# # FUNCTION
|
|
# # Find key in braille dictionary
|
|
# return None
|
|
# # ARGUMENTS
|
|
# # ARGUMENT VALIDATION
|
|
# # VARIABLE INSTANTIATION
|
|
# # METHODS
|
|
# # RETURNS
|
|
|
|
|
|
def input_product(braille_dict, products, my_option: Optional[int] = -1, my_select: Optional[str] = ''):
|
|
# FUNCTION
|
|
# Get product input from user - repeat until valid input received
|
|
# ARGUMENTS
|
|
# list[braille_trans] braile_dict
|
|
# list[product] products
|
|
# optional int my_option - if option provided in code
|
|
# ARGUMENT VALIDATION
|
|
_m = 'input_product'
|
|
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', _m)
|
|
av.val_list(products, 'products', _m, "<class 'translate_msg_2_braille.product'>", 1)
|
|
av.val_int(my_option, 'my_option', _m)
|
|
# VARIABLE INSTANTIATION
|
|
N = len(products)
|
|
select_i = my_option
|
|
valid = (my_option > 0 and my_option <= N)
|
|
# temp_dict = braille_dict['key']
|
|
# METHODS
|
|
if valid:
|
|
if my_option == N:
|
|
temp = braille_dict[braille_dict['key'] == my_select]
|
|
if len(temp.index) == 1:
|
|
products[N - 1].msg_prefix = my_select
|
|
else:
|
|
valid = False
|
|
while not valid:
|
|
print()
|
|
print('Welcome to your 3D Braille Model Generator')
|
|
print("At any time, answer the following error code to exit (excl. speech marks): '#!ERRORCODE!#'")
|
|
print()
|
|
print('Braille Products:')
|
|
for i in range(N):
|
|
print(f"{i + 1}. {products[i].name}")
|
|
print()
|
|
select_i = av.input_int(input(f"Please enter your selection (1 - {N}) from the products above\n"), 1, N)
|
|
if select_i == '#!ERRORCODE!#':
|
|
sys.exit
|
|
valid = not (str(type(select_i)) == "<class 'NoneType'>")
|
|
if valid and select_i == N:
|
|
valid = False
|
|
while not valid:
|
|
select_A = input("Please enter a character selection for your Scrabble tile\n")
|
|
if select_A == '#!ERRORCODE!#':
|
|
sys.exit
|
|
temp = braille_dict[braille_dict['key'] == select_A].index
|
|
if not len(temp) == 1:
|
|
print(f"temp = {temp}")
|
|
valid = False
|
|
else:
|
|
valid = True
|
|
products[N - 1].msg_prefix = select_A
|
|
# RETURNS
|
|
return products[select_i - 1]
|
|
|
|
def append_ifnotNone(v_list, v_item):
|
|
# FUNCTION
|
|
# append v_item to v_list if v_item is not None
|
|
# ARGUMENTS
|
|
# list v_list
|
|
# v_item
|
|
# ARGUMENT VALIDATION
|
|
if (not av.val_list(v_list, 'v_list', 'append_ifnotNone', suppress_errors = True)) or v_item == None:
|
|
# RETURNS
|
|
return v_list
|
|
v_list.append(v_item)
|
|
return v_list#.append(v_item)
|
|
|
|
|
|
def gen_product_inputs(braille_dict):
|
|
# FUNCTION
|
|
# Generate product inputs
|
|
# ARGUMENTS
|
|
# [pandas.DataFrame] braille_dict - braille dictionary
|
|
# VARIABLE INSTANTIATION
|
|
products = []
|
|
# ARGUMENT VALIDATION
|
|
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', 'gen_product_inputs')
|
|
# METHODS
|
|
products.append(product("Extended Alphabet", 10, "abcdefg@?NOTHINGhijKLMNOPQRS@?NOTHINGTUVXYZANDFOROFTHEWITHCHGHSHTHWHEDEROUOWWEABBCCDDENFF?GGINBY"))
|
|
products.append(product("Upper Groupsigns", 10, "uppe@?nothingr GRO@?NOTHINGUPSIGNsand:a@?nothingn@?nothingd for:fo@?nothingr of:o@?nothingf the:t@?nothingh@?nothinge with:wi@?nothingt@?nothingh "+"@?NEWLINECH:C@?NOTHINGH " + "GH:G@?NOTHINGH " + "SH:S@?NOTHINGH " + "TH:T@?NOTHINGH " + "WH:W@?NOTHINGH " + "ED:E@?NOTHINGD " + "ER:E@?NOTHINGR " + "OU:O@?NOTHINGU " + "OW:O@?NOTHINGW "+"st:s@?nothingt ar:a@?nothingr ble:bl@?nothinge ing:i@?nothingng"))
|
|
products.append(product("Upper Wordsigns", 24, gen_difficulty_msgstr(braille_dict, difficulty(3))))
|
|
products.append(product("Alphabet", 10, "ABCDEFG@?NOTHINGHIJKLMNOPQRSTUVWXYZ"))
|
|
products.append(product("Travel", 5, "ABCDEFG@?NOTHINGHIJ"))
|
|
products.append(product("Scrabble Alphabet of Tiles", 1, ''))
|
|
products.append(product("Scrabble Character Tile", 1, ''))
|
|
# RETURNS
|
|
return products
|
|
|
|
def gen_braille_inputs_4_openscad(msgin, line_length, brailledict): # , hyphenate = False
|
|
# FUNCTION
|
|
# Convert message to Braille for openSCAD generation
|
|
# ARGUMENTS
|
|
# str msgin - partially translated message containing only brailledict keys and blankspace
|
|
# int line_length - number of Braille characters per row on keyboard
|
|
# pandas.DataFrame brailledict - Braille translations with diffculty
|
|
# # bool hyphenate - hyphenate words that cross lines or start on new line
|
|
# ARGUMENT VALIDATION
|
|
_m = 'gen_braille_inputs_4_openscad'
|
|
av.val_str(msgin, 'msgin', _m, 1)
|
|
av.val_int(line_length, 'line_length', _m)
|
|
av.val_type(brailledict, "<class 'pandas.core.frame.DataFrame'>", 'brailledict', _m)
|
|
# VARIABLE INSTANTIATION
|
|
# dict txtdict - delimiters for Braille translation
|
|
msgin = msgin.upper()
|
|
braille = []
|
|
letters = ["", ]
|
|
n_rows = 1
|
|
start_of_word = 0 # position within cum
|
|
numbers = []
|
|
cum = [0] # 0-based cumulative starting position of Braille translation of message segments
|
|
#lmsg = [0] * len(msgin) # length of braille message
|
|
last_is_num = False
|
|
new_word = True
|
|
iter_lim = len(msgin)
|
|
print(f"iteration limit = {iter_lim}") #len(msgin))
|
|
msg_i_0 = -1
|
|
maxstrlen = max_key_len(brailledict)
|
|
# METHODS
|
|
print(f"msgin = {msgin}")
|
|
while (msg_i_0 < iter_lim):
|
|
msg_i_0 = msg_i_0 + 1
|
|
found = False
|
|
print(f"msg_i_0 = {msg_i_0}")
|
|
for phrase_len in range(min(len(msgin) - msg_i_0, maxstrlen), 0, -1):
|
|
if found:
|
|
continue
|
|
phrase = msgin[msg_i_0 : msg_i_0 + phrase_len] # message segment to search for in Braille translation keys
|
|
print(f'phrase = {phrase}')
|
|
|
|
# generate braille if a code has been found
|
|
if (phrase_len == 0):
|
|
if (ord(phrase) >= 48 and ord(phrase) <= 57): # numbers
|
|
b_num_pre = brailledict[brailledict['key'] == "@?NUM"]['braille'].values[0]
|
|
b_num = brailledict[brailledict['key'] == ("J" if (ord(phrase) == 48) else chr(ord(phrase)+16))]['braille'].values[0]
|
|
if last_is_num == True:
|
|
braille[len(braille) - 1].append(b_num[0])
|
|
new_cum = 1
|
|
# temp = temp2
|
|
else:
|
|
braille.append([b_num_pre[0], b_num[0]])
|
|
new_cum = 2
|
|
# temp = [temp1[0], temp2[0]]
|
|
print('braille(numeric phrase) = ', braille[len(braille) - 1])
|
|
last_is_num = True
|
|
else:
|
|
# new_cum = len(brailledict[brailledict['key'] == phrase].index)
|
|
found = (len(brailledict[brailledict['key'] == phrase].index) == 1)
|
|
if found:
|
|
last_is_num = False
|
|
# temp = brailledict.get(phrase)
|
|
else:
|
|
# new_cum = len(brailledict[brailledict['key'] == phrase].index)
|
|
found = (len(brailledict[brailledict['key'] == phrase].index) == 1)
|
|
if found:
|
|
last_is_num = False
|
|
# temp = brailledict.get(phrase)
|
|
#print("tempsearch = ", temp)
|
|
|
|
# organise placement of braille phrase onto end of whole message
|
|
if found or last_is_num: # (temp != None): #
|
|
# found = True
|
|
# last_is_num = False
|
|
new_num = [-1]
|
|
if (len(phrase) == 1):
|
|
if (ord(phrase) >= 65 and ord(phrase) <= 90): # letters
|
|
new_num = [ord(phrase) - 64]
|
|
elif (ord(phrase) >= 48 and ord(phrase) <= 57): # numbers
|
|
new_num = [ord(phrase) - 48]
|
|
# last_is_num = True
|
|
if found:
|
|
braille.append(brailledict[brailledict['key'] == phrase]['braille'].values[0])
|
|
new_cum = len(braille[len(braille) - 1])
|
|
numbers.append(new_num)
|
|
new_cum = cum[len(cum) - 1] + new_cum
|
|
cum.append(new_cum)
|
|
n_rows_0 = n_lines_at_pos(start_of_word, line_length)
|
|
n_rows_next = n_lines_at_pos(new_cum, line_length)
|
|
if (n_rows_0 < n_rows_next and not n_rows_0 % line_length == 0):
|
|
delta_cum_new_line = n_rows_next * line_length + 1 - cum[start_of_word]
|
|
for msg_j in range(len(cum) - start_of_word - 1):
|
|
cum[start_of_word + msg_j] += delta_cum_new_line
|
|
#if (cum[len(cum)-1] % line_length > 0):
|
|
# cum[len(cum)-1] = cum[len(cum)-1] + line_length - (1+(cum[len(cum)-1]-1) % line_length)
|
|
# print("clean_rows",cum[len(cum)-1])
|
|
# print("phrase_len=",phrase_len)
|
|
msg_i_0 += phrase_len - 1
|
|
letters.append(brailledict[brailledict['key'] == phrase]['plaintext'].values[0])
|
|
# temptxt = txtdict.get(phrase)
|
|
# if temptxt == None:
|
|
# letters.append(phrase)
|
|
# else:
|
|
# letters.append(temptxt)
|
|
elif phrase == "@?NOTHING":
|
|
msg_i_0 += 8 # 9
|
|
print('found nothing')
|
|
found = True
|
|
elif phrase == "@?NEWLINE":
|
|
msg_i_0 += 8 # 9
|
|
print('forced newline')
|
|
cum[len(cum) - 1] += line_length - 1 - ((cum[len(cum) - 1] - 1) % line_length)
|
|
found = True
|
|
start_of_word = True
|
|
elif phrase == " ": # and (cum[len(cum)-1] % line_length > 0)): # no space at start of line # or letters[len(cum)-1] == " " or msgin[ni+1] == " ")
|
|
# msg_i_0 += 1
|
|
cum[len(cum)-1] = cum[len(cum)-1] + 1
|
|
print('space')
|
|
start_of_word = True
|
|
# word start position
|
|
if new_word:
|
|
start_of_word = len(cum) - 1 # position within cum
|
|
# unfound character??
|
|
if phrase_len == 0 and not (found or (ord(phrase) >= 48 and ord(phrase) <= 57)):
|
|
print(f"Unfound phrase: {phrase}")
|
|
# OUTPUTS
|
|
# console output
|
|
n_keys = max(cum)
|
|
letters = letters[1:len(letters)] # why does element 0 exist?
|
|
# print(f"message length b = {n_keys}")
|
|
# print(f"braille = {braille}")
|
|
# print(f"cum = {cum}")
|
|
# print(f"numbers = {numbers}")
|
|
# print(f"letters = {letters}")
|
|
|
|
## file output
|
|
f = open('Braille.txt','a')
|
|
f.truncate()
|
|
f.write(f'cum = {str(cum)};\n')
|
|
|
|
f.write('msgstr = [')
|
|
for i in range(len(letters)):
|
|
f.write('"')
|
|
f.write(str(letters[i]))
|
|
if i < len(letters) - 1:
|
|
f.write('", ')
|
|
f.write('"];\n')
|
|
|
|
f.write('numbers = [')
|
|
for i in range(len(numbers)):
|
|
#f.write('"')
|
|
f.write(str(numbers[i]))
|
|
if i < len(numbers) - 1:
|
|
f.write(', ')
|
|
f.write('];\n')
|
|
|
|
f.write(f"inA = {str(braille)};\n")
|
|
f.write(f"lmsg = {str(len(braille))};\n")
|
|
f.write(f"N = {str(n_keys)};\n")
|
|
f.write(f"nln = {str(min(line_length, n_keys))};\n")
|
|
f.write(f"maxln = {str(n_rows)};\n")
|
|
f.close()
|
|
# RETURNS
|
|
return cum, letters, numbers, braille, n_keys, n_rows
|
|
|
|
|
|
def n_lines_at_pos(position, line_length):
|
|
# FUNCTION
|
|
# calculate number of rows of keyboard required for message of length (in Braille keys) position
|
|
# ARGUMENTS
|
|
# int position - quantity of Braille keys in message up to (+ incl.) position
|
|
# int line_length - number of Braille keys per line / row
|
|
# ARGUMENT VALIDATION
|
|
_m = 'n_lines_at_pos'
|
|
av.val_int(position, 'position', _m, 0)
|
|
av.val_int(line_length, 'line_length', _m, 1)
|
|
# RETURNS
|
|
return 1 + (position // line_length)
|
|
|
|
|
|
def max_key_len(mydict: pd.DataFrame, min_dict_len: Optional[int] = 1):
|
|
# FUNCTION
|
|
# find maximum key length in braille dictionary
|
|
# ARGUMENTS
|
|
# pandas.DataFrame mydict
|
|
# ARGUMENT VALIDATION
|
|
_m = 'max_key_len'
|
|
av.val_int(min_dict_len, 'min_dict_len', _m)
|
|
av.val_type(mydict, "<class 'pandas.core.frame.DataFrame'>", 'mydict', _m)
|
|
# VARIABLE INSTANTIATION
|
|
n = len(mydict.index)
|
|
max_len = 0
|
|
# METHODS
|
|
for i in range(n):
|
|
max_len = max(max_len, len(mydict.iloc[i]['key']))
|
|
if max_len < min_dict_len:
|
|
return -1
|
|
# RETURNS
|
|
return max_len
|
|
|
|
|
|
# ToDo: Finish this!
|
|
# def remove_words_in_word(word, maxstrlen=9):
|
|
# ln = len(word)
|
|
# minmax = min(ln, maxstrlen)
|
|
# fix = False
|
|
# skip = False
|
|
# for length in np.arange(minmax, 1, -1):
|
|
# for start in range(ln-length):
|
|
# tempstr = word[start:start+length]
|
|
# if (tempstr == "@?NOTHING"):
|
|
# skip = True
|
|
# if skip:
|
|
# continue
|
|
# tempfind = brailledict.get(tempstr)
|
|
# if not (tempbool == None):
|
|
# tempword = word[:start]
|
|
# for li in range(length):
|
|
# ## add "@?NOTHING"
|
|
|
|
# def get_translated_input(my_option: Optional[int] = -1): # REDUNDANT
|
|
# # FUNCTION
|
|
# # Get product selection input from user + convert to Braille
|
|
# # VARIABLE INSTANTIATION
|
|
# braille_translations = get_braille_translations()
|
|
# products = gen_product_inputs(braille_translations)
|
|
# delimiters = get_delimiters()
|
|
# # METHODS
|
|
# my_product = input_product(braille_translations, products, my_option)
|
|
# # cum, letters, numbers, braille, ltmsg, n_rows = gen_braille_inputs_4_openscad(my_product.msg, my_product.line_length, braille_translations, max_key_len(braille_translations), delimiters)
|
|
# # RETURNS
|
|
# return my_product, braille_translations, max_key_len(braille_translations), delimiters
|
|
|
|
# get_translated_input() ' requires translate_msg_2_braille is replaced by __main__ in type validation strings
|
|
|
|
|
|
# def process_old_dict(old_dict, difficulty):
|
|
# # FUNCTION
|
|
# # create new list of braille_trans dataclass items
|
|
# # ARGUMENTS
|
|
# # old_dict - old dictionary of keys, values
|
|
# # difficulty - level field of dataclass
|
|
# # ARGUMENT VALIDATION
|
|
# print(f"type(old_dict) = {type(old_dict)}")
|
|
# print(f"type(difficulty) = {type(difficulty)}")
|
|
# # VARIABLE INSTANTIATION
|
|
# new_dict = []
|
|
# # METHODS
|
|
# for i in range(len(old_dict)):
|
|
# temp_key, temp_value = old_dict.popitem()
|
|
# new_dict.append(braille_trans(temp_key, difficulty, temp_value))
|
|
# # RETURNS
|
|
# return new_dict
|
|
|
|
|
|
# class braille_dictionary():
|
|
|
|
# def __init__(self, keys, hardnesses, braille_translations):
|
|
# return self.push(keys, hardnesses, braille_translations)
|
|
|
|
# def push(self, keys, hardnesses, braille_translations):
|
|
# N_in = len(keys)
|
|
# if not (N_in == len(hardnesses) == len(braille_translations)):
|
|
# return False
|
|
# for i in range(N_in - 1):
|
|
# for j in range(i + 1):
|
|
# if (keys[i + 1] == keys[j]):
|
|
# return False
|
|
# for i in range(N_in):
|
|
# self.keys.append(keys[i])
|
|
# self.hards.append(hardnesses[i])
|
|
# self.brailles.append(braille_translations[i])
|
|
# return True
|
|
|
|
# def exists_key(self, key):
|
|
# try:
|
|
# i = self.keys.index(key)
|
|
# except ValueError:
|
|
# return True
|
|
# else:
|
|
# return False
|
|
|
|
# def get_key_index(self, key):
|
|
# if self.exists_key(key):
|
|
# return self.keys.index(key)
|
|
# else:
|
|
# return -1 |