Files
braille_translator/model_gen/translate_msg_2_braille_v2a.py
2024-04-08 14:09:47 +01:00

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