diff --git a/model_gen/__pycache__/argument_validation.cpython-38.pyc b/model_gen/__pycache__/argument_validation.cpython-38.pyc index 258fc50..2c5eea2 100644 Binary files a/model_gen/__pycache__/argument_validation.cpython-38.pyc and b/model_gen/__pycache__/argument_validation.cpython-38.pyc differ diff --git a/model_gen/__pycache__/array_keyboard_3d.cpython-38.pyc b/model_gen/__pycache__/array_keyboard_3d.cpython-38.pyc new file mode 100644 index 0000000..c564c16 Binary files /dev/null and b/model_gen/__pycache__/array_keyboard_3d.cpython-38.pyc differ diff --git a/model_gen/__pycache__/character_braille.cpython-38.pyc b/model_gen/__pycache__/character_braille.cpython-38.pyc new file mode 100644 index 0000000..c9a87da Binary files /dev/null and b/model_gen/__pycache__/character_braille.cpython-38.pyc differ diff --git a/model_gen/__pycache__/colour_theme_braille_character.cpython-38.pyc b/model_gen/__pycache__/colour_theme_braille_character.cpython-38.pyc new file mode 100644 index 0000000..4ade39b Binary files /dev/null and b/model_gen/__pycache__/colour_theme_braille_character.cpython-38.pyc differ diff --git a/model_gen/__pycache__/export_3d.cpython-38.pyc b/model_gen/__pycache__/export_3d.cpython-38.pyc index 1031cdc..a7bfe7b 100644 Binary files a/model_gen/__pycache__/export_3d.cpython-38.pyc and b/model_gen/__pycache__/export_3d.cpython-38.pyc differ diff --git a/model_gen/__pycache__/keyboard_3d.cpython-38.pyc b/model_gen/__pycache__/keyboard_3d.cpython-38.pyc new file mode 100644 index 0000000..9dfef8b Binary files /dev/null and b/model_gen/__pycache__/keyboard_3d.cpython-38.pyc differ diff --git a/model_gen/__pycache__/main.cpython-38.pyc b/model_gen/__pycache__/main.cpython-38.pyc new file mode 100644 index 0000000..34ec5fb Binary files /dev/null and b/model_gen/__pycache__/main.cpython-38.pyc differ diff --git a/model_gen/__pycache__/openscad_objects.cpython-38.pyc b/model_gen/__pycache__/openscad_objects.cpython-38.pyc index 8d6fa18..65e7d21 100644 Binary files a/model_gen/__pycache__/openscad_objects.cpython-38.pyc and b/model_gen/__pycache__/openscad_objects.cpython-38.pyc differ diff --git a/model_gen/__pycache__/product_braille.cpython-38.pyc b/model_gen/__pycache__/product_braille.cpython-38.pyc new file mode 100644 index 0000000..00f3665 Binary files /dev/null and b/model_gen/__pycache__/product_braille.cpython-38.pyc differ diff --git a/model_gen/__pycache__/system_commands.cpython-38.pyc b/model_gen/__pycache__/system_commands.cpython-38.pyc index a08fd41..1712701 100644 Binary files a/model_gen/__pycache__/system_commands.cpython-38.pyc and b/model_gen/__pycache__/system_commands.cpython-38.pyc differ diff --git a/model_gen/__pycache__/translate_braille_2_scad.cpython-38.pyc b/model_gen/__pycache__/translate_braille_2_scad.cpython-38.pyc index 469bda4..ac34c81 100644 Binary files a/model_gen/__pycache__/translate_braille_2_scad.cpython-38.pyc and b/model_gen/__pycache__/translate_braille_2_scad.cpython-38.pyc differ diff --git a/model_gen/__pycache__/translate_msg_2_braille.cpython-38.pyc b/model_gen/__pycache__/translate_msg_2_braille.cpython-38.pyc index 59f3c94..d03c63a 100644 Binary files a/model_gen/__pycache__/translate_msg_2_braille.cpython-38.pyc and b/model_gen/__pycache__/translate_msg_2_braille.cpython-38.pyc differ diff --git a/model_gen/__pycache__/translation_braille.cpython-38.pyc b/model_gen/__pycache__/translation_braille.cpython-38.pyc new file mode 100644 index 0000000..b8de3b6 Binary files /dev/null and b/model_gen/__pycache__/translation_braille.cpython-38.pyc differ diff --git a/model_gen/__pycache__/utils_system.cpython-38.pyc b/model_gen/__pycache__/utils_system.cpython-38.pyc new file mode 100644 index 0000000..2d14135 Binary files /dev/null and b/model_gen/__pycache__/utils_system.cpython-38.pyc differ diff --git a/model_gen/argument_validation.py b/model_gen/argument_validation.py deleted file mode 100644 index e74855a..0000000 --- a/model_gen/argument_validation.py +++ /dev/null @@ -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, "") - 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, "", 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, "", 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, "", 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, "", 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, "", 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 = "" - 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 = "" - # 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 = "" - 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 = "" - # 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, "", 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 = "" - 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 = "" - 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 = "" - 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, "", 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 = "" # 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, "", 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 = "" # 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, "", 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, "", 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, "", 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))) == "") - - -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, "", 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)) == "": - v_min = input_int(v_min, 'v_min', my_f, None, v_max, suppress_errors, suppress_console_outputs) - if str(type(v_min)) == "": return None - # v_max - if not str(type(v_max)) == "": - v_max = input_int(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs) - if str(type(v_max)) == "": return None -# METHODS - error_msg = error_msg_str(method, v_name, v_input, "", 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)) == "": - 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)) == "": - 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, "", 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)) == "": - v_min = input_int(v_min, 'v_min', method, None, v_max, suppress_errors, suppress_console_outputs) - if str(type(v_min)) == "": return False - # v_max - if not str(type(v_max)) == "": - v_max = input_int(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs) - if str(type(v_max)) == "": return False -# RETURNS - return not (str(type(input_int(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "") - - -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, "", 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)) == "": - v_min = input_float(v_min, 'v_min', my_f, None, v_max, suppress_errors, suppress_console_outputs) - if str(type(v_min)) == "": return None - # v_max - if not str(type(v_max)) == "": - v_max = input_float(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs) - if str(type(v_max)) == "": return None -# METHODS - error_msg = error_msg_str(method, v_name, v_input, "", 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)) == "": - 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)) == "": - 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, "", 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)) == "": - v_min = input_float(v_min, 'v_min', method, None, v_max, suppress_errors, suppress_console_outputs) - if str(type(v_min)) == "": return False - # v_max - if not str(type(v_max)) == "": - v_max = input_float(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs) - if str(type(v_max)) == "": return False -# RETURNS - return not (str(type(input_float(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "") - - -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, "", 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"": - 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, "", 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)) == "": 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)) == "": - # max_len = input_int(max_len, 'max_len', method, min_len, None, suppress_errors, suppress_console_outputs) - # if str(type(max_len)) == "": return False - # v_input - mytype = str(type(v_input)) - error_msg = error_msg_str(method, v_name, v_input, "") - if not mytype == "": - 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, "")) - 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, "", depth_max + 1, depth_max + 1, True, True) or v_mins == []): - error_msg = error_msg_str(my_f, 'v_mins', v_mins, "") - 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, "", depth_max + 1, depth_max + 1, True, True) or v_maxs == []): - error_msg = error_msg_str(my_f, 'v_maxs', v_maxs, "") - 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 "" - 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 \ No newline at end of file diff --git a/model_gen/array_keyboard_3d.py b/model_gen/array_keyboard_3d.py new file mode 100644 index 0000000..e486aea --- /dev/null +++ b/model_gen/array_keyboard_3d.py @@ -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() diff --git a/model_gen/character_braille.py b/model_gen/character_braille.py new file mode 100644 index 0000000..f573a9a --- /dev/null +++ b/model_gen/character_braille.py @@ -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} + """ diff --git a/model_gen/colour_theme_braille_character.py b/model_gen/colour_theme_braille_character.py new file mode 100644 index 0000000..f9d61ac --- /dev/null +++ b/model_gen/colour_theme_braille_character.py @@ -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, "", 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'] \ No newline at end of file diff --git a/model_gen/controller_braille.py b/model_gen/controller_braille.py new file mode 100644 index 0000000..e75a44f --- /dev/null +++ b/model_gen/controller_braille.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +""" +@author: Edward Middleton-Smith +""" + +class Controller_Braille(): + # \ No newline at end of file diff --git a/model_gen/export_3d.py b/model_gen/export_3d.py deleted file mode 100644 index 07f3266..0000000 --- a/model_gen/export_3d.py +++ /dev/null @@ -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, "", 'my_product', _m) - av.val_list(szs_product, 'szs_product', _m, "", 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, "", 'braille_dict', _m) - av.val_type(myproduct, "", 'myproduct', _m) - av.val_list(mymsgs, 'mymsgs', _m, "", 1) - av.val_list(myszs, 'myszs', _m, "", 1) #: - # raise ValueError(av.error_msg_str(_m, 'myszs', myszs, "")) - 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, "", 'show_braille', _m) - # av.val_type(show_let, "", 'show_let', _m) - # av.val_type(show_num, "", 'show_num', _m) - av.val_type(mystyle, "", 'mystyle', _m) - av.val_list(col_themes, 'col_themes', _m, "", 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, "") - # av.val_list(szs_product, 'szs_product', _m, "", 1) - av.val_list(myszs, 'myszs', _m, "", 1) - av.val_type(my_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, "", '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) \ No newline at end of file diff --git a/model_gen/keyboard_3d.py b/model_gen/keyboard_3d.py new file mode 100644 index 0000000..ed6f7c5 --- /dev/null +++ b/model_gen/keyboard_3d.py @@ -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, "", 'braille', _m) + av.val_type(braille, "", 'braille', _m) + av.val_type(braille, "", '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')) + diff --git a/model_gen/main.py b/model_gen/main.py index 3d39e57..d498e0f 100644 --- a/model_gen/main.py +++ b/model_gen/main.py @@ -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, "", 'show_braille', _m) - # av.val_type(show_let, "", 'show_let', _m) - # av.val_type(show_num, "", 'show_num', _m) - av.val_type(show_braille, "", 'show_braille', _m) - av.val_type(show_let, "", 'show_let', _m) - av.val_type(show_num, "", '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) \ No newline at end of file +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() diff --git a/model_gen/model_braille.py b/model_gen/model_braille.py new file mode 100644 index 0000000..96e6d6c --- /dev/null +++ b/model_gen/model_braille.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +""" +@author: Edward Middleton-Smith +""" + +class Model_Braille(): + # \ No newline at end of file diff --git a/model_gen/openscad_objects.py b/model_gen/openscad_objects.py index 9b7a65a..6328381 100644 --- a/model_gen/openscad_objects.py +++ b/model_gen/openscad_objects.py @@ -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" - ] \ No newline at end of file + ] + +""" +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() \ No newline at end of file diff --git a/model_gen/product_braille.py b/model_gen/product_braille.py new file mode 100644 index 0000000..f5c549b --- /dev/null +++ b/model_gen/product_braille.py @@ -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() diff --git a/model_gen/translate_braille_2_scad.py b/model_gen/translate_braille_2_scad.py deleted file mode 100644 index c538439..0000000 --- a/model_gen/translate_braille_2_scad.py +++ /dev/null @@ -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, "", 'braille', _m) - av.val_type(braille, "", 'braille', _m) - av.val_type(braille, "", '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, "", '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, "", 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, "") - 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, "") -# 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, "") -# 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, "") -# 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)) == ""): - 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, "") -# 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, "") -# 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, "", 'sz_scheme', _m) - av.val_type(col_theme, "", 'col_theme', _m) - av.val_type(my_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, "") - av.val_list(letters, 'letters', _m, "") - av.val_nested_list(numbers, 0, 1, 'numbers', _m, "") - av.val_nested_list(braille, 0, 2, 'braille', _m, "", -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, "", 'show_braille', _m) - # av.val_type(show_let, "", 'show_let', _m) - # av.val_type(show_num, "", 'show_num', _m) - av.val_type(mystyle, "", 'mystyle', _m) - # if not (av.val_type(col_theme, "", 'col_theme', _m, True) or av.val_type(col_theme, "", 'col_theme', _m, True)): - # raise ValueError(av.error_msg_str(_m, 'col_theme', col_theme, "")) - av.val_type(col_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 diff --git a/model_gen/translate_msg_2_braille.py b/model_gen/translate_msg_2_braille.py deleted file mode 100644 index 4bc6d90..0000000 --- a/model_gen/translate_msg_2_braille.py +++ /dev/null @@ -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)) == "" or av.val_int(level, difficulty.mini(), difficulty.maxi())) and av.val_list(braille, "") 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, "", 'level', _m, v_arg_type = v_arg_type) - av.val_nested_list(braille, 0, 1, 'braille', _m, "", -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)) == ""): - raise ValueError(av.error_msg_str(_m, 'plaintext', plaintext, "", 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, ""): - # raise ValueError(av.error_msg_str('braille_trans.__new__', 'level', level, 'attribute')) - # if not av.val_nested_list(braille, 0, 2, "", 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)) == ""): - # 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, "", 'braille_dict', _m) - av.val_type(level, "", '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, "", 'braille_dict', _m) - av.val_list(products, 'products', _m, "", 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)) == "") - 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, "", '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, "", '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, "", '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 \ No newline at end of file diff --git a/model_gen/translation_braille.py b/model_gen/translation_braille.py new file mode 100644 index 0000000..74528c8 --- /dev/null +++ b/model_gen/translation_braille.py @@ -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 + """ \ No newline at end of file diff --git a/model_gen/system_commands.py b/model_gen/utils_system.py similarity index 83% rename from model_gen/system_commands.py rename to model_gen/utils_system.py index 2d38715..50c8d2f 100644 --- a/model_gen/system_commands.py +++ b/model_gen/utils_system.py @@ -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):