Initial commit
This commit is contained in:
8
.spyproject/config/backups/codestyle.ini.bak
Normal file
8
.spyproject/config/backups/codestyle.ini.bak
Normal file
@@ -0,0 +1,8 @@
|
||||
[codestyle]
|
||||
indentation = True
|
||||
edge_line = True
|
||||
edge_line_columns = 79
|
||||
|
||||
[main]
|
||||
version = 0.2.0
|
||||
|
||||
6
.spyproject/config/backups/encoding.ini.bak
Normal file
6
.spyproject/config/backups/encoding.ini.bak
Normal file
@@ -0,0 +1,6 @@
|
||||
[encoding]
|
||||
text_encoding = utf-8
|
||||
|
||||
[main]
|
||||
version = 0.2.0
|
||||
|
||||
7
.spyproject/config/backups/vcs.ini.bak
Normal file
7
.spyproject/config/backups/vcs.ini.bak
Normal file
@@ -0,0 +1,7 @@
|
||||
[vcs]
|
||||
use_version_control = False
|
||||
version_control_system =
|
||||
|
||||
[main]
|
||||
version = 0.2.0
|
||||
|
||||
12
.spyproject/config/backups/workspace.ini.bak
Normal file
12
.spyproject/config/backups/workspace.ini.bak
Normal file
@@ -0,0 +1,12 @@
|
||||
[workspace]
|
||||
restore_data_on_startup = True
|
||||
save_data_on_exit = True
|
||||
save_history = True
|
||||
save_non_project_files = False
|
||||
project_type = 'empty-project-type'
|
||||
recent_files = ['model_gen\\main.py', 'setup.py', 'requirements.txt', 'model_gen\\translate_braille_2_scad.py', 'model_gen\\translate_msg_2_braille.py', 'model_gen\\translate_msg_2_braille_v2a.py', 'model_gen\\export_3d.py', '..\\xmas_turkey.py', '..\\monitor_stand_eng_anal.py', '..\\finance_v3.py', '..\\Fractal_Fortune_Teller\\setup.py']
|
||||
|
||||
[main]
|
||||
version = 0.2.0
|
||||
recent_files = []
|
||||
|
||||
8
.spyproject/config/codestyle.ini
Normal file
8
.spyproject/config/codestyle.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[codestyle]
|
||||
indentation = True
|
||||
edge_line = True
|
||||
edge_line_columns = 79
|
||||
|
||||
[main]
|
||||
version = 0.2.0
|
||||
|
||||
5
.spyproject/config/defaults/defaults-codestyle-0.2.0.ini
Normal file
5
.spyproject/config/defaults/defaults-codestyle-0.2.0.ini
Normal file
@@ -0,0 +1,5 @@
|
||||
[codestyle]
|
||||
indentation = True
|
||||
edge_line = True
|
||||
edge_line_columns = 79
|
||||
|
||||
3
.spyproject/config/defaults/defaults-encoding-0.2.0.ini
Normal file
3
.spyproject/config/defaults/defaults-encoding-0.2.0.ini
Normal file
@@ -0,0 +1,3 @@
|
||||
[encoding]
|
||||
text_encoding = utf-8
|
||||
|
||||
4
.spyproject/config/defaults/defaults-vcs-0.2.0.ini
Normal file
4
.spyproject/config/defaults/defaults-vcs-0.2.0.ini
Normal file
@@ -0,0 +1,4 @@
|
||||
[vcs]
|
||||
use_version_control = False
|
||||
version_control_system =
|
||||
|
||||
6
.spyproject/config/defaults/defaults-workspace-0.2.0.ini
Normal file
6
.spyproject/config/defaults/defaults-workspace-0.2.0.ini
Normal file
@@ -0,0 +1,6 @@
|
||||
[workspace]
|
||||
restore_data_on_startup = True
|
||||
save_data_on_exit = True
|
||||
save_history = True
|
||||
save_non_project_files = False
|
||||
|
||||
6
.spyproject/config/encoding.ini
Normal file
6
.spyproject/config/encoding.ini
Normal file
@@ -0,0 +1,6 @@
|
||||
[encoding]
|
||||
text_encoding = utf-8
|
||||
|
||||
[main]
|
||||
version = 0.2.0
|
||||
|
||||
7
.spyproject/config/vcs.ini
Normal file
7
.spyproject/config/vcs.ini
Normal file
@@ -0,0 +1,7 @@
|
||||
[vcs]
|
||||
use_version_control = False
|
||||
version_control_system =
|
||||
|
||||
[main]
|
||||
version = 0.2.0
|
||||
|
||||
12
.spyproject/config/workspace.ini
Normal file
12
.spyproject/config/workspace.ini
Normal file
@@ -0,0 +1,12 @@
|
||||
[workspace]
|
||||
restore_data_on_startup = True
|
||||
save_data_on_exit = True
|
||||
save_history = True
|
||||
save_non_project_files = False
|
||||
project_type = 'empty-project-type'
|
||||
recent_files = ['model_gen\\main.py', 'setup.py', 'requirements.txt', 'model_gen\\translate_braille_2_scad.py', 'model_gen\\translate_msg_2_braille.py', 'model_gen\\translate_msg_2_braille_v2a.py', 'model_gen\\export_3d.py', '..\\xmas_turkey.py', '..\\monitor_stand_eng_anal.py', '..\\finance_v3.py', '..\\Fractal_Fortune_Teller\\setup.py']
|
||||
|
||||
[main]
|
||||
version = 0.2.0
|
||||
recent_files = []
|
||||
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Edward Middleton-Smith
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
7
Makefile
Normal file
7
Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
init:
|
||||
pip install -r requirements.txt
|
||||
|
||||
test:
|
||||
py.test module_tests
|
||||
|
||||
.PHONY: init test
|
||||
8
README.rst
Normal file
8
README.rst
Normal file
@@ -0,0 +1,8 @@
|
||||
Braille Model Generator
|
||||
=====================================================================
|
||||
|
||||
Project details
|
||||
Braille Model Generator is a python module built on openpyscad for translating a passage of text into Braille and export it as a text (.txt), OpenSCAD (.scad), stereolithography (.stl), and portable network graphic (.png) types.
|
||||
The method of Braille translation can be varied to correspond to various chapters in the Standard English Braille pdf in the docs.
|
||||
|
||||
GitHub repository
|
||||
BIN
docs/Standard English Braille.pdf
Normal file
BIN
docs/Standard English Braille.pdf
Normal file
Binary file not shown.
2252
model_gen/Braille.txt
Normal file
2252
model_gen/Braille.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
model_gen/__pycache__/argument_validation.cpython-310.pyc
Normal file
BIN
model_gen/__pycache__/argument_validation.cpython-310.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/argument_validation.cpython-38.pyc
Normal file
BIN
model_gen/__pycache__/argument_validation.cpython-38.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/argument_validation.cpython-39.pyc
Normal file
BIN
model_gen/__pycache__/argument_validation.cpython-39.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/export_3d.cpython-310.pyc
Normal file
BIN
model_gen/__pycache__/export_3d.cpython-310.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/export_3d.cpython-38.pyc
Normal file
BIN
model_gen/__pycache__/export_3d.cpython-38.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/export_3d.cpython-39.pyc
Normal file
BIN
model_gen/__pycache__/export_3d.cpython-39.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/openscad_objects.cpython-310.pyc
Normal file
BIN
model_gen/__pycache__/openscad_objects.cpython-310.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/openscad_objects.cpython-38.pyc
Normal file
BIN
model_gen/__pycache__/openscad_objects.cpython-38.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/openscad_objects.cpython-39.pyc
Normal file
BIN
model_gen/__pycache__/openscad_objects.cpython-39.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/system_commands.cpython-310.pyc
Normal file
BIN
model_gen/__pycache__/system_commands.cpython-310.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/system_commands.cpython-38.pyc
Normal file
BIN
model_gen/__pycache__/system_commands.cpython-38.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/system_commands.cpython-39.pyc
Normal file
BIN
model_gen/__pycache__/system_commands.cpython-39.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/translate_braille_2_3d.cpython-39.pyc
Normal file
BIN
model_gen/__pycache__/translate_braille_2_3d.cpython-39.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/translate_braille_2_scad.cpython-310.pyc
Normal file
BIN
model_gen/__pycache__/translate_braille_2_scad.cpython-310.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/translate_braille_2_scad.cpython-38.pyc
Normal file
BIN
model_gen/__pycache__/translate_braille_2_scad.cpython-38.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/translate_braille_2_scad.cpython-39.pyc
Normal file
BIN
model_gen/__pycache__/translate_braille_2_scad.cpython-39.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/translate_msg_2_braille.cpython-310.pyc
Normal file
BIN
model_gen/__pycache__/translate_msg_2_braille.cpython-310.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/translate_msg_2_braille.cpython-38.pyc
Normal file
BIN
model_gen/__pycache__/translate_msg_2_braille.cpython-38.pyc
Normal file
Binary file not shown.
BIN
model_gen/__pycache__/translate_msg_2_braille.cpython-39.pyc
Normal file
BIN
model_gen/__pycache__/translate_msg_2_braille.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
928
model_gen/argument_validation.py
Normal file
928
model_gen/argument_validation.py
Normal file
@@ -0,0 +1,928 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Thu Apr 27 12:33:59 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
|
||||
Argument Validation
|
||||
"""
|
||||
|
||||
# CLASSES
|
||||
# ATTRIBUTE DECLARATION
|
||||
# METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
# NORMAL METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
from typing import Optional
|
||||
|
||||
def error_msg_str(method, v_name, v, v_type, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# return error message string for output of invalid argument / attribute to user
|
||||
# ARGUMENTS
|
||||
# str method - name of parent method which calls this function
|
||||
# str arg_name - name of argument throwing error
|
||||
# ? v - erroneous variable
|
||||
# str v_type - desired / expected variable type
|
||||
# str arg_type - e.g. argument, attribute
|
||||
# bool suppress_errors - should outputs not be raised as errors?
|
||||
# bool suppress_console_outputs
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'error_msg_str'
|
||||
# suppress_errors
|
||||
if not val_bool(suppress_errors, 'suppress_errors', my_f):
|
||||
error_msg = error_msg_str(my_f, 'suppress_errors', suppress_errors, "<class 'bool'>")
|
||||
raise ValueError(error_msg)
|
||||
# suppress_console_outputs
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
error_msg = error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors)
|
||||
if suppress_errors:
|
||||
print(error_msg)
|
||||
return error_msg
|
||||
else:
|
||||
raise ValueError(error_msg)
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, suppress_errors=suppress_errors, suppress_console_outputs=suppress_console_outputs):
|
||||
error_msg = error_msg_str(my_f, 'method', method, "<class 'str'>", suppress_errors, suppress_console_outputs)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return error_msg
|
||||
else:
|
||||
raise ValueError(error_msg)
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, -1, -1, suppress_errors, suppress_console_outputs):
|
||||
error_msg = error_msg_str(my_f, 'v_name', v_name, "<class 'str'>", suppress_errors, suppress_console_outputs)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return error_msg
|
||||
else:
|
||||
raise ValueError(error_msg)
|
||||
# v_type
|
||||
if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs):
|
||||
error_msg = error_msg_str(my_f, 'v_type', v_type, "<class 'str'>", suppress_errors, suppress_console_outputs)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return error_msg
|
||||
else:
|
||||
raise ValueError(error_msg)
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, -1, -1, suppress_errors, suppress_console_outputs):
|
||||
error_msg = error_msg_str(my_f, 'v_arg_type', v_arg_type, "<class 'str'>", suppress_errors, suppress_console_outputs)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return error_msg
|
||||
else:
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return f"Invalid {method} {v_type} {v_arg_type} {v_name}. Type = {str(type(v))}. Value = {v}"
|
||||
|
||||
def val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that myinput is of type bool
|
||||
# ARGUMENTS
|
||||
# bool (hopefully) myinput
|
||||
# str v_name
|
||||
# str method
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
# validate bool inputs first
|
||||
v_type = "<class 'bool'>"
|
||||
my_f = 'val_bool'
|
||||
if str(type(suppress_errors)) != v_type:
|
||||
raise ValueError(error_msg_str(my_f, 'suppress_errors', suppress_errors, v_type))
|
||||
if str(type(suppress_console_outputs)) != v_type:
|
||||
error_msg = error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, v_type, suppress_errors)
|
||||
if suppress_errors:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
v_type = "<class 'str'>"
|
||||
# method
|
||||
valid = True
|
||||
if str(type(method)) != v_type:
|
||||
valid = False
|
||||
else:
|
||||
if len(method) < 1:
|
||||
valid = False
|
||||
if not valid:
|
||||
error_msg = error_msg_str(my_f, 'method', method, v_type, suppress_errors, suppress_console_outputs)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
valid = True
|
||||
if str(type(v_name)) != v_type:
|
||||
valid = False
|
||||
else:
|
||||
if len(v_name) < 1:
|
||||
valid = False
|
||||
if not valid:
|
||||
error_msg = error_msg_str(my_f, 'v_name', v_name, v_type, suppress_errors, suppress_console_outputs)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# v_arg_type
|
||||
valid = True
|
||||
if str(type(v_arg_type)) != v_type:
|
||||
valid = False
|
||||
else:
|
||||
if len(v_arg_type) < 1:
|
||||
valid = False
|
||||
if not valid:
|
||||
error_msg = error_msg_str(my_f, 'v_arg_type', v_arg_type, v_type, suppress_errors, suppress_console_outputs)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
else:
|
||||
raise ValueError(error_msg)
|
||||
# v_input
|
||||
v_type = "<class 'bool'>"
|
||||
if (str(type(v_input)) != v_type):
|
||||
error_msg = error_msg_str(method, v_name, v_input, v_type, suppress_errors, suppress_console_outputs)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_str(v_input, v_name, method, min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type str
|
||||
# ARGUMENTS
|
||||
# str (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional int min_len
|
||||
# optional int max_len
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_str'
|
||||
v_type = "<class 'str'>"
|
||||
# suppress_errors
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
# suppress_console_outputs
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return False
|
||||
# method
|
||||
valid = True
|
||||
if str(type(method)) != v_type:
|
||||
valid = False
|
||||
else:
|
||||
if len(method) < 1:
|
||||
valid = False
|
||||
if not valid:
|
||||
error_msg = error_msg_str(my_f, 'method', method, v_type)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
valid = True
|
||||
if str(type(v_name)) != v_type:
|
||||
valid = False
|
||||
else:
|
||||
if len(v_name) < 1:
|
||||
valid = False
|
||||
if not valid:
|
||||
error_msg = error_msg_str(my_f, 'v_name', v_name, v_type)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# v_arg_type
|
||||
valid = True
|
||||
if str(type(v_arg_type)) != v_type:
|
||||
valid = False
|
||||
else:
|
||||
if len(v_arg_type) < 1:
|
||||
valid = False
|
||||
if not valid:
|
||||
error_msg = error_msg_str(my_f, 'v_arg_type', v_arg_type, v_type)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# min_len
|
||||
v_type = "<class 'int'>"
|
||||
if str(type(min_len)) != v_type:
|
||||
error_msg = error_msg_str(my_f, 'min_len', min_len, v_type)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# max_len
|
||||
v_type = "<class 'int'>"
|
||||
valid = True
|
||||
if str(type(max_len)) != v_type:
|
||||
valid = False
|
||||
else:
|
||||
if max_len != -1 and max_len < min_len:
|
||||
valid = False
|
||||
if not valid:
|
||||
error_msg = error_msg_str(my_f, 'max_len', max_len, v_type)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# v_input
|
||||
# VARIABLE INSTANTIATION
|
||||
v_type = "<class 'str'>"
|
||||
valid = True
|
||||
# METHODS
|
||||
if str(type(v_input)) != v_type:
|
||||
valid = False
|
||||
else:
|
||||
L = len(v_input)
|
||||
if min_len != -1 and L < min_len:
|
||||
valid = False
|
||||
print(f"Minimum str length {min_len} not met.")
|
||||
if max_len != -1 and L > max_len:
|
||||
print(f"Maximum str length {max_len} not met.")
|
||||
valid = False
|
||||
if not valid:
|
||||
error_msg = error_msg_str(method, v_name, v_input, v_type, suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
# def val_none(v_input, v_name, method, v_arg_type = 'argument', suppress_errors = False, suppress_console_outputs = False):
|
||||
# # FUNCTION
|
||||
# # evaluate if v_input is None
|
||||
# # ARGUMENTS
|
||||
# # ARGUMENT VALIDATION
|
||||
# # VARIABLE INSTANTIATION
|
||||
# # METHODS
|
||||
# # RETURNS
|
||||
|
||||
def val_int(v_input, v_name, method, v_min: Optional[int] = None, v_max: Optional[int] = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that myinput is of type int, and if not None, limited by v_min and v_max
|
||||
# ARGUMENTS
|
||||
# int (hopefully) myinput
|
||||
# str v_name
|
||||
# str method
|
||||
# optional int v_min
|
||||
# optional int v_max
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_int'
|
||||
# suppress_errors
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
# suppress_console_outputs
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return False
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_min
|
||||
if (v_min != None):
|
||||
if not val_int(v_min, 'v_min', my_f, None, None, suppress_errors, suppress_console_outputs):
|
||||
return False
|
||||
# v_max
|
||||
if (v_max != None):
|
||||
if not val_int(v_max, 'v_max', my_f, None, None, suppress_errors, suppress_console_outputs):
|
||||
return False
|
||||
# v_input
|
||||
# VARIABLE INSTANTIATION
|
||||
mytype = "<class 'int'>" # str(type(myinput))
|
||||
error_msg = error_msg_str(method, v_name, v_input, mytype, suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
# METHODS
|
||||
if not mytype == str(type(v_input)):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
if (v_min != None and v_max != None):
|
||||
if (v_min > v_max):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.")
|
||||
return False
|
||||
raise ValueError(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.")
|
||||
if (v_min != None):
|
||||
if (v_input < v_min):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg + f"\nValue less than minimum {v_min}.")
|
||||
return False
|
||||
raise ValueError(error_msg + f"\nValue less than minimum {v_min}.")
|
||||
if (v_max != None):
|
||||
if (v_input > v_max):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg + f"\nValue greater than maximum {v_max}.")
|
||||
return False
|
||||
raise ValueError(error_msg + f"\nValue greater than maximum {v_max}.")
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type float, and if not None, limited by v_min and v_max
|
||||
# ARGUMENTS
|
||||
# float (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional float v_min
|
||||
# optional float v_max
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_float'
|
||||
# suppress_errors
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
# suppress_console_outputs
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return False
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
my_f = method + '.' + my_f
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_min
|
||||
if (v_min != None):
|
||||
if not val_float(v_min, 'v_min', my_f, None, None, suppress_errors, suppress_console_outputs):
|
||||
return False
|
||||
# v_max
|
||||
if (v_max != None):
|
||||
if not val_float(v_max, 'v_max', my_f, None, None, suppress_errors, suppress_console_outputs):
|
||||
return False
|
||||
# v_input
|
||||
# VARIABLE INSTANTIATION
|
||||
mytype = "<class 'float'>" # str(type(myinput))
|
||||
error_msg = error_msg_str(method, v_name, v_input, mytype, suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
# METHODS
|
||||
if not mytype == str(type(v_input)):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
if (v_min != None and v_max != None):
|
||||
if (v_min > v_max):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.")
|
||||
return False
|
||||
raise ValueError(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.")
|
||||
if (v_min != None):
|
||||
if (v_input < v_min):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg + f"\nValue less than minimum {v_min}.")
|
||||
return False
|
||||
raise ValueError(error_msg + f"\nValue less than minimum {v_min}.")
|
||||
if (v_max != None):
|
||||
if (v_input > v_max):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg + f"\nValue greater than maximum {v_max}.")
|
||||
return False
|
||||
raise ValueError(error_msg + f"\nValue greater than maximum {v_max}.")
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
def input_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# input valid str, int, or bool representation of bool, or else None
|
||||
# ARGUMENTS
|
||||
# bool (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional str v_arg_type
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'input_bool'
|
||||
# suppress_errors
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
# suppress_console_outputs
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return None
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
my_f = method + '.' + my_f
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
# METHODS
|
||||
if not val_bool(v_input, v_name, my_f, suppress_errors, suppress_console_outputs):
|
||||
if not val_int(v_input, v_name, my_f, 0, 1, suppress_errors, suppress_console_outputs):
|
||||
error_msg = error_msg_str(method, v_name, v_input, "<class 'bool'>", suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
if not val_str(v_input, v_name, my_f, suppress_errors, suppress_console_outputs):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return None
|
||||
raise ValueError(error_msg)
|
||||
else:
|
||||
my_truths = ['Y', 'YE', 'YES', 'YS', 'YESH', 'YEA', 'YEAH', 'TRUE', 'TRU', 'TRUTH', 'TURE', 'T']
|
||||
my_falths = ['N', 'NO', 'FALSE', 'F', 'FAIL', 'FALS']
|
||||
for i in range(len(my_truths)):
|
||||
if my_truths[i] == v_input:
|
||||
return True
|
||||
for i in range(len(my_falths)):
|
||||
if my_falths[i] == v_input:
|
||||
return False
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return None
|
||||
raise ValueError(error_msg)
|
||||
else:
|
||||
return False if v_input == 0 else True
|
||||
# RETURNS
|
||||
return v_input
|
||||
|
||||
def full_val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that bool input is bool or valid equivalent
|
||||
# ARGUMENTS
|
||||
# bool (hopefully) my_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'full_val_bool'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return False
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# RETURNS
|
||||
return not (str(type(input_bool(v_input, v_name, method, suppress_errors, suppress_console_outputs, v_arg_type))) == "<class 'NoneType'>")
|
||||
|
||||
|
||||
def input_int(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# input int or valid equivalent, or else None
|
||||
# ARGUMENTS
|
||||
# int or str v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# v_min
|
||||
# v_min
|
||||
# bool suppress_errors
|
||||
# bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'input_int'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return None
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
# v_min
|
||||
if not str(type(v_min)) == "<class 'NoneType'>":
|
||||
v_min = input_int(v_min, 'v_min', my_f, None, v_max, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_min)) == "<class 'NoneType'>": return None
|
||||
# v_max
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
v_max = input_int(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_max)) == "<class 'NoneType'>": return None
|
||||
# METHODS
|
||||
error_msg = error_msg_str(method, v_name, v_input, "<class 'int'>", suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
# v_input
|
||||
try:
|
||||
my_int = int(v_input)
|
||||
except:
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return None
|
||||
int(v_input)
|
||||
if not str(type(v_min)) == "<class 'NoneType'>":
|
||||
if my_int < v_min:
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(f"{error_msg}\nInt input less than minimum value. Value = {v_input}, minimum = {v_min}.")
|
||||
return None
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
if my_int > v_max:
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(f"{error_msg}\nInt input greater than maximum value. Value = {v_input}, maximum = {v_max}.")
|
||||
return None
|
||||
# RETURNS
|
||||
return my_int
|
||||
|
||||
|
||||
def full_val_int(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is int or equivalent, else False, limited by v_min and v_max
|
||||
# ARGUMENTS
|
||||
# int (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional float v_min
|
||||
# optional float v_max
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'full_val_int'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return False
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_min
|
||||
if not str(type(v_min)) == "<class 'NoneType'>":
|
||||
v_min = input_int(v_min, 'v_min', method, None, v_max, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_min)) == "<class 'NoneType'>": return False
|
||||
# v_max
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
v_max = input_int(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_max)) == "<class 'NoneType'>": return False
|
||||
# RETURNS
|
||||
return not (str(type(input_int(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "<class 'NoneType'>")
|
||||
|
||||
|
||||
def input_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# input float, else return None
|
||||
# ARGUMENTS
|
||||
# float/int/str(numeric) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional float v_min
|
||||
# optional float v_min
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'input_float'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return None
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
# v_min
|
||||
if not str(type(v_min)) == "<class 'NoneType'>":
|
||||
v_min = input_float(v_min, 'v_min', my_f, None, v_max, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_min)) == "<class 'NoneType'>": return None
|
||||
# v_max
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
v_max = input_float(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_max)) == "<class 'NoneType'>": return None
|
||||
# METHODS
|
||||
error_msg = error_msg_str(method, v_name, v_input, "<class 'float'>", suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
# v_input
|
||||
try:
|
||||
my_float = float(v_input)
|
||||
except:
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return None
|
||||
float(v_input)
|
||||
if not str(type(v_min)) == "<class 'NoneType'>":
|
||||
if v_input < v_min:
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(f"{error_msg}\nInt input less than minimum value. Value = {v_input}, minimum = {v_min}.")
|
||||
return None
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
if v_input > v_max:
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(f"{error_msg}\nInt input greater than maximum value. Value = {v_input}, maximum = {v_max}.")
|
||||
return None
|
||||
# RETURNS
|
||||
return my_float
|
||||
|
||||
|
||||
def full_val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is numeric, and if not False, limited by v_min and v_max
|
||||
# ARGUMENTS
|
||||
# float (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional float v_min
|
||||
# optional float v_max
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'full_val_float'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return False
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_min
|
||||
if not str(type(v_min)) == "<class 'NoneType'>":
|
||||
v_min = input_float(v_min, 'v_min', method, None, v_max, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_min)) == "<class 'NoneType'>": return False
|
||||
# v_max
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
v_max = input_float(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_max)) == "<class 'NoneType'>": return False
|
||||
# RETURNS
|
||||
return not (str(type(input_float(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "<class 'NoneType'>")
|
||||
|
||||
|
||||
def make_ordinal(n):
|
||||
# FUNCTION
|
||||
# Get ordinal representation of number
|
||||
# ARGUMENTS
|
||||
# int n
|
||||
# ARGUMENT VALIDATION
|
||||
full_val_int(n, 'n', 'make_ordinal', 0)
|
||||
# VARIABLE INSTANTIATION
|
||||
n = int(n)
|
||||
# METHODS
|
||||
if 11 <= (n % 100):
|
||||
suffix= 'th'
|
||||
else:
|
||||
suffix = ['th', 'st', 'nd', 'rd', 'th'][min(n % 10, 4)]
|
||||
# RETURNS
|
||||
return str(n) + suffix
|
||||
|
||||
|
||||
def val_type(v_input, v_type, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type v_type
|
||||
# ARGUMENTS
|
||||
# v_type (hopefully) v_input
|
||||
# str v_type
|
||||
# str v_name
|
||||
# str method
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_type'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return False
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_type
|
||||
if not val_str(v_type, 'v_type', my_f, 6, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_input
|
||||
error_message = error_msg_str(method, v_name, v_input, v_arg_type)
|
||||
mytype = str(type(v_input))
|
||||
# if not (v_type == 'int' or v_type == 'bool' or v_type == 'float' or v_type == 'complex' or v_type == 'str' or v_type == 'NoneType'):
|
||||
if not mytype == v_type: # f"<class '{v_type}'>":
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_message)
|
||||
return False
|
||||
raise ValueError(error_message)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_list(v_input, v_name, method, v_type = '', min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs: bool = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type list, and if defined: has v_len elements of type v_type
|
||||
# ARGUMENTS
|
||||
# list[v_type] (hopefully) v_input
|
||||
# str v_name - variable name
|
||||
# str method - parent method
|
||||
# str v_type - type of list items
|
||||
# int v_len - length of list
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_list'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>", suppress_errors))
|
||||
return False
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_type
|
||||
if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# min_len
|
||||
if not full_val_int(min_len, 'min_len', my_f, None, None if max_len == -1 else max_len, suppress_errors, suppress_console_outputs): return False
|
||||
# min_len = input_int(min_len, 'min_len', method, None, max_len, suppress_errors, suppress_console_outputs)
|
||||
# if str(type(min_len)) == "<class 'NoneType'>": return False
|
||||
# max_len
|
||||
if not full_val_int(max_len, 'max_len', my_f, None if max_len == -1 else (None if min_len == -1 else min_len), None, suppress_errors, suppress_console_outputs): return False
|
||||
# if not str(type(max_len)) == "<class 'NoneType'>":
|
||||
# max_len = input_int(max_len, 'max_len', method, min_len, None, suppress_errors, suppress_console_outputs)
|
||||
# if str(type(max_len)) == "<class 'NoneType'>": return False
|
||||
# v_input
|
||||
mytype = str(type(v_input))
|
||||
error_msg = error_msg_str(method, v_name, v_input, "<class 'list'>")
|
||||
if not mytype == "<class 'list'>":
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
L = len(v_input)
|
||||
if max_len > -1 and L > max_len:
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg + f'\nInvalid list length. Maximum = {max_len}, length = {L}')
|
||||
return False
|
||||
raise ValueError(error_msg + f'\nInvalid list length. Maximum = {max_len}, length = {L}')
|
||||
if L < min_len:
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg + f"Invalid list length. Minimum = {min_len}, length = {L}")
|
||||
return False
|
||||
raise ValueError(error_msg + f'\nInvalid list length. Minimum = {min_len}, length = {L}')
|
||||
if v_type != '' and L > 0:
|
||||
for i in range(L):
|
||||
mytype = str(type(v_input[i]))
|
||||
if not mytype == v_type:
|
||||
error_msg = error_msg + '\n' + error_msg_str(my_f, v_name, v_input, v_type, False, False, 'list element')
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
def val_nested_list(v_input, depth_i, depth_max, v_name, method, v_type = '', v_min = -1, v_mins = [], v_max = -1, v_maxs: list = [], suppress_errors = False, suppress_console_outputs: bool = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type list, and if defined: has v_len elements of type v_type
|
||||
# for nested list of nested-index i
|
||||
# ARGUMENTS
|
||||
# list[v_type] (hopefully) v_input
|
||||
# int depth_i - current depth of nesting of lists
|
||||
# int depth_max - maximum depth of nesting of lists - base 0
|
||||
# str v_name
|
||||
# str method
|
||||
# Optional[str] v_type - type of list items
|
||||
# Optional[int] v_min - minimum sublist size
|
||||
# Optional[list[int]] v_mins - minimum list sizes
|
||||
# Optional[int] v_max - maximum sublist size
|
||||
# Optional[list[int]] v_maxs - maximum list sizes
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_nested_list'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(my_f, 'suppress_console_outputs', suppress_console_outputs, "<class 'bool'>"))
|
||||
return False
|
||||
# method
|
||||
if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
my_f = method + '.' + my_f
|
||||
# v_name
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_type
|
||||
if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_min
|
||||
if not val_int(v_min, 'v_min', my_f, -1, None, suppress_errors, suppress_console_outputs): return False
|
||||
# v_max
|
||||
if not val_int(v_max, 'v_max', my_f, -1, None, suppress_errors, suppress_console_outputs): return False
|
||||
# v_mins
|
||||
if not (val_list(v_mins, 'v_mins', my_f, "<class 'int'>", depth_max + 1, depth_max + 1, True, True) or v_mins == []):
|
||||
error_msg = error_msg_str(my_f, 'v_mins', v_mins, "<class 'int'>")
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# v_maxs
|
||||
if not (val_list(v_maxs, 'v_maxs', my_f, "<class 'int'>", depth_max + 1, depth_max + 1, True, True) or v_maxs == []):
|
||||
error_msg = error_msg_str(my_f, 'v_maxs', v_maxs, "<class 'int'>")
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# v_input
|
||||
mytype = v_type if depth_i == depth_max else "<class 'list'>"
|
||||
error_msg = error_msg_str(method, v_name, v_input, mytype, suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
if not val_list(v_input, v_name, method, mytype, v_min, v_max, suppress_errors, suppress_console_outputs, v_arg_type):
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
# METHODS
|
||||
L = len(v_input)
|
||||
if L == 0:
|
||||
if v_min > -1:
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg + f'\nMinimum length {v_min} not met.')
|
||||
return False
|
||||
raise ValueError(error_msg + f'\nMinimum length {v_min} not met.')
|
||||
elif depth_i < depth_max:
|
||||
for i in range(L):
|
||||
if not (v_mins == [] or v_maxs == []):
|
||||
if not val_nested_list(v_input[i], depth_i + 1, depth_max, v_name, method, v_type, v_mins[depth_i + 1], v_mins, v_maxs[depth_i + 1], v_maxs, suppress_errors, suppress_console_outputs, v_arg_type):
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
elif not v_mins == []:
|
||||
if not val_nested_list(v_input[i], depth_i + 1, depth_max, v_name, method, v_type, v_mins[depth_i + 1], v_mins, -1, v_maxs, suppress_errors, suppress_console_outputs, v_arg_type):
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
elif not v_maxs == []:
|
||||
if not val_nested_list(v_input[i], depth_i + 1, depth_max, v_name, method, v_type, -1, v_mins, v_maxs[depth_i + 1], v_maxs, suppress_errors, suppress_console_outputs, v_arg_type):
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
else:
|
||||
if not val_nested_list(v_input[i], depth_i + 1, depth_max, v_name, method, v_type, -1, v_mins, -1, v_maxs, suppress_errors, suppress_console_outputs, v_arg_type):
|
||||
if not suppress_console_outputs:
|
||||
print(error_msg)
|
||||
return False
|
||||
# RETURNS
|
||||
return True
|
||||
152
model_gen/export_3d.py
Normal file
152
model_gen/export_3d.py
Normal file
@@ -0,0 +1,152 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon May 1 03:35:45 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
|
||||
Braille 3D Model Product Creation
|
||||
"""
|
||||
|
||||
# CLASSES
|
||||
# ATTRIBUTE DECLARATION
|
||||
# METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
# NORMAL METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
|
||||
import openpyscad as ops
|
||||
import system_commands as sc
|
||||
import argument_validation as av
|
||||
from translate_msg_2_braille import product, gen_braille_inputs_4_openscad
|
||||
from translate_braille_2_scad import scrabble_dimensions, export_colour_theme, input_colour_themes, gen_openscad_braille, gen_path_braille_scrabble, input_product_size
|
||||
from typing import Optional
|
||||
|
||||
def gen_product_permutations(my_product, szs_product, sz_perms = True, sz_index = 2):
|
||||
# FUNCTION
|
||||
# generate all colour / size permutations of product
|
||||
# ARGUMENTS
|
||||
# product my_product
|
||||
# list[scrabble_dimensions] szs_product - different size profiles for products
|
||||
# optional bool szs_perms
|
||||
# optional int sz_index
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'gen_product_permutations'
|
||||
av.val_type(my_product, "<class 'translate_msg_2_braille.product'>", 'my_product', _m)
|
||||
av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 1)
|
||||
av.full_val_bool(sz_perms, 'sz_perms', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
mymsgs = [] # [msgin]
|
||||
myszs = [] # [szs_scrabble[5]]
|
||||
# METHODS
|
||||
if not sz_perms:
|
||||
my_size = input_product_size(szs_product, sz_index)
|
||||
# create list of permutations of size profiles + letters
|
||||
for j in range(len(szs_product) if sz_perms else 1):
|
||||
for i in range(26 if my_product.name == 'Scrabble Alphabet of Tiles' else 1):
|
||||
mymsgs.append(chr(65 + i) if my_product.name == 'Scrabble Character Tile' else my_product.msg)
|
||||
myszs.append(szs_product[j] if sz_perms else my_size)
|
||||
# RETURNS
|
||||
return mymsgs, myszs
|
||||
|
||||
def gen_3d_models(braille_dict, myproduct, mymsgs, myszs, line_length, path_folder, path_cmd, mystyle, col_themes):
|
||||
# FUNCTION
|
||||
# create 3D models - SCAD, STL, PNG - from product input
|
||||
# ARGUMENTS
|
||||
# list[braille_trans] braille_dict
|
||||
# product myproduct
|
||||
# list[str] mymsgs
|
||||
# list[scrabble_dimensions] myszs
|
||||
# int line_length
|
||||
# str path_folder
|
||||
# style mystyle
|
||||
# list [export_colour_themes] col_themes
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'gen_3d_models'
|
||||
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', _m)
|
||||
av.val_type(myproduct, "<class 'translate_msg_2_braille.product'>", 'myproduct', _m)
|
||||
av.val_list(mymsgs, 'mymsgs', _m, "<class 'str'>", 1)
|
||||
av.val_list(myszs, 'myszs', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 1) #:
|
||||
# raise ValueError(av.error_msg_str(_m, 'myszs', myszs, "<class 'scrabble_dimensions'>"))
|
||||
av.val_int(line_length, 'line_length', _m, 1)
|
||||
av.val_str(path_folder, 'path_folder', _m)
|
||||
av.val_str(path_cmd, 'path_cmd', _m, 1)
|
||||
# av.val_int(show_braille, 'show_braille', _m)
|
||||
# av.val_int(show_let, 'show_let', _m)
|
||||
# av.val_int(show_num, 'show_num', _m)
|
||||
# av.val_type(show_braille, "<enum 'elem_visibility'>", 'show_braille', _m)
|
||||
# av.val_type(show_let, "<enum 'elem_visibility'>", 'show_let', _m)
|
||||
# av.val_type(show_num, "<enum 'elem_visibility'>", 'show_num', _m)
|
||||
av.val_type(mystyle, "<class 'translate_braille_2_scad.style'>", 'mystyle', _m)
|
||||
av.val_list(col_themes, 'col_themes', _m, "<class 'translate_braille_2_scad.export_colour_theme'>", 1)
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
for col_y in range(len(col_themes)):
|
||||
for msg_x in range(len(mymsgs)):
|
||||
msg_x_str = mymsgs[msg_x]
|
||||
cum, letters, numbers, braille, n_keys, n_rows = gen_braille_inputs_4_openscad(msg_x_str, line_length, braille_dict)
|
||||
path_png, path_scad, path_stl = gen_openscad_braille(cum, letters, numbers, braille, n_keys, min(line_length, n_keys), n_rows, myszs[msg_x], mystyle, col_themes[col_y], msg_x_str, path_folder + myproduct.filename, quality = 100)
|
||||
# sc.render_openscad(path_scad, path_stl, path_cmd)
|
||||
# sc.render_openscad(path_scad, path_png, path_cmd)
|
||||
# # RETURNS
|
||||
# return col_themes
|
||||
|
||||
def gen_snippet_assembly(dx, dy, len_line, col_themes, myszs, my_product, path_folder, path_cmd, my_style): #, szs_product
|
||||
# FUNCTION
|
||||
# create png exports of openscad assembly of series of permutations of openscad components
|
||||
# ARGUMENTS
|
||||
# int dx - spacing along x
|
||||
# int dy - spacing along y
|
||||
# int len_line - number of components on row (along x)
|
||||
# list[export_colour_theme] col_themes
|
||||
# list[scrabble_dimensions] myszs
|
||||
# translate_msg_2_braille.product my_product
|
||||
# str path_folder
|
||||
# str path_cmd
|
||||
# style my_style
|
||||
# # list[scrabble_dimensions] szs_product
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'gen_snippet_assembly'
|
||||
av.val_int(dx, 'dx', _m)
|
||||
av.val_int(dy, 'dy', _m)
|
||||
av.val_int(len_line, 'len_line', _m, 1)
|
||||
av.val_list(col_themes, 'col_themes', _m, "<class 'translate_braille_2_scad.export_colour_theme'>")
|
||||
# av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 1)
|
||||
av.val_list(myszs, 'myszs', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 1)
|
||||
av.val_type(my_product, "<class 'translate_msg_2_braille.product'>", 'my_product', _m)
|
||||
av.val_str(path_folder, 'path_folder', _m)
|
||||
av.val_str(path_cmd, 'path_cmd', _m, 1)
|
||||
av.val_type(my_style, "<class 'translate_braille_2_scad.style'>", 'my_style', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
# mystyles = ['__l_0n'] # ['_0n', '_0l_0n', '_0b_0n', '__l_0n']
|
||||
n_style = 1 # 3
|
||||
d_pcs = [dx, dy]
|
||||
# METHODS
|
||||
for sz_i in range(len(myszs)):
|
||||
ass_braille = ops.Union()
|
||||
for let_i in range(1): # 26):
|
||||
col_i = 0 # let_i % n_col
|
||||
style_i = 0 # let_i % n_style
|
||||
# mypath = gen_path_braille_scrabble(szs_scrabble[sz_i], let_i, col_themes[col_i], 'scad')
|
||||
mypath = gen_path_braille_scrabble(myszs[sz_i], col_themes[col_i], my_style, path_folder + my_product.filename, 'scad')
|
||||
# mypath = f"C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\Braille_Scrabble_{szs_scrabble[sz_i].name}_{Chr(let_i + 65)}_{col_themes[col_i].name}"
|
||||
ass_braille.append(ops.Scad(mypath).rotate([0, 180 * let_i, 0]).translate([4 * (let_i % 2), 0, -5 * (let_i % 2)]).translate([d_pcs[0] * myszs[sz_i].dp * (let_i % len_line), d_pcs[1] * myszs[sz_i].dp * (let_i // len_line), 0])) # , convexity = 3) .translate([d_pcs * (let_i % len_line), d_pcs * (let_i // len_line), 0])
|
||||
# RETURNS
|
||||
path_scad = gen_path_braille_scrabble(myszs[0], col_themes[col_i], my_style, path_folder + 'assy', 'scad')
|
||||
path_stl = gen_path_braille_scrabble(myszs[0], col_themes[col_i], my_style, path_folder + 'assy', 'stl')
|
||||
path_png = gen_path_braille_scrabble(myszs[0], col_themes[col_i], my_style, path_folder + 'assy', 'png')
|
||||
ass_braille.write(path_scad) # , with_print=True
|
||||
print(f"writing SCAD to {path_scad}")
|
||||
# render_openscad(path_scad, path_stl)
|
||||
sc.render_openscad(path_scad, path_png, path_cmd)
|
||||
7
model_gen/init.py
Normal file
7
model_gen/init.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Wed May 3 16:25:12 2023
|
||||
|
||||
@author: edwar
|
||||
"""
|
||||
|
||||
108
model_gen/main.py
Normal file
108
model_gen/main.py
Normal file
@@ -0,0 +1,108 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Apr 24 14:26:02 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
|
||||
|
||||
|
||||
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
|
||||
|
||||
# PARAMETERS
|
||||
path_folder_cmd = 'C:\\"Program Files"\\OpenSCAD\\openscad' # 'C:\\"Program Files (x86)"\\OpenSCAD\\openscad' # local environment variable path for openscad commands
|
||||
path_folder = "C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\" # file export parent directory
|
||||
my_option = -1 # index of product option - if not valid, user console input will be required
|
||||
my_select = '' # character selection for Braille tile(s) (if chosen)
|
||||
size_permutations = False # generate models for all size options?
|
||||
size_option = -1 # size option as int index - not required if size_permutations
|
||||
colour_permutations = False # generate models for all colour options?
|
||||
colour_option = '' # colour option as str or int index - not required if colour_permutations
|
||||
show_braille = elem_visibility.VISIBLE # how should Braille be shown?
|
||||
show_let = elem_visibility.VISIBLE # EMBOSSED # how should plaintext be shown?
|
||||
show_num = elem_visibility.HIDDEN # how should ordinality be shown?
|
||||
# assembly component spacing
|
||||
dx = 5 # horizontnal
|
||||
dy = 10 # vertical
|
||||
|
||||
# METHODS
|
||||
|
||||
def generate(my_option = -1, my_select = '', size_permutations = False, size_option = -1, colour_permutations = False, colour_option = 'Purple', show_braille = elem_visibility.VISIBLE, show_let = elem_visibility.VISIBLE, show_num = elem_visibility.HIDDEN, dx = 5, dy = 10, path_folder_cmd = 'C:\\"Program Files"\\OpenSCAD\\openscad', path_folder = "C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\"):
|
||||
# FUNCTION
|
||||
# generate Braille model(s)
|
||||
# ARGUMENTS
|
||||
# int my_option - index of product option - if not valid, user console input will be required
|
||||
# str my_select - character selection for Braille tile(s) (if chosen)
|
||||
# bool size_permutation -
|
||||
# int size_option - index of product_sizes option - ignored if size_permutations
|
||||
# # bool colour_permutation
|
||||
# elem_visibility show_braille
|
||||
# elem_visibility show_let
|
||||
# elem_visibility show_num
|
||||
# float dx
|
||||
# float dy
|
||||
# str path_folder_cmd
|
||||
# str path_folder
|
||||
# VARIABLE INSTANTIATION
|
||||
_m ='generate'
|
||||
# ARGUMENT VALIDATION
|
||||
av.val_int(my_option, 'my_option', _m)
|
||||
av.val_str(my_select, 'my_select', _m)
|
||||
av.val_bool(size_permutations, 'size_permutations', _m)
|
||||
av.val_int(size_option, 'size_option', _m)
|
||||
av.val_bool(colour_permutations, 'colour_permutations', _m)
|
||||
# av.val_type(show_braille, "<enum 'translate_braille_2_scad.elem_visibility'>", 'show_braille', _m)
|
||||
# av.val_type(show_let, "<enum 'translate_braille_2_scad.elem_visibility'>", 'show_let', _m)
|
||||
# av.val_type(show_num, "<enum 'translate_braille_2_scad.elem_visibility'>", 'show_num', _m)
|
||||
av.val_type(show_braille, "<enum 'elem_visibility'>", 'show_braille', _m)
|
||||
av.val_type(show_let, "<enum 'elem_visibility'>", 'show_let', _m)
|
||||
av.val_type(show_num, "<enum 'elem_visibility'>", 'show_num', _m)
|
||||
av.val_int(dx, 'dx', _m)
|
||||
av.val_int(dy, 'dy', _m)
|
||||
av.val_str(path_folder_cmd, 'path_folder_cmd', _m)
|
||||
av.val_str(path_folder, 'path_folder', _m)
|
||||
# METHODS
|
||||
mystyle = style(show_braille, show_let, show_num)
|
||||
# Get Braille dictionary + delimiters
|
||||
braille_translations = get_braille_translations()
|
||||
# Get list of products that can be generated
|
||||
products = gen_product_inputs(braille_translations)
|
||||
# input product selection from user and translate to braille
|
||||
my_product = input_product(braille_translations, products, my_option, my_select) # my_option)
|
||||
# get list of product size configurations
|
||||
sizes_product = gen_scrabble_sizes()
|
||||
# generate product size (and content for Scrabble tile array) permutations
|
||||
mymsgs, myszs = gen_product_permutations(my_product, sizes_product, size_permutations, size_option)
|
||||
# get product colour selection
|
||||
colour_themes = input_colour_themes(colour_permutations, colour_option)
|
||||
# generate openscad, stl, and png files of selected product(s)
|
||||
gen_3d_models(braille_translations, my_product, mymsgs, myszs, my_product.line_length, path_folder, path_folder_cmd, mystyle, colour_themes)
|
||||
# generate assembly of products for promotional content, as scad + png
|
||||
gen_snippet_assembly(dx, dy, my_product.line_length, colour_themes, myszs, my_product, path_folder, path_folder_cmd, mystyle)
|
||||
|
||||
# generate()
|
||||
# generate(1, 'A')
|
||||
generate(my_option, my_select, size_permutations, size_option, colour_permutations, colour_option, show_braille, show_let, show_num, dx, dy, path_folder_cmd, path_folder)
|
||||
# generate(my_option, my_select, size_permutations, size_option, colour_permutations, colour_option, elem_visibility.VISIBLE, elem_visibility.VISIBLE, elem_visibility.VISIBLE, dx, dy, path_folder_cmd, path_folder)
|
||||
249
model_gen/openscad_objects.py
Normal file
249
model_gen/openscad_objects.py
Normal file
@@ -0,0 +1,249 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Thu Apr 27 12:03:30 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
|
||||
Procedural OpenSCAD Generation
|
||||
https://github.com/taxpon/openpyscad/blob/develop/openpyscad/base.py
|
||||
"""
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
def bool_2_str(mybool):
|
||||
# FUNCTION
|
||||
# Convert boolean to lowercase string for openscad
|
||||
# ARGUMENTS
|
||||
# bool mybool
|
||||
# ARGUMENT VALIDATION
|
||||
if not av.val_bool(mybool):
|
||||
return f'Error converting boolean to string.\nInput: {mybool}'
|
||||
# RETURNS
|
||||
return str(mybool).lower()
|
||||
|
||||
|
||||
def neg_fillet(L, r, centre = True, q = 25):
|
||||
# FUNCTION
|
||||
# return negative-space fillet object for use with boolean operation
|
||||
# ARGUMENTS
|
||||
# int L - cylinder height
|
||||
# double r - fillet radius
|
||||
# bool centre - is fillet centred vertically?
|
||||
# int q - quality / discretisation - number of points per edge
|
||||
# ARGUMENT VALIDATION
|
||||
if not (av.val_double(L, 0) and av.val_double(r, 0) and av.val_bool(centre) and av.val_int(q, 0)):
|
||||
return None
|
||||
# VARIABLE INSTANTIATION
|
||||
fillet = ops.Difference()
|
||||
# METHODS
|
||||
fillet.append(ops.Cube([r, r, L], center = "false", _fn = q))
|
||||
fillet.append(ops.Cylinder(L, r, center = "false"))
|
||||
fillet.mirror([1, 1, 0])
|
||||
fillet.translate([r, r, -L/2 if centre else 0])
|
||||
# RETURNS
|
||||
return fillet
|
||||
|
||||
|
||||
def base_fillet_cube(a, b, c, f, q, centre = True):
|
||||
# FUNCTION
|
||||
# return openpyscad object of cube with base edges and corners filleted with radius f
|
||||
# ARGUMENTS
|
||||
# double a, b, c - cube dimensions x, y, z
|
||||
# double f - fillet radius
|
||||
# int q - quality / discretisation - number of points per edge
|
||||
# bool centre - is base-filleted cube centred?
|
||||
# ARGUMENT VALIDATION
|
||||
if not (av.val_double(a, 0) and av.val_double(a, 0) and av.val_double(a, 0)):
|
||||
return None
|
||||
if not (av.val_double(f, 0, min(a, b, c)) and av.val_int(q, 1) and av.val_bool(centre)):
|
||||
return None
|
||||
# VARIABLE INSTANTIATION
|
||||
my_dif = ops.Difference()
|
||||
# METHODS
|
||||
my_dif.append(ops.Cube([a, b, c], center = "true", _fn = q).translate([0, 0, c/2]))
|
||||
my_dif.append(neg_fillet(a, f, True, q).rotate([90, 0, 0]))
|
||||
my_dif.append(neg_fillet(a, f, True, q).rotate([90, 0, 0]).mirror([0, 1, 0]).translate([f + a, 0, 0]))
|
||||
my_dif.append(neg_fillet(a, f, True, q).rotate([0, 90, 0]))
|
||||
my_dif.append(neg_fillet(a, f, True, q).rotate([0, 90, 0]).mirror([1, 0, 0]).translate([0, f + b, 0]))
|
||||
# RETURNS
|
||||
return my_dif.translate([0 if centre else a/2, 0 if centre else b/2, -c/2 if centre else 0])
|
||||
|
||||
|
||||
def triprism(a, L, centre = True):
|
||||
# FUNCTION
|
||||
# Triangular-based prism
|
||||
# ARGUMENTS
|
||||
# double a - triangle side-length
|
||||
# double L - depth in Z-direction
|
||||
# bool centre - is triprism centred by volume?
|
||||
# ARGUMENT VALIDATION
|
||||
if not (av.val_double(a, 0) and av.val_double(L, 0) and av.val_bool(centre)):
|
||||
return None
|
||||
# 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():
|
||||
return [ # openscad_colours = [
|
||||
"Lavender",
|
||||
"Thistle",
|
||||
"Plum",
|
||||
"Violet",
|
||||
"Orchid",
|
||||
"Fuchsia",
|
||||
"Magenta",
|
||||
"MediumOrchid",
|
||||
"MediumPurple",
|
||||
"BlueViolet",
|
||||
"DarkViolet",
|
||||
"DarkOrchid",
|
||||
"DarkMagenta",
|
||||
"Purple",
|
||||
"Indigo",
|
||||
"DarkSlateBlue",
|
||||
"SlateBlue",
|
||||
"MediumSlateBlue",
|
||||
"Pink",
|
||||
"LightPink",
|
||||
"HotPink",
|
||||
"DeepPink",
|
||||
"MediumVioletRed",
|
||||
"PaleVioletRed",
|
||||
"Aqua",
|
||||
"Cyan",
|
||||
"LightCyan",
|
||||
"PaleTurquoise",
|
||||
"Aquamarine",
|
||||
"Turquoise",
|
||||
"MediumTurquoise",
|
||||
"DarkTurquoise",
|
||||
"CadetBlue",
|
||||
"SteelBlue",
|
||||
"LightSteelBlue",
|
||||
"PowderBlue",
|
||||
"LightBlue",
|
||||
"SkyBlue",
|
||||
"LightSkyBlue",
|
||||
"DeepSkyBlue",
|
||||
"DodgerBlue",
|
||||
"CornflowerBlue",
|
||||
"RoyalBlue",
|
||||
"Blue",
|
||||
"MediumBlue",
|
||||
"DarkBlue",
|
||||
"Navy",
|
||||
"MidnightBlue",
|
||||
"IndianRed",
|
||||
"LightCoral",
|
||||
"Salmon",
|
||||
"DarkSalmon",
|
||||
"LightSalmon",
|
||||
"Red",
|
||||
"Crimson",
|
||||
"FireBrick",
|
||||
"DarkRed",
|
||||
"GreenYellow",
|
||||
"Chartreuse",
|
||||
"LawnGreen",
|
||||
"Lime",
|
||||
"LimeGreen",
|
||||
"PaleGreen",
|
||||
"LightGreen",
|
||||
"MediumSpringGreen",
|
||||
"SpringGreen",
|
||||
"MediumSeaGreen",
|
||||
"SeaGreen",
|
||||
"ForestGreen",
|
||||
"Green",
|
||||
"DarkGreen",
|
||||
"YellowGreen",
|
||||
"OliveDrab",
|
||||
"Olive",
|
||||
"DarkOliveGreen",
|
||||
"MediumAquamarine",
|
||||
"DarkSeaGreen",
|
||||
"LightSeaGreen",
|
||||
"DarkCyan",
|
||||
"Teal",
|
||||
"LightSalmon",
|
||||
"Coral",
|
||||
"Tomato",
|
||||
"OrangeRed",
|
||||
"DarkOrange",
|
||||
"Orange",
|
||||
"Gold",
|
||||
"Yellow",
|
||||
"LightYellow",
|
||||
"LemonChiffon",
|
||||
"LightGoldenrodYellow",
|
||||
"PapayaWhip",
|
||||
"Moccasin",
|
||||
"PeachPuff",
|
||||
"PaleGoldenrod",
|
||||
"Khaki",
|
||||
"DarkKhaki",
|
||||
"Cornsilk",
|
||||
"BlanchedAlmond",
|
||||
"Bisque",
|
||||
"NavajoWhite",
|
||||
"Wheat",
|
||||
"BurlyWood",
|
||||
"Tan",
|
||||
"RosyBrown",
|
||||
"SandyBrown",
|
||||
"Goldenrod",
|
||||
"DarkGoldenrod",
|
||||
"Peru",
|
||||
"Chocolate",
|
||||
"SaddleBrown",
|
||||
"Sienna",
|
||||
"Brown",
|
||||
"Maroon",
|
||||
"White",
|
||||
"Snow",
|
||||
"Honeydew",
|
||||
"MintCream",
|
||||
"Azure",
|
||||
"AliceBlue",
|
||||
"GhostWhite",
|
||||
"WhiteSmoke",
|
||||
"Seashell",
|
||||
"Beige",
|
||||
"OldLace",
|
||||
"FloralWhite",
|
||||
"Ivory",
|
||||
"AntiqueWhite",
|
||||
"Linen",
|
||||
"LavenderBlush",
|
||||
"MistyRose",
|
||||
"Gainsboro",
|
||||
"LightGrey",
|
||||
"Silver",
|
||||
"DarkGray",
|
||||
"Gray",
|
||||
"DimGray",
|
||||
"LightSlateGray",
|
||||
"SlateGray",
|
||||
"DarkSlateGray",
|
||||
"Black"
|
||||
]
|
||||
79
model_gen/system_commands.py
Normal file
79
model_gen/system_commands.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Thu Apr 27 16:47:54 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
|
||||
File Operations OpenSCAD, Cura Engine
|
||||
|
||||
"""
|
||||
|
||||
# CLASSES
|
||||
# ATTRIBUTE DECLARATION
|
||||
# METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
# NORMAL METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def render_openscad(path_scad, path_stl, path_cmd = 'C:\\"Program Files (x86)"\\OpenSCAD\\openscad'):
|
||||
# FUNCTION
|
||||
# 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
|
||||
exec_oscmd(cmd)
|
||||
|
||||
def make_openscad(path_scad, path_stl, path_cmd = 'C:\\"Program Files (x86)"\\OpenSCAD\\openscad'):
|
||||
# FUNCTION
|
||||
# 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} "{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):
|
||||
# FUNCTION
|
||||
# slice stl file using Cura Engine
|
||||
# ARGUMENTS
|
||||
# str path_stl - filepath for input stl
|
||||
# str path_stl - filepath to store gcode
|
||||
# VARIABLE INSTANTIATION
|
||||
cmd = f'C:\\"Program Files\\Ultimaker Cura 4.11.0\\CuraEngine ' # ToDo FINISH THIS
|
||||
# METHODS
|
||||
exec_oscmd(cmd)
|
||||
664
model_gen/translate_braille_2_scad.py
Normal file
664
model_gen/translate_braille_2_scad.py
Normal file
@@ -0,0 +1,664 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Wed Apr 26 17:11:57 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
|
||||
Braille 3D Model Product Creation
|
||||
|
||||
Plaintext message translation into Braille for 3D modelling
|
||||
|
||||
Procedural OpenSCAD Generation
|
||||
Braille Scrabble Pieces
|
||||
"""
|
||||
|
||||
# CLASSES
|
||||
# ATTRIBUTE DECLARATION
|
||||
# METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
# NORMAL METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
|
||||
import openpyscad as ops
|
||||
import numpy as np
|
||||
import argument_validation as av
|
||||
from openscad_objects import gen_openscad_colours
|
||||
from typing import Optional
|
||||
from prettytable import PrettyTable
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class elem_visibility(Enum):
|
||||
EMBOSSED = -1
|
||||
HIDDEN = 0
|
||||
VISIBLE = 1
|
||||
def mini():
|
||||
# FUNCTION
|
||||
# Get minimum value in enumerator
|
||||
# RETURNS
|
||||
return min([e.value for e in elem_visibility])
|
||||
def maxi():
|
||||
# FUNCTION
|
||||
# Get maximum value in enumerator
|
||||
# RETURNS
|
||||
return max([e.value for e in elem_visibility])
|
||||
|
||||
class style():
|
||||
# ATTRIBUTE DECLARATION
|
||||
braille: elem_visibility
|
||||
letter: elem_visibility
|
||||
number: elem_visibility
|
||||
|
||||
def __new__(cls, braille, letter, number):
|
||||
_m = 'style.__new__'
|
||||
av.val_type(braille, "<enum 'elem_visibility'>", 'braille', _m)
|
||||
av.val_type(braille, "<enum 'elem_visibility'>", 'braille', _m)
|
||||
av.val_type(braille, "<enum 'elem_visibility'>", 'braille', _m)
|
||||
return super(style, cls).__new__(cls)
|
||||
|
||||
def __init__(self, braille, letter, number):
|
||||
self.braille = braille
|
||||
self.letter = letter
|
||||
self.number = number
|
||||
|
||||
def gen_filetxt(mystyle):
|
||||
# FUNCTION
|
||||
# generate filename text for style settings
|
||||
# ARGUMENTS
|
||||
# style mystyle
|
||||
# ARGUMENT VALIDATION
|
||||
av.val_type(mystyle, "<class 'translate_braille_2_scad.style'>", 'mystyle', 'get_style_filetxt')
|
||||
# VARIABLE INSTANTIATION
|
||||
style_txt = '_0b' if (mystyle.braille == elem_visibility.HIDDEN) else ''
|
||||
style_txt += '_0l' if (mystyle.letter == elem_visibility.HIDDEN) else ''
|
||||
style_txt += '__l' if (mystyle.letter == elem_visibility.EMBOSSED) else ''
|
||||
style_txt += '_0n' if (mystyle.number == elem_visibility.HIDDEN) else ''
|
||||
# RETURNS
|
||||
return style_txt
|
||||
|
||||
def base_fillet_cube(a, b, c, f, q, centre = "true"):
|
||||
# fillets removed as they print horribly
|
||||
# now just cube
|
||||
my_dif = ops.Difference();
|
||||
my_dif.append(ops.Cube([a, b, c], center = "true", _fn = q));
|
||||
return my_dif.translate([0 if (centre == "true") else a/2, 0 if (centre == "true") else b/2, 0 if (centre == "true") else c/2])
|
||||
|
||||
|
||||
def triprism(a, L, centre = "true"):
|
||||
return ops.Polygon([[0,0], [0, a], [a, 0]]).linear_extrude(L, center = "true").translate([0, 0, 0 if (centre == "true") else L/2]);
|
||||
|
||||
|
||||
class scrabble_dimensions:
|
||||
# ATTRIBUTE DECLARATION
|
||||
name: str
|
||||
dp: float # distance between dots
|
||||
hblock: float # height of
|
||||
s: float # spacing between keys on keyboard
|
||||
base_height: float # height of
|
||||
hcyl: float # height of Braille dots
|
||||
rcyl: float # base radius of Braille dots
|
||||
rsphere: float # top radius of Braille dots
|
||||
|
||||
# METHODS
|
||||
def __new__(cls, name, dp, hblock, s, base_height, hcyl, rcyl, rsphere):
|
||||
# FUNCTION
|
||||
# Initialise class object
|
||||
# ARGUMENTS
|
||||
# str name - name size scheme
|
||||
# float dp - distance between braille pins
|
||||
# float hblock - height of base of each key
|
||||
# float s - spacing
|
||||
# float base_height - height of base block - board
|
||||
# float hcyl - height of braille pins
|
||||
# float rcyl - base radius of braille pins
|
||||
# float rsphere - tip radius of braille pins
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'scrabble_dimensions.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_str(name, 'name', _m, 1, v_arg_type = v_arg_type)
|
||||
av.full_val_float(dp, 'dp', _m, 0, v_arg_type = v_arg_type)
|
||||
av.full_val_float(hblock, 'hblock', _m, v_arg_type = v_arg_type)
|
||||
av.full_val_float(s, 's', _m, 0, v_arg_type = v_arg_type)
|
||||
av.full_val_float(base_height, 'base_height', _m, 0, v_arg_type = v_arg_type)
|
||||
av.full_val_float(hcyl, 'hcyl', _m, 0, v_arg_type = v_arg_type)
|
||||
av.full_val_float(rcyl, 'rcyl', _m, 0, v_arg_type = v_arg_type)
|
||||
av.full_val_float(rsphere, 'rsphere', _m, 0, v_arg_type = v_arg_type)
|
||||
# RETURNS
|
||||
return super(scrabble_dimensions, cls).__new__(cls)
|
||||
|
||||
def __init__(self, name, dp, hblock, s, base_height, hcyl, rcyl, rsphere):
|
||||
# FUNCTION
|
||||
# Construct class object
|
||||
# ARGUMENTS
|
||||
# str name
|
||||
# float dp
|
||||
# float hblock
|
||||
# float s
|
||||
# float base_height
|
||||
# float hcyl
|
||||
# float rcyl
|
||||
# float rsphere
|
||||
# ARGUMENT VALIDATION
|
||||
# see __new__()
|
||||
# ATTRIBUTE INSTANTIATION
|
||||
self.name = name
|
||||
self.dp = dp
|
||||
self.hblock = hblock
|
||||
self.s = s
|
||||
self.base_height = base_height
|
||||
self.hcyl = hcyl
|
||||
self.rcyl = rcyl
|
||||
self.rsphere = rsphere
|
||||
|
||||
def __repr__(self):
|
||||
# FUNCTION
|
||||
# Convert object to str representation
|
||||
# RETURNS
|
||||
return f"name = {self.name}, dp = {self.dp}, hblock = {self.hblock}, s = {self.s}, base_height = {self.base_height}, hcyl = {self.hcyl}, rcyl = {self.rcyl}, rsphere = {self.rsphere}"
|
||||
|
||||
def as_dict(self):
|
||||
# FUNCTION
|
||||
# Convert object attribute, value pairs to dictionary representation
|
||||
# RETURNS
|
||||
return {'name': self.name, 'dp': self.dp, 'hblock': self.hblock, 's': self.s, 'base_height': self.base_height, 'hcyl': self.hcyl, 'rcyl': self.rcyl, 'rsphere': self.rsphere}
|
||||
|
||||
|
||||
# colour themes: # ToDo: include in arguments to generator!!
|
||||
class export_colour_theme:
|
||||
# ATTRIBUTE DECLARATION
|
||||
name: str
|
||||
coltop: str
|
||||
colbase: str
|
||||
|
||||
# METHODS
|
||||
def __new__(cls, name, coltop, colbase, openscad_colours):
|
||||
# FUNCTION
|
||||
# Initialise class object
|
||||
# ARGUMENTS
|
||||
# str name - user reference to colour theme
|
||||
# str coltop - a valid openSCAD colour e.g. '#010101'
|
||||
# str colbase - a valid openSCAD colour e.g. 'blue'
|
||||
# list[str] openscad_colours
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'export_colour_theme.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_str(name, 'name', _m, 1, v_arg_type = v_arg_type)
|
||||
av.val_list(openscad_colours, 'openscad_colours', _m, "<class 'str'>", 1, v_arg_type = v_arg_type)
|
||||
if not validate_openscad_colour(coltop, openscad_colours):
|
||||
raise ValueError(f"Invalid export_colour_theme attribute coltop. Type = {str(type(coltop))}. Value = {coltop}")
|
||||
if not validate_openscad_colour(colbase, openscad_colours):
|
||||
raise ValueError(f"Invalid export_colour_theme attribute colbase. Type = {str(type(colbase))}. Value = {colbase}")
|
||||
# RETURNS
|
||||
return super(export_colour_theme, cls).__new__(cls)
|
||||
|
||||
def __init__(self, name, coltop, colbase, openscad_colours):
|
||||
# FUNCTION
|
||||
# Initialise class object
|
||||
# ARGUMENTS
|
||||
# str name - user reference to colour theme
|
||||
# str coltop - a valid openSCAD colour e.g. '#010101'
|
||||
# str colbase - a valid openSCAD colour e.g. 'blue'
|
||||
# list[str] openscad_colours # redundant in this function - used for argument validation
|
||||
# ARGUMENT VALIDATION
|
||||
# see __new__()
|
||||
# ATTRIBUTE INSTANTIATION
|
||||
self.name = name
|
||||
self.top = coltop
|
||||
self.base = colbase
|
||||
|
||||
def __repr__(self):
|
||||
# FUNCTION
|
||||
# Convert object to str representation
|
||||
# RETURNS
|
||||
return f"name = {self.name}, colour top = {self.top}, colour base = {self.base}" # , openscad_colours = {self.openscad_colours}
|
||||
|
||||
def as_dict(self):
|
||||
# FUNCTION
|
||||
# Convert object attribute, value pairs to dictionary representation
|
||||
# RETURNS
|
||||
return {'name': self.name, 'colour top': self.top, 'colour base': self.base} # , 'openscad_colours': self.openscad_colours
|
||||
|
||||
def as_row(self):
|
||||
# FUNCTION
|
||||
# Convert object values to list representation
|
||||
# RETURNS
|
||||
return [self.name, self.top, self.base] # , 'openscad_colours': self.openscad_colours
|
||||
|
||||
|
||||
def gen_scrabble_sizes(s: Optional[float] = 0.5):
|
||||
# default scrabble sizes
|
||||
# s = 1/2
|
||||
# def __init__(self, name, dp, hblock, s, base_height, hcyl, rcyl, rsphere):
|
||||
k = 2.3622
|
||||
szs_scrabble = []
|
||||
szs_scrabble.append(scrabble_dimensions('sz_1', 2.5, 2*s, s, 4*s, 1.2, 2/3, 1/2))
|
||||
szs_scrabble.append(scrabble_dimensions('sz_2', 4, 1.28, s, 4*s, 1.2, 3/2, 1))
|
||||
szs_scrabble.append(scrabble_dimensions('sz_3', 8, 2.5, s, 6*s, 1.2, 3/2, 1))
|
||||
szs_scrabble.append(scrabble_dimensions('sz_4', 10, 3, 1, 6*s, 1.2, 3/2, 1))
|
||||
szs_scrabble.append(scrabble_dimensions('sz_5', 10, 1, 1, 6*s, 1.2, 3/2, 1))
|
||||
szs_scrabble.append(scrabble_dimensions('keyboard', 2.5, 0.8, 0.5, 4, 1.2, 2/3, 0.5))
|
||||
szs_scrabble.append(scrabble_dimensions('poster', 2.5, 0.8, 0.5, 2, 1.2, 2/3, 0.5))
|
||||
szs_scrabble.append(scrabble_dimensions('poster_big', 2.5*k, 0.8, 0.5*k, 2, 1.2, 2/3*k, 0.5*k))
|
||||
# print('szs_scrabble')
|
||||
# print(szs_scrabble)
|
||||
return szs_scrabble # pd.DataFrame([x.as_dict() for x in szs_scrabble])
|
||||
|
||||
|
||||
def input_product_size(szs_product, v_size = 2):
|
||||
# FUNCTION
|
||||
# input valid product size from user
|
||||
# ARGUMENTS
|
||||
# list[scrabble_dimensions] szs_product
|
||||
# int v_size
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'get_product_size'
|
||||
av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>")
|
||||
av.val_int(v_size, 'v_size', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
n = len(szs_product)
|
||||
# METHODS
|
||||
if v_size > 0 and v_size <= n:
|
||||
return szs_product[v_size - 1]
|
||||
my_table = PrettyTable()
|
||||
my_table.field_names = ['index', 'name', 'dp', 'hblock', 's', 'base_height', 'hcyl', 'rcyl', 'rsphere']
|
||||
for i in range(n):
|
||||
prod = szs_product[i]
|
||||
my_table.add_row([i + 1, prod.name, prod.dp, prod.hblock, prod.s, prod.base_height, prod.hcyl, prod.rcyl, prod.rsphere])
|
||||
print()
|
||||
print("Please select product dimensions configuration from below:")
|
||||
print(my_table)
|
||||
# loopy = False
|
||||
while True:
|
||||
my_input = input("Product dimensions configuration (name or index): ")
|
||||
if my_input == "#!ERRORCODE!#": exit
|
||||
for i in range(n):
|
||||
if validate_input_product_size(my_input, szs_product):
|
||||
# loopy = True
|
||||
# RETURNS
|
||||
return get_product_size(my_input, szs_product)
|
||||
|
||||
|
||||
def get_product_size(product_option, szs_product):
|
||||
# FUNCTION
|
||||
# get valid product size from list of scrabble_dimensions
|
||||
# ARGUMENTS
|
||||
# str/int product_option
|
||||
# list[scrabble_dimensions] szs_product
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'get_product_size'
|
||||
error_msg = av.error_msg_str(_m, product_option, 'product_option', 'scrabble_dimensions identifier')
|
||||
if not (av.val_int(product_option, 'product_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(product_option, 'product_option', _m, suppress_errors = True, suppress_console_outputs = True)):
|
||||
raise ValueError(error_msg)
|
||||
av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>")
|
||||
# VARIABLE INSTANTIATION
|
||||
n = len(szs_product)
|
||||
# METHODS
|
||||
if av.full_val_int(product_option, 'product_option', _m, suppress_errors = True):
|
||||
product_option = av.input_int(product_option, 'product_option', _m)
|
||||
return szs_product[product_option - 1]
|
||||
for col_i in range(n):
|
||||
my_product = szs_product[col_i]
|
||||
if product_option == my_product.name:
|
||||
return my_product
|
||||
# RETURNS
|
||||
raise ValueError(error_msg)
|
||||
|
||||
|
||||
def validate_input_product_size(product_option, szs_product):
|
||||
# FUNCTION
|
||||
# evaluate if product_option relates to a szs_product
|
||||
# ARGUMENTS
|
||||
# str/int product_option
|
||||
# list[scrabble_dimensions] szs_product
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'validate_input_product_size'
|
||||
if not (av.val_int(product_option, 'product_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(product_option, 'product_option', _m, suppress_errors = True, suppress_console_outputs = True)): return False
|
||||
av.val_list(szs_product, 'szs_product', _m, "<class 'translate_braille_2_scad.scrabble_dimensions'>")
|
||||
# VARIABLE INSTANTIATION
|
||||
n = len(szs_product)
|
||||
# METHODS
|
||||
if av.full_val_int(product_option, 'product_option', _m, suppress_errors = True):
|
||||
product_option = av.input_int(product_option, 'product_option', _m)
|
||||
return (0 < product_option and product_option <= n)
|
||||
for prod_i in range(n):
|
||||
if product_option == szs_product[prod_i].name:
|
||||
return True
|
||||
# RETURNS
|
||||
return False
|
||||
|
||||
|
||||
def validate_openscad_colour(mycolour, openscad_colours):
|
||||
# FUNCTION
|
||||
# validate argument openscad colour as string
|
||||
# ARGUMENTS
|
||||
# str mycolour - to be validated
|
||||
# list[str] openscad_colours - to search through
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'validate_openscad_colour'
|
||||
av.val_str(mycolour, 'mycolour', _m)
|
||||
av.val_list(openscad_colours, 'openscad_colours', _m, "<class 'str'>")
|
||||
# VARIABLE INSTANTIATION
|
||||
N = len(mycolour)
|
||||
# METHODS
|
||||
if (N == 7):
|
||||
if (mycolour[0] == '#' and mycolour[0:5].isnumeric):
|
||||
return True
|
||||
for i in range(len(openscad_colours)):
|
||||
if (mycolour == openscad_colours[i]):
|
||||
return True
|
||||
# RETURNS
|
||||
return False
|
||||
|
||||
|
||||
# inputs
|
||||
# path_scad = "C:/Users/edwar/OneDrive/Documents/OpenSCAD"
|
||||
# path_stl = "C:/Users/edwar/OneDrive/Documents/OpenSCAD/STL"
|
||||
# filename = "Braille_Scrabble_"
|
||||
# cum = [0, 1]
|
||||
# letters = ["B"]
|
||||
# braille = [[2]]
|
||||
# braille = [[[1, 1, 0, 0, 0, 0]]]
|
||||
# lmsg = 1
|
||||
# N = 1
|
||||
# n_row_keys = 1
|
||||
# maxln = 2
|
||||
|
||||
def gen_col_themes():
|
||||
# FUNCTION
|
||||
# create colour themes for image export of 3D models
|
||||
# REQUIRES
|
||||
# class export_colour_theme
|
||||
# function gen_openscad_colours
|
||||
# VARIABLE INSTANTIATION
|
||||
openscad_colours = gen_openscad_colours()
|
||||
col_themes = []
|
||||
col_themes.append(export_colour_theme("Blue", "#337AFF", "#337AFF", openscad_colours))
|
||||
col_themes.append(export_colour_theme("Purple", "#8E44AD", "#8E44AD", openscad_colours))
|
||||
col_themes.append(export_colour_theme("Red", "#F7322F", "#F7322F", openscad_colours))
|
||||
col_themes.append(export_colour_theme("Black", "Black", "#17202A", openscad_colours))
|
||||
col_themes.append(export_colour_theme("White", "White", "White", openscad_colours))
|
||||
# RETURNS
|
||||
# list[export_colour_theme] col_themes - colour themes with name, top colour, base colour
|
||||
return col_themes
|
||||
|
||||
|
||||
def input_colour_themes(colour_permutations = False, colour_option = None):
|
||||
# FUNCTION
|
||||
# get valid colour option using parameter, else user console input
|
||||
# ARGUMENTS
|
||||
# bool colour_permutations
|
||||
# int colour_option
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'input_colour_themes'
|
||||
av.val_bool(colour_permutations, 'colour_permutations', _m)
|
||||
if not (av.val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True) or str(type(colour_option)) == "<class 'NoneType'>"):
|
||||
raise ValueError(av.error_msg_str(_m, 'colour_option', colour_option, "export_colour_theme identifier"))
|
||||
# VARIABLE INSTANTIATION
|
||||
colour_themes = gen_col_themes()
|
||||
if colour_permutations: return colour_themes
|
||||
n = len(colour_themes)
|
||||
# METHODS
|
||||
if not validate_input_colour(colour_option, colour_themes):
|
||||
colour_table = PrettyTable(field_names=['index', 'name', 'colour top', 'colour base'])
|
||||
for col_i in range(n):
|
||||
colour_table.add_row([col_i + 1] + colour_themes[col_i].as_row()) # .insert(0, str(col_i + 1))
|
||||
print(colour_table)
|
||||
while not validate_input_colour(colour_option, colour_themes):
|
||||
colour_option = input("Please input colour selection by name or index above.")
|
||||
# RETURNS
|
||||
return [get_colour_theme(colour_option, colour_themes)]
|
||||
|
||||
|
||||
def validate_input_colour(colour_option, colour_themes):
|
||||
# FUNCTION
|
||||
# evaluate if colour_option relates to a colour_theme
|
||||
# ARGUMENTS
|
||||
# str/int colour_option
|
||||
# list[export_colour_themes] colour_themes
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'validate_input_colour'
|
||||
if not (av.val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True)): return False
|
||||
av.val_list(colour_themes, 'colour_themes', _m, "<class 'translate_braille_2_scad.export_colour_theme'>")
|
||||
# VARIABLE INSTANTIATION
|
||||
n = len(colour_themes)
|
||||
# METHODS
|
||||
if av.full_val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True):
|
||||
colour_option = av.input_int(colour_option, 'colour_option', _m)
|
||||
return (0 < colour_option and colour_option <= n)
|
||||
for col_i in range(n):
|
||||
if colour_option == colour_themes[col_i].name:
|
||||
return True
|
||||
# RETURNS
|
||||
return False
|
||||
|
||||
|
||||
def get_colour_theme(colour_option, colour_themes):
|
||||
# FUNCTION
|
||||
# get valid colour_option from colour_themes
|
||||
# ARGUMENTS
|
||||
# str/int colour_option
|
||||
# list[export_colour_themes] colour_themes
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'get_colour_theme'
|
||||
error_msg = av.error_msg_str(_m, colour_option, 'colour_option', 'export_colour_theme identifier')
|
||||
if not (av.val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True) or av.val_str(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True)):
|
||||
raise ValueError(error_msg)
|
||||
av.val_list(colour_themes, 'colour_themes', _m, "<class 'translate_braille_2_scad.export_colour_theme'>")
|
||||
# VARIABLE INSTANTIATION
|
||||
n = len(colour_themes)
|
||||
# METHODS
|
||||
if av.full_val_int(colour_option, 'colour_option', _m, suppress_errors = True, suppress_console_outputs = True):
|
||||
colour_option = av.input_int(colour_option, 'colour_option', _m)
|
||||
return colour_themes[colour_option - 1]
|
||||
for col_i in range(n):
|
||||
my_colour = colour_themes[col_i]
|
||||
if colour_option == my_colour.name:
|
||||
return my_colour
|
||||
# ERROR HANDLING
|
||||
raise ValueError(error_msg)
|
||||
|
||||
|
||||
def gen_path_braille_scrabble(sz_scheme, col_theme, my_style, path_file = "C:\\Users\\edwar\\OneDrive\\Documents\\Programming\\Python Scripts\\Braille_Scrabble", suffix = "stl", presuffix=""):
|
||||
# FUNCTION
|
||||
# generate file path for braille scrabble design
|
||||
# ARGUMENTS
|
||||
# scrabble_dimensions sz_scheme
|
||||
# int letter - index in the alphabet with base 0
|
||||
# export_colour_theme col_theme
|
||||
# style my_style
|
||||
# string path_file - path of folder + filename (message text)
|
||||
# string suffix - file type
|
||||
# string presuffix - text before file type
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'gen_path_braille_scrabble'
|
||||
av.val_type(sz_scheme, "<class 'translate_braille_2_scad.scrabble_dimensions'>", 'sz_scheme', _m)
|
||||
av.val_type(col_theme, "<class 'translate_braille_2_scad.export_colour_theme'>", 'col_theme', _m)
|
||||
av.val_type(my_style, "<class 'translate_braille_2_scad.style'>", 'my_style', _m)
|
||||
av.val_str(path_file, 'path_file', _m)
|
||||
av.val_str(suffix, 'suffix', _m)
|
||||
av.val_str(presuffix, 'presuffix', _m)
|
||||
# RETURNS
|
||||
return f"{path_file}_{sz_scheme.name}_{col_theme.name}{my_style.gen_filetxt()}.{suffix}"
|
||||
|
||||
|
||||
def gen_openscad_braille(cum, letters, numbers, braille, n_keys, n_row_keys, n_rows, mydims, mystyle, col_theme, filename, path_file="C:/Users/edwar/OneDrive/Documents/Programming/Python Scripts/Braille", quality = 25):
|
||||
# FUNCTION
|
||||
# generate openscad model of Braille product
|
||||
# ARGUMENTS
|
||||
# list[int] cum
|
||||
# list[str] letters - array of plaintext for output
|
||||
# list[int] numbers - ordinality of translated keys in alphabet / number line (where appropriate)
|
||||
# list[list[int]] braille - translated keys
|
||||
# int n_keys - number of keys in Braille message
|
||||
# int n_row_keys - number of Braille keys per row on keyboard
|
||||
# int n_rows - number of rows of keys on keyboard
|
||||
# scrabble_dimensions mydims - sizing parameters
|
||||
# style mystyle
|
||||
# export_colour_themes col_theme
|
||||
# str filename - excl. path
|
||||
# str path_file
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'gen_openscad_braille'
|
||||
av.val_list(cum, 'cum', _m, "<class 'int'>")
|
||||
av.val_list(letters, 'letters', _m, "<class 'str'>")
|
||||
av.val_nested_list(numbers, 0, 1, 'numbers', _m, "<class 'int'>")
|
||||
av.val_nested_list(braille, 0, 2, 'braille', _m, "<class 'int'>", -1, [-1, -1, 6], -1, [-1, -1, 6])
|
||||
av.val_int(n_keys, 'n_keys', _m)
|
||||
av.val_int(n_row_keys, 'n_row_keys', _m)
|
||||
av.val_int(n_rows, 'n_rows', _m)
|
||||
# av.val_int(show_braille, 'show_braille', _m)
|
||||
# av.val_int(show_let, 'show_let', _m)
|
||||
# av.val_int(show_num, 'show_num', _m)
|
||||
# av.val_type(show_braille, "<enum 'elem_visibility'>", 'show_braille', _m)
|
||||
# av.val_type(show_let, "<enum 'elem_visibility'>", 'show_let', _m)
|
||||
# av.val_type(show_num, "<enum 'elem_visibility'>", 'show_num', _m)
|
||||
av.val_type(mystyle, "<class 'translate_braille_2_scad.style'>", 'mystyle', _m)
|
||||
# if not (av.val_type(col_theme, "<class 'export_colour_theme'>", 'col_theme', _m, True) or av.val_type(col_theme, "<class 'translate_braille_2_scad.export_colour_theme'>", 'col_theme', _m, True)):
|
||||
# raise ValueError(av.error_msg_str(_m, 'col_theme', col_theme, "<class 'export_colour_theme'>"))
|
||||
av.val_type(col_theme, "<class 'translate_braille_2_scad.export_colour_theme'>", 'col_theme', _m)
|
||||
av.val_str(filename, 'filename', _m)
|
||||
av.val_str(path_file, 'path_file', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
# integer boolean conversions for position
|
||||
i_s_braille = int(mystyle.braille == elem_visibility.VISIBLE)
|
||||
i_s_let = int(mystyle.letter == elem_visibility.VISIBLE)
|
||||
i_s_num = int(mystyle.number == elem_visibility.VISIBLE)
|
||||
print(f'i_s_b = {i_s_braille}\ni_s_let = {i_s_let}\ni_s_num = {i_s_num}\n')
|
||||
# dimensions
|
||||
dp = mydims.dp # horizontal and vertical spacing between dots = 2.2 - 2.8mm
|
||||
h_block = mydims.hblock # block height
|
||||
s = mydims.s # inter-block spacing
|
||||
h_base = mydims.base_height # thickness of base block
|
||||
# derived from: horizontal distance between corresponding braille dots in adjacent cells = 5.1 - 6.8mm
|
||||
# and also conforms to: vertical distance between corresponding braille dots in adjacent cells = 10 - 15mm
|
||||
hcyl = mydims.hcyl # braille dot height
|
||||
rcyl = mydims.rcyl #3/2; # braille dot base-radius
|
||||
rsphere = mydims.rsphere #3/2*4/5; # braille dot top-radius
|
||||
xb = dp + 2 * s + rcyl * 2
|
||||
R_base_letter = [xb, xb] # alphabet block dimensions [x, y]
|
||||
R_base_braille = [xb, xb + dp] # braille block dimensions [x, y]
|
||||
R_base_number = np.array([xb, xb - 2 * s]) * i_s_num # number block dimensions [x, y] ' adjust to scalar coefficient rather than linear translation
|
||||
htxt = hcyl # height of text
|
||||
stxt = xb - 4 * s
|
||||
snum = stxt * 0.75
|
||||
ntxtsfn = 0.65 # scale factor for shrinking number text to fit more letters in single char space
|
||||
ntxtsfm = 0.75 # scale factor for shrinking message text to fit more letters in single char space
|
||||
font = '"Arial:style=Bold"'
|
||||
_fn = quality
|
||||
|
||||
# keyboard layout
|
||||
#maxln = 10;
|
||||
#nln = min(maxln, N); # renamed n_row_keys
|
||||
# temp = 1 + (N - 1) % nln
|
||||
|
||||
# yn = (N + nln - temp) / nln # - 0 ** (temp)
|
||||
# print(f"number of rows = {yn}")
|
||||
|
||||
R_board = [n_row_keys * R_base_letter[0] + (n_row_keys + 3) * s,
|
||||
n_rows * (R_base_braille[1] * i_s_braille + R_base_letter[1] * i_s_let + R_base_number[1] * i_s_num + s * (i_s_braille + i_s_let + i_s_num)) + 3 * s, # - 3 * s,
|
||||
h_base] # +R_base_number[1]
|
||||
print(f"R_board = {R_board}")
|
||||
obj_dif = ops.Difference()
|
||||
obj_uni = ops.Union()
|
||||
|
||||
# obj_uni.append(base_fillet_cube(R_board[0], R_board[1], R_board[2], h_block, centre = "false").translate([-2 * s - rcyl, 2 * s + rcyl - R_board[1], -h_block - R_board[2]]).color(col_theme.base))
|
||||
obj_uni.append(ops.Cube([R_board[0], R_board[1], R_board[2]], h_block, centre = "false").translate([-3 * s - rcyl, 3 * s + rcyl - R_board[1], -h_block - R_board[2]]).color(col_theme.base))
|
||||
|
||||
# METHODS
|
||||
for ab_i in range(len(braille)): # alpha-braille iterator
|
||||
char = braille[ab_i]
|
||||
print(f"char = braille[{ab_i}]") # " = {char}")
|
||||
for char_j in range(len(char)):
|
||||
char_old = [0, 0, 0, 0, 0, 0] if (ab_i == 0 and char_j == 0) else braille[0][char_j - 1] if (char_j > 0) else braille[ab_i - 1][len(braille[ab_i - 1]) - 1]
|
||||
char_new = char[char_j]
|
||||
print(f"char_new = {char_new}")
|
||||
ab_n = (cum[ab_i] + char_j) % n_row_keys
|
||||
ab_len = ((cum[ab_i] + char_j) - ab_n) / n_row_keys
|
||||
ab_p = [ab_n * (R_base_braille[0] + s), -ab_len * (R_base_braille[1] * i_s_braille + R_base_letter[1] * i_s_let + R_base_number[1] * i_s_num + s * (i_s_braille + i_s_let + i_s_num)), 0]
|
||||
# Bases
|
||||
if (letters[ab_i] != " "):
|
||||
if (mystyle.braille == elem_visibility.VISIBLE):
|
||||
obj_uni.append(ops.Cube([R_base_braille[0], R_base_braille[1], h_block]).color(col_theme.base).translate([-(s + rcyl), s + rcyl - R_base_braille[1], -h_block]).translate(ab_p))
|
||||
if (mystyle.letter == elem_visibility.VISIBLE):
|
||||
obj_uni.append(ops.Cube([R_base_letter[0], R_base_letter[1], h_block]).color(col_theme.base).translate([-(s + rcyl), s + rcyl -R_base_letter[1], 0]).translate([0, -(R_base_braille[1] + s) * i_s_braille, -h_block]).translate(ab_p)) # should this be: rcyl - R_base_letter[1] ?????!?!?!?!!!!
|
||||
|
||||
# Braille message
|
||||
# Dots
|
||||
if (mystyle.braille == elem_visibility.VISIBLE):
|
||||
for dot_y in range(3):
|
||||
for dot_x in range(2):
|
||||
if (char_new[dot_y + 3 * dot_x] == 1):
|
||||
obj_uni.append(ops.Cylinder(hcyl, None, rcyl, rsphere, _fn = _fn, center = 'true').color(col_theme.top).translate([dot_x * dp, -dot_y * dp, 0]).translate(ab_p))
|
||||
# Text
|
||||
if (mystyle.letter == elem_visibility.VISIBLE):
|
||||
obj_uni.append(ops.Text(f'"{letters[ab_i]}"', stxt * ntxtsfm ** (len(letters[ab_i]) - 1), font, halign = '"center"', valign = '"center"', _fn = _fn).linear_extrude(htxt, center = "false").translate([R_base_letter[0] / 2, R_base_letter[1] / 2, 0]).color(col_theme.top).translate([-(s + rcyl), s + rcyl -R_base_letter[1], 0]).translate([0, - (R_base_braille[1] + s) * i_s_braille, 0]).translate(ab_p))
|
||||
# Text ordinality
|
||||
num_new = numbers[ab_i]
|
||||
if (num_new != [-1] and mystyle.number == elem_visibility.VISIBLE):
|
||||
print(f"num_new = {num_new}, type = {type(num_new)}")
|
||||
for num_x in range(len(num_new)):
|
||||
snum = (R_base_number[1] - s * (len(num_new) + 1)) / (len(num_new) ** ntxtsfn)
|
||||
# Base
|
||||
obj_uni.append(ops.Cube([R_base_number[0], R_base_number[1], h_block]).color(col_theme.base).translate([0, -R_base_number[1], 0]).translate([-(s + rcyl), s + rcyl -(R_base_letter[1] + s) * i_s_let, 0]).translate([0, -(R_base_braille[1] + s) * i_s_braille, -h_block]).translate(ab_p))
|
||||
# Number (text)
|
||||
obj_uni.append(ops.Text(f'"{num_new[num_x]}"', snum, font, halign = '"center"', valign = '"center"', _fn = _fn).linear_extrude(htxt, center = "true").color(col_theme.top).translate([R_base_number[0] / 2 if (len(num_new) == 1) else R_base_number[0] / 2 + 1.6 * snum * (num_x - (len(num_new) - 1) / 2), R_base_number[1] * 0.25, htxt / 2]).translate([-s, s -R_base_number[1], 0]).translate([0, -(R_base_letter[1] - s) * i_s_let, 0]).translate([s-(s + rcyl), s - (R_base_braille[1] + s) * i_s_braille, -h_block * 0]).translate(ab_p))
|
||||
|
||||
obj_dif.append(obj_uni)
|
||||
# remove excess plastic if no numbers on final row regardless of mystyle.number
|
||||
remove_num_space = True
|
||||
for ab_i in range(n_row_keys):
|
||||
remove_num_space &= numbers[len(numbers) - ab_i - 1] == [-1]
|
||||
# Trimming tools for no numbers:
|
||||
if remove_num_space:
|
||||
obj_dif.append(ops.Cube([R_board[0], R_base_number[1] + s, R_board[2]], center = "true").translate([R_board[0] / 2 - 3 * s - rcyl, 3 * s + rcyl + (R_base_number[1] + s) / 2 - R_board[1], -R_board[2] / 2 - h_block]))
|
||||
# obj_dif.append(triprism(h_block, R[0], centre = "true").rotate([0, 90, 0]).translate([R[0] / 2 - 1.6, (12+4) * s - R[1], -1/1000 - R[2] - h_block]))
|
||||
|
||||
# embossed characters
|
||||
for ab_i in range(len(braille)):
|
||||
char = braille[ab_i]
|
||||
print(f"char = braille[{ab_i}]") # " = {char}")
|
||||
for char_j in range(len(char)):
|
||||
# what is the purpose of char_old?
|
||||
char_old = [0, 0, 0, 0, 0, 0] if (ab_i == 0 and char_j == 0) else braille[0][char_j - 1] if (char_j > 0) else braille[ab_i - 1][len(braille[ab_i - 1]) - 1]
|
||||
char_new = char[char_j]
|
||||
ab_n = (cum[ab_i] + char_j) % n_row_keys
|
||||
ab_len = ((cum[ab_i] + char_j) - ab_n) / n_row_keys
|
||||
ab_p = [ab_n * (R_base_braille[0] + s), -ab_len * (R_base_braille[1] * i_s_braille + R_base_letter[1] * i_s_let + R_base_number[1] * i_s_num + s * (i_s_braille + i_s_let + i_s_num)), 0]
|
||||
|
||||
# Text
|
||||
if (mystyle.letter == elem_visibility.EMBOSSED):
|
||||
obj_dif.append(ops.Text(f'"{letters[ab_i]}"', stxt * ntxtsfm ** (len(letters[ab_i]) - 1) * 1.15, font, halign = '"center"', valign = '"center"', _fn = _fn).linear_extrude(htxt, center = "false").mirror([1, 0, 0]).translate([R_base_letter[0] / 2, R_base_letter[1] * 3 / 4, - R_board[2]]).color(col_theme.top).translate([0, -R_base_braille[1], 0]).translate([-(s + rcyl), s + rcyl - (R_base_braille[1] + s) * i_s_braille * 0, -h_block]).translate(ab_p))
|
||||
|
||||
# my_prefix = '_0b' if (mystyle.braille == elem_visibility.HIDDEN) else ''
|
||||
# my_prefix += '_0l' if (mystyle.letter == elem_visibility.HIDDEN) else ''
|
||||
# my_prefix += '__l' if (mystyle.letter == elem_visibility.EMBOSSED) else ''
|
||||
# my_prefix += '_0n' if (mystyle.number == elem_visibility.HIDDEN) else ''
|
||||
# my_prefix = mystyle.gen_filetxt()
|
||||
|
||||
path_png = gen_path_braille_scrabble(mydims, col_theme, mystyle, path_file, 'png')
|
||||
path_scad = gen_path_braille_scrabble(mydims, col_theme, mystyle, path_file, 'scad')
|
||||
path_stl = gen_path_braille_scrabble(mydims, col_theme, mystyle, path_file, 'stl')
|
||||
# RETURNS
|
||||
obj_dif.write(path_scad)
|
||||
print("writing SCAD")
|
||||
# obj_dif.write(path_png)
|
||||
return path_png, path_scad, path_stl
|
||||
|
||||
|
||||
# def get_shownum(braille):
|
||||
# shownum = 1
|
||||
# for n_x in range(len(braille)):
|
||||
# shownum &= not (not braille[n_x])
|
||||
# return 0 # 1 if shownum else 0
|
||||
801
model_gen/translate_msg_2_braille.py
Normal file
801
model_gen/translate_msg_2_braille.py
Normal file
@@ -0,0 +1,801 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Apr 24 14:26:02 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
|
||||
Braille 3D Model Product Creation
|
||||
|
||||
Braille Dictionary Conversion / Creation
|
||||
Plaintext message translation into Braille for 3D modelling
|
||||
"""
|
||||
|
||||
# CLASSES
|
||||
# ATTRIBUTE DECLARATION
|
||||
# METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
# NORMAL METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
|
||||
import pandas as pd
|
||||
from typing import Optional
|
||||
from enum import Enum
|
||||
import argument_validation as av
|
||||
import sys
|
||||
|
||||
class difficulty(Enum):
|
||||
ALPHABETPUNCTUATION = 1
|
||||
SIMPLEWORDGROUPSIGNS = 2
|
||||
LOWERCONTRACTIONS = 3
|
||||
def mini():
|
||||
# FUNCTION
|
||||
# Get minimum value in enumerator
|
||||
# RETURNS
|
||||
return min([e.value for e in difficulty])
|
||||
def maxi():
|
||||
# FUNCTION
|
||||
# Get maximum value in enumerator
|
||||
# RETURNS
|
||||
return max([e.value for e in difficulty])
|
||||
|
||||
class braille_trans():
|
||||
# ATTRIBUTE DECLARATION
|
||||
key: str # search key in input messages for Braille translation - includes additional characters for literal processing
|
||||
level: difficulty # stage of learning at which this translation is discovered
|
||||
braille: list # list[list[int]] # Braille translation of plaintext
|
||||
plaintext: str # English plaintext key
|
||||
# METHODS
|
||||
# def argvalinit(key: str, level: difficulty, braille: list, plaintext: Optional[str] = None):
|
||||
# # run before instantiating braille_trans
|
||||
# # av.val_list(braille, 'list')=
|
||||
# # _m = 'braille_trans.argvalinit'
|
||||
# # if not av.val_str(key, 'key', method, min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument')
|
||||
# if not (av.val_str(key) and (str(type(level)) == "<enum 'difficulty'>" or av.val_int(level, difficulty.mini(), difficulty.maxi())) and av.val_list(braille, "<class 'list'>") and (av.val_str(plaintext, -1, -1, True) or plaintext == None)):
|
||||
# print(f'Invalid braille_trans instantiation. key = {key}, level = {level}, braille = {braille}, plaintext = {plaintext}')
|
||||
# return None
|
||||
# return braille_trans(key, level, braille, plaintext)
|
||||
|
||||
def __new__(cls, key: str, level: difficulty, braille: list, plaintext: Optional[str] = None):
|
||||
# FUNCTION
|
||||
# Initialise class object
|
||||
# ARGUMENTS
|
||||
# str key
|
||||
# difficulty level
|
||||
# list[list[int]] braille
|
||||
# optional str plaintext
|
||||
# VARIABLE DECLARATION
|
||||
_m = 'braille_trans.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
# ARGUMENT VALIDATION
|
||||
av.val_str(key, 'key', _m, 1, -1, v_arg_type = v_arg_type)
|
||||
av.val_type(level, "<enum 'difficulty'>", 'level', _m, v_arg_type = v_arg_type)
|
||||
av.val_nested_list(braille, 0, 1, 'braille', _m, "<class 'int'>", -1, [-1, 6], -1, [-1, 6], v_arg_type = v_arg_type)
|
||||
if not (av.val_str(plaintext, 'plaintext', _m, -1, -1, True, True, v_arg_type) or str(type(plaintext)) == "<class 'NoneType'>"):
|
||||
raise ValueError(av.error_msg_str(_m, 'plaintext', plaintext, "<class 'str'>", v_arg_type = v_arg_type))
|
||||
# if not av.val_str(key):
|
||||
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'key', key, 'attribute'))
|
||||
# if not av.val_type(level, "<enum 'difficulty'>"):
|
||||
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'level', level, 'attribute'))
|
||||
# if not av.val_nested_list(braille, 0, 2, "<class 'int'>", 6, [1, 6], 6, [-1, 6]):
|
||||
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'braille', braille, 'attribute'))
|
||||
# if not (av.val_str(plaintext) or str(type(plaintext)) == "<class 'NoneType'>"):
|
||||
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'plaintext', plaintext, 'attribute'))
|
||||
# RETURNS
|
||||
return super(braille_trans, cls).__new__(cls)
|
||||
|
||||
def __init__(self, key: str, level: difficulty, braille: list, plaintext: Optional[str] = None):
|
||||
# FUNCTION
|
||||
# Construct class object
|
||||
# ARGUMENTS
|
||||
# str key
|
||||
# difficulty level
|
||||
# list[list[int]] braille
|
||||
# optional str plaintext
|
||||
# ARGUMENT VALIDATION
|
||||
# see __new__()
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
self.key = key
|
||||
self.level = level
|
||||
self.braille = braille
|
||||
self.plaintext = self.key if (plaintext is None) else plaintext
|
||||
|
||||
def __repr__(self):
|
||||
return f"key = {self.key}, level = {self.level}, braille = {self.braille}, plaintext = {self.plaintext}"
|
||||
|
||||
# def query_lvl(self):
|
||||
# return ' & '.join(["{}=='{}'".format(key, value)
|
||||
# for key, value in self.__dict__.items()
|
||||
# if not value is None])
|
||||
|
||||
def as_dict(self):
|
||||
return {'key': self.key, 'level': self.level, 'braille': self.braille, 'plaintext': self.plaintext}
|
||||
|
||||
class product():
|
||||
# ATTRIBUTE DECLARATION
|
||||
name: str
|
||||
line_length: int # number of Braille characters per line on keyboard
|
||||
msg: str # pre-translated English (with necessary modifications for input to this programme e.g. splitting up undesired translations with hidden delimiter character @?NOTHING)
|
||||
msg_prefix: str # additional pre-translated str as above to pre-append to product for adding header to creation of product messages from dictionary queries
|
||||
filename: str # filename - name without spaces
|
||||
# METHODS
|
||||
# def argvalinit(name: str, line_length: int, msg: str, msg_prefix: Optional[str] = ''):
|
||||
# # run before instantiating product
|
||||
# if not (av.val_str(name) and av.val_int(line_length, 0) and av.val_str(msg) and av.val_str(msg_prefix)):
|
||||
# print(f'Invalid product instantiation. name = {name}, line_length = {line_length}, msg = {msg}, msg_prefix = {msg_prefix}')
|
||||
# return None
|
||||
# return product(name, line_length, msg, msg_prefix)
|
||||
|
||||
def __new__(cls, name, line_length, msg, msg_prefix = '', filename = ''):
|
||||
# FUNCTION
|
||||
# Initialise class object
|
||||
# ARGUMENTS
|
||||
# str name
|
||||
# int line_length
|
||||
# str msg
|
||||
# str msg_prefix
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'product.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_str(name, 'name', _m, 1, -1, v_arg_type = v_arg_type)
|
||||
av.val_int(line_length, 'line_length', _m, 1, v_arg_type = v_arg_type)
|
||||
av.val_str(msg, 'msg', _m, -1, -1, v_arg_type = v_arg_type)
|
||||
av.val_str(msg_prefix, 'msg_prefix', _m, -1, -1, v_arg_type = v_arg_type)
|
||||
av.val_str(filename, 'filename', _m, -1, -1, v_arg_type = v_arg_type)
|
||||
# if not av.val_str(name):
|
||||
# raise ValueError(av.error_msg_str('product.__new__', 'name', name, 'attribute'))
|
||||
# if not av.val_int(line_length, 1):
|
||||
# raise ValueError(av.error_msg_str('product.__new__', 'line_length', line_length, 'attribute'))
|
||||
# if not av.val_str(msg):
|
||||
# raise ValueError(av.error_msg_str('product.__new__', 'msg', msg, 'attribute'))
|
||||
# if not av.val_str(msg_prefix):
|
||||
# raise ValueError(av.error_msg_str('product.__new__', 'msg_prefix', msg_prefix, 'attribute'))
|
||||
# RETURNS
|
||||
return super(product, cls).__new__(cls)
|
||||
|
||||
def __init__(self, name, line_length, msg, msg_prefix = '', filename = ''):
|
||||
# FUNCTION
|
||||
# Construct class object
|
||||
# ARGUMENTS
|
||||
# str name
|
||||
# int line_length
|
||||
# str msg
|
||||
# str msg_prefix
|
||||
# ARGUMENT VALIDATION
|
||||
# see __new__()
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
self.name = name
|
||||
self.line_length = line_length
|
||||
self.msg = msg
|
||||
self.msg_prefix = msg_prefix # for procedurally-generated messages from difficulty selection
|
||||
self.filename = name.replace(' ', '_') if filename == '' else filename
|
||||
|
||||
def __repr__(self):
|
||||
return f"name = {self.name}, line_length = {self.line_length}, msg = {self.msg}, msg_prefix = {self.msg_prefix}, filename = {self.filename}"
|
||||
|
||||
def get_braille_translations():
|
||||
# FUNCTION
|
||||
# return list of braille translations
|
||||
# longer keys get priority in translation
|
||||
# VARIABLE INSTANTIATION
|
||||
temp_dict = [braille_trans("A", difficulty(1), [[1, 0, 0, 0, 0, 0]]),
|
||||
braille_trans("B", difficulty(1), [[1, 1, 0, 0, 0, 0]]),
|
||||
braille_trans("C", difficulty(1), [[1, 0, 0, 1, 0, 0]]),
|
||||
braille_trans("D", difficulty(1), [[1, 0, 0, 1, 1, 0]]),
|
||||
braille_trans("E", difficulty(1), [[1, 0, 0, 0, 1, 0]]),
|
||||
braille_trans("F", difficulty(1), [[1, 1, 0, 1, 0, 0]]),
|
||||
braille_trans("G", difficulty(1), [[1, 1, 0, 1, 1, 0]]),
|
||||
braille_trans("H", difficulty(1), [[1, 1, 0, 0, 1, 0]]),
|
||||
braille_trans("I", difficulty(1), [[0, 1, 0, 1, 0, 0]]),
|
||||
braille_trans("J", difficulty(1), [[0, 1, 0, 1, 1, 0]]),
|
||||
braille_trans("K", difficulty(1), [[1, 0, 1, 0, 0, 0]]),
|
||||
braille_trans("L", difficulty(1), [[1, 1, 1, 0, 0, 0]]),
|
||||
braille_trans("M", difficulty(1), [[1, 0, 1, 1, 0, 0]]),
|
||||
braille_trans("N", difficulty(1), [[1, 0, 1, 1, 1, 0]]),
|
||||
braille_trans("O", difficulty(1), [[1, 0, 1, 0, 1, 0]]),
|
||||
braille_trans("P", difficulty(1), [[1, 1, 1, 1, 0, 0]]),
|
||||
braille_trans("Q", difficulty(1), [[1, 1, 1, 1, 1, 0]]),
|
||||
braille_trans("R", difficulty(1), [[1, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("S", difficulty(1), [[0, 1, 1, 1, 0, 0]]),
|
||||
braille_trans("T", difficulty(1), [[0, 1, 1, 1, 1, 0]]),
|
||||
braille_trans("U", difficulty(1), [[1, 0, 1, 0, 0, 1]]),
|
||||
braille_trans("V", difficulty(1), [[1, 1, 1, 0, 0, 1]]),
|
||||
braille_trans("W", difficulty(1), [[0, 1, 0, 1, 1, 1]]),
|
||||
braille_trans("X", difficulty(1), [[1, 0, 1, 1, 0, 1]]),
|
||||
braille_trans("Y", difficulty(1), [[1, 0, 1, 1, 1, 1]]),
|
||||
braille_trans("Z", difficulty(1), [[1, 0, 1, 0, 1, 1]]),
|
||||
braille_trans("@?NUM", difficulty(1), [[0, 0, 1, 1, 1, 1]], 'NUMBER'),
|
||||
#" ", difficulty(1), [[0, 0, 0, 0, 0, 0]]),
|
||||
braille_trans(",", difficulty(1), [[0, 1, 0, 0, 0, 0]]),
|
||||
braille_trans(";", difficulty(1), [[0, 1, 1, 0, 0, 0]]),
|
||||
braille_trans(":", difficulty(1), [[0, 1, 0, 0, 1, 0]]),
|
||||
braille_trans(".", difficulty(1), [[0, 1, 0, 0, 1, 1]]),
|
||||
braille_trans("!", difficulty(1), [[0, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("(", difficulty(1), [[0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans(")", difficulty(1), [[0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("?", difficulty(1), [[0, 1, 1, 0, 0, 1]]),
|
||||
braille_trans('"@?BO', difficulty(1), [[0, 1, 1, 0, 0, 1]], '"'),
|
||||
braille_trans('"@?BC', difficulty(1), [[0, 0, 1, 0, 1, 1]], '"'),
|
||||
braille_trans("'", difficulty(1), [[0, 0, 1, 0, 0, 0]]),
|
||||
braille_trans("@?ABBREV1", difficulty(1), [[0, 0, 0, 1, 0, 0]], "ABBREV"),
|
||||
braille_trans("@?ABBREV2", difficulty(1), [[0, 0, 0, 1, 1, 0]], "ABBREV"),
|
||||
braille_trans("@?ABBREV3", difficulty(1), [[0, 0, 0, 1, 1, 1]], "ABBREV"),
|
||||
braille_trans("@?ABBREV4", difficulty(1), [[0, 0, 0, 0, 1, 0]], "ABBREV"),
|
||||
braille_trans("...", difficulty(1), [[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0]]),
|
||||
braille_trans("-", difficulty(1), [[0, 0, 1, 0, 0, 1]]),
|
||||
braille_trans("-@?S", difficulty(1), [[0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1]], "-"),
|
||||
braille_trans("-@?L", difficulty(1), [[0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1]], "-"),
|
||||
braille_trans("/@?B", difficulty(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "/"),
|
||||
braille_trans("\@?B", difficulty(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "\\"),
|
||||
braille_trans("[@?BPH", difficulty(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "["),
|
||||
braille_trans("]@?BPH", difficulty(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "]"),
|
||||
braille_trans("<", difficulty(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans(">", difficulty(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("/", difficulty(1), [[0, 0, 0, 1, 1, 1], [0, 0, 1, 1, 0, 0]]),
|
||||
braille_trans("{", difficulty(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("}", difficulty(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("[@?BSQ", difficulty(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 1]], "["),
|
||||
braille_trans("]@?BSQ", difficulty(1), [[0, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1]], "]"),
|
||||
braille_trans("'@?BO", difficulty(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 0, 1]], "'"),
|
||||
braille_trans("'@?BC", difficulty(1), [[0, 1, 1, 0, 0, 1], [0, 0, 0, 0, 0, 1]], "'"),
|
||||
# oldbrailledict_2 = {
|
||||
# Simple Upper Wordsigns
|
||||
braille_trans("BUT", difficulty(2), [[1, 1, 0, 0, 0, 0]]),
|
||||
braille_trans("CAN", difficulty(2), [[1, 0, 0, 1, 0, 0]]),
|
||||
braille_trans("DO", difficulty(2), [[1, 0, 0, 1, 1, 0]]),
|
||||
braille_trans("EVERY", difficulty(2), [[1, 0, 0, 0, 1, 0]]),
|
||||
braille_trans("FROM", difficulty(2), [[1, 1, 0, 1, 0, 0]]),
|
||||
braille_trans("GO", difficulty(2), [[1, 1, 0, 1, 1, 0]]),
|
||||
braille_trans("HAVE", difficulty(2), [[1, 1, 0, 0, 1, 0]]),
|
||||
braille_trans("JUST", difficulty(2), [[0, 1, 0, 1, 1, 0]]),
|
||||
braille_trans("KNOWLEDGE", difficulty(2), [[1, 0, 1, 0, 0, 0]]),
|
||||
braille_trans("LIKE", difficulty(2), [[1, 1, 1, 0, 0, 0]]),
|
||||
braille_trans("MORE", difficulty(2), [[1, 0, 1, 1, 0, 0]]),
|
||||
braille_trans("NOT", difficulty(2), [[1, 0, 1, 1, 1, 0]]),
|
||||
braille_trans("PEOPLE", difficulty(2), [[1, 1, 1, 1, 0, 0]]),
|
||||
braille_trans("QUITE", difficulty(2), [[1, 1, 1, 1, 1, 0]]),
|
||||
braille_trans("RATHER", difficulty(2), [[1, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("SO", difficulty(2), [[0, 1, 1, 1, 0, 0]]),
|
||||
braille_trans("THAT", difficulty(2), [[0, 1, 1, 1, 1, 0]]),
|
||||
braille_trans("US", difficulty(2), [[1, 0, 1, 0, 0, 1]]),
|
||||
braille_trans("VERY", difficulty(2), [[1, 1, 1, 0, 0, 1]]),
|
||||
braille_trans("WILL", difficulty(2), [[0, 1, 0, 1, 1, 1]]),
|
||||
braille_trans("IT", difficulty(2), [[1, 0, 1, 1, 0, 1]]),
|
||||
braille_trans("YOU", difficulty(2), [[1, 0, 1, 1, 1, 1]]),
|
||||
braille_trans("AS", difficulty(2), [[1, 0, 1, 0, 1, 1]]),
|
||||
braille_trans("CHILD", difficulty(2), [[1, 0, 0, 0, 0, 1]]),
|
||||
braille_trans("SHALL", difficulty(2), [[1, 0, 0, 1, 0, 1]]),
|
||||
braille_trans("THIS", difficulty(2), [[1, 0, 0, 1, 1, 1]]),
|
||||
braille_trans("WHICH", difficulty(2), [[1, 0, 0, 0, 1, 1]]),
|
||||
braille_trans("OUT", difficulty(2), [[1, 1, 0, 0, 1, 1]]),
|
||||
braille_trans("STILL", difficulty(2), [[0, 0, 1, 1, 0, 0]]),
|
||||
# Simple Upper Groupsigns
|
||||
braille_trans("AND", difficulty(2), [[1, 1, 1, 1, 0, 1]]),
|
||||
braille_trans("FOR", difficulty(2), [[1, 1, 1, 1, 1, 1]]),
|
||||
braille_trans("OF", difficulty(2), [[1, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("THE", difficulty(2), [[0, 1, 1, 1, 0, 1]]),
|
||||
braille_trans("WITH", difficulty(2), [[0, 1, 1, 1, 1, 1]]),
|
||||
braille_trans("CH", difficulty(2), [[1, 0, 0, 0, 0, 1]]),
|
||||
braille_trans("GH", difficulty(2), [[1, 1, 0, 0, 0, 1]]),
|
||||
braille_trans("SH", difficulty(2), [[1, 0, 0, 1, 0, 1]]),
|
||||
braille_trans("TH", difficulty(2), [[1, 0, 0, 1, 1, 1]]),
|
||||
braille_trans("WH", difficulty(2), [[1, 0, 0, 0, 1, 1]]),
|
||||
braille_trans("ED", difficulty(2), [[1, 1, 0, 1, 0, 1]]),
|
||||
braille_trans("ER", difficulty(2), [[1, 1, 0, 1, 1, 1]]),
|
||||
braille_trans("OU", difficulty(2), [[1, 1, 0, 0, 1, 1]]),
|
||||
braille_trans("OW", difficulty(2), [[0, 1, 0, 1, 0, 1]]),
|
||||
braille_trans("ST", difficulty(2), [[0, 0, 1, 1, 0, 0]]),
|
||||
braille_trans("AR", difficulty(2), [[0, 0, 1, 1, 1, 0]]),
|
||||
braille_trans("ING", difficulty(2), [[0, 0, 1, 1, 0, 1]]),
|
||||
braille_trans("BLE", difficulty(2), [[0, 0, 1, 1, 1, 1]]),
|
||||
# oldbrailledict_3 = {
|
||||
# Lower Contractions
|
||||
# Initial Groupsigns
|
||||
braille_trans("BE", difficulty(3), [[0, 1, 1, 0, 0, 0]]),
|
||||
braille_trans("COM", difficulty(3), [[0, 0, 1, 0, 0, 1]]),
|
||||
braille_trans("CON", difficulty(3), [[0, 1, 0, 0, 1, 0]]),
|
||||
braille_trans("DIS", difficulty(3), [[0, 1, 0, 0, 1, 1]]),
|
||||
# Initial-Medial-Terminal Groupsigns
|
||||
braille_trans("EN", difficulty(3), [[0, 1, 0, 0, 0, 1]]),
|
||||
braille_trans("IN", difficulty(3), [[0, 0, 1, 0, 1, 0]]),
|
||||
# Medial Groupsigns
|
||||
braille_trans("EA", difficulty(3), [[0, 1, 0, 0, 0, 0]]),
|
||||
braille_trans("BB", difficulty(3), [[0, 1, 1, 0, 0, 0]]),
|
||||
braille_trans("CC", difficulty(3), [[0, 1, 0, 0, 1, 0]]),
|
||||
braille_trans("DD", difficulty(3), [[0, 1, 0, 0, 1, 1]]),
|
||||
braille_trans("FF", difficulty(3), [[0, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("GG", difficulty(3), [[0, 1, 1, 0, 1, 1]]),
|
||||
# Wordsigns
|
||||
braille_trans("ENOUGH", difficulty(3), [[0, 1, 0, 0, 0, 1]]),
|
||||
braille_trans("TO", difficulty(3), [[0, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("WERE", difficulty(3), [[0, 1, 1, 0 , 1, 1]]),
|
||||
braille_trans("HIS", difficulty(3), [[0, 1, 1, 0, 0, 1]]),
|
||||
braille_trans("INTO", difficulty(3), [[0, 0, 1, 0, 1, 0], [0, 1, 1, 0, 1, 0]]), #(sequenced)
|
||||
braille_trans("BY", difficulty(3), [[0, 0, 1, 0, 1, 1]]), #(sequenced)
|
||||
braille_trans("WAS", difficulty(3), [[0, 0 , 1, 0 , 1, 1]]),
|
||||
|
||||
# Modifiers
|
||||
braille_trans("@?LET", difficulty(3), [[0, 0, 0, 0, 1, 1]], "LET"),
|
||||
braille_trans("@?CAPS", difficulty(3), [[0, 0, 0, 0, 0, 1]], "CAPS"),
|
||||
braille_trans("@?EMPH", difficulty(3), [[0, 0, 0, 1, 0, 1]], "EMPH"),
|
||||
]
|
||||
# remove None 's - rejected inputs
|
||||
valid = False
|
||||
while not valid:
|
||||
try:
|
||||
temp_dict.remove(None)
|
||||
except:
|
||||
valid = True
|
||||
braille_dict = pd.DataFrame([x.as_dict() for x in temp_dict]) # , columns=['key', 'level', 'msg', 'msg_prefix'])
|
||||
# RETURNS
|
||||
# print('Braille Dictionary Creation')
|
||||
# print(f"type(temp_dict) = {type(temp_dict)}")
|
||||
# print("temp_dict = ")
|
||||
# for i in range(len(temp_dict)):
|
||||
# print(f"{temp_dict[i]}")
|
||||
# print('')
|
||||
# print(f"type(braille_dict) = {type(braille_dict)}")
|
||||
# print(f"braille_dict = {braille_dict}")
|
||||
|
||||
return braille_dict # temp_dict # braille_dict
|
||||
|
||||
def get_delimiters():
|
||||
# FUNCTION
|
||||
# delimiters and special character codes for plaintext message before braille translation
|
||||
# VARIABLE INSTANTIATION
|
||||
txtdict = {"@?NUM" : "NUMBER",
|
||||
"@?NOTHING" : "",
|
||||
#" " : "",
|
||||
'"@?BO' : '"',
|
||||
'"@?BC' : '"',
|
||||
"-@?S" : "-",
|
||||
"-@?L" : "-",
|
||||
"/@?B" : "/",
|
||||
"[@?BPH" : "[",
|
||||
"]@?BPH" : "]",
|
||||
"[@?BSQ" : "[",
|
||||
"]@?BSQ" : "]",
|
||||
"'@?BO" : "'",
|
||||
"'@?BC" : "'",
|
||||
"@?LET" : "LET",
|
||||
"@?CAPS" : "CAPS",
|
||||
"@?EMPH" : "EMPH",
|
||||
"@?ABBREV1" : "ABBREV",
|
||||
"@?ABBREV2" : "ABBREV",
|
||||
"@?ABBREV3" : "ABBREV",
|
||||
"@?ABBREV4" : "ABBREV",
|
||||
}
|
||||
# RETURNS
|
||||
return txtdict
|
||||
|
||||
def gen_difficulty_msgstr(braille_dict, level: difficulty = difficulty(1)):
|
||||
# FUNCTION
|
||||
# generate keyboard message for specified difficulty
|
||||
# ARGUMENTS
|
||||
# list[braille_trans] braille_dict
|
||||
# difficulty level
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'gen_difficulty_msgstr'
|
||||
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', _m)
|
||||
av.val_type(level, "<enum 'difficulty'>", 'level', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
str_out = ''
|
||||
# n = len(braille_dict)
|
||||
# METHODS
|
||||
# print(f"len(braille_dict) = {n}")
|
||||
# print(f"braille_dict.columns =")
|
||||
# for i in braille_dict.columns:
|
||||
# print(braille_dict.columns[i])
|
||||
# temp_dict = braille_dict['key']
|
||||
dict_iterator = braille_dict[braille_dict['level'] == level]
|
||||
# print(f"dict_iterator.index = {dict_iterator.index}")
|
||||
for bd_i in range(len(dict_iterator.index)):
|
||||
bd_n = dict_iterator['key'][dict_iterator.index[bd_i]]
|
||||
# print(f"bd_i = {bd_i}")
|
||||
# print(f"bd_n = {bd_n}")
|
||||
str_out += "@?NOTHING" + bd_n
|
||||
# for i in range(n):
|
||||
# bd_i = braille_dict.loc[i][0]
|
||||
# # print(f"bd_i = {bd_i}")
|
||||
# # print(f"type(bd_i) = {str(type(bd_i))}")
|
||||
# if (bd_i.level == difficulty):
|
||||
# str_out += "@?NOTHING" + bd_i.key
|
||||
# RETURNS
|
||||
return str_out
|
||||
|
||||
# def get_braille_by_key(braille_dict: pd.DataFrame, key: str):
|
||||
# # FUNCTION
|
||||
# # Find key in braille dictionary
|
||||
# return None
|
||||
# # ARGUMENTS
|
||||
# # ARGUMENT VALIDATION
|
||||
# # VARIABLE INSTANTIATION
|
||||
# # METHODS
|
||||
# # RETURNS
|
||||
|
||||
|
||||
def input_product(braille_dict, products, my_option: Optional[int] = -1, my_select: Optional[str] = ''):
|
||||
# FUNCTION
|
||||
# Get product input from user - repeat until valid input received
|
||||
# ARGUMENTS
|
||||
# list[braille_trans] braile_dict
|
||||
# list[product] products
|
||||
# optional int my_option - if option provided in code
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'input_product'
|
||||
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', _m)
|
||||
av.val_list(products, 'products', _m, "<class 'translate_msg_2_braille.product'>", 1)
|
||||
av.val_int(my_option, 'my_option', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
N = len(products)
|
||||
select_i = my_option
|
||||
valid = (my_option > 0 and my_option <= N)
|
||||
# temp_dict = braille_dict['key']
|
||||
# METHODS
|
||||
if valid:
|
||||
if my_option == N:
|
||||
temp = braille_dict[braille_dict['key'] == my_select]
|
||||
if len(temp.index) == 1:
|
||||
products[N - 1].msg_prefix = my_select
|
||||
else:
|
||||
valid = False
|
||||
while not valid:
|
||||
print()
|
||||
print('Welcome to your 3D Braille Model Generator')
|
||||
print("At any time, answer the following error code to exit (excl. speech marks): '#!ERRORCODE!#'")
|
||||
print()
|
||||
print('Braille Products:')
|
||||
for i in range(N):
|
||||
print(f"{i + 1}. {products[i].name}")
|
||||
print()
|
||||
select_i = av.input_int(input(f"Please enter your selection (1 - {N}) from the products above\n"), 'select_i', _m, 1, N)
|
||||
if select_i == '#!ERRORCODE!#':
|
||||
sys.exit
|
||||
valid = not (str(type(select_i)) == "<class 'NoneType'>")
|
||||
if valid and select_i == N:
|
||||
valid = False
|
||||
while not valid:
|
||||
select_A = input("Please enter a character selection for your Scrabble tile\n")
|
||||
if select_A == '#!ERRORCODE!#':
|
||||
sys.exit
|
||||
temp = braille_dict[braille_dict['key'] == select_A].index
|
||||
if not len(temp) == 1:
|
||||
print(f"temp = {temp}")
|
||||
valid = False
|
||||
else:
|
||||
valid = True
|
||||
products[N - 1].msg_prefix = select_A
|
||||
# RETURNS
|
||||
return products[select_i - 1]
|
||||
|
||||
def append_ifnotNone(v_list, v_item):
|
||||
# FUNCTION
|
||||
# append v_item to v_list if v_item is not None
|
||||
# ARGUMENTS
|
||||
# list v_list
|
||||
# v_item
|
||||
# ARGUMENT VALIDATION
|
||||
if (not av.val_list(v_list, 'v_list', 'append_ifnotNone', suppress_errors = True)) or v_item == None:
|
||||
# RETURNS
|
||||
return v_list
|
||||
v_list.append(v_item)
|
||||
return v_list#.append(v_item)
|
||||
|
||||
|
||||
def gen_product_inputs(braille_dict):
|
||||
# FUNCTION
|
||||
# Generate product inputs
|
||||
# ARGUMENTS
|
||||
# [pandas.DataFrame] braille_dict - braille dictionary
|
||||
# VARIABLE INSTANTIATION
|
||||
products = []
|
||||
# ARGUMENT VALIDATION
|
||||
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', 'gen_product_inputs')
|
||||
# METHODS
|
||||
products.append(product("Extended Alphabet", 10, "abcdefg@?NOTHINGhijKLMNOPQRS@?NOTHINGTUVXYZANDFOROFTHEWITHCHGHSHTHWHEDEROUOWWEABBCCDDENFF?GGINBY"))
|
||||
products.append(product("Upper Groupsigns", 10, "uppe@?nothingr GRO@?NOTHINGUPSIGNsand:a@?nothingn@?nothingd for:fo@?nothingr of:o@?nothingf the:t@?nothingh@?nothinge with:wi@?nothingt@?nothingh "+"@?NEWLINECH:C@?NOTHINGH " + "GH:G@?NOTHINGH " + "SH:S@?NOTHINGH " + "TH:T@?NOTHINGH " + "WH:W@?NOTHINGH " + "ED:E@?NOTHINGD " + "ER:E@?NOTHINGR " + "OU:O@?NOTHINGU " + "OW:O@?NOTHINGW "+"st:s@?nothingt ar:a@?nothingr ble:bl@?nothinge ing:i@?nothingng"))
|
||||
products.append(product("Upper Wordsigns", 24, gen_difficulty_msgstr(braille_dict, difficulty(3))))
|
||||
products.append(product("Alphabet", 10, "ABCDEFG@?NOTHINGHIJKLMNOPQRSTUVWXYZ"))
|
||||
# products.append(product("Travel", 5, "ABCDEFG@?NOTHINGHIJ"))
|
||||
products.append(product("Demo", 9, "BRAILLE"))
|
||||
products.append(product("Scrabble Alphabet of Tiles", 1, '', filename = 'Scrabble_Tile_Set'))
|
||||
products.append(product("Scrabble Character Tile", 1, '', filename = 'Scrabble_Tile'))
|
||||
# RETURNS
|
||||
return products
|
||||
|
||||
def gen_braille_inputs_4_openscad(msgin, line_length, brailledict): # , hyphenate = False
|
||||
# FUNCTION
|
||||
# Convert message to Braille for openSCAD generation
|
||||
# ARGUMENTS
|
||||
# str msgin - partially translated message containing only brailledict keys and blankspace
|
||||
# int line_length - number of Braille characters per row on keyboard
|
||||
# pandas.DataFrame brailledict - Braille translations with diffculty
|
||||
# # bool hyphenate - hyphenate words that cross lines or start on new line
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'gen_braille_inputs_4_openscad'
|
||||
av.val_str(msgin, 'msgin', _m, 1)
|
||||
av.val_int(line_length, 'line_length', _m)
|
||||
av.val_type(brailledict, "<class 'pandas.core.frame.DataFrame'>", 'brailledict', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
# dict txtdict - delimiters for Braille translation
|
||||
msgin = msgin.upper()
|
||||
braille = []
|
||||
letters = []
|
||||
n_rows = 1
|
||||
start_of_word = 0 # position within cum
|
||||
numbers = []
|
||||
cum = [0, ] # 0-based cumulative starting position of Braille translation of message segments
|
||||
#lmsg = [0] * len(msgin) # length of braille message
|
||||
last_is_num = False
|
||||
new_word = True
|
||||
iter_lim = len(msgin)
|
||||
print(f"iteration limit = {iter_lim}") #len(msgin))
|
||||
msg_i_0 = 0
|
||||
maxstrlen = max_key_len(brailledict)
|
||||
# METHODS
|
||||
print(f"msgin = {msgin}")
|
||||
while (msg_i_0 < iter_lim):
|
||||
found = False
|
||||
print(f"msg_i_0 = {msg_i_0}")
|
||||
for phrase_len in range(min(len(msgin) - msg_i_0, maxstrlen), 0, -1):
|
||||
if found:
|
||||
continue
|
||||
phrase = msgin[msg_i_0 : msg_i_0 + phrase_len] # message segment to search for in Braille translation keys
|
||||
print(f'phrase = {phrase}')
|
||||
|
||||
# generate braille if a code has been found
|
||||
if (phrase_len == 0):
|
||||
if (ord(phrase) >= 48 and ord(phrase) <= 57): # numbers
|
||||
b_num_pre = brailledict[brailledict['key'] == "@?NUM"]['braille'].values[0]
|
||||
b_num = brailledict[brailledict['key'] == ("J" if (ord(phrase) == 48) else chr(ord(phrase)+16))]['braille'].values[0]
|
||||
if last_is_num == True:
|
||||
braille[len(braille) - 1].append(b_num[0])
|
||||
new_cum = 1
|
||||
# temp = temp2
|
||||
else:
|
||||
braille.append([b_num_pre[0], b_num[0]])
|
||||
new_cum = 2
|
||||
# temp = [temp1[0], temp2[0]]
|
||||
print('braille(numeric phrase) = ', braille[len(braille) - 1])
|
||||
last_is_num = True
|
||||
else:
|
||||
# new_cum = len(brailledict[brailledict['key'] == phrase].index)
|
||||
found = (len(brailledict[brailledict['key'] == phrase].index) == 1)
|
||||
if found:
|
||||
last_is_num = False
|
||||
# temp = brailledict.get(phrase)
|
||||
else:
|
||||
# new_cum = len(brailledict[brailledict['key'] == phrase].index)
|
||||
found = (len(brailledict[brailledict['key'] == phrase].index) == 1)
|
||||
if found:
|
||||
last_is_num = False
|
||||
# temp = brailledict.get(phrase)
|
||||
#print("tempsearch = ", temp)
|
||||
|
||||
# organise placement of braille phrase onto end of whole message
|
||||
if found or last_is_num: # (temp != None): #
|
||||
# found = True
|
||||
# last_is_num = False
|
||||
new_num = [-1]
|
||||
if (len(phrase) == 1):
|
||||
if (ord(phrase) >= 65 and ord(phrase) <= 90): # letters
|
||||
new_num = [ord(phrase) - 64]
|
||||
elif (ord(phrase) >= 48 and ord(phrase) <= 57): # numbers
|
||||
new_num = [ord(phrase) - 48]
|
||||
# last_is_num = True
|
||||
if found:
|
||||
braille.append(brailledict[brailledict['key'] == phrase]['braille'].values[0])
|
||||
new_cum = len(braille[len(braille) - 1])
|
||||
numbers.append(new_num)
|
||||
new_cum = cum[len(cum) - 1] + new_cum
|
||||
cum.append(new_cum)
|
||||
n_rows_0 = n_lines_at_pos(cum[start_of_word], line_length)
|
||||
n_rows_next = n_lines_at_pos(new_cum, line_length)
|
||||
if ((not new_word) and n_rows_0 < n_rows_next and not (cum[start_of_word] % line_length == 0)):
|
||||
delta_cum_new_line = n_rows_next * line_length + 1 - cum[start_of_word]
|
||||
for msg_j in range(len(cum) - start_of_word - 1):
|
||||
cum[start_of_word + msg_j] += delta_cum_new_line
|
||||
#if (cum[len(cum)-1] % line_length > 0):
|
||||
# cum[len(cum)-1] = cum[len(cum)-1] + line_length - (1+(cum[len(cum)-1]-1) % line_length)
|
||||
# print("clean_rows",cum[len(cum)-1])
|
||||
# print("phrase_len=",phrase_len)
|
||||
msg_i_0 += phrase_len
|
||||
letters.append(brailledict[brailledict['key'] == phrase]['plaintext'].values[0])
|
||||
elif phrase == "@?NOTHING":
|
||||
msg_i_0 += 9
|
||||
print('found nothing')
|
||||
found = True
|
||||
elif phrase == "@?NEWLINE":
|
||||
msg_i_0 += 9
|
||||
print('forced newline')
|
||||
cum[len(cum) - 1] += (line_length - (cum[len(cum) - 1] % line_length)) % line_length
|
||||
found = True
|
||||
new_word = True
|
||||
elif phrase == " ": # and (cum[len(cum)-1] % line_length > 0)): # no space at start of line # or letters[len(cum)-1] == " " or msgin[ni+1] == " ")
|
||||
msg_i_0 += 1
|
||||
cum[len(cum) - 1] = cum[len(cum) - 1] + 1
|
||||
print('space')
|
||||
new_word = True
|
||||
# unfound character??
|
||||
if phrase_len == 0 and not (found or (ord(phrase) >= 48 and ord(phrase) <= 57)):
|
||||
print(f"Unfound phrase: {phrase}")
|
||||
msg_i_0 += 1
|
||||
new_word = True
|
||||
# word start position
|
||||
if new_word:
|
||||
start_of_word = len(cum) - 1 # position within cum
|
||||
# OUTPUTS
|
||||
# console output
|
||||
n_keys = max(cum)
|
||||
n_rows = n_rows_0
|
||||
cum = cum[0 : len(cum) - 1]
|
||||
# letters = letters[1:len(letters)] # why does element 0 exist?
|
||||
# print(f"message length b = {n_keys}")
|
||||
# print(f"braille = {braille}")
|
||||
# print(f"cum = {cum}")
|
||||
# print(f"numbers = {numbers}")
|
||||
# print(f"letters = {letters}")
|
||||
|
||||
## file output
|
||||
f = open('Braille.txt','a')
|
||||
f.truncate()
|
||||
f.write(f'cum = {str(cum)};\n')
|
||||
|
||||
f.write('msgstr = [')
|
||||
for i in range(len(letters)):
|
||||
f.write('"')
|
||||
f.write(str(letters[i]))
|
||||
if i < len(letters) - 1:
|
||||
f.write('", ')
|
||||
f.write('"];\n')
|
||||
|
||||
f.write('numbers = [')
|
||||
for i in range(len(numbers)):
|
||||
#f.write('"')
|
||||
f.write(str(numbers[i]))
|
||||
if i < len(numbers) - 1:
|
||||
f.write(', ')
|
||||
f.write('];\n')
|
||||
|
||||
f.write(f"inA = {str(braille)};\n")
|
||||
f.write(f"lmsg = {str(len(braille))};\n")
|
||||
f.write(f"N = {str(n_keys)};\n")
|
||||
f.write(f"nln = {str(min(line_length, n_keys))};\n")
|
||||
f.write(f"maxln = {str(n_rows)};\n")
|
||||
f.close()
|
||||
# RETURNS
|
||||
return cum, letters, numbers, braille, n_keys, n_rows
|
||||
|
||||
|
||||
def n_lines_at_pos(position, line_length):
|
||||
# FUNCTION
|
||||
# calculate number of rows of keyboard required for message of length (in Braille keys) position
|
||||
# ARGUMENTS
|
||||
# int position - quantity of Braille keys in message up to (+ incl.) position
|
||||
# int line_length - number of Braille keys per line / row
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'n_lines_at_pos'
|
||||
av.val_int(position, 'position', _m, 0)
|
||||
av.val_int(line_length, 'line_length', _m, 1)
|
||||
# RETURNS
|
||||
return 1 + (position // line_length)
|
||||
|
||||
|
||||
def max_key_len(mydict: pd.DataFrame, min_dict_len: Optional[int] = 1):
|
||||
# FUNCTION
|
||||
# find maximum key length in braille dictionary
|
||||
# ARGUMENTS
|
||||
# pandas.DataFrame mydict
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'max_key_len'
|
||||
av.val_int(min_dict_len, 'min_dict_len', _m)
|
||||
av.val_type(mydict, "<class 'pandas.core.frame.DataFrame'>", 'mydict', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
n = len(mydict.index)
|
||||
max_len = 0
|
||||
# METHODS
|
||||
for i in range(n):
|
||||
max_len = max(max_len, len(mydict.iloc[i]['key']))
|
||||
if max_len < min_dict_len:
|
||||
return -1
|
||||
# RETURNS
|
||||
return max_len
|
||||
|
||||
|
||||
# ToDo: Finish this!
|
||||
# def remove_words_in_word(word, maxstrlen=9):
|
||||
# ln = len(word)
|
||||
# minmax = min(ln, maxstrlen)
|
||||
# fix = False
|
||||
# skip = False
|
||||
# for length in np.arange(minmax, 1, -1):
|
||||
# for start in range(ln-length):
|
||||
# tempstr = word[start:start+length]
|
||||
# if (tempstr == "@?NOTHING"):
|
||||
# skip = True
|
||||
# if skip:
|
||||
# continue
|
||||
# tempfind = brailledict.get(tempstr)
|
||||
# if not (tempbool == None):
|
||||
# tempword = word[:start]
|
||||
# for li in range(length):
|
||||
# ## add "@?NOTHING"
|
||||
|
||||
# def get_translated_input(my_option: Optional[int] = -1): # REDUNDANT
|
||||
# # FUNCTION
|
||||
# # Get product selection input from user + convert to Braille
|
||||
# # VARIABLE INSTANTIATION
|
||||
# braille_translations = get_braille_translations()
|
||||
# products = gen_product_inputs(braille_translations)
|
||||
# delimiters = get_delimiters()
|
||||
# # METHODS
|
||||
# my_product = input_product(braille_translations, products, my_option)
|
||||
# # cum, letters, numbers, braille, ltmsg, n_rows = gen_braille_inputs_4_openscad(my_product.msg, my_product.line_length, braille_translations, max_key_len(braille_translations), delimiters)
|
||||
# # RETURNS
|
||||
# return my_product, braille_translations, max_key_len(braille_translations), delimiters
|
||||
|
||||
# get_translated_input() ' requires translate_msg_2_braille is replaced by __main__ in type validation strings
|
||||
|
||||
|
||||
# def process_old_dict(old_dict, difficulty):
|
||||
# # FUNCTION
|
||||
# # create new list of braille_trans dataclass items
|
||||
# # ARGUMENTS
|
||||
# # old_dict - old dictionary of keys, values
|
||||
# # difficulty - level field of dataclass
|
||||
# # ARGUMENT VALIDATION
|
||||
# print(f"type(old_dict) = {type(old_dict)}")
|
||||
# print(f"type(difficulty) = {type(difficulty)}")
|
||||
# # VARIABLE INSTANTIATION
|
||||
# new_dict = []
|
||||
# # METHODS
|
||||
# for i in range(len(old_dict)):
|
||||
# temp_key, temp_value = old_dict.popitem()
|
||||
# new_dict.append(braille_trans(temp_key, difficulty, temp_value))
|
||||
# # RETURNS
|
||||
# return new_dict
|
||||
|
||||
|
||||
# class braille_dictionary():
|
||||
|
||||
# def __init__(self, keys, hardnesses, braille_translations):
|
||||
# return self.push(keys, hardnesses, braille_translations)
|
||||
|
||||
# def push(self, keys, hardnesses, braille_translations):
|
||||
# N_in = len(keys)
|
||||
# if not (N_in == len(hardnesses) == len(braille_translations)):
|
||||
# return False
|
||||
# for i in range(N_in - 1):
|
||||
# for j in range(i + 1):
|
||||
# if (keys[i + 1] == keys[j]):
|
||||
# return False
|
||||
# for i in range(N_in):
|
||||
# self.keys.append(keys[i])
|
||||
# self.hards.append(hardnesses[i])
|
||||
# self.brailles.append(braille_translations[i])
|
||||
# return True
|
||||
|
||||
# def exists_key(self, key):
|
||||
# try:
|
||||
# i = self.keys.index(key)
|
||||
# except ValueError:
|
||||
# return True
|
||||
# else:
|
||||
# return False
|
||||
|
||||
# def get_key_index(self, key):
|
||||
# if self.exists_key(key):
|
||||
# return self.keys.index(key)
|
||||
# else:
|
||||
# return -1
|
||||
801
model_gen/translate_msg_2_braille_v2a.py
Normal file
801
model_gen/translate_msg_2_braille_v2a.py
Normal file
@@ -0,0 +1,801 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Apr 24 14:26:02 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
|
||||
Braille 3D Model Product Creation
|
||||
|
||||
Braille Dictionary Conversion / Creation
|
||||
Plaintext message translation into Braille for 3D modelling
|
||||
"""
|
||||
|
||||
# CLASSES
|
||||
# ATTRIBUTE DECLARATION
|
||||
# METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
# NORMAL METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
|
||||
import pandas as pd
|
||||
from typing import Optional
|
||||
from enum import Enum
|
||||
import argument_validation as av
|
||||
import sys
|
||||
|
||||
class difficulty(Enum):
|
||||
ALPHABETPUNCTUATION = 1
|
||||
SIMPLEWORDGROUPSIGNS = 2
|
||||
LOWERCONTRACTIONS = 3
|
||||
def mini():
|
||||
# FUNCTION
|
||||
# Get minimum value in enumerator
|
||||
# RETURNS
|
||||
return min([e.value for e in difficulty])
|
||||
def maxi():
|
||||
# FUNCTION
|
||||
# Get maximum value in enumerator
|
||||
# RETURNS
|
||||
return max([e.value for e in difficulty])
|
||||
|
||||
class braille_trans():
|
||||
# ATTRIBUTE DECLARATION
|
||||
key: str # search key in input messages for Braille translation - includes additional characters for literal processing
|
||||
level: difficulty # stage of learning at which this translation is discovered
|
||||
braille: list # list[list[int]] # Braille translation of plaintext
|
||||
plaintext: str # English plaintext key
|
||||
# METHODS
|
||||
# def argvalinit(key: str, level: difficulty, braille: list, plaintext: Optional[str] = None):
|
||||
# # run before instantiating braille_trans
|
||||
# # av.val_list(braille, 'list')=
|
||||
# # _m = 'braille_trans.argvalinit'
|
||||
# # if not av.val_str(key, 'key', method, min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument')
|
||||
# if not (av.val_str(key) and (str(type(level)) == "<enum 'difficulty'>" or av.val_int(level, difficulty.mini(), difficulty.maxi())) and av.val_list(braille, "<class 'list'>") and (av.val_str(plaintext, -1, -1, True) or plaintext == None)):
|
||||
# print(f'Invalid braille_trans instantiation. key = {key}, level = {level}, braille = {braille}, plaintext = {plaintext}')
|
||||
# return None
|
||||
# return braille_trans(key, level, braille, plaintext)
|
||||
|
||||
def __new__(cls, key: str, level: difficulty, braille: list, plaintext: Optional[str] = None):
|
||||
# FUNCTION
|
||||
# Initialise class object
|
||||
# ARGUMENTS
|
||||
# str key
|
||||
# difficulty level
|
||||
# list[list[int]] braille
|
||||
# optional str plaintext
|
||||
# VARIABLE DECLARATION
|
||||
_m = 'braille_trans.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
# ARGUMENT VALIDATION
|
||||
av.val_str(key, 'key', _m, 1, -1, v_arg_type = v_arg_type)
|
||||
av.val_type(level, "<enum 'difficulty'>", 'level', _m, v_arg_type = v_arg_type)
|
||||
av.val_nested_list(braille, 0, 1, 'braille', _m, "<class 'int'>", -1, [-1, 6], -1, [-1, 6], v_arg_type = v_arg_type)
|
||||
if not (av.val_str(plaintext, 'plaintext', _m, -1, -1, True, True, v_arg_type) or str(type(plaintext)) == "<class 'NoneType'>"):
|
||||
raise ValueError(av.error_msg_str(_m, 'plaintext', plaintext, "<class 'str'>", v_arg_type = v_arg_type))
|
||||
# if not av.val_str(key):
|
||||
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'key', key, 'attribute'))
|
||||
# if not av.val_type(level, "<enum 'difficulty'>"):
|
||||
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'level', level, 'attribute'))
|
||||
# if not av.val_nested_list(braille, 0, 2, "<class 'int'>", 6, [1, 6], 6, [-1, 6]):
|
||||
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'braille', braille, 'attribute'))
|
||||
# if not (av.val_str(plaintext) or str(type(plaintext)) == "<class 'NoneType'>"):
|
||||
# raise ValueError(av.error_msg_str('braille_trans.__new__', 'plaintext', plaintext, 'attribute'))
|
||||
# RETURNS
|
||||
return super(braille_trans, cls).__new__(cls)
|
||||
|
||||
def __init__(self, key: str, level: difficulty, braille: list, plaintext: Optional[str] = None):
|
||||
# FUNCTION
|
||||
# Construct class object
|
||||
# ARGUMENTS
|
||||
# str key
|
||||
# difficulty level
|
||||
# list[list[int]] braille
|
||||
# optional str plaintext
|
||||
# ARGUMENT VALIDATION
|
||||
# see __new__()
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
self.key = key
|
||||
self.level = level
|
||||
self.braille = braille
|
||||
self.plaintext = self.key if (plaintext is None) else plaintext
|
||||
|
||||
def __repr__(self):
|
||||
return f"key = {self.key}, level = {self.level}, braille = {self.braille}, plaintext = {self.plaintext}"
|
||||
|
||||
# def query_lvl(self):
|
||||
# return ' & '.join(["{}=='{}'".format(key, value)
|
||||
# for key, value in self.__dict__.items()
|
||||
# if not value is None])
|
||||
|
||||
def as_dict(self):
|
||||
return {'key': self.key, 'level': self.level, 'braille': self.braille, 'plaintext': self.plaintext}
|
||||
|
||||
class product():
|
||||
# ATTRIBUTE DECLARATION
|
||||
name: str
|
||||
line_length: int # number of Braille characters per line on keyboard
|
||||
msg: str # pre-translated English (with necessary modifications for input to this programme e.g. splitting up undesired translations with hidden delimiter character @?NOTHING)
|
||||
msg_prefix: str # additional pre-translated str as above to pre-append to product for adding header to creation of product messages from dictionary queries
|
||||
filename: str # filename - name without spaces
|
||||
# METHODS
|
||||
# def argvalinit(name: str, line_length: int, msg: str, msg_prefix: Optional[str] = ''):
|
||||
# # run before instantiating product
|
||||
# if not (av.val_str(name) and av.val_int(line_length, 0) and av.val_str(msg) and av.val_str(msg_prefix)):
|
||||
# print(f'Invalid product instantiation. name = {name}, line_length = {line_length}, msg = {msg}, msg_prefix = {msg_prefix}')
|
||||
# return None
|
||||
# return product(name, line_length, msg, msg_prefix)
|
||||
|
||||
def __new__(cls, name, line_length, msg, msg_prefix = ''):
|
||||
# FUNCTION
|
||||
# Initialise class object
|
||||
# ARGUMENTS
|
||||
# str name
|
||||
# int line_length
|
||||
# str msg
|
||||
# str msg_prefix
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'product.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_str(name, 'name', _m, 1, -1, v_arg_type = v_arg_type)
|
||||
av.val_int(line_length, 'line_length', _m, 1, v_arg_type = v_arg_type)
|
||||
av.val_str(msg, 'msg', _m, -1, -1, v_arg_type = v_arg_type)
|
||||
av.val_str(msg_prefix, 'msg_prefix', _m, -1, -1, v_arg_type = v_arg_type)
|
||||
# if not av.val_str(name):
|
||||
# raise ValueError(av.error_msg_str('product.__new__', 'name', name, 'attribute'))
|
||||
# if not av.val_int(line_length, 1):
|
||||
# raise ValueError(av.error_msg_str('product.__new__', 'line_length', line_length, 'attribute'))
|
||||
# if not av.val_str(msg):
|
||||
# raise ValueError(av.error_msg_str('product.__new__', 'msg', msg, 'attribute'))
|
||||
# if not av.val_str(msg_prefix):
|
||||
# raise ValueError(av.error_msg_str('product.__new__', 'msg_prefix', msg_prefix, 'attribute'))
|
||||
# RETURNS
|
||||
return super(product, cls).__new__(cls)
|
||||
|
||||
def __init__(self, name: str, line_length: int, msg: str, msg_prefix: Optional[str] = ''):
|
||||
# FUNCTION
|
||||
# Construct class object
|
||||
# ARGUMENTS
|
||||
# str name
|
||||
# int line_length
|
||||
# str msg
|
||||
# str msg_prefix
|
||||
# ARGUMENT VALIDATION
|
||||
# see __new__()
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
self.name = name
|
||||
self.line_length = line_length
|
||||
self.msg = msg
|
||||
self.msg_prefix = msg_prefix # for procedurally-generated messages from difficulty selection
|
||||
self.filename = name.replace(' ', '_')
|
||||
|
||||
def __repr__(self):
|
||||
return f"name = {self.name}, line_length = {self.line_length}, msg = {self.msg}, msg_prefix = {self.msg_prefix}, filename = {self.filename}"
|
||||
|
||||
def get_braille_translations():
|
||||
# FUNCTION
|
||||
# return list of braille translations
|
||||
# longer keys get priority in translation
|
||||
# VARIABLE INSTANTIATION
|
||||
temp_dict = [braille_trans("A", difficulty(1), [[1, 0, 0, 0, 0, 0]]),
|
||||
braille_trans("B", difficulty(1), [[1, 1, 0, 0, 0, 0]]),
|
||||
braille_trans("C", difficulty(1), [[1, 0, 0, 1, 0, 0]]),
|
||||
braille_trans("D", difficulty(1), [[1, 0, 0, 1, 1, 0]]),
|
||||
braille_trans("E", difficulty(1), [[1, 0, 0, 0, 1, 0]]),
|
||||
braille_trans("F", difficulty(1), [[1, 1, 0, 1, 0, 0]]),
|
||||
braille_trans("G", difficulty(1), [[1, 1, 0, 1, 1, 0]]),
|
||||
braille_trans("H", difficulty(1), [[1, 1, 0, 0, 1, 0]]),
|
||||
braille_trans("I", difficulty(1), [[0, 1, 0, 1, 0, 0]]),
|
||||
braille_trans("J", difficulty(1), [[0, 1, 0, 1, 1, 0]]),
|
||||
braille_trans("K", difficulty(1), [[1, 0, 1, 0, 0, 0]]),
|
||||
braille_trans("L", difficulty(1), [[1, 1, 1, 0, 0, 0]]),
|
||||
braille_trans("M", difficulty(1), [[1, 0, 1, 1, 0, 0]]),
|
||||
braille_trans("N", difficulty(1), [[1, 0, 1, 1, 1, 0]]),
|
||||
braille_trans("O", difficulty(1), [[1, 0, 1, 0, 1, 0]]),
|
||||
braille_trans("P", difficulty(1), [[1, 1, 1, 1, 0, 0]]),
|
||||
braille_trans("Q", difficulty(1), [[1, 1, 1, 1, 1, 0]]),
|
||||
braille_trans("R", difficulty(1), [[1, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("S", difficulty(1), [[0, 1, 1, 1, 0, 0]]),
|
||||
braille_trans("T", difficulty(1), [[0, 1, 1, 1, 1, 0]]),
|
||||
braille_trans("U", difficulty(1), [[1, 0, 1, 0, 0, 1]]),
|
||||
braille_trans("V", difficulty(1), [[1, 1, 1, 0, 0, 1]]),
|
||||
braille_trans("W", difficulty(1), [[0, 1, 0, 1, 1, 1]]),
|
||||
braille_trans("X", difficulty(1), [[1, 0, 1, 1, 0, 1]]),
|
||||
braille_trans("Y", difficulty(1), [[1, 0, 1, 1, 1, 1]]),
|
||||
braille_trans("Z", difficulty(1), [[1, 0, 1, 0, 1, 1]]),
|
||||
braille_trans("@?NUM", difficulty(1), [[0, 0, 1, 1, 1, 1]], 'NUMBER'),
|
||||
#" ", difficulty(1), [[0, 0, 0, 0, 0, 0]]),
|
||||
braille_trans(",", difficulty(1), [[0, 1, 0, 0, 0, 0]]),
|
||||
braille_trans(";", difficulty(1), [[0, 1, 1, 0, 0, 0]]),
|
||||
braille_trans(":", difficulty(1), [[0, 1, 0, 0, 1, 0]]),
|
||||
braille_trans(".", difficulty(1), [[0, 1, 0, 0, 1, 1]]),
|
||||
braille_trans("!", difficulty(1), [[0, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("(", difficulty(1), [[0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans(")", difficulty(1), [[0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("?", difficulty(1), [[0, 1, 1, 0, 0, 1]]),
|
||||
braille_trans('"@?BO', difficulty(1), [[0, 1, 1, 0, 0, 1]], '"'),
|
||||
braille_trans('"@?BC', difficulty(1), [[0, 0, 1, 0, 1, 1]], '"'),
|
||||
braille_trans("'", difficulty(1), [[0, 0, 1, 0, 0, 0]]),
|
||||
braille_trans("@?ABBREV1", difficulty(1), [[0, 0, 0, 1, 0, 0]], "ABBREV"),
|
||||
braille_trans("@?ABBREV2", difficulty(1), [[0, 0, 0, 1, 1, 0]], "ABBREV"),
|
||||
braille_trans("@?ABBREV3", difficulty(1), [[0, 0, 0, 1, 1, 1]], "ABBREV"),
|
||||
braille_trans("@?ABBREV4", difficulty(1), [[0, 0, 0, 0, 1, 0]], "ABBREV"),
|
||||
braille_trans("...", difficulty(1), [[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0]]),
|
||||
braille_trans("-", difficulty(1), [[0, 0, 1, 0, 0, 1]]),
|
||||
braille_trans("-@?S", difficulty(1), [[0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1]], "-"),
|
||||
braille_trans("-@?L", difficulty(1), [[0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1]], "-"),
|
||||
braille_trans("/@?B", difficulty(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "/"),
|
||||
braille_trans("\@?B", difficulty(1), [[0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 1, 1]], "\\"),
|
||||
braille_trans("[@?BPH", difficulty(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "["),
|
||||
braille_trans("]@?BPH", difficulty(1), [[0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1]], "]"),
|
||||
braille_trans("<", difficulty(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans(">", difficulty(1), [[0, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("/", difficulty(1), [[0, 0, 0, 1, 1, 1], [0, 0, 1, 1, 0, 0]]),
|
||||
braille_trans("{", difficulty(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("}", difficulty(1), [[0, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("[@?BSQ", difficulty(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 1]], "["),
|
||||
braille_trans("]@?BSQ", difficulty(1), [[0, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1]], "]"),
|
||||
braille_trans("'@?BO", difficulty(1), [[0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 0, 1]], "'"),
|
||||
braille_trans("'@?BC", difficulty(1), [[0, 1, 1, 0, 0, 1], [0, 0, 0, 0, 0, 1]], "'"),
|
||||
# oldbrailledict_2 = {
|
||||
# Simple Upper Wordsigns
|
||||
braille_trans("BUT", difficulty(2), [[1, 1, 0, 0, 0, 0]]),
|
||||
braille_trans("CAN", difficulty(2), [[1, 0, 0, 1, 0, 0]]),
|
||||
braille_trans("DO", difficulty(2), [[1, 0, 0, 1, 1, 0]]),
|
||||
braille_trans("EVERY", difficulty(2), [[1, 0, 0, 0, 1, 0]]),
|
||||
braille_trans("FROM", difficulty(2), [[1, 1, 0, 1, 0, 0]]),
|
||||
braille_trans("GO", difficulty(2), [[1, 1, 0, 1, 1, 0]]),
|
||||
braille_trans("HAVE", difficulty(2), [[1, 1, 0, 0, 1, 0]]),
|
||||
braille_trans("JUST", difficulty(2), [[0, 1, 0, 1, 1, 0]]),
|
||||
braille_trans("KNOWLEDGE", difficulty(2), [[1, 0, 1, 0, 0, 0]]),
|
||||
braille_trans("LIKE", difficulty(2), [[1, 1, 1, 0, 0, 0]]),
|
||||
braille_trans("MORE", difficulty(2), [[1, 0, 1, 1, 0, 0]]),
|
||||
braille_trans("NOT", difficulty(2), [[1, 0, 1, 1, 1, 0]]),
|
||||
braille_trans("PEOPLE", difficulty(2), [[1, 1, 1, 1, 0, 0]]),
|
||||
braille_trans("QUITE", difficulty(2), [[1, 1, 1, 1, 1, 0]]),
|
||||
braille_trans("RATHER", difficulty(2), [[1, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("SO", difficulty(2), [[0, 1, 1, 1, 0, 0]]),
|
||||
braille_trans("THAT", difficulty(2), [[0, 1, 1, 1, 1, 0]]),
|
||||
braille_trans("US", difficulty(2), [[1, 0, 1, 0, 0, 1]]),
|
||||
braille_trans("VERY", difficulty(2), [[1, 1, 1, 0, 0, 1]]),
|
||||
braille_trans("WILL", difficulty(2), [[0, 1, 0, 1, 1, 1]]),
|
||||
braille_trans("IT", difficulty(2), [[1, 0, 1, 1, 0, 1]]),
|
||||
braille_trans("YOU", difficulty(2), [[1, 0, 1, 1, 1, 1]]),
|
||||
braille_trans("AS", difficulty(2), [[1, 0, 1, 0, 1, 1]]),
|
||||
braille_trans("CHILD", difficulty(2), [[1, 0, 0, 0, 0, 1]]),
|
||||
braille_trans("SHALL", difficulty(2), [[1, 0, 0, 1, 0, 1]]),
|
||||
braille_trans("THIS", difficulty(2), [[1, 0, 0, 1, 1, 1]]),
|
||||
braille_trans("WHICH", difficulty(2), [[1, 0, 0, 0, 1, 1]]),
|
||||
braille_trans("OUT", difficulty(2), [[1, 1, 0, 0, 1, 1]]),
|
||||
braille_trans("STILL", difficulty(2), [[0, 0, 1, 1, 0, 0]]),
|
||||
# Simple Upper Groupsigns
|
||||
braille_trans("AND", difficulty(2), [[1, 1, 1, 1, 0, 1]]),
|
||||
braille_trans("FOR", difficulty(2), [[1, 1, 1, 1, 1, 1]]),
|
||||
braille_trans("OF", difficulty(2), [[1, 1, 1, 0, 1, 1]]),
|
||||
braille_trans("THE", difficulty(2), [[0, 1, 1, 1, 0, 1]]),
|
||||
braille_trans("WITH", difficulty(2), [[0, 1, 1, 1, 1, 1]]),
|
||||
braille_trans("CH", difficulty(2), [[1, 0, 0, 0, 0, 1]]),
|
||||
braille_trans("GH", difficulty(2), [[1, 1, 0, 0, 0, 1]]),
|
||||
braille_trans("SH", difficulty(2), [[1, 0, 0, 1, 0, 1]]),
|
||||
braille_trans("TH", difficulty(2), [[1, 0, 0, 1, 1, 1]]),
|
||||
braille_trans("WH", difficulty(2), [[1, 0, 0, 0, 1, 1]]),
|
||||
braille_trans("ED", difficulty(2), [[1, 1, 0, 1, 0, 1]]),
|
||||
braille_trans("ER", difficulty(2), [[1, 1, 0, 1, 1, 1]]),
|
||||
braille_trans("OU", difficulty(2), [[1, 1, 0, 0, 1, 1]]),
|
||||
braille_trans("OW", difficulty(2), [[0, 1, 0, 1, 0, 1]]),
|
||||
braille_trans("ST", difficulty(2), [[0, 0, 1, 1, 0, 0]]),
|
||||
braille_trans("AR", difficulty(2), [[0, 0, 1, 1, 1, 0]]),
|
||||
braille_trans("ING", difficulty(2), [[0, 0, 1, 1, 0, 1]]),
|
||||
braille_trans("BLE", difficulty(2), [[0, 0, 1, 1, 1, 1]]),
|
||||
# oldbrailledict_3 = {
|
||||
# Lower Contractions
|
||||
# Initial Groupsigns
|
||||
braille_trans("BE", difficulty(3), [[0, 1, 1, 0, 0, 0]]),
|
||||
braille_trans("COM", difficulty(3), [[0, 0, 1, 0, 0, 1]]),
|
||||
braille_trans("CON", difficulty(3), [[0, 1, 0, 0, 1, 0]]),
|
||||
braille_trans("DIS", difficulty(3), [[0, 1, 0, 0, 1, 1]]),
|
||||
# Initial-Medial-Terminal Groupsigns
|
||||
braille_trans("EN", difficulty(3), [[0, 1, 0, 0, 0, 1]]),
|
||||
braille_trans("IN", difficulty(3), [[0, 0, 1, 0, 1, 0]]),
|
||||
# Medial Groupsigns
|
||||
braille_trans("EA", difficulty(3), [[0, 1, 0, 0, 0, 0]]),
|
||||
braille_trans("BB", difficulty(3), [[0, 1, 1, 0, 0, 0]]),
|
||||
braille_trans("CC", difficulty(3), [[0, 1, 0, 0, 1, 0]]),
|
||||
braille_trans("DD", difficulty(3), [[0, 1, 0, 0, 1, 1]]),
|
||||
braille_trans("FF", difficulty(3), [[0, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("GG", difficulty(3), [[0, 1, 1, 0, 1, 1]]),
|
||||
# Wordsigns
|
||||
braille_trans("ENOUGH", difficulty(3), [[0, 1, 0, 0, 0, 1]]),
|
||||
braille_trans("TO", difficulty(3), [[0, 1, 1, 0, 1, 0]]),
|
||||
braille_trans("WERE", difficulty(3), [[0, 1, 1, 0 , 1, 1]]),
|
||||
braille_trans("HIS", difficulty(3), [[0, 1, 1, 0, 0, 1]]),
|
||||
braille_trans("INTO", difficulty(3), [[0, 0, 1, 0, 1, 0], [0, 1, 1, 0, 1, 0]]), #(sequenced)
|
||||
braille_trans("BY", difficulty(3), [[0, 0, 1, 0, 1, 1]]), #(sequenced)
|
||||
braille_trans("WAS", difficulty(3), [[0, 0 , 1, 0 , 1, 1]]),
|
||||
|
||||
# Modifiers
|
||||
braille_trans("@?LET", difficulty(3), [[0, 0, 0, 0, 1, 1]], "LET"),
|
||||
braille_trans("@?CAPS", difficulty(3), [[0, 0, 0, 0, 0, 1]], "CAPS"),
|
||||
braille_trans("@?EMPH", difficulty(3), [[0, 0, 0, 1, 0, 1]], "EMPH"),
|
||||
]
|
||||
# remove None 's - rejected inputs
|
||||
valid = False
|
||||
while not valid:
|
||||
try:
|
||||
temp_dict.remove(None)
|
||||
except:
|
||||
valid = True
|
||||
braille_dict = pd.DataFrame([x.as_dict() for x in temp_dict]) # , columns=['key', 'level', 'msg', 'msg_prefix'])
|
||||
# RETURNS
|
||||
# print('Braille Dictionary Creation')
|
||||
# print(f"type(temp_dict) = {type(temp_dict)}")
|
||||
# print("temp_dict = ")
|
||||
# for i in range(len(temp_dict)):
|
||||
# print(f"{temp_dict[i]}")
|
||||
# print('')
|
||||
# print(f"type(braille_dict) = {type(braille_dict)}")
|
||||
# print(f"braille_dict = {braille_dict}")
|
||||
|
||||
return braille_dict # temp_dict # braille_dict
|
||||
|
||||
def get_delimiters():
|
||||
# FUNCTION
|
||||
# delimiters and special character codes for plaintext message before braille translation
|
||||
# VARIABLE INSTANTIATION
|
||||
txtdict = {"@?NUM" : "NUMBER",
|
||||
"@?NOTHING" : "",
|
||||
#" " : "",
|
||||
'"@?BO' : '"',
|
||||
'"@?BC' : '"',
|
||||
"-@?S" : "-",
|
||||
"-@?L" : "-",
|
||||
"/@?B" : "/",
|
||||
"[@?BPH" : "[",
|
||||
"]@?BPH" : "]",
|
||||
"[@?BSQ" : "[",
|
||||
"]@?BSQ" : "]",
|
||||
"'@?BO" : "'",
|
||||
"'@?BC" : "'",
|
||||
"@?LET" : "LET",
|
||||
"@?CAPS" : "CAPS",
|
||||
"@?EMPH" : "EMPH",
|
||||
"@?ABBREV1" : "ABBREV",
|
||||
"@?ABBREV2" : "ABBREV",
|
||||
"@?ABBREV3" : "ABBREV",
|
||||
"@?ABBREV4" : "ABBREV",
|
||||
}
|
||||
# RETURNS
|
||||
return txtdict
|
||||
|
||||
def gen_difficulty_msgstr(braille_dict, level: difficulty = difficulty(1)):
|
||||
# FUNCTION
|
||||
# generate keyboard message for specified difficulty
|
||||
# ARGUMENTS
|
||||
# list[braille_trans] braille_dict
|
||||
# difficulty level
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'gen_difficulty_msgstr'
|
||||
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', _m)
|
||||
av.val_type(level, "<enum 'difficulty'>", 'level', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
str_out = ''
|
||||
# n = len(braille_dict)
|
||||
# METHODS
|
||||
# print(f"len(braille_dict) = {n}")
|
||||
# print(f"braille_dict.columns =")
|
||||
# for i in braille_dict.columns:
|
||||
# print(braille_dict.columns[i])
|
||||
# temp_dict = braille_dict['key']
|
||||
dict_iterator = braille_dict[braille_dict['level'] == level]
|
||||
print(f"dict_iterator.index = {dict_iterator.index}")
|
||||
for bd_i in range(len(dict_iterator.index)):
|
||||
bd_n = dict_iterator['key'][dict_iterator.index[bd_i]]
|
||||
# print(f"bd_i = {bd_i}")
|
||||
# print(f"bd_n = {bd_n}")
|
||||
str_out += "@?NOTHING" + bd_n
|
||||
# for i in range(n):
|
||||
# bd_i = braille_dict.loc[i][0]
|
||||
# # print(f"bd_i = {bd_i}")
|
||||
# # print(f"type(bd_i) = {str(type(bd_i))}")
|
||||
# if (bd_i.level == difficulty):
|
||||
# str_out += "@?NOTHING" + bd_i.key
|
||||
# RETURNS
|
||||
return str_out
|
||||
|
||||
# def get_braille_by_key(braille_dict: pd.DataFrame, key: str):
|
||||
# # FUNCTION
|
||||
# # Find key in braille dictionary
|
||||
# return None
|
||||
# # ARGUMENTS
|
||||
# # ARGUMENT VALIDATION
|
||||
# # VARIABLE INSTANTIATION
|
||||
# # METHODS
|
||||
# # RETURNS
|
||||
|
||||
|
||||
def input_product(braille_dict, products, my_option: Optional[int] = -1, my_select: Optional[str] = ''):
|
||||
# FUNCTION
|
||||
# Get product input from user - repeat until valid input received
|
||||
# ARGUMENTS
|
||||
# list[braille_trans] braile_dict
|
||||
# list[product] products
|
||||
# optional int my_option - if option provided in code
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'input_product'
|
||||
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', _m)
|
||||
av.val_list(products, 'products', _m, "<class 'translate_msg_2_braille.product'>", 1)
|
||||
av.val_int(my_option, 'my_option', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
N = len(products)
|
||||
select_i = my_option
|
||||
valid = (my_option > 0 and my_option <= N)
|
||||
# temp_dict = braille_dict['key']
|
||||
# METHODS
|
||||
if valid:
|
||||
if my_option == N:
|
||||
temp = braille_dict[braille_dict['key'] == my_select]
|
||||
if len(temp.index) == 1:
|
||||
products[N - 1].msg_prefix = my_select
|
||||
else:
|
||||
valid = False
|
||||
while not valid:
|
||||
print()
|
||||
print('Welcome to your 3D Braille Model Generator')
|
||||
print("At any time, answer the following error code to exit (excl. speech marks): '#!ERRORCODE!#'")
|
||||
print()
|
||||
print('Braille Products:')
|
||||
for i in range(N):
|
||||
print(f"{i + 1}. {products[i].name}")
|
||||
print()
|
||||
select_i = av.input_int(input(f"Please enter your selection (1 - {N}) from the products above\n"), 1, N)
|
||||
if select_i == '#!ERRORCODE!#':
|
||||
sys.exit
|
||||
valid = not (str(type(select_i)) == "<class 'NoneType'>")
|
||||
if valid and select_i == N:
|
||||
valid = False
|
||||
while not valid:
|
||||
select_A = input("Please enter a character selection for your Scrabble tile\n")
|
||||
if select_A == '#!ERRORCODE!#':
|
||||
sys.exit
|
||||
temp = braille_dict[braille_dict['key'] == select_A].index
|
||||
if not len(temp) == 1:
|
||||
print(f"temp = {temp}")
|
||||
valid = False
|
||||
else:
|
||||
valid = True
|
||||
products[N - 1].msg_prefix = select_A
|
||||
# RETURNS
|
||||
return products[select_i - 1]
|
||||
|
||||
def append_ifnotNone(v_list, v_item):
|
||||
# FUNCTION
|
||||
# append v_item to v_list if v_item is not None
|
||||
# ARGUMENTS
|
||||
# list v_list
|
||||
# v_item
|
||||
# ARGUMENT VALIDATION
|
||||
if (not av.val_list(v_list, 'v_list', 'append_ifnotNone', suppress_errors = True)) or v_item == None:
|
||||
# RETURNS
|
||||
return v_list
|
||||
v_list.append(v_item)
|
||||
return v_list#.append(v_item)
|
||||
|
||||
|
||||
def gen_product_inputs(braille_dict):
|
||||
# FUNCTION
|
||||
# Generate product inputs
|
||||
# ARGUMENTS
|
||||
# [pandas.DataFrame] braille_dict - braille dictionary
|
||||
# VARIABLE INSTANTIATION
|
||||
products = []
|
||||
# ARGUMENT VALIDATION
|
||||
av.val_type(braille_dict, "<class 'pandas.core.frame.DataFrame'>", 'braille_dict', 'gen_product_inputs')
|
||||
# METHODS
|
||||
products.append(product("Extended Alphabet", 10, "abcdefg@?NOTHINGhijKLMNOPQRS@?NOTHINGTUVXYZANDFOROFTHEWITHCHGHSHTHWHEDEROUOWWEABBCCDDENFF?GGINBY"))
|
||||
products.append(product("Upper Groupsigns", 10, "uppe@?nothingr GRO@?NOTHINGUPSIGNsand:a@?nothingn@?nothingd for:fo@?nothingr of:o@?nothingf the:t@?nothingh@?nothinge with:wi@?nothingt@?nothingh "+"@?NEWLINECH:C@?NOTHINGH " + "GH:G@?NOTHINGH " + "SH:S@?NOTHINGH " + "TH:T@?NOTHINGH " + "WH:W@?NOTHINGH " + "ED:E@?NOTHINGD " + "ER:E@?NOTHINGR " + "OU:O@?NOTHINGU " + "OW:O@?NOTHINGW "+"st:s@?nothingt ar:a@?nothingr ble:bl@?nothinge ing:i@?nothingng"))
|
||||
products.append(product("Upper Wordsigns", 24, gen_difficulty_msgstr(braille_dict, difficulty(3))))
|
||||
products.append(product("Alphabet", 10, "ABCDEFG@?NOTHINGHIJKLMNOPQRSTUVWXYZ"))
|
||||
products.append(product("Travel", 5, "ABCDEFG@?NOTHINGHIJ"))
|
||||
products.append(product("Scrabble Alphabet of Tiles", 1, ''))
|
||||
products.append(product("Scrabble Character Tile", 1, ''))
|
||||
# RETURNS
|
||||
return products
|
||||
|
||||
def gen_braille_inputs_4_openscad(msgin, line_length, brailledict): # , hyphenate = False
|
||||
# FUNCTION
|
||||
# Convert message to Braille for openSCAD generation
|
||||
# ARGUMENTS
|
||||
# str msgin - partially translated message containing only brailledict keys and blankspace
|
||||
# int line_length - number of Braille characters per row on keyboard
|
||||
# pandas.DataFrame brailledict - Braille translations with diffculty
|
||||
# # bool hyphenate - hyphenate words that cross lines or start on new line
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'gen_braille_inputs_4_openscad'
|
||||
av.val_str(msgin, 'msgin', _m, 1)
|
||||
av.val_int(line_length, 'line_length', _m)
|
||||
av.val_type(brailledict, "<class 'pandas.core.frame.DataFrame'>", 'brailledict', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
# dict txtdict - delimiters for Braille translation
|
||||
msgin = msgin.upper()
|
||||
braille = []
|
||||
letters = ["", ]
|
||||
n_rows = 1
|
||||
start_of_word = 0 # position within cum
|
||||
numbers = []
|
||||
cum = [0] # 0-based cumulative starting position of Braille translation of message segments
|
||||
#lmsg = [0] * len(msgin) # length of braille message
|
||||
last_is_num = False
|
||||
new_word = True
|
||||
iter_lim = len(msgin)
|
||||
print(f"iteration limit = {iter_lim}") #len(msgin))
|
||||
msg_i_0 = -1
|
||||
maxstrlen = max_key_len(brailledict)
|
||||
# METHODS
|
||||
print(f"msgin = {msgin}")
|
||||
while (msg_i_0 < iter_lim):
|
||||
msg_i_0 = msg_i_0 + 1
|
||||
found = False
|
||||
print(f"msg_i_0 = {msg_i_0}")
|
||||
for phrase_len in range(min(len(msgin) - msg_i_0, maxstrlen), 0, -1):
|
||||
if found:
|
||||
continue
|
||||
phrase = msgin[msg_i_0 : msg_i_0 + phrase_len] # message segment to search for in Braille translation keys
|
||||
print(f'phrase = {phrase}')
|
||||
|
||||
# generate braille if a code has been found
|
||||
if (phrase_len == 0):
|
||||
if (ord(phrase) >= 48 and ord(phrase) <= 57): # numbers
|
||||
b_num_pre = brailledict[brailledict['key'] == "@?NUM"]['braille'].values[0]
|
||||
b_num = brailledict[brailledict['key'] == ("J" if (ord(phrase) == 48) else chr(ord(phrase)+16))]['braille'].values[0]
|
||||
if last_is_num == True:
|
||||
braille[len(braille) - 1].append(b_num[0])
|
||||
new_cum = 1
|
||||
# temp = temp2
|
||||
else:
|
||||
braille.append([b_num_pre[0], b_num[0]])
|
||||
new_cum = 2
|
||||
# temp = [temp1[0], temp2[0]]
|
||||
print('braille(numeric phrase) = ', braille[len(braille) - 1])
|
||||
last_is_num = True
|
||||
else:
|
||||
# new_cum = len(brailledict[brailledict['key'] == phrase].index)
|
||||
found = (len(brailledict[brailledict['key'] == phrase].index) == 1)
|
||||
if found:
|
||||
last_is_num = False
|
||||
# temp = brailledict.get(phrase)
|
||||
else:
|
||||
# new_cum = len(brailledict[brailledict['key'] == phrase].index)
|
||||
found = (len(brailledict[brailledict['key'] == phrase].index) == 1)
|
||||
if found:
|
||||
last_is_num = False
|
||||
# temp = brailledict.get(phrase)
|
||||
#print("tempsearch = ", temp)
|
||||
|
||||
# organise placement of braille phrase onto end of whole message
|
||||
if found or last_is_num: # (temp != None): #
|
||||
# found = True
|
||||
# last_is_num = False
|
||||
new_num = [-1]
|
||||
if (len(phrase) == 1):
|
||||
if (ord(phrase) >= 65 and ord(phrase) <= 90): # letters
|
||||
new_num = [ord(phrase) - 64]
|
||||
elif (ord(phrase) >= 48 and ord(phrase) <= 57): # numbers
|
||||
new_num = [ord(phrase) - 48]
|
||||
# last_is_num = True
|
||||
if found:
|
||||
braille.append(brailledict[brailledict['key'] == phrase]['braille'].values[0])
|
||||
new_cum = len(braille[len(braille) - 1])
|
||||
numbers.append(new_num)
|
||||
new_cum = cum[len(cum) - 1] + new_cum
|
||||
cum.append(new_cum)
|
||||
n_rows_0 = n_lines_at_pos(start_of_word, line_length)
|
||||
n_rows_next = n_lines_at_pos(new_cum, line_length)
|
||||
if (n_rows_0 < n_rows_next and not n_rows_0 % line_length == 0):
|
||||
delta_cum_new_line = n_rows_next * line_length + 1 - cum[start_of_word]
|
||||
for msg_j in range(len(cum) - start_of_word - 1):
|
||||
cum[start_of_word + msg_j] += delta_cum_new_line
|
||||
#if (cum[len(cum)-1] % line_length > 0):
|
||||
# cum[len(cum)-1] = cum[len(cum)-1] + line_length - (1+(cum[len(cum)-1]-1) % line_length)
|
||||
# print("clean_rows",cum[len(cum)-1])
|
||||
# print("phrase_len=",phrase_len)
|
||||
msg_i_0 += phrase_len - 1
|
||||
letters.append(brailledict[brailledict['key'] == phrase]['plaintext'].values[0])
|
||||
# temptxt = txtdict.get(phrase)
|
||||
# if temptxt == None:
|
||||
# letters.append(phrase)
|
||||
# else:
|
||||
# letters.append(temptxt)
|
||||
elif phrase == "@?NOTHING":
|
||||
msg_i_0 += 8 # 9
|
||||
print('found nothing')
|
||||
found = True
|
||||
elif phrase == "@?NEWLINE":
|
||||
msg_i_0 += 8 # 9
|
||||
print('forced newline')
|
||||
cum[len(cum) - 1] += line_length - 1 - ((cum[len(cum) - 1] - 1) % line_length)
|
||||
found = True
|
||||
start_of_word = True
|
||||
elif phrase == " ": # and (cum[len(cum)-1] % line_length > 0)): # no space at start of line # or letters[len(cum)-1] == " " or msgin[ni+1] == " ")
|
||||
# msg_i_0 += 1
|
||||
cum[len(cum)-1] = cum[len(cum)-1] + 1
|
||||
print('space')
|
||||
start_of_word = True
|
||||
# word start position
|
||||
if new_word:
|
||||
start_of_word = len(cum) - 1 # position within cum
|
||||
# unfound character??
|
||||
if phrase_len == 0 and not (found or (ord(phrase) >= 48 and ord(phrase) <= 57)):
|
||||
print(f"Unfound phrase: {phrase}")
|
||||
# OUTPUTS
|
||||
# console output
|
||||
n_keys = max(cum)
|
||||
letters = letters[1:len(letters)] # why does element 0 exist?
|
||||
# print(f"message length b = {n_keys}")
|
||||
# print(f"braille = {braille}")
|
||||
# print(f"cum = {cum}")
|
||||
# print(f"numbers = {numbers}")
|
||||
# print(f"letters = {letters}")
|
||||
|
||||
## file output
|
||||
f = open('Braille.txt','a')
|
||||
f.truncate()
|
||||
f.write(f'cum = {str(cum)};\n')
|
||||
|
||||
f.write('msgstr = [')
|
||||
for i in range(len(letters)):
|
||||
f.write('"')
|
||||
f.write(str(letters[i]))
|
||||
if i < len(letters) - 1:
|
||||
f.write('", ')
|
||||
f.write('"];\n')
|
||||
|
||||
f.write('numbers = [')
|
||||
for i in range(len(numbers)):
|
||||
#f.write('"')
|
||||
f.write(str(numbers[i]))
|
||||
if i < len(numbers) - 1:
|
||||
f.write(', ')
|
||||
f.write('];\n')
|
||||
|
||||
f.write(f"inA = {str(braille)};\n")
|
||||
f.write(f"lmsg = {str(len(braille))};\n")
|
||||
f.write(f"N = {str(n_keys)};\n")
|
||||
f.write(f"nln = {str(min(line_length, n_keys))};\n")
|
||||
f.write(f"maxln = {str(n_rows)};\n")
|
||||
f.close()
|
||||
# RETURNS
|
||||
return cum, letters, numbers, braille, n_keys, n_rows
|
||||
|
||||
|
||||
def n_lines_at_pos(position, line_length):
|
||||
# FUNCTION
|
||||
# calculate number of rows of keyboard required for message of length (in Braille keys) position
|
||||
# ARGUMENTS
|
||||
# int position - quantity of Braille keys in message up to (+ incl.) position
|
||||
# int line_length - number of Braille keys per line / row
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'n_lines_at_pos'
|
||||
av.val_int(position, 'position', _m, 0)
|
||||
av.val_int(line_length, 'line_length', _m, 1)
|
||||
# RETURNS
|
||||
return 1 + (position // line_length)
|
||||
|
||||
|
||||
def max_key_len(mydict: pd.DataFrame, min_dict_len: Optional[int] = 1):
|
||||
# FUNCTION
|
||||
# find maximum key length in braille dictionary
|
||||
# ARGUMENTS
|
||||
# pandas.DataFrame mydict
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'max_key_len'
|
||||
av.val_int(min_dict_len, 'min_dict_len', _m)
|
||||
av.val_type(mydict, "<class 'pandas.core.frame.DataFrame'>", 'mydict', _m)
|
||||
# VARIABLE INSTANTIATION
|
||||
n = len(mydict.index)
|
||||
max_len = 0
|
||||
# METHODS
|
||||
for i in range(n):
|
||||
max_len = max(max_len, len(mydict.iloc[i]['key']))
|
||||
if max_len < min_dict_len:
|
||||
return -1
|
||||
# RETURNS
|
||||
return max_len
|
||||
|
||||
|
||||
# ToDo: Finish this!
|
||||
# def remove_words_in_word(word, maxstrlen=9):
|
||||
# ln = len(word)
|
||||
# minmax = min(ln, maxstrlen)
|
||||
# fix = False
|
||||
# skip = False
|
||||
# for length in np.arange(minmax, 1, -1):
|
||||
# for start in range(ln-length):
|
||||
# tempstr = word[start:start+length]
|
||||
# if (tempstr == "@?NOTHING"):
|
||||
# skip = True
|
||||
# if skip:
|
||||
# continue
|
||||
# tempfind = brailledict.get(tempstr)
|
||||
# if not (tempbool == None):
|
||||
# tempword = word[:start]
|
||||
# for li in range(length):
|
||||
# ## add "@?NOTHING"
|
||||
|
||||
# def get_translated_input(my_option: Optional[int] = -1): # REDUNDANT
|
||||
# # FUNCTION
|
||||
# # Get product selection input from user + convert to Braille
|
||||
# # VARIABLE INSTANTIATION
|
||||
# braille_translations = get_braille_translations()
|
||||
# products = gen_product_inputs(braille_translations)
|
||||
# delimiters = get_delimiters()
|
||||
# # METHODS
|
||||
# my_product = input_product(braille_translations, products, my_option)
|
||||
# # cum, letters, numbers, braille, ltmsg, n_rows = gen_braille_inputs_4_openscad(my_product.msg, my_product.line_length, braille_translations, max_key_len(braille_translations), delimiters)
|
||||
# # RETURNS
|
||||
# return my_product, braille_translations, max_key_len(braille_translations), delimiters
|
||||
|
||||
# get_translated_input() ' requires translate_msg_2_braille is replaced by __main__ in type validation strings
|
||||
|
||||
|
||||
# def process_old_dict(old_dict, difficulty):
|
||||
# # FUNCTION
|
||||
# # create new list of braille_trans dataclass items
|
||||
# # ARGUMENTS
|
||||
# # old_dict - old dictionary of keys, values
|
||||
# # difficulty - level field of dataclass
|
||||
# # ARGUMENT VALIDATION
|
||||
# print(f"type(old_dict) = {type(old_dict)}")
|
||||
# print(f"type(difficulty) = {type(difficulty)}")
|
||||
# # VARIABLE INSTANTIATION
|
||||
# new_dict = []
|
||||
# # METHODS
|
||||
# for i in range(len(old_dict)):
|
||||
# temp_key, temp_value = old_dict.popitem()
|
||||
# new_dict.append(braille_trans(temp_key, difficulty, temp_value))
|
||||
# # RETURNS
|
||||
# return new_dict
|
||||
|
||||
|
||||
# class braille_dictionary():
|
||||
|
||||
# def __init__(self, keys, hardnesses, braille_translations):
|
||||
# return self.push(keys, hardnesses, braille_translations)
|
||||
|
||||
# def push(self, keys, hardnesses, braille_translations):
|
||||
# N_in = len(keys)
|
||||
# if not (N_in == len(hardnesses) == len(braille_translations)):
|
||||
# return False
|
||||
# for i in range(N_in - 1):
|
||||
# for j in range(i + 1):
|
||||
# if (keys[i + 1] == keys[j]):
|
||||
# return False
|
||||
# for i in range(N_in):
|
||||
# self.keys.append(keys[i])
|
||||
# self.hards.append(hardnesses[i])
|
||||
# self.brailles.append(braille_translations[i])
|
||||
# return True
|
||||
|
||||
# def exists_key(self, key):
|
||||
# try:
|
||||
# i = self.keys.index(key)
|
||||
# except ValueError:
|
||||
# return True
|
||||
# else:
|
||||
# return False
|
||||
|
||||
# def get_key_index(self, key):
|
||||
# if self.exists_key(key):
|
||||
# return self.keys.index(key)
|
||||
# else:
|
||||
# return -1
|
||||
11
requirements.txt
Normal file
11
requirements.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
# Requirements
|
||||
pandas
|
||||
numpy
|
||||
prettytable
|
||||
openpyscad
|
||||
|
||||
# built-in
|
||||
# enum
|
||||
# os
|
||||
# sys
|
||||
# typing
|
||||
25
setup.py
Normal file
25
setup.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Package and distribution management
|
||||
|
||||
# Learn more: {github_repo}
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
with open('README.rst') as f:
|
||||
readme = f.read()
|
||||
|
||||
with open('LICENSE') as f:
|
||||
license = f.read()
|
||||
|
||||
setup(
|
||||
name='project/package name',
|
||||
version='0.1.0',
|
||||
description='Project/package description',
|
||||
long_description=readme,
|
||||
author='Edward Middleton-Smith',
|
||||
author_email='edward.middletonsmith@gmail.com',
|
||||
url='github_repo',
|
||||
license=license,
|
||||
packages=find_packages(exclude('tests', 'docs'))
|
||||
)
|
||||
17
tests/context.py
Normal file
17
tests/context.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Sun May 14 13:48:42 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Project: Braille Model Generator
|
||||
|
||||
Feature: test context
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||
|
||||
import model_gen
|
||||
15
tests/test_advanced.py
Normal file
15
tests/test_advanced.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Sun May 14 13:48:42 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
Company: Precision And Research Technology Systems Limited
|
||||
|
||||
Project: Braille Model Generator
|
||||
|
||||
Feature: advanced / comprehensive unit test procedure
|
||||
"""
|
||||
|
||||
from .context import model_gen
|
||||
|
||||
model_gen.main.generate()
|
||||
15
tests/test_basic.py
Normal file
15
tests/test_basic.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Sun May 14 13:48:42 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
Company: Precision And Research Technology Systems Limited
|
||||
|
||||
Project: Braille Model Generator
|
||||
|
||||
Feature: basic unit test procedure
|
||||
"""
|
||||
|
||||
from .context import model_gen
|
||||
|
||||
model_gen.main.generate(7, 'A')
|
||||
Reference in New Issue
Block a user