Project OOP refactorisation.

This commit is contained in:
2024-06-11 08:02:41 +01:00
parent 1423d81a05
commit e88f8d50ff
29 changed files with 1779 additions and 2669 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,928 +0,0 @@
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 27 12:33:59 2023
@author: Edward Middleton-Smith
Argument Validation
"""
# CLASSES
# ATTRIBUTE DECLARATION
# METHODS
# FUNCTION
# ARGUMENTS
# ARGUMENT VALIDATION
# ATTRIBUTE + VARIABLE INSTANTIATION
# METHODS
# RETURNS
# NORMAL METHODS
# FUNCTION
# ARGUMENTS
# ARGUMENT VALIDATION
# VARIABLE INSTANTIATION
# METHODS
# RETURNS
from typing import Optional
def error_msg_str(method, v_name, v, v_type, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# return error message string for output of invalid argument / attribute to user
# ARGUMENTS
# str method - name of parent method which calls this function
# str arg_name - name of argument throwing error
# ? v - erroneous variable
# str v_type - desired / expected variable type
# str arg_type - e.g. argument, attribute
# bool suppress_errors - should outputs not be raised as errors?
# bool suppress_console_outputs
# ARGUMENT VALIDATION
my_f = 'error_msg_str'
# suppress_errors
if not val_bool(suppress_errors, 'suppress_errors', my_f):
error_msg = error_msg_str(my_f, 'suppress_errors', suppress_errors, "<class 'bool'>")
raise ValueError(error_msg)
# suppress_console_outputs
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
error_msg = error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors)
if suppress_errors:
print(error_msg)
return error_msg
else:
raise ValueError(error_msg)
# method
if not val_str(method, 'method', my_f, suppress_errors=suppress_errors, suppress_console_outputs=suppress_console_outputs):
error_msg = error_msg_str(my_f, 'method', method, "<class 'str'>", suppress_errors, suppress_console_outputs)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return error_msg
else:
raise ValueError(error_msg)
my_f = method + '.' + my_f
# v_name
if not val_str(v_name, 'v_name', my_f, -1, -1, suppress_errors, suppress_console_outputs):
error_msg = error_msg_str(my_f, 'v_name', v_name, "<class 'str'>", suppress_errors, suppress_console_outputs)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return error_msg
else:
raise ValueError(error_msg)
# v_type
if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs):
error_msg = error_msg_str(my_f, 'v_type', v_type, "<class 'str'>", suppress_errors, suppress_console_outputs)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return error_msg
else:
raise ValueError(error_msg)
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, -1, -1, suppress_errors, suppress_console_outputs):
error_msg = error_msg_str(my_f, 'v_arg_type', v_arg_type, "<class 'str'>", suppress_errors, suppress_console_outputs)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return error_msg
else:
raise ValueError(error_msg)
# RETURNS
return f"Invalid {method} {v_type} {v_arg_type} {v_name}. Type = {str(type(v))}. Value = {v}"
def val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# validate that myinput is of type bool
# ARGUMENTS
# bool (hopefully) myinput
# str v_name
# str method
# optional bool suppress_errors
# optional bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
# validate bool inputs first
v_type = "<class 'bool'>"
my_f = 'val_bool'
if str(type(suppress_errors)) != v_type:
raise ValueError(error_msg_str(my_f, 'suppress_errors', suppress_errors, v_type))
if str(type(suppress_console_outputs)) != v_type:
error_msg = error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, v_type, suppress_errors)
if suppress_errors:
print(error_msg)
return False
raise ValueError(error_msg)
v_type = "<class 'str'>"
# method
valid = True
if str(type(method)) != v_type:
valid = False
else:
if len(method) < 1:
valid = False
if not valid:
error_msg = error_msg_str(my_f, 'method', method, v_type, suppress_errors, suppress_console_outputs)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
my_f = method + '.' + my_f
# v_name
valid = True
if str(type(v_name)) != v_type:
valid = False
else:
if len(v_name) < 1:
valid = False
if not valid:
error_msg = error_msg_str(my_f, 'v_name', v_name, v_type, suppress_errors, suppress_console_outputs)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# v_arg_type
valid = True
if str(type(v_arg_type)) != v_type:
valid = False
else:
if len(v_arg_type) < 1:
valid = False
if not valid:
error_msg = error_msg_str(my_f, 'v_arg_type', v_arg_type, v_type, suppress_errors, suppress_console_outputs)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
else:
raise ValueError(error_msg)
# v_input
v_type = "<class 'bool'>"
if (str(type(v_input)) != v_type):
error_msg = error_msg_str(method, v_name, v_input, v_type, suppress_errors, suppress_console_outputs)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# RETURNS
return True
def val_str(v_input, v_name, method, min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# validate that v_input is of type str
# ARGUMENTS
# str (hopefully) v_input
# str v_name
# str method
# optional int min_len
# optional int max_len
# optional bool suppress_errors
# optional bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
my_f = 'val_str'
v_type = "<class 'str'>"
# suppress_errors
val_bool(suppress_errors, 'suppress_errors', my_f)
# suppress_console_outputs
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return False
# method
valid = True
if str(type(method)) != v_type:
valid = False
else:
if len(method) < 1:
valid = False
if not valid:
error_msg = error_msg_str(my_f, 'method', method, v_type)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
my_f = method + '.' + my_f
# v_name
valid = True
if str(type(v_name)) != v_type:
valid = False
else:
if len(v_name) < 1:
valid = False
if not valid:
error_msg = error_msg_str(my_f, 'v_name', v_name, v_type)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# v_arg_type
valid = True
if str(type(v_arg_type)) != v_type:
valid = False
else:
if len(v_arg_type) < 1:
valid = False
if not valid:
error_msg = error_msg_str(my_f, 'v_arg_type', v_arg_type, v_type)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# min_len
v_type = "<class 'int'>"
if str(type(min_len)) != v_type:
error_msg = error_msg_str(my_f, 'min_len', min_len, v_type)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# max_len
v_type = "<class 'int'>"
valid = True
if str(type(max_len)) != v_type:
valid = False
else:
if max_len != -1 and max_len < min_len:
valid = False
if not valid:
error_msg = error_msg_str(my_f, 'max_len', max_len, v_type)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# v_input
# VARIABLE INSTANTIATION
v_type = "<class 'str'>"
valid = True
# METHODS
if str(type(v_input)) != v_type:
valid = False
else:
L = len(v_input)
if min_len != -1 and L < min_len:
valid = False
print(f"Minimum str length {min_len} not met.")
if max_len != -1 and L > max_len:
print(f"Maximum str length {max_len} not met.")
valid = False
if not valid:
error_msg = error_msg_str(method, v_name, v_input, v_type, suppress_errors, suppress_console_outputs, v_arg_type)
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# RETURNS
return True
# def val_none(v_input, v_name, method, v_arg_type = 'argument', suppress_errors = False, suppress_console_outputs = False):
# # FUNCTION
# # evaluate if v_input is None
# # ARGUMENTS
# # ARGUMENT VALIDATION
# # VARIABLE INSTANTIATION
# # METHODS
# # RETURNS
def val_int(v_input, v_name, method, v_min: Optional[int] = None, v_max: Optional[int] = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# validate that myinput is of type int, and if not None, limited by v_min and v_max
# ARGUMENTS
# int (hopefully) myinput
# str v_name
# str method
# optional int v_min
# optional int v_max
# optional bool suppress_errors
# optional bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
my_f = 'val_int'
# suppress_errors
val_bool(suppress_errors, 'suppress_errors', my_f)
# suppress_console_outputs
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return False
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
my_f = method + '.' + my_f
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_min
if (v_min != None):
if not val_int(v_min, 'v_min', my_f, None, None, suppress_errors, suppress_console_outputs):
return False
# v_max
if (v_max != None):
if not val_int(v_max, 'v_max', my_f, None, None, suppress_errors, suppress_console_outputs):
return False
# v_input
# VARIABLE INSTANTIATION
mytype = "<class 'int'>" # str(type(myinput))
error_msg = error_msg_str(method, v_name, v_input, mytype, suppress_errors, suppress_console_outputs, v_arg_type)
# METHODS
if not mytype == str(type(v_input)):
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
if (v_min != None and v_max != None):
if (v_min > v_max):
if suppress_errors:
if not suppress_console_outputs:
print(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.")
return False
raise ValueError(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.")
if (v_min != None):
if (v_input < v_min):
if suppress_errors:
if not suppress_console_outputs:
print(error_msg + f"\nValue less than minimum {v_min}.")
return False
raise ValueError(error_msg + f"\nValue less than minimum {v_min}.")
if (v_max != None):
if (v_input > v_max):
if suppress_errors:
if not suppress_console_outputs:
print(error_msg + f"\nValue greater than maximum {v_max}.")
return False
raise ValueError(error_msg + f"\nValue greater than maximum {v_max}.")
# RETURNS
return True
def val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# validate that v_input is of type float, and if not None, limited by v_min and v_max
# ARGUMENTS
# float (hopefully) v_input
# str v_name
# str method
# optional float v_min
# optional float v_max
# optional bool suppress_errors
# optional bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
my_f = 'val_float'
# suppress_errors
val_bool(suppress_errors, 'suppress_errors', my_f)
# suppress_console_outputs
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return False
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
my_f = method + '.' + my_f
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_min
if (v_min != None):
if not val_float(v_min, 'v_min', my_f, None, None, suppress_errors, suppress_console_outputs):
return False
# v_max
if (v_max != None):
if not val_float(v_max, 'v_max', my_f, None, None, suppress_errors, suppress_console_outputs):
return False
# v_input
# VARIABLE INSTANTIATION
mytype = "<class 'float'>" # str(type(myinput))
error_msg = error_msg_str(method, v_name, v_input, mytype, suppress_errors, suppress_console_outputs, v_arg_type)
# METHODS
if not mytype == str(type(v_input)):
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
if (v_min != None and v_max != None):
if (v_min > v_max):
if suppress_errors:
if not suppress_console_outputs:
print(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.")
return False
raise ValueError(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.")
if (v_min != None):
if (v_input < v_min):
if suppress_errors:
if not suppress_console_outputs:
print(error_msg + f"\nValue less than minimum {v_min}.")
return False
raise ValueError(error_msg + f"\nValue less than minimum {v_min}.")
if (v_max != None):
if (v_input > v_max):
if suppress_errors:
if not suppress_console_outputs:
print(error_msg + f"\nValue greater than maximum {v_max}.")
return False
raise ValueError(error_msg + f"\nValue greater than maximum {v_max}.")
# RETURNS
return True
def input_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# input valid str, int, or bool representation of bool, or else None
# ARGUMENTS
# bool (hopefully) v_input
# str v_name
# str method
# optional str v_arg_type
# optional bool suppress_errors
# optional bool suppress_console_outputs
# ARGUMENT VALIDATION
my_f = 'input_bool'
# suppress_errors
val_bool(suppress_errors, 'suppress_errors', my_f)
# suppress_console_outputs
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return None
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
my_f = method + '.' + my_f
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
# METHODS
if not val_bool(v_input, v_name, my_f, suppress_errors, suppress_console_outputs):
if not val_int(v_input, v_name, my_f, 0, 1, suppress_errors, suppress_console_outputs):
error_msg = error_msg_str(method, v_name, v_input, "<class 'bool'>", suppress_errors, suppress_console_outputs, v_arg_type)
if not val_str(v_input, v_name, my_f, suppress_errors, suppress_console_outputs):
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return None
raise ValueError(error_msg)
else:
my_truths = ['Y', 'YE', 'YES', 'YS', 'YESH', 'YEA', 'YEAH', 'TRUE', 'TRU', 'TRUTH', 'TURE', 'T']
my_falths = ['N', 'NO', 'FALSE', 'F', 'FAIL', 'FALS']
for i in range(len(my_truths)):
if my_truths[i] == v_input:
return True
for i in range(len(my_falths)):
if my_falths[i] == v_input:
return False
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return None
raise ValueError(error_msg)
else:
return False if v_input == 0 else True
# RETURNS
return v_input
def full_val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# validate that bool input is bool or valid equivalent
# ARGUMENTS
# bool (hopefully) my_input
# str v_name
# str method
# optional bool suppress_errors
# optional bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
my_f = 'full_val_bool'
val_bool(suppress_errors, 'suppress_errors', my_f)
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return False
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
my_f = method + '.' + my_f
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# RETURNS
return not (str(type(input_bool(v_input, v_name, method, suppress_errors, suppress_console_outputs, v_arg_type))) == "<class 'NoneType'>")
def input_int(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# input int or valid equivalent, or else None
# ARGUMENTS
# int or str v_input
# str v_name
# str method
# v_min
# v_min
# bool suppress_errors
# bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
my_f = 'input_int'
val_bool(suppress_errors, 'suppress_errors', my_f)
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return None
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
my_f = method + '.' + my_f
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
# v_min
if not str(type(v_min)) == "<class 'NoneType'>":
v_min = input_int(v_min, 'v_min', my_f, None, v_max, suppress_errors, suppress_console_outputs)
if str(type(v_min)) == "<class 'NoneType'>": return None
# v_max
if not str(type(v_max)) == "<class 'NoneType'>":
v_max = input_int(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs)
if str(type(v_max)) == "<class 'NoneType'>": return None
# METHODS
error_msg = error_msg_str(method, v_name, v_input, "<class 'int'>", suppress_errors, suppress_console_outputs, v_arg_type)
# v_input
try:
my_int = int(v_input)
except:
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return None
int(v_input)
if not str(type(v_min)) == "<class 'NoneType'>":
if my_int < v_min:
if suppress_errors:
if not suppress_console_outputs:
print(f"{error_msg}\nInt input less than minimum value. Value = {v_input}, minimum = {v_min}.")
return None
if not str(type(v_max)) == "<class 'NoneType'>":
if my_int > v_max:
if suppress_errors:
if not suppress_console_outputs:
print(f"{error_msg}\nInt input greater than maximum value. Value = {v_input}, maximum = {v_max}.")
return None
# RETURNS
return my_int
def full_val_int(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# validate that v_input is int or equivalent, else False, limited by v_min and v_max
# ARGUMENTS
# int (hopefully) v_input
# str v_name
# str method
# optional float v_min
# optional float v_max
# optional bool suppress_errors
# optional bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
my_f = 'full_val_int'
val_bool(suppress_errors, 'suppress_errors', my_f)
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return False
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_min
if not str(type(v_min)) == "<class 'NoneType'>":
v_min = input_int(v_min, 'v_min', method, None, v_max, suppress_errors, suppress_console_outputs)
if str(type(v_min)) == "<class 'NoneType'>": return False
# v_max
if not str(type(v_max)) == "<class 'NoneType'>":
v_max = input_int(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs)
if str(type(v_max)) == "<class 'NoneType'>": return False
# RETURNS
return not (str(type(input_int(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "<class 'NoneType'>")
def input_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# input float, else return None
# ARGUMENTS
# float/int/str(numeric) v_input
# str v_name
# str method
# optional float v_min
# optional float v_min
# optional bool suppress_errors
# optional bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
my_f = 'input_float'
val_bool(suppress_errors, 'suppress_errors', my_f)
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return None
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
my_f = method + '.' + my_f
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
# v_min
if not str(type(v_min)) == "<class 'NoneType'>":
v_min = input_float(v_min, 'v_min', my_f, None, v_max, suppress_errors, suppress_console_outputs)
if str(type(v_min)) == "<class 'NoneType'>": return None
# v_max
if not str(type(v_max)) == "<class 'NoneType'>":
v_max = input_float(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs)
if str(type(v_max)) == "<class 'NoneType'>": return None
# METHODS
error_msg = error_msg_str(method, v_name, v_input, "<class 'float'>", suppress_errors, suppress_console_outputs, v_arg_type)
# v_input
try:
my_float = float(v_input)
except:
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return None
float(v_input)
if not str(type(v_min)) == "<class 'NoneType'>":
if v_input < v_min:
if suppress_errors:
if not suppress_console_outputs:
print(f"{error_msg}\nInt input less than minimum value. Value = {v_input}, minimum = {v_min}.")
return None
if not str(type(v_max)) == "<class 'NoneType'>":
if v_input > v_max:
if suppress_errors:
if not suppress_console_outputs:
print(f"{error_msg}\nInt input greater than maximum value. Value = {v_input}, maximum = {v_max}.")
return None
# RETURNS
return my_float
def full_val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# validate that v_input is numeric, and if not False, limited by v_min and v_max
# ARGUMENTS
# float (hopefully) v_input
# str v_name
# str method
# optional float v_min
# optional float v_max
# optional bool suppress_errors
# optional bool suppress_console_outputs
# ARGUMENT VALIDATION
my_f = 'full_val_float'
val_bool(suppress_errors, 'suppress_errors', my_f)
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return False
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
my_f = method + '.' + my_f
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_min
if not str(type(v_min)) == "<class 'NoneType'>":
v_min = input_float(v_min, 'v_min', method, None, v_max, suppress_errors, suppress_console_outputs)
if str(type(v_min)) == "<class 'NoneType'>": return False
# v_max
if not str(type(v_max)) == "<class 'NoneType'>":
v_max = input_float(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs)
if str(type(v_max)) == "<class 'NoneType'>": return False
# RETURNS
return not (str(type(input_float(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "<class 'NoneType'>")
def make_ordinal(n):
# FUNCTION
# Get ordinal representation of number
# ARGUMENTS
# int n
# ARGUMENT VALIDATION
full_val_int(n, 'n', 'make_ordinal', 0)
# VARIABLE INSTANTIATION
n = int(n)
# METHODS
if 11 <= (n % 100):
suffix= 'th'
else:
suffix = ['th', 'st', 'nd', 'rd', 'th'][min(n % 10, 4)]
# RETURNS
return str(n) + suffix
def val_type(v_input, v_type, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
# FUNCTION
# validate that v_input is of type v_type
# ARGUMENTS
# v_type (hopefully) v_input
# str v_type
# str v_name
# str method
# optional bool suppress_errors
# optional bool suppress_console_outputs
# str v_arg_type
# ARGUMENT VALIDATION
my_f = 'val_type'
val_bool(suppress_errors, 'suppress_errors', my_f)
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return False
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
my_f = method + '.' + my_f
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_type
if not val_str(v_type, 'v_type', my_f, 6, -1, suppress_errors, suppress_console_outputs): return False
# v_input
error_message = error_msg_str(method, v_name, v_input, v_arg_type)
mytype = str(type(v_input))
# if not (v_type == 'int' or v_type == 'bool' or v_type == 'float' or v_type == 'complex' or v_type == 'str' or v_type == 'NoneType'):
if not mytype == v_type: # f"<class '{v_type}'>":
if suppress_errors:
if not suppress_console_outputs:
print(error_message)
return False
raise ValueError(error_message)
# RETURNS
return True
def val_list(v_input, v_name, method, v_type = '', min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs: bool = False, v_arg_type = 'argument'):
# FUNCTION
# validate that v_input is of type list, and if defined: has v_len elements of type v_type
# ARGUMENTS
# list[v_type] (hopefully) v_input
# str v_name - variable name
# str method - parent method
# str v_type - type of list items
# int v_len - length of list
# optional bool suppress_errors
# optional bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
my_f = 'val_list'
val_bool(suppress_errors, 'suppress_errors', my_f)
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
return False
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
my_f = method + '.' + my_f
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_type
if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): return False
# min_len
if not full_val_int(min_len, 'min_len', my_f, None, None if max_len == -1 else max_len, suppress_errors, suppress_console_outputs): return False
# min_len = input_int(min_len, 'min_len', method, None, max_len, suppress_errors, suppress_console_outputs)
# if str(type(min_len)) == "<class 'NoneType'>": return False
# max_len
if not full_val_int(max_len, 'max_len', my_f, None if max_len == -1 else (None if min_len == -1 else min_len), None, suppress_errors, suppress_console_outputs): return False
# if not str(type(max_len)) == "<class 'NoneType'>":
# max_len = input_int(max_len, 'max_len', method, min_len, None, suppress_errors, suppress_console_outputs)
# if str(type(max_len)) == "<class 'NoneType'>": return False
# v_input
mytype = str(type(v_input))
error_msg = error_msg_str(method, v_name, v_input, "<class 'list'>")
if not mytype == "<class 'list'>":
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
L = len(v_input)
if max_len > -1 and L > max_len:
if suppress_errors:
if not suppress_console_outputs:
print(error_msg + f'\nInvalid list length. Maximum = {max_len}, length = {L}')
return False
raise ValueError(error_msg + f'\nInvalid list length. Maximum = {max_len}, length = {L}')
if L < min_len:
if suppress_errors:
if not suppress_console_outputs:
print(error_msg + f"Invalid list length. Minimum = {min_len}, length = {L}")
return False
raise ValueError(error_msg + f'\nInvalid list length. Minimum = {min_len}, length = {L}')
if v_type != '' and L > 0:
for i in range(L):
mytype = str(type(v_input[i]))
if not mytype == v_type:
error_msg = error_msg + '\n' + error_msg_str(my_f, v_name, v_input, v_type, False, False, 'list element')
if suppress_errors:
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# RETURNS
return True
def val_nested_list(v_input, depth_i, depth_max, v_name, method, v_type = '', v_min = -1, v_mins = [], v_max = -1, v_maxs: list = [], suppress_errors = False, suppress_console_outputs: bool = False, v_arg_type = 'argument'):
# FUNCTION
# validate that v_input is of type list, and if defined: has v_len elements of type v_type
# for nested list of nested-index i
# ARGUMENTS
# list[v_type] (hopefully) v_input
# int depth_i - current depth of nesting of lists
# int depth_max - maximum depth of nesting of lists - base 0
# str v_name
# str method
# Optional[str] v_type - type of list items
# Optional[int] v_min - minimum sublist size
# Optional[list[int]] v_mins - minimum list sizes
# Optional[int] v_max - maximum sublist size
# Optional[list[int]] v_maxs - maximum list sizes
# optional bool suppress_errors
# optional bool suppress_console_outputs
# optional str v_arg_type
# ARGUMENT VALIDATION
my_f = 'val_nested_list'
val_bool(suppress_errors, 'suppress_errors', my_f)
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>"))
return False
# method
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
my_f = method + '.' + my_f
# v_name
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_arg_type
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
# v_type
if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): return False
# v_min
if not val_int(v_min, 'v_min', my_f, -1, None, suppress_errors, suppress_console_outputs): return False
# v_max
if not val_int(v_max, 'v_max', my_f, -1, None, suppress_errors, suppress_console_outputs): return False
# v_mins
if not (val_list(v_mins, 'v_mins', my_f, "<class 'int'>", depth_max + 1, depth_max + 1, True, True) or v_mins == []):
error_msg = error_msg_str(my_f, 'v_mins', v_mins, "<class 'int'>")
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# v_maxs
if not (val_list(v_maxs, 'v_maxs', my_f, "<class 'int'>", depth_max + 1, depth_max + 1, True, True) or v_maxs == []):
error_msg = error_msg_str(my_f, 'v_maxs', v_maxs, "<class 'int'>")
if not suppress_console_outputs:
print(error_msg)
return False
raise ValueError(error_msg)
# v_input
mytype = v_type if depth_i == depth_max else "<class 'list'>"
error_msg = error_msg_str(method, v_name, v_input, mytype, suppress_errors, suppress_console_outputs, v_arg_type)
if not val_list(v_input, v_name, method, mytype, v_min, v_max, suppress_errors, suppress_console_outputs, v_arg_type):
if not suppress_console_outputs:
print(error_msg)
return False
# METHODS
L = len(v_input)
if L == 0:
if v_min > -1:
if suppress_errors:
if not suppress_console_outputs:
print(error_msg + f'\nMinimum length {v_min} not met.')
return False
raise ValueError(error_msg + f'\nMinimum length {v_min} not met.')
elif depth_i < depth_max:
for i in range(L):
if not (v_mins == [] or v_maxs == []):
if not val_nested_list(v_input[i], depth_i + 1, depth_max, v_name, method, v_type, v_mins[depth_i + 1], v_mins, v_maxs[depth_i + 1], v_maxs, suppress_errors, suppress_console_outputs, v_arg_type):
if not suppress_console_outputs:
print(error_msg)
return False
elif not v_mins == []:
if not val_nested_list(v_input[i], depth_i + 1, depth_max, v_name, method, v_type, v_mins[depth_i + 1], v_mins, -1, v_maxs, suppress_errors, suppress_console_outputs, v_arg_type):
if not suppress_console_outputs:
print(error_msg)
return False
elif not v_maxs == []:
if not val_nested_list(v_input[i], depth_i + 1, depth_max, v_name, method, v_type, -1, v_mins, v_maxs[depth_i + 1], v_maxs, suppress_errors, suppress_console_outputs, v_arg_type):
if not suppress_console_outputs:
print(error_msg)
return False
else:
if not val_nested_list(v_input[i], depth_i + 1, depth_max, v_name, method, v_type, -1, v_mins, -1, v_maxs, suppress_errors, suppress_console_outputs, v_arg_type):
if not suppress_console_outputs:
print(error_msg)
return False
# RETURNS
return True

View File

@@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
"""
Created on Thursday May 30 2024
@author: Edward Middleton-Smith
"""
# import argument_validation as av
# from translate_msg_2_braille import product, gen_braille_inputs_4_openscad
# from translate_braille_2_scad import scrabble_dimensions, export_colour_theme, input_colour_themes, gen_openscad_braille, gen_path_braille_scrabble, input_product_size
# from character_braille import Size_Character_Braille, Style_Character_Braille, Colour_Theme_Character_Braille
from keyboard_3d import Size_Character_Braille, Style_Character_Braille, Colour_Theme_Character_Braille, Enum_Justification_Text, Keyboard_3D
# import model_gen.utils_system
from translation_braille import Translation_Braille
import openpyscad as ops #, Assembly, Union
from typing import Optional, List
from pydantic import BaseModel, Field
from itertools import product
class Array_Keyboard_3D(BaseModel):
sizes_characters: List[Size_Character_Braille]
styles_characters: List[Style_Character_Braille]
colour_themes: List[Colour_Theme_Character_Braille]
justifications_text: List[Enum_Justification_Text]
path_dir: str
max_characters_per_rows: List[int]
translations: List[Translation_Braille]
fn: int = Field(ge=0)
keyboards: List[Keyboard_3D] = []
has_files_openscad: bool = False
has_files_stl: bool = False
has_files_png: bool = False
def __init__(self, **data):
super().__init__(**data)
if len(self.sizes_characters) == 0:
self.sizes_characters = Size_Character_Braille.get_defaults()
if len(self.styles_characters) == 0:
self.styles_characters = [Style_Character_Braille.get_default()]
if len(self.colour_themes) == 0:
self.colour_themes = Colour_Theme_Character_Braille.get_defaults()
if len(self.justifications_text) == 0:
self.justifications_text = [Enum_Justification_Text.get_default()]
self.make_combinations()
self.has_files_openscad = False
self.has_files_stl = False
self.has_files_png = False
def make_combinations(self):
configuration_keyboards = product(self.sizes_characters, self.styles_characters, self.colour_themes, self.justifications_text, self.max_characters_per_rows, self.translations)
self.keyboards = []
for configuration_keyboard in configuration_keyboards:
# self.keyboards.append(Keyboard_3D(*configuration_keyboard))
# Keyboard_3D(size_characters=size_default, style_characters=style_default,
# colour_theme=colour_default, justification_text=justification_default, path_dir=path_dir, max_characters_per_row=10, translation=translation_extended_alphabet, fn=25)
self.keyboards.append( Keyboard_3D(size_characters=configuration_keyboard[0], style_characters=configuration_keyboard[1], colour_theme=configuration_keyboard[2],
justification_text=configuration_keyboard[3], path_dir=self.path_dir, max_characters_per_row=configuration_keyboard[4], translation=configuration_keyboard[5], fn=self.fn))
def update_configurations_styles(self, sizes_characters, style_characters, colour_themes, justifications_text):
self.sizes_characters = sizes_characters
self.styles_characters = style_characters
self.colour_themes = colour_themes
self.justifications_text = justifications_text
self.make_combinations()
def make_combined_assembly(self, dx, dy, max_keyboards_per_row):
count_keyboards_in_row = 0
count_rows = 0
assembly = ops.Assembly()
for keyboard in self.keyboards:
assembly.add(keyboard.make_model_openpyscad().translate([dx * count_keyboards_in_row, dy * count_rows, 0]))
count_keyboards_in_row += 1
if count_keyboards_in_row >= max_keyboards_per_row:
count_keyboards_in_row = 0
count_rows += 1
return assembly
def make_files_openscad(self):
for keyboard in self.keyboards:
keyboard.make_file_openscad()
self.has_files_openscad = True
def make_files_stl(self):
for keyboard in self.keyboards:
keyboard.make_file_stl()
self.has_files_stl = True
def make_files_png(self):
for keyboard in self.keyboards:
keyboard.make_file_png()
self.has_files_png = True
def make_files(self):
for keyboard in self.keyboards:
keyboard.make_file_openscad()
keyboard.make_file_stl()
keyboard.make_file_png()

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
"""
Created on 29/05/2024
@author: Edward Middleton-Smith
"""
import pandas as pd
from typing import Optional, List
from pydantic import BaseModel, conlist, validator, field_validator, validator
from enum import Enum
# import argument_validation as av
import sys
class Character_Braille(BaseModel):
plaintext: str # English plaintext key
list_dots_braille: List[bool] # braille: list # list[list[int]] # Braille translation of plaintext
def __init__(self, plaintext, list_dots_braille):
super().__init__(plaintext=plaintext, list_dots_braille=list_dots_braille)
@validator('list_dots_braille')
def validate_list_dots_braille(cls, value):
"""
if (len(value) != 6):
raise ValueError('List must have 6 elements')
for row in value:
"""
if (len(value) != 6):
raise ValueError('List must have rows of 6 colunns')
if not all(isinstance(dot, bool) for dot in value):
raise ValueError('List must contain only boolean values')
return value
@validator('plaintext')
def validate_plaintext(cls, value):
"""
known_translations = Character_Braille.get_Translation_Brailles()
if not known_translations['Character_Braille'].apply(lambda x: x.plaintext == value).any():
raise ValueError('Plaintext not in known translations')
"""
return value
"""
@validator('matrix_braille_dots')
def validate_matrix_braille_dots(cls, value):
if (len(value) != 3):
raise ValueError('Matrix must have 3 rows')
for row in value:
if (len(row) != 2):
raise ValueError('Matrix must have rows of 2 colunns')
if not all(isinstance(item, bool) for item in row):
raise ValueError('Matrix must contain only boolean values')
return value
@validator('plaintext')
def validate_plaintext(cls, value):
known_translations = Character_Braille.get_translation_Brailles()
if not known_translations['Character_Braille'].apply(lambda x: x.plaintext == value).any():
raise ValueError('Plaintext not in known translations')
return value
"""
def get_blank_character_Braille():
return Character_Braille("BLANK_SPACE", [0, 0, 0, 0, 0, 0]) # , Enum_Braille_Proficiency_Level(0)
def __repr__(self):
# return f"key = {self.key}, level = {self.level}, braille = {self.braille}, plaintext = {self.plaintext}"
return f'plaintext = {self.plaintext}, list_dots_braille = {self.list_dots_braille}' # , translation_proficiency_level = {self.translation_proficiency_level}
# 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}
return {'plaintext': self.plaintext, 'translation_proficiency_level': self.translation_proficiency_level, 'matrix_dots_braille': self.matrix_dots_braille}
"""

View File

@@ -0,0 +1,210 @@
# -*- coding: utf-8 -*-
"""
@author: Edward Middleton-Smith
"""
import openpyscad as ops # , Union, Difference
import numpy as np
from typing import Optional, List, Union
from prettytable import PrettyTable
from enum import Enum
from pydantic import BaseModel, Field, ValidationError, validate_arguments, validator
from abc import ABC, abstractmethod
# from color import Color
# from termcolor import colored
# from colorama import init, Fore, Style
import webcolors
from builtins import staticmethod
import os
import string
import pandas as pd
# init()
class BaseStyle(ABC):
"""
@abstractmethod
def minimum():
pass
@abstractmethod
def maximum():
pass
"""
@abstractmethod
def get_defaults():
pass
@abstractmethod
def get_list_headings():
pass
@abstractmethod
def as_row(self):
pass
def input_from_console(cls):
# pass
options = cls.get_defaults()
count_options = len(options)
table_output = PrettyTable()
table_output.field_names = ['index'] + cls.get_list_headings() # ['index', 'name', 'dot spacing', 'block height', 'character spacing', 'base height', 'dot height', 'dot bottom radius', 'dot top radius']
for index_option in range(count_options):
option = options[index_option]
table_output.add_row([index_option + 1] + option.as_row())
print()
print("Please select product dimensions configuration from below :")
print(table_output)
while True:
option = str(input("Product dimensions configuration (by index):"))
print(option + " selected")
if option == "#!ERRORCODE!#": exit
for index_option in range(count_options):
if option == str(index_option + 1): # option == options[index_option].name or
return options[index_option]
"""
@abstractmethod
# @staticmethod
def get_classname(self):
""
stack = inspect.stack()
return stack[2][0].f_locals["__qualname__"]
""
return self.__class__.__name__
"""
def input_many_from_console(cls):
selected = []
print(f'Inputting many {cls.__name__} objects')
print()
while True:
try:
count_inputs = int(input(f'Quantity of {cls.__name__} objects to enter:'))
except: continue
for index_input in range(count_inputs):
print(f'Inputting {cls.__name__} object {index_input + 1}')
selected_new = cls.input_from_console(cls)
selected.append(selected_new)
break
return selected
class Colour_Field(str):
def __new__(cls, value: Union[str, int, tuple]):
try:
# colour = colored('', value)
# colour = colour.split(Style.RESET_ALL)[0]
try:
hex_code = webcolors.normalize_hex(value)
return str.__new__(cls, hex_code)
except:
hex_code = webcolors.name_to_hex(value)
return str.__new__(cls, hex_code)
except ValueError:
raise ValidationError(f"Invalid colour value: {value}")
@classmethod
def __get_pydantic_core_schema__(cls, handler):
return {
'type': 'str',
}
class Colour_Theme_Character_Braille(BaseModel, BaseStyle):
# ATTRIBUTE DECLARATION
name: str
colour_top: Colour_Field
colour_base: Colour_Field
def __init__(self, name, colour_top, colour_base):
super().__init__(name=name, colour_top=colour_top, colour_base=colour_base)
"""
# METHODS
def __new__(cls, name, coltop, colbase, openscad_colours):
# FUNCTION
# Initialise class object
# ARGUMENTS
# str name - user reference to colour theme
# str coltop - a valid openSCAD colour e.g. '#010101'
# str colbase - a valid openSCAD colour e.g. 'blue'
# list[str] openscad_colours
# ARGUMENT VALIDATION
_m = 'export_colour_theme.__new__'
v_arg_type = 'class attribute'
av.val_str(name, 'name', _m, 1, v_arg_type = v_arg_type)
av.val_list(openscad_colours, 'openscad_colours', _m, "<class 'str'>", 1, v_arg_type = v_arg_type)
if not validate_openscad_colour(coltop, openscad_colours):
raise ValueError(f"Invalid export_colour_theme attribute coltop. Type = {str(type(coltop))}. Value = {coltop}")
if not validate_openscad_colour(colbase, openscad_colours):
raise ValueError(f"Invalid export_colour_theme attribute colbase. Type = {str(type(colbase))}. Value = {colbase}")
# RETURNS
return super(export_colour_theme, cls).__new__(cls)
def __init__(self, name, coltop, colbase, openscad_colours):
# FUNCTION
# Initialise class object
# ARGUMENTS
# str name - user reference to colour theme
# str coltop - a valid openSCAD colour e.g. '#010101'
# str colbase - a valid openSCAD colour e.g. 'blue'
# list[str] openscad_colours # redundant in this function - used for argument validation
# ARGUMENT VALIDATION
# see __new__()
# ATTRIBUTE INSTANTIATION
self.name = name
self.top = coltop
self.base = colbase
"""
def __repr__(self):
# FUNCTION
# Convert object to str representation
# RETURNS
return f"name = {self.name}, colour top = {self.colour_top}, colour base = {self.colour_base}" # , openscad_colours = {self.openscad_colours}
def as_dict(self):
# FUNCTION
# Convert object attribute, value pairs to dictionary representation
# RETURNS
return {'name': self.name, 'colour top': self.colour_top, 'colour base': self.colour_base} # , 'openscad_colours': self.openscad_colours
def as_row(self):
# FUNCTION
# Convert object values to list representation
# RETURNS
return [self.name, self.colour_top, self.colour_base] # , 'openscad_colours': self.openscad_colours
def get_defaults():
# openscad_colours = get_openscad_colours()
colour_themes = []
colour_themes.append(Colour_Theme_Character_Braille("Blue", "#337AFF", "#337AFF")) #, openscad_colours))
colour_themes.append(Colour_Theme_Character_Braille("Purple", "#8E44AD", "#8E44AD")) #, openscad_colours))
colour_themes.append(Colour_Theme_Character_Braille("Red", "#F7322F", "#F7322F")) #, openscad_colours))
colour_themes.append(Colour_Theme_Character_Braille("Black", "Black", "#17202A")) #, openscad_colours))
colour_themes.append(Colour_Theme_Character_Braille("White", "White", "White")) #, openscad_colours))
return colour_themes # , columns=['Name', 'Colour Top', 'Colour base']) # Colour_Theme_Character_Braille.__name__]) # colour_themes
def get_defaults_DataFrame():
return pd.DataFrame(data={Colour_Theme_Character_Braille.__name__: Colour_Theme_Character_Braille.get_defaults()}) # , columns=['Name', 'Colour Top', 'Colour base']) # Colour_Theme_Character_Braille.__name__]) # colour_themes
def get_default():
colours_default = Colour_Theme_Character_Braille.get_defaults_DataFrame()
return colours_default[Colour_Theme_Character_Braille.__name__].apply(lambda x: x if x.name == 'Blue' else None).dropna()[0]
"""
def input_from_console():
colour_themes = Colour_Theme_Character_Braille.get_defaults()
count_colours = len(colour_themes)
colour_table = PrettyTable()
colour_table.field_names = ['index', 'name', 'colour top', 'colour base']
for col_i in range(count_colours):
colour_table.add_row([col_i + 1] + colour_themes[col_i].as_row())
print()
print("Please select colour theme from below:")
print(colour_table)
while True:
colour_input = input("Colour theme (name or index): ")
print(str(colour_input) + " selected")
if colour_input == "#!ERRORCODE!#": exit
for i_colour in range(count_colours):
if colour_input == colour_themes[i_colour].name:
return colour_themes[i_colour]
"""
def get_list_headings():
return ['name', 'colour top', 'colour base']

View File

@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
"""
@author: Edward Middleton-Smith
"""
class Controller_Braille():
#

View File

@@ -1,152 +0,0 @@
# -*- coding: utf-8 -*-
"""
Created on Mon May 1 03:35:45 2023
@author: Edward Middleton-Smith
Braille 3D Model Product Creation
"""
# CLASSES
# ATTRIBUTE DECLARATION
# METHODS
# FUNCTION
# ARGUMENTS
# ARGUMENT VALIDATION
# ATTRIBUTE + VARIABLE INSTANTIATION
# METHODS
# RETURNS
# NORMAL METHODS
# FUNCTION
# ARGUMENTS
# ARGUMENT VALIDATION
# VARIABLE INSTANTIATION
# METHODS
# RETURNS
import openpyscad as ops
import system_commands as sc
import argument_validation as av
from translate_msg_2_braille import product, gen_braille_inputs_4_openscad
from translate_braille_2_scad import scrabble_dimensions, export_colour_theme, input_colour_themes, gen_openscad_braille, gen_path_braille_scrabble, input_product_size
from typing import Optional
def gen_product_permutations(my_product, szs_product, sz_perms = True, sz_index = 2):
# FUNCTION
# generate all colour / size permutations of product
# ARGUMENTS
# product my_product
# list[scrabble_dimensions] szs_product - different size profiles for products
# optional bool szs_perms
# optional int sz_index
# ARGUMENT VALIDATION
_m = 'gen_product_permutations'
av.val_type(my_product, "<class 'translate_msg_2_braille.product'>", 'my_product', _m)
av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 1)
av.full_val_bool(sz_perms, 'sz_perms', _m)
# VARIABLE INSTANTIATION
mymsgs = [] # [msgin]
myszs = [] # [szs_scrabble[5]]
# METHODS
if not sz_perms:
my_size = input_product_size(szs_product, sz_index)
# create list of permutations of size profiles + letters
for j in range(len(szs_product) if sz_perms else 1):
for i in range(26 if my_product.name == 'Scrabble Alphabet of Tiles' else 1):
mymsgs.append(chr(65 + i) if my_product.name == 'Scrabble Character Tile' else my_product.msg)
myszs.append(szs_product[j] if sz_perms else my_size)
# RETURNS
return mymsgs, myszs
def gen_3d_models(braille_dict, myproduct, mymsgs, myszs, line_length, path_folder, path_cmd, mystyle, col_themes):
# FUNCTION
# create 3D models - SCAD, STL, PNG - from product input
# ARGUMENTS
# list[braille_trans] braille_dict
# product myproduct
# list[str] mymsgs
# list[scrabble_dimensions] myszs
# int line_length
# str path_folder
# style mystyle
# list [export_colour_themes] col_themes
# ARGUMENT VALIDATION
_m = 'gen_3d_models'
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', _m)
av.val_type(myproduct, "<class 'translate_msg_2_braille.product'>", 'myproduct', _m)
av.val_list(mymsgs, 'mymsgs', _m, "<class 'str'>", 1)
av.val_list(myszs, 'myszs', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 1) #:
# raise ValueError(av.error_msg_str(_m, 'myszs', myszs, "<class 'scrabble_dimensions'>"))
av.val_int(line_length, 'line_length', _m, 1)
av.val_str(path_folder, 'path_folder', _m)
av.val_str(path_cmd, 'path_cmd', _m, 1)
# av.val_int(show_braille, 'show_braille', _m)
# av.val_int(show_let, 'show_let', _m)
# av.val_int(show_num, 'show_num', _m)
# av.val_type(show_braille, "<enum 'elem_visibility'>", 'show_braille', _m)
# av.val_type(show_let, "<enum 'elem_visibility'>", 'show_let', _m)
# av.val_type(show_num, "<enum 'elem_visibility'>", 'show_num', _m)
av.val_type(mystyle, "<class 'translate_braille_2_scad.style'>", 'mystyle', _m)
av.val_list(col_themes, 'col_themes', _m, "<class 'translate_braille_2_scad.export_colour_theme'>", 1)
# VARIABLE INSTANTIATION
# METHODS
for col_y in range(len(col_themes)):
for msg_x in range(len(mymsgs)):
msg_x_str = mymsgs[msg_x]
cum, letters, numbers, braille, n_keys, n_rows = gen_braille_inputs_4_openscad(msg_x_str, line_length, braille_dict)
path_png, path_scad, path_stl = gen_openscad_braille(cum, letters, numbers, braille, n_keys, min(line_length, n_keys), n_rows, myszs[msg_x], mystyle, col_themes[col_y], msg_x_str, path_folder + myproduct.filename, quality = 100)
# sc.render_openscad(path_scad, path_stl, path_cmd)
# sc.render_openscad(path_scad, path_png, path_cmd)
# # RETURNS
# return col_themes
def gen_snippet_assembly(dx, dy, len_line, col_themes, myszs, my_product, path_folder, path_cmd, my_style): #, szs_product
# FUNCTION
# create png exports of openscad assembly of series of permutations of openscad components
# ARGUMENTS
# int dx - spacing along x
# int dy - spacing along y
# int len_line - number of components on row (along x)
# list[export_colour_theme] col_themes
# list[scrabble_dimensions] myszs
# translate_msg_2_braille.product my_product
# str path_folder
# str path_cmd
# style my_style
# # list[scrabble_dimensions] szs_product
# ARGUMENT VALIDATION
_m = 'gen_snippet_assembly'
av.val_int(dx, 'dx', _m)
av.val_int(dy, 'dy', _m)
av.val_int(len_line, 'len_line', _m, 1)
av.val_list(col_themes, 'col_themes', _m, "<class 'translate_braille_2_scad.export_colour_theme'>")
# av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 1)
av.val_list(myszs, 'myszs', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 1)
av.val_type(my_product, "<class 'translate_msg_2_braille.product'>", 'my_product', _m)
av.val_str(path_folder, 'path_folder', _m)
av.val_str(path_cmd, 'path_cmd', _m, 1)
av.val_type(my_style, "<class 'translate_braille_2_scad.style'>", 'my_style', _m)
# VARIABLE INSTANTIATION
# mystyles = ['__l_0n'] # ['_0n', '_0l_0n', '_0b_0n', '__l_0n']
n_style = 1 # 3
d_pcs = [dx, dy]
# METHODS
for sz_i in range(len(myszs)):
ass_braille = ops.Union()
for let_i in range(1): # 26):
col_i = 0 # let_i % n_col
style_i = 0 # let_i % n_style
# mypath = gen_path_braille_scrabble(szs_scrabble[sz_i], let_i, col_themes[col_i], 'scad')
mypath = gen_path_braille_scrabble(myszs[sz_i], col_themes[col_i], my_style, path_folder + my_product.filename, 'scad')
# mypath = f"C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\Braille_Scrabble_{szs_scrabble[sz_i].name}_{Chr(let_i + 65)}_{col_themes[col_i].name}"
ass_braille.append(ops.Scad(mypath).rotate([0, 180 * let_i, 0]).translate([4 * (let_i % 2), 0, -5 * (let_i % 2)]).translate([d_pcs[0] * myszs[sz_i].dp * (let_i % len_line), d_pcs[1] * myszs[sz_i].dp * (let_i // len_line), 0])) # , convexity = 3) .translate([d_pcs * (let_i % len_line), d_pcs * (let_i // len_line), 0])
# RETURNS
path_scad = gen_path_braille_scrabble(myszs[0], col_themes[col_i], my_style, path_folder + 'assy', 'scad')
path_stl = gen_path_braille_scrabble(myszs[0], col_themes[col_i], my_style, path_folder + 'assy', 'stl')
path_png = gen_path_braille_scrabble(myszs[0], col_themes[col_i], my_style, path_folder + 'assy', 'png')
ass_braille.write(path_scad) # , with_print=True
print(f"writing SCAD to {path_scad}")
# render_openscad(path_scad, path_stl)
sc.render_openscad(path_scad, path_png, path_cmd)

549
model_gen/keyboard_3d.py Normal file
View File

@@ -0,0 +1,549 @@
# -*- coding: utf-8 -*-
"""
@author: Edward Middleton-Smith
"""
# import argument_validation as av
from colour_theme_braille_character import Colour_Theme_Character_Braille, BaseStyle
from openscad_objects import ModelOpenSCAD # get_openscad_colours
# from translate_msg_2_braille import Character_Braille
from character_braille import Character_Braille
from translation_braille import Translation_Braille, Enum_Braille_Proficiency_Level
from utils_system import render_openscad, make_openscad, exec_oscmd
import openpyscad as ops # Union, Difference
import numpy as np
from typing import Optional, List
from prettytable import PrettyTable
from enum import Enum
from pydantic import BaseModel, Field, ValidationError, validate_arguments, validator
# from color import Color
from builtins import staticmethod
import os
import string
from abc import ABC, abstractmethod
import inspect
"""
class EnumBaseStyleMeta(type(Enum), type(BaseStyle)):
pass
"""
class Enum_Visibility_Character_Braille(Enum): # BaseStyle, metaclass=EnumBaseStyleMeta):
EMBOSSED = -1
HIDDEN = 0
VISIBLE = 1
def minimum():
return min([e.value for e in Enum_Visibility_Character_Braille])
def maximum():
return max([e.value for e in Enum_Visibility_Character_Braille])
def get_text_filename(self):
return '_0' if (self == Enum_Visibility_Character_Braille.HIDDEN) else '__' if (self == Enum_Visibility_Character_Braille.EMBOSSED) else '_1'
class Style_Character_Braille(BaseModel, BaseStyle):
show_braille: Enum_Visibility_Character_Braille # = Enum_Visibility_Character_Braille.VISIBLE
show_letter: Enum_Visibility_Character_Braille # = Enum_Visibility_Character_Braille.VISIBLE
show_number: Enum_Visibility_Character_Braille # = Enum_Visibility_Character_Braille.VISIBLE
"""
def __new__(cls, braille, letter, number):
_m = 'style.__new__'
av.val_type(braille, "<enum 'elem_visibility'>", 'braille', _m)
av.val_type(braille, "<enum 'elem_visibility'>", 'braille', _m)
av.val_type(braille, "<enum 'elem_visibility'>", 'braille', _m)
return super(style, cls).__new__(cls)
def __init__(self, braille, letter, number):
self.braille = braille
self.letter = letter
self.number = number
"""
def get_text_filename(self):
return f"{self.show_braille.get_text_filename()}{self.show_letter.get_text_filename()}{self.show_number.get_text_filename()}"
@staticmethod
def get_default():
return Style_Character_Braille(show_braille=Enum_Visibility_Character_Braille.VISIBLE, show_letter=Enum_Visibility_Character_Braille.VISIBLE, show_number=Enum_Visibility_Character_Braille.VISIBLE)
@staticmethod
def get_defaults():
return [Style_Character_Braille.get_default()]
def as_row(self):
return [self.show_braille.name, self.show_letter.name, self.show_number.name]
"""
def input_from_console():
sizes = Size_Character_Braille.get_defaults()
count_sizes = len(sizes)
table_output = PrettyTable()
table_output.field_names = ['index', 'name', 'dot spacing', 'block height', 'character spacing', 'base height', 'dot height', 'dot bottom radius', 'dot top radius']
for index_size in range(count_sizes):
size_index = sizes[index_size]
table_output.add_row([index_size + 1] + size_index.as_row())
print()
print("Please select product dimensions configuration from below:")
print(table_output)
while True:
size_input = str(input("Product dimensions configuration (name or index): "))
print(size_input + " selected")
if size_input == "#!ERRORCODE!#": exit
for index_size in range(count_sizes):
if size_input == sizes[index_size].name or size_input == str(index_size + 1):
return sizes[index_size]
def input_many_from_console():
sizes_selected = []
print('Inputting many Size_Character_Braille objects')
print()
while True:
try:
count_sizes = int(input('Quantity of size objects to enter:'))
except: continue
for index_size in range(count_sizes):
print(f'Inputting size object {index_size + 1}')
size_new = Size_Character_Braille.input_from_console()
sizes_selected.append(size_new)
break
return sizes_selected
"""
def get_list_headings():
return ['show braille', 'show letter', 'show number']
class Size_Character_Braille(BaseModel, BaseStyle):
# ATTRIBUTE DECLARATION
name: str
spacing_dot: float = Field(ge = 0) # dp distance between dots
height_block: float = Field(ge = 0) # hblock height of
spacing_character: float = Field(ge = 0) # spacing between keys on keyboard
height_base: float = Field(ge = 0) # height of
height_dot: float = Field(ge = 0) # height of Braille dots
radius_bottom_dot: float = Field(ge = 0) # base radius of Braille dots
radius_top_dot : float = Field(ge = 0) # top radius of Braille dots
width_character_braille: float = 0
R_block_letter: List[float] = [0, 0, 0]
R_block_braille: List[float] = [0, 0, 0]
R_block_number: List[float] = [0, 0, 0]
size_font_alphabetic: float = 0
size_font_numeric: float = 0
sf_size_font_word_length: float = 0
sf_size_font_number_length: float = 0
def __init__(self, name, spacing_dot, height_block, spacing_character, height_base, height_dot, radius_bottom_dot, radius_top_dot):
BaseModel.__init__(self, name=name, spacing_dot=spacing_dot, height_block=height_block, spacing_character=spacing_character, height_base=height_base, height_dot=height_dot, radius_bottom_dot=radius_bottom_dot, radius_top_dot=radius_top_dot)
self.width_character_braille = self.spacing_dot + 2 * self.spacing_character + self.radius_bottom_dot * 2
self.R_block_letter = [self.width_character_braille, self.width_character_braille, self.height_block] # alphabet block dimensions [x, y]
self.R_block_braille = [self.width_character_braille, self.width_character_braille + self.spacing_dot, self.height_block] # braille block dimensions [x, y]
self.R_block_number = [self.width_character_braille, self.width_character_braille - 2 * self.spacing_character, self.height_block] #np.array(* i_s_num # number block dimensions [x, y] ' adjust to scalar coefficient rather than linear translation
self.size_font_alphabetic = self.R_block_letter[0] - 4 * self.spacing_character
self.size_font_numeric = self.size_font_alphabetic * 0.75
self.sf_size_font_word_length = 0.65 # scale factor for shrinking number text to fit more letters in single char space
self.sf_size_font_number_length = 0.75 # scale factor for shrinking message text to fit more letters in single char space
"""
# METHODS
def __new__(cls, name, dp, hblock, s, base_height, hcyl, rcyl, rsphere):
# FUNCTION
# Initialise class object
# ARGUMENTS
# str name - name size scheme
# float dp - distance between braille pins
# float hblock - height of base of each key
# float s - spacing
# float base_height - height of base block - board
# float hcyl - height of braille pins
# float rcyl - base radius of braille pins
# float rsphere - tip radius of braille pins
# ARGUMENT VALIDATION
_m = 'scrabble_dimensions.__new__'
v_arg_type = 'class attribute'
av.val_str(name, 'name', _m, 1, v_arg_type = v_arg_type)
av.full_val_float(dp, 'dp', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(hblock, 'hblock', _m, v_arg_type = v_arg_type)
av.full_val_float(s, 's', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(base_height, 'base_height', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(hcyl, 'hcyl', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(rcyl, 'rcyl', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(rsphere, 'rsphere', _m, 0, v_arg_type = v_arg_type)
# RETURNS
return super(scrabble_dimensions, cls).__new__(cls)
def __init__(self, name, dp, hblock, s, base_height, hcyl, rcyl, rsphere):
# FUNCTION
# Construct class object
# ARGUMENTS
# str name
# float dp
# float hblock
# float s
# float base_height
# float hcyl
# float rcyl
# float rsphere
# ARGUMENT VALIDATION
# see __new__()
# ATTRIBUTE INSTANTIATION
self.name = name
self.dp = dp
self.hblock = hblock
self.s = s
self.base_height = base_height
self.hcyl = hcyl
self.rcyl = rcyl
self.rsphere = rsphere
"""
def __repr__(self):
# FUNCTION
# Convert object to str representation
# RETURNS
return f"name = {self.name}, spacing_dot = {self.spacing_dot}, height_block = {self.height_block}, spacing_character = {self.spacing_character}, height_base = {self.height_base}, height_dot = {self.height_dot}, radius_bottom_dot = {self.radius_bottom_dot}, radius_top_dot = {self.radius_top_dot}"
def as_dict(self):
# FUNCTION
# Convert object attribute, value pairs to dictionary representation
# RETURNS
return {'name': self.name, 'spacing_dot': self.spacing_dot, 'height_block': self.height_block, 'spacing_character': self.spacing_character, 'height_base': self.height_base, 'height_dot': self.height_dot, 'radius_bottom_dot': self.radius_bottom_dot, 'radius_top_dot': self.radius_top_dot}
def as_row(self):
return [self.name, self.spacing_dot, self.height_block, self.spacing_character, self.height_base, self.height_dot, self.radius_bottom_dot, self.radius_top_dot]
def get_defaults():
k = 2.3622
s = 1
sizes = []
sizes.append(Size_Character_Braille('sz_1', 2.5, 2*s, s, 4*s, 1.2, 2/3, 1/2))
sizes.append(Size_Character_Braille('sz_2', 4, 1.28, s, 4*s, 1.2, 3/2, 1))
sizes.append(Size_Character_Braille('sz_3', 8, 2.5, s, 6*s, 1.2, 3/2, 1))
sizes.append(Size_Character_Braille('sz_4', 10, 3, 1, 6*s, 1.2, 3/2, 1))
sizes.append(Size_Character_Braille('sz_5', 10, 1, 1, 6*s, 1.2, 3/2, 1))
sizes.append(Size_Character_Braille('keyboard', 2.5, 0.8, 0.5, 4, 1.2, 2/3, 0.5))
sizes.append(Size_Character_Braille('poster', 2.5, 0.8, 0.5, 2, 1.2, 2/3, 0.5))
sizes.append(Size_Character_Braille('poster_big', 2.5*k, 0.8, 0.5*k, 2, 1.2, 2/3*k, 0.5*k))
# print('szs_scrabble')
return sizes
def get_default():
sizes_default = Size_Character_Braille.get_defaults()
return sizes_default['Character_Braille'].apply(lambda x: x if x.name == 'Keyboard' else None).dropna()[0]
"""
def input_from_console():
sizes = Size_Character_Braille.get_defaults()
count_sizes = len(sizes)
table_output = PrettyTable()
table_output.field_names = ['index', 'name', 'dot spacing', 'block height', 'character spacing', 'base height', 'dot height', 'dot bottom radius', 'dot top radius']
for index_size in range(count_sizes):
size_index = sizes[index_size]
table_output.add_row([index_size + 1] + size_index.as_row())
print()
print("Please select product dimensions configuration from below:")
print(table_output)
while True:
size_input = str(input("Product dimensions configuration (name or index): "))
print(size_input + " selected")
if size_input == "#!ERRORCODE!#": exit
for index_size in range(count_sizes):
if size_input == sizes[index_size].name or size_input == str(index_size + 1):
return sizes[index_size]
def input_many_from_console():
sizes_selected = []
print('Inputting many Size_Character_Braille objects')
print()
while True:
try:
count_sizes = int(input('Quantity of size objects to enter:'))
except: continue
for index_size in range(count_sizes):
print(f'Inputting size object {index_size + 1}')
size_new = Size_Character_Braille.input_from_console()
sizes_selected.append(size_new)
break
return sizes_selected
"""
def get_list_headings():
return ['name', 'dot spacing', 'block height', 'character spacing', 'base height', 'dot height', 'dot bottom radius', 'dot top radius']
"""
class Utils_Size_Character_Braille:
@staticmethod
@validate_arguments
def is_valid_size_input(size_input: str, sizes_valid: List[Size_Character_Braille]):
count_sizes_valid = len(sizes_valid)
for i_size_valid in range(count_sizes_valid):
if size_input == sizes_valid[i_size_valid].name:
return True
return False
"""
class Enum_Justification_Text(Enum):
LEFT = 0
CENTRE = 1
RIGHT = 2
def minimum():
return min([e.value for e in Enum_Visibility_Character_Braille])
def maximum():
return max([e.value for e in Enum_Visibility_Character_Braille])
def input_from_console(cls):
print("Please select justification for text:")
print("0. Left")
print("1. Centre")
print("2. Right")
while True:
justification_input = input("Justification (0, 1, 2): ")
print(str(justification_input) + " selected")
if justification_input == "#!ERRORCODE!#": exit
try:
justification_input = int(justification_input)
except: continue
# if justification_input is not int: continue
if justification_input < Enum_Justification_Text.minimum() or justification_input > Enum_Justification_Text.maximum(): continue
return Enum_Justification_Text(justification_input)
def get_default():
return Enum_Justification_Text(0)
def input_many_from_console():
return BaseStyle.input_many_from_console(Enum_Justification_Text)
class Keyboard_3D(ModelOpenSCAD): #, BaseModel):
size_characters: Size_Character_Braille
style_characters: Style_Character_Braille
colour_theme: Colour_Theme_Character_Braille
justification_text: Enum_Justification_Text
max_characters_per_row: int
translation: Translation_Braille # List[List[Character_Braille]]
# fn: int = Field(ge=0, default=25)
# filename: str = ''
def __init__(self, **kwargs): # , size_characters, style_characters, colour_theme, justification_text, path_dir, max_characters_per_row, translation, fn=25, filename=''):
# print(f'size_characters, style_characters, colour_theme, justification_text, path_dir, max_characters_per_row, translation, fn, filename: {size_characters, style_characters, colour_theme, justification_text, path_dir, max_characters_per_row, translation, fn, filename}')
# BaseModel.__init__(self, size_characters=size_characters, style_characters=style_characters, colour_theme=colour_theme, justification_text=justification_text, path_dir=path_dir, max_characters_per_row=max_characters_per_row, translation=translation, fn=fn, filename=filename)
# BaseModel.__init__(self, size_characters=size_characters, style_characters=style_characters, justification_text=justification_text, max_characters_per_row=max_characters_per_row, translation=translation, filename='')
# self.filename = self.get_filename()
ModelOpenSCAD.__init__(self, **{**kwargs, 'filename': '', 'model': None}) # , path_dir=path_dir, filename=filename, colour_theme=colour_theme, fn=fn)
# BaseModel.__init__(self, size_characters=size_characters, style_characters=style_characters, justification_text=justification_text, max_characters_per_row=max_characters_per_row, translation=translation)
# BaseModel.__init__(self, **kwargs) # , size_characters=size_characters, style_characters=style_characters, colour_theme=colour_theme, justification_text=justification_text, path_dir=path_dir, max_characters_per_row=max_characters_per_row, translation=translation, fn=fn, filename=filename)
self.filename = self.get_filename()
def get_filename(self): #, sz_scheme, col_theme, my_style, path_file = "C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\Braille_Scrabble", suffix = "stl", presuffix=""):
"""
av.val_str(path_file, 'path_file', _m)
av.val_str(suffix, 'suffix', _m)
av.val_str(presuffix, 'presuffix', _m)
"""
return f"{self.size_characters.name}_{self.colour_theme.name}{self.style_characters.get_text_filename()}"
def get_path_file(self, suffix):
return f"{self.path_dir}/{self.filename}.{suffix}"
@staticmethod
@validate_arguments
def make_from_styles_and_plaintext_and_proficiency_level(size_characters: Size_Character_Braille, style_characters: Style_Character_Braille, colour_theme: Colour_Theme_Character_Braille, justification_text: Enum_Justification_Text, path_dir: str, max_characters_per_row: int, plaintext: str, proficiency_level: Enum_Braille_Proficiency_Level):
braille_translation = Translation_Braille(plaintext, proficiency_level)
return Keyboard_3D(size_characters = size_characters, style_characters = style_characters, colour_theme = colour_theme, justification_text = justification_text, path_dir = path_dir, max_characters_per_row = max_characters_per_row, translation = braille_translation)
def make_model_openpyscad(self):
# integer boolean conversions for position
show_braille = (self.style_characters.show_braille == Enum_Visibility_Character_Braille.VISIBLE) # or self.style_characters.show_braille == Enum_Visibility_Character_Braille.EMBOSSED)
show_letter = (self.style_characters.show_letter == Enum_Visibility_Character_Braille.VISIBLE) # or self.style_characters.show_letter == Enum_Visibility_Character_Braille.EMBOSSED)
show_number = (self.style_characters.show_number == Enum_Visibility_Character_Braille.VISIBLE) # or self.style_characters.show_number == Enum_Visibility_Character_Braille.EMBOSSED)
# dimensions
"""
width_character_braille = self.size_characters.spacing_dot + 2 * self.size_characters.spacing_character + self.size_characters.radius_bottom_dot * 2
R_base_letter = [width_character_braille, width_character_braille, self.size_characters.height_block] # alphabet block dimensions [x, y]
R_base_braille = [width_character_braille, width_character_braille + self.size_characters.spacing_dot, self.size_characters.height_block] # braille block dimensions [x, y]
R_base_number = [width_character_braille, width_character_braille - 2 * self.size_characters.spacing_character, self.size_characters.height_block] #np.array(* i_s_num # number block dimensions [x, y] ' adjust to scalar coefficient rather than linear translation
"""
# _fn = self.fn
model_positive = ops.Union()
model_negative = ops.Union()
count_rows = 0
count_characters_in_row = 0
size_character = np.array([
self.size_characters.spacing_character + self.size_characters.width_character_braille,
self.size_characters.R_base_braille[1] * show_braille + self.size_characters.R_base_letter[1] * show_letter + self.size_characters.R_base_number[1] * show_number + self.size_characters.spacing_character * (show_braille + show_letter + show_number),
0
])
origin_character = np.array([-self.size_characters.spacing_character, -self.size_characters.spacing_character, 0])
for braille_translation in self.translation:
length_translation = len(braille_translation.braille_text)
if count_characters_in_row + length_translation > self.max_characters_per_row or (braille_translation.plaintext == 'NEWLINE' and braille_translation.list_dots_braille == [0, 0, 0, 0, 0, 0] and count_characters_in_row > 0):
count_rows += 1
count_characters_in_row = 0
for character in braille_translation.braille_text:
model_character_positive, model_character_negative = self.make_model_openscad_from_character(character) # character.make_model_openpyscad()
position_character = origin_character + np.array([
(self.size_characters.spacing_character + size_character[0]) * count_characters_in_row,
(self.size_characters.spacing_character + size_character[1]) * count_rows,
0
])
model_character_positive.translate(position_character)
model_positive.append(model_character_positive)
model_character_negative.translate(position_character)
model_negative.append(model_character_negative)
count_characters_in_row += 1
self.model = ops.Difference()
self.model.append(model_character_positive)
self.model.append(model_character_negative)
return self.model
@validate_arguments
def make_model_openscad_from_character(self, character: Character_Braille): # origin_character: List[float] , show_braille: bool, show_letter: bool, show_number: bool
show_braille = (self.style_characters.show_braille == Enum_Visibility_Character_Braille.VISIBLE) # or self.style_characters.show_braille == Enum_Visibility_Character_Braille.EMBOSSED)
show_letter = (self.style_characters.show_letter == Enum_Visibility_Character_Braille.VISIBLE or self.style_characters.show_letter == Enum_Visibility_Character_Braille.EMBOSSED)
show_number = (self.style_characters.show_number == Enum_Visibility_Character_Braille.VISIBLE) # or self.style_characters.show_number == Enum_Visibility_Character_Braille.EMBOSSED)
model_positive = ops.Union()
model_negative = ops.Union()
origin_block = np.array([0, 0, 0])
if show_braille:
block = self.make_model_openscad_block_braille_from_character(character)
block.translate(origin_block)
model_positive.append(block)
origin_block += np.array([
0,
-self.size_characters.spacing_character - self.size_characters.R_block_braille[1],
0
])
if show_letter:
block = self.make_model_openscad_block_letter_from_character(character)
block.translate(origin_block)
if self.style_characters.show_letter == Enum_Visibility_Character_Braille.VISIBLE:
model_positive.append(block)
else:
model_negative.append(block)
origin_block += np.array([
0,
-self.size_characters.spacing_character - self.size_characters.R_block_letter[1],
0
])
if show_number:
block = self.make_model_openscad_block_number_from_character(character)
block.translate(origin_block)
model_positive.append(block)
return model_positive, model_negative
"""
@validator('origin_character')
def validate_origin_character(cls, value):
if len(value) != 3:
raise ValueError("origin_character must have 3 elements")
for element in value:
if not isinstance(element, (int, float)):
raise ValueError("origin_character must be a list of integers or floats")
return value
@validator('R_block_braille')
def validate_R_block_braille(cls, value):
if len(value) != 3:
raise ValueError("R_block_braille must have 3 elements")
return value
@validator('R_block_letter')
def validate_R_block_letter(cls, value):
if len(value) != 3:
raise ValueError("R_block_letter must have 3 elements")
return value
@validator('R_block_number')
def validate_R_block_number(cls, value):
if len(value) != 3:
raise ValueError("R_block_number must have 3 elements")
return value
"""
@validate_arguments
def make_model_openscad_block_braille_from_character(self, character: Character_Braille):
model_block_braille = ops.Union()
if (self.style_characters.show_letter == Enum_Visibility_Character_Braille.HIDDEN): return model_block_braille
if (self.style_characters.show_letter == Enum_Visibility_Character_Braille.VISIBLE):
block = ops.Cube(self.size_characters.R_block_braille, center = False)
block.translate([0, -self.size_characters.R_block_braille[1], -self.size_characters.R_block_braille[2]])
block.color(self.colour_theme.colour_base)
model_block_braille.append(block)
if (self.style_characters.show_braille == Enum_Visibility_Character_Braille.VISIBLE):
for index_dot_braille_y in range(3):
for index_dot_braille_x in range(2):
if (character.matrix_braille_dots[index_dot_braille_y][index_dot_braille_x]):
dot_braille = ops.Cylinder(
h = self.size_characters.height_cylinder,
r1 = self.size_characters.radius_bottom_cylinder,
r2 = self.size_characters.radius_top_cylinder,
center = True,
_fn = self.fn
)
dot_braille.translate([
index_dot_braille_x * self.size_characters.spacing_dot,
-index_dot_braille_y * self.size_characters.spacing_dot,
0
])
dot_braille.color(self.colour_theme.colour_top)
model_block_braille.append(dot_braille)
return model_block_braille
@validate_arguments
def make_model_openscad_block_letter_from_character(self, character: Character_Braille):
font = '"Arial:style=Bold"'
model_block_letter = ops.Union()
if (self.style_characters.show_letter == Enum_Visibility_Character_Braille.HIDDEN): return model_block_letter
if (self.style_characters.show_letter == Enum_Visibility_Character_Braille.VISIBLE):
block = ops.Cube(self.size_characters.R_block_letter, center = False)
block.translate([0, -self.size_characters.R_block_letter[1], -self.size_characters.R_block_letter[2]])
block.color(self.colour_theme.colour_base)
model_block_letter.append(block)
size_text = self.size_characters.size_font_alphabetic * self.size_characters.scale_text ** (len(character.plaintext) - 1)
model_letter = ops.Text(f'"{character.plaintext}"', size_text, font, halign = '"center"', valign = '"center"', _fn = self.fn)
model_letter.linear_extrude(self.size_characters.height_dot, center = False)
model_letter.color(self.colour_theme.colour_top)
model_letter.translate([
self.size_characters.R_block_letter[0] / 2,
self.size_characters.R_block_letter[1] / 2 if (self.style_characters.show_letter == Enum_Visibility_Character_Braille.VISIBLE) else self.size_characters.R_block_braille[1] / 2,
0 if (self.style_characters.show_letter == Enum_Visibility_Character_Braille.VISIBLE) else self.size_characters.height_dot - self.size_characters.height_block - self.size_characters.height_base
])
model_block_letter.append(model_letter)
return model_block_letter
@validate_arguments
def make_model_openscad_block_number_from_character(self, character: Character_Braille):
model_block_number = ops.Union()
if (self.style_characters.show_number == Enum_Visibility_Character_Braille.HIDDEN or self.style_characters.show_number == Enum_Visibility_Character_Braille.EMBOSSED or len(character.plaintext) != 1): return model_block_number
font = '"Arial:style=Bold"'
number = string.ascii_lowercase.index(character.plaintext.lower()) + 1
length_number = len(str(number))
if (number < 1 or number > 26): return model_block_number
block = ops.Cube(self.size_characters.R_block_number, center = True)
block.translate([])
block.color(self.colour_theme.colour_base)
model_block_number.append(block)
size_text = (self.size_characters.R_block_number[1] - self.size_characters.spacing_character * (len(number) + 1)) / (len(number) ** self.size_characters.sf_size_font_number_length)
model_number = ops.Text(f'"{number}"', size_text, font, halign = '"center"', valign = '"center"', _fn = self.fn)
model_number.linear_extrude(self.size_characters.height_dot, center = True)
model_number.color(self.colour_theme.colour_top)
model_number.translate([
self.size_characters.R_block_number[0] / 2 if (length_number == 1) else self.size_characters.R_block_number[0] / 2 + 1.6 * size_text * (number - (length_number - 1) / 2),
self.size_characters.R_block_number[1] * 0.25,
self.size_characters.height_dot / 2
])
model_block_number.append(model_number)
return model_block_number
def make_file_openscad(self):
if self.model is None:
self.make_model_openpyscad()
self.model.write(self.get_path_file('scad'))
def make_file_stl(self):
if not os.path.exists(self.get_path_file('scad')):
self.make_file_openscad()
render_openscad(self.get_path_file('scad'), self.get_path_file('stl'))
def make_file_png(self):
if not os.path.exists(self.get_path_file('scad')):
self.make_file_openscad()
render_openscad(self.get_path_file('scad'), self.get_path_file('png'))

View File

@@ -1,88 +1,24 @@
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 24 14:26:02 2023
@author: Edward Middleton-Smith
Braille 3D Model Product Creation
"""
from translate_msg_2_braille import get_braille_translations, gen_product_inputs, input_product
from translate_braille_2_scad import gen_scrabble_sizes, elem_visibility, input_colour_themes, style
from export_3d import gen_product_permutations, gen_3d_models, gen_snippet_assembly
import argument_validation as av
# from translate_msg_2_braille import get_braille_translations, gen_product_inputs, input_product
# from translate_braille_2_scad import gen_scrabble_sizes, elem_visibility, input_colour_themes, style
# from export_3d import gen_product_permutations, gen_3d_models, gen_snippet_assembly
# import argument_validation as av
from product_braille import Product_Braille
"""
# PARAMETERS
path_folder_cmd = 'C:\\"Program Files"\\OpenSCAD\\openscad' # 'C:\\"Program Files (x86)"\\OpenSCAD\\openscad' # local environment variable path for openscad commands
path_folder = "C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\" # file export parent directory
my_option = -1 # index of product option - if not valid, user console input will be required
my_select = '' # character selection for Braille tile(s) (if chosen)
size_permutations = False # generate models for all size options?
size_option = -1 # size option as int index - not required if size_permutations
colour_permutations = False # generate models for all colour options?
colour_option = '' # colour option as str or int index - not required if colour_permutations
show_braille = elem_visibility.VISIBLE # how should Braille be shown?
show_let = elem_visibility.VISIBLE # EMBOSSED # how should plaintext be shown?
show_num = elem_visibility.HIDDEN # how should ordinality be shown?
# assembly component spacing
dx = 5 # horizontnal
dy = 10 # vertical
"""
# METHODS
def generate(my_option = -1, my_select = '', size_permutations = False, size_option = -1, colour_permutations = False, colour_option = 'Purple', show_braille = elem_visibility.VISIBLE, show_let = elem_visibility.VISIBLE, show_num = elem_visibility.HIDDEN, dx = 5, dy = 10, path_folder_cmd = 'C:\\"Program Files"\\OpenSCAD\\openscad', path_folder = "C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\"):
# FUNCTION
# generate Braille model(s)
# ARGUMENTS
# int my_option - index of product option - if not valid, user console input will be required
# str my_select - character selection for Braille tile(s) (if chosen)
# bool size_permutation -
# int size_option - index of product_sizes option - ignored if size_permutations
# # bool colour_permutation
# elem_visibility show_braille
# elem_visibility show_let
# elem_visibility show_num
# float dx
# float dy
# str path_folder_cmd
# str path_folder
# VARIABLE INSTANTIATION
_m ='generate'
# ARGUMENT VALIDATION
av.val_int(my_option, 'my_option', _m)
av.val_str(my_select, 'my_select', _m)
av.val_bool(size_permutations, 'size_permutations', _m)
av.val_int(size_option, 'size_option', _m)
av.val_bool(colour_permutations, 'colour_permutations', _m)
# av.val_type(show_braille, "<enum 'translate_braille_2_scad.elem_visibility'>", 'show_braille', _m)
# av.val_type(show_let, "<enum 'translate_braille_2_scad.elem_visibility'>", 'show_let', _m)
# av.val_type(show_num, "<enum 'translate_braille_2_scad.elem_visibility'>", 'show_num', _m)
av.val_type(show_braille, "<enum 'elem_visibility'>", 'show_braille', _m)
av.val_type(show_let, "<enum 'elem_visibility'>", 'show_let', _m)
av.val_type(show_num, "<enum 'elem_visibility'>", 'show_num', _m)
av.val_int(dx, 'dx', _m)
av.val_int(dy, 'dy', _m)
av.val_str(path_folder_cmd, 'path_folder_cmd', _m)
av.val_str(path_folder, 'path_folder', _m)
# METHODS
mystyle = style(show_braille, show_let, show_num)
# Get Braille dictionary + delimiters
braille_translations = get_braille_translations()
# Get list of products that can be generated
products = gen_product_inputs(braille_translations)
# input product selection from user and translate to braille
my_product = input_product(braille_translations, products, my_option, my_select) # my_option)
# get list of product size configurations
sizes_product = gen_scrabble_sizes()
# generate product size (and content for Scrabble tile array) permutations
mymsgs, myszs = gen_product_permutations(my_product, sizes_product, size_permutations, size_option)
# get product colour selection
colour_themes = input_colour_themes(colour_permutations, colour_option)
# generate openscad, stl, and png files of selected product(s)
gen_3d_models(braille_translations, my_product, mymsgs, myszs, my_product.line_length, path_folder, path_folder_cmd, mystyle, colour_themes)
# generate assembly of products for promotional content, as scad + png
gen_snippet_assembly(dx, dy, my_product.line_length, colour_themes, myszs, my_product, path_folder, path_folder_cmd, mystyle)
# generate()
# generate(1, 'A')
generate(my_option, my_select, size_permutations, size_option, colour_permutations, colour_option, show_braille, show_let, show_num, dx, dy, path_folder_cmd, path_folder)
# generate(my_option, my_select, size_permutations, size_option, colour_permutations, colour_option, elem_visibility.VISIBLE, elem_visibility.VISIBLE, elem_visibility.VISIBLE, dx, dy, path_folder_cmd, path_folder)
if __name__ == '__main__':
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()
product = Product_Braille.input_from_console()
product.make_files()

View File

@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
"""
@author: Edward Middleton-Smith
"""
class Model_Braille():
#

View File

@@ -7,29 +7,16 @@ Created on Thu Apr 27 12:03:30 2023
Procedural OpenSCAD Generation
https://github.com/taxpon/openpyscad/blob/develop/openpyscad/base.py
"""
#import argument_validation as av
from colour_theme_braille_character import Colour_Theme_Character_Braille
# CLASSES
# ATTRIBUTE DECLARATION
# METHODS
# FUNCTION
# ARGUMENTS
# ARGUMENT VALIDATION
# ATTRIBUTE + VARIABLE INSTANTIATION
# METHODS
# RETURNS
# NORMAL METHODS
# FUNCTION
# ARGUMENTS
# ARGUMENT VALIDATION
# VARIABLE INSTANTIATION
# METHODS
# RETURNS
import openpyscad as ops
import argument_validation as av
# import openpyscad as ops
from openpyscad import Union
from typing import Optional
from pydantic import BaseModel, Field, validator
# from pydantic.fields import ModelField
from abc import ABC, abstractmethod
import os
def bool_2_str(mybool):
# FUNCTION
@@ -103,7 +90,7 @@ def triprism(a, L, centre = True):
# RETURNS
return ops.Polygon([[0,0], [0, a], [a, 0]]).linear_extrude(L, center = bool_2_str(centre)).translate([-a/2 if centre else 0, -a/3 if centre else 0, 0])
def gen_openscad_colours():
def get_openscad_colours():
return [ # openscad_colours = [
"Lavender",
"Thistle",
@@ -246,4 +233,84 @@ def gen_openscad_colours():
"SlateGray",
"DarkSlateGray",
"Black"
]
]
"""
def base_fillet_cube(a, b, c, f, q, centre = "true"):
# fillets removed as they print horribly
# now just cube
my_dif = ops.Difference();
my_dif.append(ops.Cube([a, b, c], center = "true", _fn = q));
return my_dif.translate([0 if (centre == "true") else a/2, 0 if (centre == "true") else b/2, 0 if (centre == "true") else c/2])
def triprism(a, L, centre = "true"):
return ops.Polygon([[0,0], [0, a], [a, 0]]).linear_extrude(L, center = "true").translate([0, 0, 0 if (centre == "true") else L/2]);
"""
"""
def __get_pydantic_core_schema__(cls, handler):
return handler.generate_schema(ops.Union)
ops.Union.__get_pydantic_core_schema__ = classmethod(__get_pydantic_core_schema__)
class Union_Field(ModelField):
def __init__(self, **kwargs):
super().__init__(**kwargs)
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, value):
if not isinstance(value, Union):
raise ValueError(f'Union_Field: {value} is not a valid Union. Type: {type(value)}')
return value
"""
class ObjectOpenSCAD(BaseModel, ABC):
path_dir: str
filename: str
def __init__(self, **kwargs): # , path_dir, filename
# print(f'ObjectOpenSCAD: {path_dir}, {filename}')
# BaseModel.__init__(self, path_dir=path_dir, filename=filename)
# super().__init__(path_dir=path_dir, filename=filename, **kwargs)
BaseModel.__init__(self, **kwargs)
@validator('path_dir')
def validate_path_dir(cls, value):
if not os.path.exists(value):
raise ValueError("Path not found: " + value)
return value
@abstractmethod
def write(self):
pass
class ModelOpenSCAD(ObjectOpenSCAD): # , BaseModel):
colour_theme: Colour_Theme_Character_Braille
fn: int = 25
model: Optional[Union] = None #= Field(default_factory=Union) # : Optional[ops.Union] = None
def __init__(self, **kwargs): # , path_dir, filename, colour_theme, fn):
# print(f'ModelOpenSCAD: {path_dir}, {filename}, {colour_theme}, {fn}')
ObjectOpenSCAD.__init__(self, **kwargs) # , path_dir=path_dir, filename=filename)
BaseModel.__init__(self, **{**kwargs, 'model': None}) # , colour_theme=colour_theme, fn=fn)
self.model = Union()
def write(self):
self.model.write(self.path_dir + self.filename + '.scad')
class Config:
arbitrary_types_allowed = True
class AssemblyOpenSCAD(ObjectOpenSCAD): # , BaseModel):
dx: int
dy: int
max_models_per_row: int
fn: int = Field(ge=0)
def __init__(self, path_dir, filename, dx, dy, max_models_per_row, fn=25):
ObjectOpenSCAD.__init__(self, path_dir, filename)
BaseModel.__init__(self, dx, dy, max_models_per_row, fn)
self.assembly = ops.Assembly()

View File

@@ -0,0 +1,278 @@
# -*- coding: utf-8 -*-
"""
@author: Edward Middleton-Smith
"""
import openpyscad as ops
import numpy as np
# import argument_validation as av
# from openscad_objects import get_openscad_colours
from character_braille import Character_Braille
from keyboard_3d import Keyboard_3D, Size_Character_Braille, Style_Character_Braille, Enum_Justification_Text
from array_keyboard_3d import Array_Keyboard_3D
from colour_theme_braille_character import Colour_Theme_Character_Braille
from translation_braille import Translation_Braille, Enum_Braille_Proficiency_Level
from typing import Optional, Union, List
from prettytable import PrettyTable
from enum import Enum
from pydantic import BaseModel, Field, ValidationError, validate_arguments
# from color import Color
class Product_Braille(BaseModel):
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
"""
keyboards: Array_Keyboard_3D
def __init__(self, name, keyboards, **kwargs):
BaseModel.__init__(self, name=name, keyboards=keyboards, **kwargs)
"""
def __new__(cls, name, line_length, msg, msg_prefix = '', filename = ''):
# 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)
av.val_str(filename, 'filename', _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, line_length, msg, msg_prefix = '', filename = ''):
# 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(' ', '_') if filename == '' else filename
def __repr__(self):
return f"name = {self.name}, line_length = {self.line_length}, msg = {self.msg}, msg_prefix = {self.msg_prefix}, filename = {self.filename}"
size_characters: Size_Character_Braille
style_characters: Style_Character_Braille
colour_theme: Colour_Theme_Character_Braille
style_keyboard: Style_Keyboard_Braille
path_dir: str
# filename: str
characters: List[Character_Braille]
max_characters_per_row: int
"""
def get_defaults():
sizes_default = Size_Character_Braille.get_defaults()
size_default = sizes_default[5]
print(f'type of size_default: {str(type(size_default))}')
style_default = Style_Character_Braille.get_default()
print(f'type of style_default: {str(type(style_default))}')
colour_default = Colour_Theme_Character_Braille.get_default()
print(f'type of colour_default: {str(type(colour_default))}')
# colour_default = colours_default[0]
justification_default = Enum_Justification_Text(0)
print(f'type of justification_default: {str(type(justification_default))}')
proficiency_level_default = Enum_Braille_Proficiency_Level(1)
print(f'type of proficiency_level_default: {str(type(proficiency_level_default))}')
path_dir = "C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\Braille\\models_3d"
print(f'type of path_dir: {str(type(path_dir))}')
defaults = []
translation_extended_alphabet = Translation_Braille("abcdefg@?NOTHINGhijKLMNOPQRS@?NOTHINGTUVXYZANDFOROFTHEWITHCHGHSHTHWHEDEROUOWWEABBCCDDENFF?GGINBY", proficiency_level_default)
print(f'type of translation_extended_alphabet: {str(type(translation_extended_alphabet))}')
# keyboard_extended_alphabet = Keyboard_3D(size_characters=size_default, style_characters=style_default, colour_theme=colour_default, justification_text=justification_default, path_dir=path_dir, max_characters_per_row=10, translation=translation_extended_alphabet, fn=25)
defaults.append(Product_Braille("Extended Alphabet",
# [keyboard_extended_alphabet]
Array_Keyboard_3D(
sizes_characters = [size_default],
styles_characters = [style_default],
colour_themes = [colour_default],
justifications_text = [justification_default],
path_dir= path_dir,
max_characters_per_rows = [10],
translations = [translation_extended_alphabet],
fn = 25
)
))
defaults.append(Product_Braille("Upper Groupsigns",
# [keyboard_extended_alphabet]
Array_Keyboard_3D(
sizes_characters = [size_default],
styles_characters = [style_default],
colour_themes = [colour_default],
justifications_text = [justification_default],
path_dir= path_dir,
max_characters_per_rows = [10],
translations = [Translation_Braille("uppe@?nothingr@?BLANK_SPACEGRO@?NOTHINGUPSIGNsand:a@?nothingn@?nothingd@?BLANK_SPACEfor:fo@?nothingr@?BLANK_SPACEof:o@?nothingf@?BLANK_SPACEthe:t@?nothingh@?nothinge@?BLANK_SPACEwith:wi@?nothingt@?nothingh@?BLANK_SPACE"+"@?NEWLINECH:C@?NOTHINGH@?BLANK_SPACE" + "GH:G@?NOTHINGH@?BLANK_SPACE" + "SH:S@?NOTHINGH@?BLANK_SPACE@?BLANK_SPACE" + "TH:T@?NOTHINGH@?BLANK_SPACE" + "WH:W@?NOTHINGH@?BLANK_SPACE" + "ED:E@?NOTHINGD@?BLANK_SPACE@?BLANK_SPACE" + "ER:E@?NOTHINGR@?BLANK_SPACE" + "OU:O@?NOTHINGU@?BLANK_SPACE" + "OW:O@?NOTHINGW@?BLANK_SPACE@?BLANK_SPACE"+"st:s@?nothingt@?BLANK_SPACEar:a@?nothingr@?BLANK_SPACEble:bl@?nothinge@?BLANK_SPACE@?BLANK_SPACEing:i@?nothingng", proficiency_level_default)],
fn = 25
)
))
# defaults.append(Product_Braille("Upper Wordsigns", [Keyboard_3D(size_default, style_default, colour_default, justification_default, path_dir, 24, gen_difficulty_msgstr(braille_dict, difficulty(3)), 25)]))
defaults.append(Product_Braille("Alphabet",
# [keyboard_extended_alphabet]
Array_Keyboard_3D(
sizes_characters = [size_default],
styles_characters = [style_default],
colour_themes = [colour_default],
justifications_text = [justification_default],
path_dir= path_dir,
max_characters_per_rows = [10],
translations = [Translation_Braille("ABCDEFG@?NOTHINGHIJKLMNOPQRSTUVWXYZ", proficiency_level_default)],
fn = 25
)
))
# defaults.append(Product_Braille("Travel", [Keyboard_3D(size_default, style_default, colour_default, justification_default, path_dir, 5, Translation_Braille("ABCDEFG@?NOTHINGHIJ", proficiency_level_default), 25)]))
defaults.append(Product_Braille("Demo",
# [keyboard_extended_alphabet]
Array_Keyboard_3D(
sizes_characters = [size_default],
styles_characters = [style_default],
colour_themes = [colour_default],
justifications_text = [justification_default],
path_dir= path_dir,
max_characters_per_rows = [9],
translations = [Translation_Braille("BRAILLE", proficiency_level_default)],
fn = 25
)
))
defaults.append(Product_Braille("Scrabble Alphabet of Tiles",
# [keyboard_extended_alphabet]
Array_Keyboard_3D(
sizes_characters = [size_default],
styles_characters = [style_default],
colour_themes = [colour_default],
justifications_text = [justification_default],
path_dir= path_dir,
max_characters_per_rows = [1],
translations = [Translation_Braille("uppe@?nothingr@?BLANK_SPACEGRO@?NOTHINGUPSIGNsand:a@?nothingn@?nothingd@?BLANK_SPACEfor:fo@?nothingr@?BLANK_SPACEof:o@?nothingf@?BLANK_SPACEthe:t@?nothingh@?nothinge@?BLANK_SPACEwith:wi@?nothingt@?nothingh@?BLANK_SPACE"+"@?NEWLINECH:C@?NOTHINGH@?BLANK_SPACE" + "GH:G@?NOTHINGH@?BLANK_SPACE" + "SH:S@?NOTHINGH@?BLANK_SPACE@?BLANK_SPACE" + "TH:T@?NOTHINGH@?BLANK_SPACE" + "WH:W@?NOTHINGH@?BLANK_SPACE" + "ED:E@?NOTHINGD@?BLANK_SPACE@?BLANK_SPACE" + "ER:E@?NOTHINGR@?BLANK_SPACE" + "OU:O@?NOTHINGU@?BLANK_SPACE" + "OW:O@?NOTHINGW@?BLANK_SPACE@?BLANK_SPACE"+"st:s@?nothingt@?BLANK_SPACEar:a@?nothingr@?BLANK_SPACEble:bl@?nothinge@?BLANK_SPACE@?BLANK_SPACEing:i@?nothingng", proficiency_level_default)],
fn = 25
)
))
defaults.append(Product_Braille("Scrabble Character Tile",
# [keyboard_extended_alphabet]
Array_Keyboard_3D(
sizes_characters = [size_default],
styles_characters = [style_default],
colour_themes = [colour_default],
justifications_text = [justification_default],
path_dir= path_dir,
max_characters_per_rows = [1],
translations = [Translation_Braille("uppe@?nothingr@?BLANK_SPACEGRO@?NOTHINGUPSIGNsand:a@?nothingn@?nothingd@?BLANK_SPACEfor:fo@?nothingr@?BLANK_SPACEof:o@?nothingf@?BLANK_SPACEthe:t@?nothingh@?nothinge@?BLANK_SPACEwith:wi@?nothingt@?nothingh@?BLANK_SPACE"+"@?NEWLINECH:C@?NOTHINGH@?BLANK_SPACE" + "GH:G@?NOTHINGH@?BLANK_SPACE" + "SH:S@?NOTHINGH@?BLANK_SPACE@?BLANK_SPACE" + "TH:T@?NOTHINGH@?BLANK_SPACE" + "WH:W@?NOTHINGH@?BLANK_SPACE" + "ED:E@?NOTHINGD@?BLANK_SPACE@?BLANK_SPACE" + "ER:E@?NOTHINGR@?BLANK_SPACE" + "OU:O@?NOTHINGU@?BLANK_SPACE" + "OW:O@?NOTHINGW@?BLANK_SPACE@?BLANK_SPACE"+"st:s@?nothingt@?BLANK_SPACEar:a@?nothingr@?BLANK_SPACEble:bl@?nothinge@?BLANK_SPACE@?BLANK_SPACEing:i@?nothingng", proficiency_level_default)],
fn = 25
)
))
return defaults
def input_from_console(): # (braille_dict, products, my_option: Optional[int] = -1, my_select: Optional[str] = ''):
products = Product_Braille.get_defaults()
count_products = len(products)
print('Braille Products:')
for i in range(count_products):
print(f"{i + 1}. {products[i].name}")
print()
known_translations = Translation_Braille.get_defaults() # Character_Braille.get_Translation_Brailles()
while True:
index_selected = input(f"Please enter your selection (1 - {count_products}) from the products above\n") #, 'select_i'
print(index_selected + " selected")
if index_selected == '#!ERRORCODE!#':
exit
try:
index_selected = int(index_selected)
# if index_selected is not int:
except:
print('not int')
continue
if index_selected < 1 or index_selected > count_products:
print('out of range')
continue
product_selected = products[index_selected - 1]
if index_selected == count_products:
while True:
plaintext = str(input("Please enter a character selection for your Scrabble tile\n"))
print(plaintext + " selected")
if plaintext == '#!ERRORCODE!#':
exit
if plaintext is not str:
continue
"""
if len(plaintext) != 1:
continue
"""
if not known_translations.apply(lambda x: x.plaintext == plaintext).any():
continue
translation = known_translations.apply(lambda x: x if x.plaintext == plaintext else None).dropna().values[0]
product_selected.keyboard = Keyboard_3D(product_selected.keyboard.size_characters, product_selected.keyboard.style_characters, product_selected.keyboard.colour_theme, product_selected.keyboard.justification_text, product_selected.keyboard.path_dir, translation, product_selected.keyboard.max_characters_per_row)
break
"""
for keyboard in product_selected.keyboards:
keyboard.size_characters = Size_Character_Braille.input_from_console()
keyboard.style_characters = Style_Character_Braille.input_from_console()
keyboard.colour_theme = Colour_Theme_Character_Braille.input_from_console()
keyboard.justification_text = Enum_Justification_Text.input_from_console()
"""
sizes_characters = Size_Character_Braille.input_many_from_console(Size_Character_Braille)
styles_characters = Style_Character_Braille.input_many_from_console(Style_Character_Braille)
colour_themes = Colour_Theme_Character_Braille.input_many_from_console(Colour_Theme_Character_Braille)
justifications_text = Enum_Justification_Text.input_many_from_console()
product_selected.keyboards.update_configurations_styles(sizes_characters, styles_characters, colour_themes, justifications_text)
print(product_selected.__repr__() + " selected")
return product_selected
"""
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 make_combined_assembly(self, dx, dy, max_keyboards_per_row):
self.keyboards.make_combined_assembly(dx, dy, max_keyboards_per_row)
def make_files_openscad(self):
self.keyboards.make_files_openscad()
def make_files_stl(self):
self.keyboards.make_files_stl()
def make_files_png(self):
self.keyboards.make_files_png()
def make_files(self):
self.keyboards.make_files()

View File

@@ -1,664 +0,0 @@
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 26 17:11:57 2023
@author: Edward Middleton-Smith
Braille 3D Model Product Creation
Plaintext message translation into Braille for 3D modelling
Procedural OpenSCAD Generation
Braille Scrabble Pieces
"""
# CLASSES
# ATTRIBUTE DECLARATION
# METHODS
# FUNCTION
# ARGUMENTS
# ARGUMENT VALIDATION
# ATTRIBUTE + VARIABLE INSTANTIATION
# METHODS
# RETURNS
# NORMAL METHODS
# FUNCTION
# ARGUMENTS
# ARGUMENT VALIDATION
# VARIABLE INSTANTIATION
# METHODS
# RETURNS
import openpyscad as ops
import numpy as np
import argument_validation as av
from openscad_objects import gen_openscad_colours
from typing import Optional
from prettytable import PrettyTable
from enum import Enum
class elem_visibility(Enum):
EMBOSSED = -1
HIDDEN = 0
VISIBLE = 1
def mini():
# FUNCTION
# Get minimum value in enumerator
# RETURNS
return min([e.value for e in elem_visibility])
def maxi():
# FUNCTION
# Get maximum value in enumerator
# RETURNS
return max([e.value for e in elem_visibility])
class style():
# ATTRIBUTE DECLARATION
braille: elem_visibility
letter: elem_visibility
number: elem_visibility
def __new__(cls, braille, letter, number):
_m = 'style.__new__'
av.val_type(braille, "<enum 'elem_visibility'>", 'braille', _m)
av.val_type(braille, "<enum 'elem_visibility'>", 'braille', _m)
av.val_type(braille, "<enum 'elem_visibility'>", 'braille', _m)
return super(style, cls).__new__(cls)
def __init__(self, braille, letter, number):
self.braille = braille
self.letter = letter
self.number = number
def gen_filetxt(mystyle):
# FUNCTION
# generate filename text for style settings
# ARGUMENTS
# style mystyle
# ARGUMENT VALIDATION
av.val_type(mystyle, "<class 'translate_braille_2_scad.style'>", 'mystyle', 'get_style_filetxt')
# VARIABLE INSTANTIATION
style_txt = '_0b' if (mystyle.braille == elem_visibility.HIDDEN) else ''
style_txt += '_0l' if (mystyle.letter == elem_visibility.HIDDEN) else ''
style_txt += '__l' if (mystyle.letter == elem_visibility.EMBOSSED) else ''
style_txt += '_0n' if (mystyle.number == elem_visibility.HIDDEN) else ''
# RETURNS
return style_txt
def base_fillet_cube(a, b, c, f, q, centre = "true"):
# fillets removed as they print horribly
# now just cube
my_dif = ops.Difference();
my_dif.append(ops.Cube([a, b, c], center = "true", _fn = q));
return my_dif.translate([0 if (centre == "true") else a/2, 0 if (centre == "true") else b/2, 0 if (centre == "true") else c/2])
def triprism(a, L, centre = "true"):
return ops.Polygon([[0,0], [0, a], [a, 0]]).linear_extrude(L, center = "true").translate([0, 0, 0 if (centre == "true") else L/2]);
class scrabble_dimensions:
# ATTRIBUTE DECLARATION
name: str
dp: float # distance between dots
hblock: float # height of
s: float # spacing between keys on keyboard
base_height: float # height of
hcyl: float # height of Braille dots
rcyl: float # base radius of Braille dots
rsphere: float # top radius of Braille dots
# METHODS
def __new__(cls, name, dp, hblock, s, base_height, hcyl, rcyl, rsphere):
# FUNCTION
# Initialise class object
# ARGUMENTS
# str name - name size scheme
# float dp - distance between braille pins
# float hblock - height of base of each key
# float s - spacing
# float base_height - height of base block - board
# float hcyl - height of braille pins
# float rcyl - base radius of braille pins
# float rsphere - tip radius of braille pins
# ARGUMENT VALIDATION
_m = 'scrabble_dimensions.__new__'
v_arg_type = 'class attribute'
av.val_str(name, 'name', _m, 1, v_arg_type = v_arg_type)
av.full_val_float(dp, 'dp', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(hblock, 'hblock', _m, v_arg_type = v_arg_type)
av.full_val_float(s, 's', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(base_height, 'base_height', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(hcyl, 'hcyl', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(rcyl, 'rcyl', _m, 0, v_arg_type = v_arg_type)
av.full_val_float(rsphere, 'rsphere', _m, 0, v_arg_type = v_arg_type)
# RETURNS
return super(scrabble_dimensions, cls).__new__(cls)
def __init__(self, name, dp, hblock, s, base_height, hcyl, rcyl, rsphere):
# FUNCTION
# Construct class object
# ARGUMENTS
# str name
# float dp
# float hblock
# float s
# float base_height
# float hcyl
# float rcyl
# float rsphere
# ARGUMENT VALIDATION
# see __new__()
# ATTRIBUTE INSTANTIATION
self.name = name
self.dp = dp
self.hblock = hblock
self.s = s
self.base_height = base_height
self.hcyl = hcyl
self.rcyl = rcyl
self.rsphere = rsphere
def __repr__(self):
# FUNCTION
# Convert object to str representation
# RETURNS
return f"name = {self.name}, dp = {self.dp}, hblock = {self.hblock}, s = {self.s}, base_height = {self.base_height}, hcyl = {self.hcyl}, rcyl = {self.rcyl}, rsphere = {self.rsphere}"
def as_dict(self):
# FUNCTION
# Convert object attribute, value pairs to dictionary representation
# RETURNS
return {'name': self.name, 'dp': self.dp, 'hblock': self.hblock, 's': self.s, 'base_height': self.base_height, 'hcyl': self.hcyl, 'rcyl': self.rcyl, 'rsphere': self.rsphere}
# colour themes: # ToDo: include in arguments to generator!!
class export_colour_theme:
# ATTRIBUTE DECLARATION
name: str
coltop: str
colbase: str
# METHODS
def __new__(cls, name, coltop, colbase, openscad_colours):
# FUNCTION
# Initialise class object
# ARGUMENTS
# str name - user reference to colour theme
# str coltop - a valid openSCAD colour e.g. '#010101'
# str colbase - a valid openSCAD colour e.g. 'blue'
# list[str] openscad_colours
# ARGUMENT VALIDATION
_m = 'export_colour_theme.__new__'
v_arg_type = 'class attribute'
av.val_str(name, 'name', _m, 1, v_arg_type = v_arg_type)
av.val_list(openscad_colours, 'openscad_colours', _m, "<class 'str'>", 1, v_arg_type = v_arg_type)
if not validate_openscad_colour(coltop, openscad_colours):
raise ValueError(f"Invalid export_colour_theme attribute coltop. Type = {str(type(coltop))}. Value = {coltop}")
if not validate_openscad_colour(colbase, openscad_colours):
raise ValueError(f"Invalid export_colour_theme attribute colbase. Type = {str(type(colbase))}. Value = {colbase}")
# RETURNS
return super(export_colour_theme, cls).__new__(cls)
def __init__(self, name, coltop, colbase, openscad_colours):
# FUNCTION
# Initialise class object
# ARGUMENTS
# str name - user reference to colour theme
# str coltop - a valid openSCAD colour e.g. '#010101'
# str colbase - a valid openSCAD colour e.g. 'blue'
# list[str] openscad_colours # redundant in this function - used for argument validation
# ARGUMENT VALIDATION
# see __new__()
# ATTRIBUTE INSTANTIATION
self.name = name
self.top = coltop
self.base = colbase
def __repr__(self):
# FUNCTION
# Convert object to str representation
# RETURNS
return f"name = {self.name}, colour top = {self.top}, colour base = {self.base}" # , openscad_colours = {self.openscad_colours}
def as_dict(self):
# FUNCTION
# Convert object attribute, value pairs to dictionary representation
# RETURNS
return {'name': self.name, 'colour top': self.top, 'colour base': self.base} # , 'openscad_colours': self.openscad_colours
def as_row(self):
# FUNCTION
# Convert object values to list representation
# RETURNS
return [self.name, self.top, self.base] # , 'openscad_colours': self.openscad_colours
def gen_scrabble_sizes(s: Optional[float] = 0.5):
# default scrabble sizes
# s = 1/2
# def __init__(self, name, dp, hblock, s, base_height, hcyl, rcyl, rsphere):
k = 2.3622
szs_scrabble = []
szs_scrabble.append(scrabble_dimensions('sz_1', 2.5, 2*s, s, 4*s, 1.2, 2/3, 1/2))
szs_scrabble.append(scrabble_dimensions('sz_2', 4, 1.28, s, 4*s, 1.2, 3/2, 1))
szs_scrabble.append(scrabble_dimensions('sz_3', 8, 2.5, s, 6*s, 1.2, 3/2, 1))
szs_scrabble.append(scrabble_dimensions('sz_4', 10, 3, 1, 6*s, 1.2, 3/2, 1))
szs_scrabble.append(scrabble_dimensions('sz_5', 10, 1, 1, 6*s, 1.2, 3/2, 1))
szs_scrabble.append(scrabble_dimensions('keyboard', 2.5, 0.8, 0.5, 4, 1.2, 2/3, 0.5))
szs_scrabble.append(scrabble_dimensions('poster', 2.5, 0.8, 0.5, 2, 1.2, 2/3, 0.5))
szs_scrabble.append(scrabble_dimensions('poster_big', 2.5*k, 0.8, 0.5*k, 2, 1.2, 2/3*k, 0.5*k))
# print('szs_scrabble')
# print(szs_scrabble)
return szs_scrabble # pd.DataFrame([x.as_dict() for x in szs_scrabble])
def input_product_size(szs_product, v_size = 2):
# FUNCTION
# input valid product size from user
# ARGUMENTS
# list[scrabble_dimensions] szs_product
# int v_size
# ARGUMENT VALIDATION
_m = 'get_product_size'
av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>")
av.val_int(v_size, 'v_size', _m)
# VARIABLE INSTANTIATION
n = len(szs_product)
# METHODS
if v_size > 0 and v_size <= n:
return szs_product[v_size - 1]
my_table = PrettyTable()
my_table.field_names = ['index', 'name', 'dp', 'hblock', 's', 'base_height', 'hcyl', 'rcyl', 'rsphere']
for i in range(n):
prod = szs_product[i]
my_table.add_row([i + 1, prod.name, prod.dp, prod.hblock, prod.s, prod.base_height, prod.hcyl, prod.rcyl, prod.rsphere])
print()
print("Please select product dimensions configuration from below:")
print(my_table)
# loopy = False
while True:
my_input = input("Product dimensions configuration (name or index): ")
if my_input == "#!ERRORCODE!#": exit
for i in range(n):
if validate_input_product_size(my_input, szs_product):
# loopy = True
# RETURNS
return get_product_size(my_input, szs_product)
def get_product_size(product_option, szs_product):
# FUNCTION
# get valid product size from list of scrabble_dimensions
# ARGUMENTS
# str/int product_option
# list[scrabble_dimensions] szs_product
# ARGUMENT VALIDATION
_m = 'get_product_size'
error_msg = av.error_msg_str(_m, product_option, 'product_option', 'scrabble_dimensions identifier')
if not (av.val_int(product_option, 'product_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(product_option, 'product_option', _m, suppress_errors = True, suppress_console_outputs = True)):
raise ValueError(error_msg)
av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>")
# VARIABLE INSTANTIATION
n = len(szs_product)
# METHODS
if av.full_val_int(product_option, 'product_option', _m, suppress_errors = True):
product_option = av.input_int(product_option, 'product_option', _m)
return szs_product[product_option - 1]
for col_i in range(n):
my_product = szs_product[col_i]
if product_option == my_product.name:
return my_product
# RETURNS
raise ValueError(error_msg)
def validate_input_product_size(product_option, szs_product):
# FUNCTION
# evaluate if product_option relates to a szs_product
# ARGUMENTS
# str/int product_option
# list[scrabble_dimensions] szs_product
# ARGUMENT VALIDATION
_m = 'validate_input_product_size'
if not (av.val_int(product_option, 'product_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(product_option, 'product_option', _m, suppress_errors = True, suppress_console_outputs = True)): return False
av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>")
# VARIABLE INSTANTIATION
n = len(szs_product)
# METHODS
if av.full_val_int(product_option, 'product_option', _m, suppress_errors = True):
product_option = av.input_int(product_option, 'product_option', _m)
return (0 < product_option and product_option <= n)
for prod_i in range(n):
if product_option == szs_product[prod_i].name:
return True
# RETURNS
return False
def validate_openscad_colour(mycolour, openscad_colours):
# FUNCTION
# validate argument openscad colour as string
# ARGUMENTS
# str mycolour - to be validated
# list[str] openscad_colours - to search through
# ARGUMENT VALIDATION
_m = 'validate_openscad_colour'
av.val_str(mycolour, 'mycolour', _m)
av.val_list(openscad_colours, 'openscad_colours', _m, "<class 'str'>")
# VARIABLE INSTANTIATION
N = len(mycolour)
# METHODS
if (N == 7):
if (mycolour[0] == '#' and mycolour[0:5].isnumeric):
return True
for i in range(len(openscad_colours)):
if (mycolour == openscad_colours[i]):
return True
# RETURNS
return False
# inputs
# path_scad = "C:/Users/edwar/OneDrive/Documents/OpenSCAD"
# path_stl = "C:/Users/edwar/OneDrive/Documents/OpenSCAD/STL"
# filename = "Braille_Scrabble_"
# cum = [0, 1]
# letters = ["B"]
# braille = [[2]]
# braille = [[[1, 1, 0, 0, 0, 0]]]
# lmsg = 1
# N = 1
# n_row_keys = 1
# maxln = 2
def gen_col_themes():
# FUNCTION
# create colour themes for image export of 3D models
# REQUIRES
# class export_colour_theme
# function gen_openscad_colours
# VARIABLE INSTANTIATION
openscad_colours = gen_openscad_colours()
col_themes = []
col_themes.append(export_colour_theme("Blue", "#337AFF", "#337AFF", openscad_colours))
col_themes.append(export_colour_theme("Purple", "#8E44AD", "#8E44AD", openscad_colours))
col_themes.append(export_colour_theme("Red", "#F7322F", "#F7322F", openscad_colours))
col_themes.append(export_colour_theme("Black", "Black", "#17202A", openscad_colours))
col_themes.append(export_colour_theme("White", "White", "White", openscad_colours))
# RETURNS
# list[export_colour_theme] col_themes - colour themes with name, top colour, base colour
return col_themes
def input_colour_themes(colour_permutations = False, colour_option = None):
# FUNCTION
# get valid colour option using parameter, else user console input
# ARGUMENTS
# bool colour_permutations
# int colour_option
# ARGUMENT VALIDATION
_m = 'input_colour_themes'
av.val_bool(colour_permutations, 'colour_permutations', _m)
if not (av.val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True) or str(type(colour_option)) == "<class 'NoneType'>"):
raise ValueError(av.error_msg_str(_m, 'colour_option', colour_option, "export_colour_theme identifier"))
# VARIABLE INSTANTIATION
colour_themes = gen_col_themes()
if colour_permutations: return colour_themes
n = len(colour_themes)
# METHODS
if not validate_input_colour(colour_option, colour_themes):
colour_table = PrettyTable(field_names=['index', 'name', 'colour top', 'colour base'])
for col_i in range(n):
colour_table.add_row([col_i + 1] + colour_themes[col_i].as_row()) # .insert(0, str(col_i + 1))
print(colour_table)
while not validate_input_colour(colour_option, colour_themes):
colour_option = input("Please input colour selection by name or index above.")
# RETURNS
return [get_colour_theme(colour_option, colour_themes)]
def validate_input_colour(colour_option, colour_themes):
# FUNCTION
# evaluate if colour_option relates to a colour_theme
# ARGUMENTS
# str/int colour_option
# list[export_colour_themes] colour_themes
# ARGUMENT VALIDATION
_m = 'validate_input_colour'
if not (av.val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True)): return False
av.val_list(colour_themes, 'colour_themes', _m, "<class 'translate_braille_2_scad.export_colour_theme'>")
# VARIABLE INSTANTIATION
n = len(colour_themes)
# METHODS
if av.full_val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True):
colour_option = av.input_int(colour_option, 'colour_option', _m)
return (0 < colour_option and colour_option <= n)
for col_i in range(n):
if colour_option == colour_themes[col_i].name:
return True
# RETURNS
return False
def get_colour_theme(colour_option, colour_themes):
# FUNCTION
# get valid colour_option from colour_themes
# ARGUMENTS
# str/int colour_option
# list[export_colour_themes] colour_themes
# ARGUMENT VALIDATION
_m = 'get_colour_theme'
error_msg = av.error_msg_str(_m, colour_option, 'colour_option', 'export_colour_theme identifier')
if not (av.val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True)):
raise ValueError(error_msg)
av.val_list(colour_themes, 'colour_themes', _m, "<class 'translate_braille_2_scad.export_colour_theme'>")
# VARIABLE INSTANTIATION
n = len(colour_themes)
# METHODS
if av.full_val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True):
colour_option = av.input_int(colour_option, 'colour_option', _m)
return colour_themes[colour_option - 1]
for col_i in range(n):
my_colour = colour_themes[col_i]
if colour_option == my_colour.name:
return my_colour
# ERROR HANDLING
raise ValueError(error_msg)
def gen_path_braille_scrabble(sz_scheme, col_theme, my_style, path_file = "C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\Braille_Scrabble", suffix = "stl", presuffix=""):
# FUNCTION
# generate file path for braille scrabble design
# ARGUMENTS
# scrabble_dimensions sz_scheme
# int letter - index in the alphabet with base 0
# export_colour_theme col_theme
# style my_style
# string path_file - path of folder + filename (message text)
# string suffix - file type
# string presuffix - text before file type
# ARGUMENT VALIDATION
_m = 'gen_path_braille_scrabble'
av.val_type(sz_scheme, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 'sz_scheme', _m)
av.val_type(col_theme, "<class 'translate_braille_2_scad.export_colour_theme'>", 'col_theme', _m)
av.val_type(my_style, "<class 'translate_braille_2_scad.style'>", 'my_style', _m)
av.val_str(path_file, 'path_file', _m)
av.val_str(suffix, 'suffix', _m)
av.val_str(presuffix, 'presuffix', _m)
# RETURNS
return f"{path_file}_{sz_scheme.name}_{col_theme.name}{my_style.gen_filetxt()}.{suffix}"
def gen_openscad_braille(cum, letters, numbers, braille, n_keys, n_row_keys, n_rows, mydims, mystyle, col_theme, filename, path_file="C:/Users/edwar/OneDrive/Documents/Programming/Python Scripts/Braille", quality = 25):
# FUNCTION
# generate openscad model of Braille product
# ARGUMENTS
# list[int] cum
# list[str] letters - array of plaintext for output
# list[int] numbers - ordinality of translated keys in alphabet / number line (where appropriate)
# list[list[int]] braille - translated keys
# int n_keys - number of keys in Braille message
# int n_row_keys - number of Braille keys per row on keyboard
# int n_rows - number of rows of keys on keyboard
# scrabble_dimensions mydims - sizing parameters
# style mystyle
# export_colour_themes col_theme
# str filename - excl. path
# str path_file
# ARGUMENT VALIDATION
_m = 'gen_openscad_braille'
av.val_list(cum, 'cum', _m, "<class 'int'>")
av.val_list(letters, 'letters', _m, "<class 'str'>")
av.val_nested_list(numbers, 0, 1, 'numbers', _m, "<class 'int'>")
av.val_nested_list(braille, 0, 2, 'braille', _m, "<class 'int'>", -1, [-1, -1, 6], -1, [-1, -1, 6])
av.val_int(n_keys, 'n_keys', _m)
av.val_int(n_row_keys, 'n_row_keys', _m)
av.val_int(n_rows, 'n_rows', _m)
# av.val_int(show_braille, 'show_braille', _m)
# av.val_int(show_let, 'show_let', _m)
# av.val_int(show_num, 'show_num', _m)
# av.val_type(show_braille, "<enum 'elem_visibility'>", 'show_braille', _m)
# av.val_type(show_let, "<enum 'elem_visibility'>", 'show_let', _m)
# av.val_type(show_num, "<enum 'elem_visibility'>", 'show_num', _m)
av.val_type(mystyle, "<class 'translate_braille_2_scad.style'>", 'mystyle', _m)
# if not (av.val_type(col_theme, "<class 'export_colour_theme'>", 'col_theme', _m, True) or av.val_type(col_theme, "<class 'translate_braille_2_scad.export_colour_theme'>", 'col_theme', _m, True)):
# raise ValueError(av.error_msg_str(_m, 'col_theme', col_theme, "<class 'export_colour_theme'>"))
av.val_type(col_theme, "<class 'translate_braille_2_scad.export_colour_theme'>", 'col_theme', _m)
av.val_str(filename, 'filename', _m)
av.val_str(path_file, 'path_file', _m)
# VARIABLE INSTANTIATION
# integer boolean conversions for position
i_s_braille = int(mystyle.braille == elem_visibility.VISIBLE)
i_s_let = int(mystyle.letter == elem_visibility.VISIBLE)
i_s_num = int(mystyle.number == elem_visibility.VISIBLE)
print(f'i_s_b = {i_s_braille}\ni_s_let = {i_s_let}\ni_s_num = {i_s_num}\n')
# dimensions
dp = mydims.dp # horizontal and vertical spacing between dots = 2.2 - 2.8mm
h_block = mydims.hblock # block height
s = mydims.s # inter-block spacing
h_base = mydims.base_height # thickness of base block
# derived from: horizontal distance between corresponding braille dots in adjacent cells = 5.1 - 6.8mm
# and also conforms to: vertical distance between corresponding braille dots in adjacent cells = 10 - 15mm
hcyl = mydims.hcyl # braille dot height
rcyl = mydims.rcyl #3/2; # braille dot base-radius
rsphere = mydims.rsphere #3/2*4/5; # braille dot top-radius
xb = dp + 2 * s + rcyl * 2
R_base_letter = [xb, xb] # alphabet block dimensions [x, y]
R_base_braille = [xb, xb + dp] # braille block dimensions [x, y]
R_base_number = np.array([xb, xb - 2 * s]) * i_s_num # number block dimensions [x, y] ' adjust to scalar coefficient rather than linear translation
htxt = hcyl # height of text
stxt = xb - 4 * s
snum = stxt * 0.75
ntxtsfn = 0.65 # scale factor for shrinking number text to fit more letters in single char space
ntxtsfm = 0.75 # scale factor for shrinking message text to fit more letters in single char space
font = '"Arial:style=Bold"'
_fn = quality
# keyboard layout
#maxln = 10;
#nln = min(maxln, N); # renamed n_row_keys
# temp = 1 + (N - 1) % nln
# yn = (N + nln - temp) / nln # - 0 ** (temp)
# print(f"number of rows = {yn}")
R_board = [n_row_keys * R_base_letter[0] + (n_row_keys + 3) * s,
n_rows * (R_base_braille[1] * i_s_braille + R_base_letter[1] * i_s_let + R_base_number[1] * i_s_num + s * (i_s_braille + i_s_let + i_s_num)) + 3 * s, # - 3 * s,
h_base] # +R_base_number[1]
print(f"R_board = {R_board}")
obj_dif = ops.Difference()
obj_uni = ops.Union()
# obj_uni.append(base_fillet_cube(R_board[0], R_board[1], R_board[2], h_block, centre = "false").translate([-2 * s - rcyl, 2 * s + rcyl - R_board[1], -h_block - R_board[2]]).color(col_theme.base))
obj_uni.append(ops.Cube([R_board[0], R_board[1], R_board[2]], h_block, centre = "false").translate([-3 * s - rcyl, 3 * s + rcyl - R_board[1], -h_block - R_board[2]]).color(col_theme.base))
# METHODS
for ab_i in range(len(braille)): # alpha-braille iterator
char = braille[ab_i]
print(f"char = braille[{ab_i}]") # " = {char}")
for char_j in range(len(char)):
char_old = [0, 0, 0, 0, 0, 0] if (ab_i == 0 and char_j == 0) else braille[0][char_j - 1] if (char_j > 0) else braille[ab_i - 1][len(braille[ab_i - 1]) - 1]
char_new = char[char_j]
print(f"char_new = {char_new}")
ab_n = (cum[ab_i] + char_j) % n_row_keys
ab_len = ((cum[ab_i] + char_j) - ab_n) / n_row_keys
ab_p = [ab_n * (R_base_braille[0] + s), -ab_len * (R_base_braille[1] * i_s_braille + R_base_letter[1] * i_s_let + R_base_number[1] * i_s_num + s * (i_s_braille + i_s_let + i_s_num)), 0]
# Bases
if (letters[ab_i] != " "):
if (mystyle.braille == elem_visibility.VISIBLE):
obj_uni.append(ops.Cube([R_base_braille[0], R_base_braille[1], h_block]).color(col_theme.base).translate([-(s + rcyl), s + rcyl - R_base_braille[1], -h_block]).translate(ab_p))
if (mystyle.letter == elem_visibility.VISIBLE):
obj_uni.append(ops.Cube([R_base_letter[0], R_base_letter[1], h_block]).color(col_theme.base).translate([-(s + rcyl), s + rcyl -R_base_letter[1], 0]).translate([0, -(R_base_braille[1] + s) * i_s_braille, -h_block]).translate(ab_p)) # should this be: rcyl - R_base_letter[1] ?????!?!?!?!!!!
# Braille message
# Dots
if (mystyle.braille == elem_visibility.VISIBLE):
for dot_y in range(3):
for dot_x in range(2):
if (char_new[dot_y + 3 * dot_x] == 1):
obj_uni.append(ops.Cylinder(hcyl, None, rcyl, rsphere, _fn = _fn, center = 'true').color(col_theme.top).translate([dot_x * dp, -dot_y * dp, 0]).translate(ab_p))
# Text
if (mystyle.letter == elem_visibility.VISIBLE):
obj_uni.append(ops.Text(f'"{letters[ab_i]}"', stxt * ntxtsfm ** (len(letters[ab_i]) - 1), font, halign = '"center"', valign = '"center"', _fn = _fn).linear_extrude(htxt, center = "false").translate([R_base_letter[0] / 2, R_base_letter[1] / 2, 0]).color(col_theme.top).translate([-(s + rcyl), s + rcyl -R_base_letter[1], 0]).translate([0, - (R_base_braille[1] + s) * i_s_braille, 0]).translate(ab_p))
# Text ordinality
num_new = numbers[ab_i]
if (num_new != [-1] and mystyle.number == elem_visibility.VISIBLE):
print(f"num_new = {num_new}, type = {type(num_new)}")
for num_x in range(len(num_new)):
snum = (R_base_number[1] - s * (len(num_new) + 1)) / (len(num_new) ** ntxtsfn)
# Base
obj_uni.append(ops.Cube([R_base_number[0], R_base_number[1], h_block]).color(col_theme.base).translate([0, -R_base_number[1], 0]).translate([-(s + rcyl), s + rcyl -(R_base_letter[1] + s) * i_s_let, 0]).translate([0, -(R_base_braille[1] + s) * i_s_braille, -h_block]).translate(ab_p))
# Number (text)
obj_uni.append(ops.Text(f'"{num_new[num_x]}"', snum, font, halign = '"center"', valign = '"center"', _fn = _fn).linear_extrude(htxt, center = "true").color(col_theme.top).translate([R_base_number[0] / 2 if (len(num_new) == 1) else R_base_number[0] / 2 + 1.6 * snum * (num_x - (len(num_new) - 1) / 2), R_base_number[1] * 0.25, htxt / 2]).translate([-s, s -R_base_number[1], 0]).translate([0, -(R_base_letter[1] - s) * i_s_let, 0]).translate([s-(s + rcyl), s - (R_base_braille[1] + s) * i_s_braille, -h_block * 0]).translate(ab_p))
obj_dif.append(obj_uni)
# remove excess plastic if no numbers on final row regardless of mystyle.number
remove_num_space = True
for ab_i in range(n_row_keys):
remove_num_space &= numbers[len(numbers) - ab_i - 1] == [-1]
# Trimming tools for no numbers:
if remove_num_space:
obj_dif.append(ops.Cube([R_board[0], R_base_number[1] + s, R_board[2]], center = "true").translate([R_board[0] / 2 - 3 * s - rcyl, 3 * s + rcyl + (R_base_number[1] + s) / 2 - R_board[1], -R_board[2] / 2 - h_block]))
# obj_dif.append(triprism(h_block, R[0], centre = "true").rotate([0, 90, 0]).translate([R[0] / 2 - 1.6, (12+4) * s - R[1], -1/1000 - R[2] - h_block]))
# embossed characters
for ab_i in range(len(braille)):
char = braille[ab_i]
print(f"char = braille[{ab_i}]") # " = {char}")
for char_j in range(len(char)):
# what is the purpose of char_old?
char_old = [0, 0, 0, 0, 0, 0] if (ab_i == 0 and char_j == 0) else braille[0][char_j - 1] if (char_j > 0) else braille[ab_i - 1][len(braille[ab_i - 1]) - 1]
char_new = char[char_j]
ab_n = (cum[ab_i] + char_j) % n_row_keys
ab_len = ((cum[ab_i] + char_j) - ab_n) / n_row_keys
ab_p = [ab_n * (R_base_braille[0] + s), -ab_len * (R_base_braille[1] * i_s_braille + R_base_letter[1] * i_s_let + R_base_number[1] * i_s_num + s * (i_s_braille + i_s_let + i_s_num)), 0]
# Text
if (mystyle.letter == elem_visibility.EMBOSSED):
obj_dif.append(ops.Text(f'"{letters[ab_i]}"', stxt * ntxtsfm ** (len(letters[ab_i]) - 1) * 1.15, font, halign = '"center"', valign = '"center"', _fn = _fn).linear_extrude(htxt, center = "false").mirror([1, 0, 0]).translate([R_base_letter[0] / 2, R_base_letter[1] * 3 / 4, - R_board[2]]).color(col_theme.top).translate([0, -R_base_braille[1], 0]).translate([-(s + rcyl), s + rcyl - (R_base_braille[1] + s) * i_s_braille * 0, -h_block]).translate(ab_p))
# my_prefix = '_0b' if (mystyle.braille == elem_visibility.HIDDEN) else ''
# my_prefix += '_0l' if (mystyle.letter == elem_visibility.HIDDEN) else ''
# my_prefix += '__l' if (mystyle.letter == elem_visibility.EMBOSSED) else ''
# my_prefix += '_0n' if (mystyle.number == elem_visibility.HIDDEN) else ''
# my_prefix = mystyle.gen_filetxt()
path_png = gen_path_braille_scrabble(mydims, col_theme, mystyle, path_file, 'png')
path_scad = gen_path_braille_scrabble(mydims, col_theme, mystyle, path_file, 'scad')
path_stl = gen_path_braille_scrabble(mydims, col_theme, mystyle, path_file, 'stl')
# RETURNS
obj_dif.write(path_scad)
print("writing SCAD")
# obj_dif.write(path_png)
return path_png, path_scad, path_stl
# def get_shownum(braille):
# shownum = 1
# for n_x in range(len(braille)):
# shownum &= not (not braille[n_x])
# return 0 # 1 if shownum else 0

View File

@@ -1,801 +0,0 @@
# -*- 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 = '', filename = ''):
# 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)
av.val_str(filename, 'filename', _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, line_length, msg, msg_prefix = '', filename = ''):
# 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(' ', '_') if filename == '' else filename
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"), 'select_i', _m, 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("Demo", 9, "BRAILLE"))
products.append(product("Scrabble Alphabet of Tiles", 1, '', filename = 'Scrabble_Tile_Set'))
products.append(product("Scrabble Character Tile", 1, '', filename = 'Scrabble_Tile'))
# 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 = 0
maxstrlen = max_key_len(brailledict)
# METHODS
print(f"msgin = {msgin}")
while (msg_i_0 < iter_lim):
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(cum[start_of_word], line_length)
n_rows_next = n_lines_at_pos(new_cum, line_length)
if ((not new_word) and n_rows_0 < n_rows_next and not (cum[start_of_word] % 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
letters.append(brailledict[brailledict['key'] == phrase]['plaintext'].values[0])
elif phrase == "@?NOTHING":
msg_i_0 += 9
print('found nothing')
found = True
elif phrase == "@?NEWLINE":
msg_i_0 += 9
print('forced newline')
cum[len(cum) - 1] += (line_length - (cum[len(cum) - 1] % line_length)) % line_length
found = True
new_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')
new_word = True
# unfound character??
if phrase_len == 0 and not (found or (ord(phrase) >= 48 and ord(phrase) <= 57)):
print(f"Unfound phrase: {phrase}")
msg_i_0 += 1
new_word = True
# word start position
if new_word:
start_of_word = len(cum) - 1 # position within cum
# OUTPUTS
# console output
n_keys = max(cum)
n_rows = n_rows_0
cum = cum[0 : len(cum) - 1]
# 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

View File

@@ -0,0 +1,433 @@
# -*- coding: utf-8 -*-
"""
Created on 29/05/2024
@author: Edward Middleton-Smith
"""
from character_braille import Character_Braille
import pandas as pd
from typing import Optional, List
from pydantic import BaseModel, conlist, validator
from enum import Enum
# import argument_validation as av
import sys
class Enum_Braille_Proficiency_Level(Enum):
ALPHABET_PUNCTUATION = 1
SIMPLE_WORD_AND_GROUPSIGNS = 2
LOWER_CONTRACTIONS = 3
def minimum():
return min([e.value for e in Enum_Braille_Proficiency_Level])
def maximum():
return max([e.value for e in Enum_Braille_Proficiency_Level])
# Matrix_Braille_Dots = Annotated(List[List[bool]], conlist(conlist(bool, min_items=2, max_items=2), min_items=3, max_items=3))
class Translation_Braille(BaseModel):
plaintext: str # English plaintext key
translation_proficiency_level: Enum_Braille_Proficiency_Level # stage of learning at which this translation is discovered
braille_text: List[Character_Braille] = [] # Braille translation of plaintext
search_key: Optional[str] = None
def __init__(self, plaintext, translation_proficiency_level, braille_text=[], search_key= None):
super().__init__(plaintext=plaintext, translation_proficiency_level=translation_proficiency_level, braille_text=braille_text, search_key=search_key)
self.plaintext = self.plaintext.upper()
if braille_text == []:
self.braille_text = self.translate_text_to_Braille()
if search_key is None:
self.search_key = plaintext
def __repr__(self):
return f"{self.plaintext} - {self.translation_proficiency_level} - {self.braille_text}"
def translate_text_to_Braille(self):
known_translations = Translation_Braille.get_defaults_DataFrame()
# print(f'known_translations: {known_translations}')
delimiters = Translation_Braille.get_delimiters()
braille_text = []
max_key_length = known_translations.apply(lambda x: len(x[3]), axis=1).max() # [Translation_Braille.__name__]
length_plaintext = len(self.plaintext)
# dict_iterator = braille_dict[braille_dict['level'] == level]
index_key_start = 0
while index_key_start < length_plaintext:
found_key = False
for key_length in range(min(max_key_length, length_plaintext - index_key_start), 0, -1):
key = self.plaintext[index_key_start : index_key_start + key_length]
"""if key in delimiters:
character_braille = Character_Braille.get_blank_Character_Braille()
character_braille.plaintext = delimiters[key]
braille_text.append(character_braille)
index_key_start += key_length
continue
el"""
if key == "@?NOTHING":
index_key_start += key_length
found_key = True
break
elif key == "@?NEWLINE":
character_braille = Character_Braille("NEWLINE", [0, 0, 0, 0, 0, 0])
braille_text.append(character_braille)
index_key_start += key_length
found_key = True
break
if known_translations.apply(lambda x: x[3] == key and x[1].value <= self.translation_proficiency_level.value, axis=1).any():
translation_Braille = known_translations.apply(lambda x: x if (x[3] == key and x[1].value <= self.translation_proficiency_level.value) else None, axis=1).dropna().values.tolist()[0]
# print(f'translation_Braille: {translation_Braille}')
# character_braille = known_translations[index_Character_Braille]
braille_text.append(translation_Braille[2])
# print(f'braille_text: {braille_text}')
index_key_start += key_length
found_key = True
break
#elif key_length == 1:
if not found_key:
raise KeyError("Key not found starting from: ", key)
"""
for key in range(len(dict_iterator.index)):
bd_n = dict_iterator['key'][dict_iterator.index[bd_i]]
str_out += "@?NOTHING" + bd_n
"""
return braille_text
def get_delimiters():
return {
"@?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",
}
def get_defaults_DataFrame():
df = pd.DataFrame(data=[
["A", Enum_Braille_Proficiency_Level(1), [[1, 0, 0, 0, 0, 0]], None],
["B", Enum_Braille_Proficiency_Level(1), [[1, 1, 0, 0, 0, 0]], None],
["C", Enum_Braille_Proficiency_Level(1), [[1, 0, 0, 1, 0, 0]], None],
["D", Enum_Braille_Proficiency_Level(1), [[1, 0, 0, 1, 1, 0]], None],
["E", Enum_Braille_Proficiency_Level(1), [[1, 0, 0, 0, 1, 0]], None],
["F", Enum_Braille_Proficiency_Level(1), [[1, 1, 0, 1, 0, 0]], None],
["G", Enum_Braille_Proficiency_Level(1), [[1, 1, 0, 1, 1, 0]], None],
["H", Enum_Braille_Proficiency_Level(1), [[1, 1, 0, 0, 1, 0]], None],
["I", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 1, 0, 0]], None],
["J", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 1, 1, 0]], None],
["K", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 0, 0, 0]], None],
["L", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 0, 0, 0]], None],
["M", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 1, 0, 0]], None],
["N", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 1, 1, 0]], None],
["O", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 0, 1, 0]], None],
["P", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 1, 0, 0]], None],
["Q", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 1, 1, 0]], None],
["R", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 0, 1, 0]], None],
["S", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 1, 0, 0]], None],
["T", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 1, 1, 0]], None],
["U", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 0, 0, 1]], None],
["V", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 0, 0, 1]], None],
["W", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 1, 1, 1]], None],
["X", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 1, 0, 1]], None],
["Y", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 1, 1, 1]], None],
["Z", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 0, 1, 1]], None],
['NUMBER', Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 1, 1, 1]], "@?NUM"],
#" ", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 0, 0, 0]], None],
[",", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 0, 0, 0]], None],
[";", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 0, 0]], None],
[":", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 0, 1, 0]], None],
[".", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 0, 1, 1]], None],
["!", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 1, 0]], None],
["(", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 1, 1]], None],
[")", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 1, 1]], None],
["?", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 0, 1]], None],
['"', Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 0, 1]], '"@?BO'],
['"', Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 1, 1]], '"@?BC'],
["'", Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 0, 0]], None],
["ABBREV", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 0]], "@?ABBREV1"],
["ABBREV", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 0]], "@?ABBREV2"],
["ABBREV", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 1]], "@?ABBREV3"],
["ABBREV", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 0, 1, 0]], "@?ABBREV4"],
["...", Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0]], None],
["-", Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 0, 1]], None],
["-", Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1]], "-@?S"],
["-", Enum_Braille_Proficiency_Level(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]], "-@?L"],
["/", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "/@?B"],
["\\", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "\@?B"],
["[", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "[@?BPH"],
["]", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "]@?BPH"],
["<", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]], None],
[">", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]], None],
["/", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 1], [0, 0, 1, 1, 0, 0]], None],
["{", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]], None],
["}", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]], None],
["[", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 1]], "[@?BSQ"],
["]", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1]], "]@?BSQ"],
["'", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 0, 1]], "'@?BO"],
["'", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 0, 1], [0, 0, 0, 0, 0, 1]], "'@?BC"],
# oldbrailledict_2 = {
# Simple Upper Wordsigns
["BUT", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 0, 0]], None],
["CAN", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 0, 0]], None],
["DO", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 1, 0]], None],
["EVERY", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 1, 0]], None],
["FROM", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 1, 0, 0]], None],
["GO", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 1, 1, 0]], None],
["HAVE", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 1, 0]], None],
["JUST", Enum_Braille_Proficiency_Level(2), [[0, 1, 0, 1, 1, 0]], None],
["KNOWLEDGE", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 0, 0, 0]], None],
["LIKE", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 0, 0, 0]], None],
["MORE", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 1, 0, 0]], None],
["NOT", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 1, 1, 0]], None],
["PEOPLE", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 1, 0, 0]], None],
["QUITE", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 1, 1, 0]], None],
["RATHER", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 0, 1, 0]], None],
["SO", Enum_Braille_Proficiency_Level(2), [[0, 1, 1, 1, 0, 0]], None],
["THAT", Enum_Braille_Proficiency_Level(2), [[0, 1, 1, 1, 1, 0]], None],
["US", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 0, 0, 1]], None],
["VERY", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 0, 0, 1]], None],
["WILL", Enum_Braille_Proficiency_Level(2), [[0, 1, 0, 1, 1, 1]], None],
["IT", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 1, 0, 1]], None],
["YOU", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 1, 1, 1]], None],
["AS", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 0, 1, 1]], None],
["CHILD", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 0, 1]], None],
["SHALL", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 0, 1]], None],
["THIS", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 1, 1]], None],
["WHICH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 1, 1]], None],
["OUT", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 1, 1]], None],
["STILL", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 0, 0]], None],
# Simple Upper Groupsigns
["AND", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 1, 0, 1]], None],
["FOR", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 1, 1, 1]], None],
["OF", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 0, 1, 1]], None],
["THE", Enum_Braille_Proficiency_Level(2), [[0, 1, 1, 1, 0, 1]], None],
["WITH", Enum_Braille_Proficiency_Level(2), [[0, 1, 1, 1, 1, 1]], None],
["CH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 0, 1]], None],
["GH", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 0, 1]], None],
["SH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 0, 1]], None],
["TH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 1, 1]], None],
["WH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 1, 1]], None],
["ED", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 1, 0, 1]], None],
["ER", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 1, 1, 1]], None],
["OU", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 1, 1]], None],
["OW", Enum_Braille_Proficiency_Level(2), [[0, 1, 0, 1, 0, 1]], None],
["ST", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 0, 0]], None],
["AR", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 1, 0]], None],
["ING", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 0, 1]], None],
["BLE", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 1, 1]], None],
# oldbrailledict_3 = {
# Lower Contractions
# Initial Groupsigns
["BE", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 0, 0]], None],
["COM", Enum_Braille_Proficiency_Level(3), [[0, 0, 1, 0, 0, 1]], None],
["CON", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 1, 0]], None],
["DIS", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 1, 1]], None],
# Initial-Medial-Terminal Groupsigns
["EN", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 0, 1]], None],
["IN", Enum_Braille_Proficiency_Level(3), [[0, 0, 1, 0, 1, 0]], None],
# Medial Groupsigns
["EA", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 0, 0]], None],
["BB", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 0, 0]], None],
["CC", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 1, 0]], None],
["DD", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 1, 1]], None],
["FF", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 1, 0]], None],
["GG", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 1, 1]], None],
# Wordsigns
["ENOUGH", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 0, 1]], None],
["TO", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 1, 0]], None],
["WERE", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0 , 1, 1]], None],
["HIS", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 0, 1]], None],
["INTO", Enum_Braille_Proficiency_Level(3), [[0, 0, 1, 0, 1, 0], [0, 1, 1, 0, 1, 0]], None], #(sequenced)
["BY", Enum_Braille_Proficiency_Level(3), [[0, 0, 1, 0, 1, 1]], None], #(sequenced)
["WAS", Enum_Braille_Proficiency_Level(3), [[0, 0 , 1, 0 , 1, 1]], None],
# Modifiers
["LET", Enum_Braille_Proficiency_Level(3), [[0, 0, 0, 0, 1, 1]], "@?LET"],
["CAPS", Enum_Braille_Proficiency_Level(3), [[0, 0, 0, 0, 0, 1]], "@?CAPS"],
["EMPH", Enum_Braille_Proficiency_Level(3), [[0, 0, 0, 1, 0, 1]], "@?EMPH"],
[" ", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 0, 0, 0]], "@?BLANK_SPACE"],
], columns=['plaintext', 'translation_proficiency_level', 'lists_dots_braille', 'search_key']) # Translation_Braille.__name__])
df.loc[df["search_key"].isnull(), "search_key"] = df["plaintext"]
return df
def get_defaults():
# return [Translation_Braille(plaintext, translation_proficiency_level, lists_dots_braille, search_key) for [plaintext, translation_proficiency_level, lists_dots_braille, search_key] in Translation_Braille.get_defaults_DataFrame()]
return pd.DataFrame(data={Translation_Braille.__name__: Translation_Braille.get_defaults_DataFrame().apply(lambda x: Translation_Braille(x[0], x[1], [Character_Braille(x[0] if index_y == 0 else '', x[2][index_y]) for index_y in range(len(x[2]))], x[3]), axis=1)})
"""
def get_defaults():
return pd.DataFrame(data={Translation_Braille.__name__: [
Character_Braille("A", Enum_Braille_Proficiency_Level(1), [[1, 0, 0, 0, 0, 0]]),
Character_Braille("B", Enum_Braille_Proficiency_Level(1), [[1, 1, 0, 0, 0, 0]]),
Character_Braille("C", Enum_Braille_Proficiency_Level(1), [[1, 0, 0, 1, 0, 0]]),
Character_Braille("D", Enum_Braille_Proficiency_Level(1), [[1, 0, 0, 1, 1, 0]]),
Character_Braille("E", Enum_Braille_Proficiency_Level(1), [[1, 0, 0, 0, 1, 0]]),
Character_Braille("F", Enum_Braille_Proficiency_Level(1), [[1, 1, 0, 1, 0, 0]]),
Character_Braille("G", Enum_Braille_Proficiency_Level(1), [[1, 1, 0, 1, 1, 0]]),
Character_Braille("H", Enum_Braille_Proficiency_Level(1), [[1, 1, 0, 0, 1, 0]]),
Character_Braille("I", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 1, 0, 0]]),
Character_Braille("J", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 1, 1, 0]]),
Character_Braille("K", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 0, 0, 0]]),
Character_Braille("L", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 0, 0, 0]]),
Character_Braille("M", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 1, 0, 0]]),
Character_Braille("N", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 1, 1, 0]]),
Character_Braille("O", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 0, 1, 0]]),
Character_Braille("P", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 1, 0, 0]]),
Character_Braille("Q", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 1, 1, 0]]),
Character_Braille("R", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 0, 1, 0]]),
Character_Braille("S", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 1, 0, 0]]),
Character_Braille("T", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 1, 1, 0]]),
Character_Braille("U", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 0, 0, 1]]),
Character_Braille("V", Enum_Braille_Proficiency_Level(1), [[1, 1, 1, 0, 0, 1]]),
Character_Braille("W", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 1, 1, 1]]),
Character_Braille("X", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 1, 0, 1]]),
Character_Braille("Y", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 1, 1, 1]]),
Character_Braille("Z", Enum_Braille_Proficiency_Level(1), [[1, 0, 1, 0, 1, 1]]),
Character_Braille('NUMBER', Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 1, 1, 1]], "@?NUM"),
#" ", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 0, 0, 0]]),
Character_Braille(",", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 0, 0, 0]]),
Character_Braille(";", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 0, 0]]),
Character_Braille(":", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 0, 1, 0]]),
Character_Braille(".", Enum_Braille_Proficiency_Level(1), [[0, 1, 0, 0, 1, 1]]),
Character_Braille("!", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 1, 0]]),
Character_Braille("(", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 1, 1]]),
Character_Braille(")", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 1, 1]]),
Character_Braille("?", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 0, 1]]),
Character_Braille('"', Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 0, 1]], '"@?BO'),
Character_Braille('"', Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 1, 1]], '"@?BC'),
Character_Braille("'", Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 0, 0]]),
Character_Braille("ABBREV", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 0]], "@?ABBREV1"),
Character_Braille("ABBREV", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 0]], "@?ABBREV2"),
Character_Braille("ABBREV", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 1]], "@?ABBREV3"),
Character_Braille("ABBREV", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 0, 1, 0]], "@?ABBREV4"),
Character_Braille("...", Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0]]),
Character_Braille("-", Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 0, 1]]),
Character_Braille("-", Enum_Braille_Proficiency_Level(1), [[0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1]], "-@?S"),
Character_Braille("-", Enum_Braille_Proficiency_Level(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]], "-@?L"),
Character_Braille("/", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "/@?B"),
Character_Braille("\\", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "\@?B"),
Character_Braille("[", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "[@?BPH"),
Character_Braille("]", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "]@?BPH"),
Character_Braille("<", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]]),
Character_Braille(">", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]]),
Character_Braille("/", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 1, 1], [0, 0, 1, 1, 0, 0]]),
Character_Braille("{", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]]),
Character_Braille("}", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]]),
Character_Braille("[", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 1]], "[@?BSQ"),
Character_Braille("]", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1]], "]@?BSQ"),
Character_Braille("'", Enum_Braille_Proficiency_Level(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 0, 1]], "'@?BO"),
Character_Braille("'", Enum_Braille_Proficiency_Level(1), [[0, 1, 1, 0, 0, 1], [0, 0, 0, 0, 0, 1]], "'@?BC"),
# oldbrailledict_2 = {
# Simple Upper Wordsigns
Character_Braille("BUT", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 0, 0]]),
Character_Braille("CAN", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 0, 0]]),
Character_Braille("DO", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 1, 0]]),
Character_Braille("EVERY", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 1, 0]]),
Character_Braille("FROM", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 1, 0, 0]]),
Character_Braille("GO", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 1, 1, 0]]),
Character_Braille("HAVE", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 1, 0]]),
Character_Braille("JUST", Enum_Braille_Proficiency_Level(2), [[0, 1, 0, 1, 1, 0]]),
Character_Braille("KNOWLEDGE", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 0, 0, 0]]),
Character_Braille("LIKE", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 0, 0, 0]]),
Character_Braille("MORE", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 1, 0, 0]]),
Character_Braille("NOT", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 1, 1, 0]]),
Character_Braille("PEOPLE", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 1, 0, 0]]),
Character_Braille("QUITE", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 1, 1, 0]]),
Character_Braille("RATHER", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 0, 1, 0]]),
Character_Braille("SO", Enum_Braille_Proficiency_Level(2), [[0, 1, 1, 1, 0, 0]]),
Character_Braille("THAT", Enum_Braille_Proficiency_Level(2), [[0, 1, 1, 1, 1, 0]]),
Character_Braille("US", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 0, 0, 1]]),
Character_Braille("VERY", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 0, 0, 1]]),
Character_Braille("WILL", Enum_Braille_Proficiency_Level(2), [[0, 1, 0, 1, 1, 1]]),
Character_Braille("IT", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 1, 0, 1]]),
Character_Braille("YOU", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 1, 1, 1]]),
Character_Braille("AS", Enum_Braille_Proficiency_Level(2), [[1, 0, 1, 0, 1, 1]]),
Character_Braille("CHILD", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 0, 1]]),
Character_Braille("SHALL", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 0, 1]]),
Character_Braille("THIS", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 1, 1]]),
Character_Braille("WHICH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 1, 1]]),
Character_Braille("OUT", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 1, 1]]),
Character_Braille("STILL", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 0, 0]]),
# Simple Upper Groupsigns
Character_Braille("AND", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 1, 0, 1]]),
Character_Braille("FOR", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 1, 1, 1]]),
Character_Braille("OF", Enum_Braille_Proficiency_Level(2), [[1, 1, 1, 0, 1, 1]]),
Character_Braille("THE", Enum_Braille_Proficiency_Level(2), [[0, 1, 1, 1, 0, 1]]),
Character_Braille("WITH", Enum_Braille_Proficiency_Level(2), [[0, 1, 1, 1, 1, 1]]),
Character_Braille("CH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 0, 1]]),
Character_Braille("GH", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 0, 1]]),
Character_Braille("SH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 0, 1]]),
Character_Braille("TH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 1, 1, 1]]),
Character_Braille("WH", Enum_Braille_Proficiency_Level(2), [[1, 0, 0, 0, 1, 1]]),
Character_Braille("ED", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 1, 0, 1]]),
Character_Braille("ER", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 1, 1, 1]]),
Character_Braille("OU", Enum_Braille_Proficiency_Level(2), [[1, 1, 0, 0, 1, 1]]),
Character_Braille("OW", Enum_Braille_Proficiency_Level(2), [[0, 1, 0, 1, 0, 1]]),
Character_Braille("ST", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 0, 0]]),
Character_Braille("AR", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 1, 0]]),
Character_Braille("ING", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 0, 1]]),
Character_Braille("BLE", Enum_Braille_Proficiency_Level(2), [[0, 0, 1, 1, 1, 1]]),
# oldbrailledict_3 = {
# Lower Contractions
# Initial Groupsigns
Character_Braille("BE", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 0, 0]]),
Character_Braille("COM", Enum_Braille_Proficiency_Level(3), [[0, 0, 1, 0, 0, 1]]),
Character_Braille("CON", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 1, 0]]),
Character_Braille("DIS", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 1, 1]]),
# Initial-Medial-Terminal Groupsigns
Character_Braille("EN", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 0, 1]]),
Character_Braille("IN", Enum_Braille_Proficiency_Level(3), [[0, 0, 1, 0, 1, 0]]),
# Medial Groupsigns
Character_Braille("EA", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 0, 0]]),
Character_Braille("BB", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 0, 0]]),
Character_Braille("CC", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 1, 0]]),
Character_Braille("DD", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 1, 1]]),
Character_Braille("FF", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 1, 0]]),
Character_Braille("GG", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 1, 1]]),
# Wordsigns
Character_Braille("ENOUGH", Enum_Braille_Proficiency_Level(3), [[0, 1, 0, 0, 0, 1]]),
Character_Braille("TO", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 1, 0]]),
Character_Braille("WERE", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0 , 1, 1]]),
Character_Braille("HIS", Enum_Braille_Proficiency_Level(3), [[0, 1, 1, 0, 0, 1]]),
Character_Braille("INTO", Enum_Braille_Proficiency_Level(3), [[0, 0, 1, 0, 1, 0], [0, 1, 1, 0, 1, 0]]), #(sequenced)
Character_Braille("BY", Enum_Braille_Proficiency_Level(3), [[0, 0, 1, 0, 1, 1]]), #(sequenced)
Character_Braille("WAS", Enum_Braille_Proficiency_Level(3), [[0, 0 , 1, 0 , 1, 1]]),
# Modifiers
Character_Braille("LET", Enum_Braille_Proficiency_Level(3), [[0, 0, 0, 0, 1, 1]], "@?LET"),
Character_Braille("CAPS", Enum_Braille_Proficiency_Level(3), [[0, 0, 0, 0, 0, 1]], "@?CAPS"),
Character_Braille("EMPH", Enum_Braille_Proficiency_Level(3), [[0, 0, 0, 1, 0, 1]], "@?EMPH"),
]}, columns=[Translation_Braille.__name__])
# 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
"""

View File

@@ -30,18 +30,24 @@ File Operations OpenSCAD, Cura Engine
import os
def render_openscad(path_scad, path_stl, path_cmd = 'C:\\"Program Files (x86)"\\OpenSCAD\\openscad'):
# FUNCTION
def render_openscad(path_scad, path_stl, path_cmd = 'C:\\"Program Files"\\openscad\\openscad'): # 'C:\\"Program Files (x86)"\\OpenSCAD\\openscad'
# render openscad file and store as file type defined by path_stl
# ARGUMENTS
# str path_scad - filepath of openscad model
# str path_stl - filepath to store (stl)
# VARIABLE INSTANTIATION
cmd = f'{path_cmd} -o "{path_stl}" "{path_scad}"'
# METHODS
print(os.path.exists(path_scad))
exec_oscmd(cmd)
def exec_oscmd(cmd):
# execute os system command
# - validation conducted by os system following python execution - NOT SAFE
print()
print('command')
print(cmd)
# METHODS
# os.system('cd C:\\"Program Files (x86)"\\OpenSCAD\\') # pre-command for openscad commands, alt: os.system('C:\\"Program Files (x86)"\\OpenSCAD\\openscad ...')
os.system(cmd)
def make_openscad(path_scad, path_stl, path_cmd = 'C:\\"Program Files (x86)"\\OpenSCAD\\openscad'):
def make_openscad(path_scad, path_cmd = 'C:\\"Program Files (x86)"\\OpenSCAD\\openscad'):
# FUNCTION
# render openscad file and store as file type defined by path_stl
# ARGUMENTS
@@ -51,20 +57,6 @@ def make_openscad(path_scad, path_stl, path_cmd = 'C:\\"Program Files (x86)"\\Op
cmd = f'{path_cmd} "{path_scad}"'
# METHODS
exec_oscmd(cmd)
def exec_oscmd(cmd):
# FUNCTION
# execute os system command
# - validation conducted by os system following python execution - NOT SAFE
# ARGUMENTS
# str cmd - command
# RETURNS
print()
print('command')
print(cmd)
# METHODS
# os.system('cd C:\\"Program Files (x86)"\\OpenSCAD\\') # pre-command for openscad commands, alt: os.system('C:\\"Program Files (x86)"\\OpenSCAD\\openscad ...')
os.system(cmd)
def slice_model(path_stl, path_gcode):