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