
class Vocabulary :

	symbols = {
	    "letters_lower" : [chr(i) for i in range(97, 123)],
	    "letters_upper" : [chr(i) for i in range(65, 91)],
	    "digits"        : [chr(i) for i in range(48, 58)],
	    "punctuation"   : [chr(i) for i in [33,44,45,46,58,59,63,39,34]],
	    "brackets"      : [chr(i) for i in [40,41,91,93,123,125, 60,62]],
	    "math"          : [chr(i) for i in [43,45,42,47,61,37, 94,126]],
	    "special"       : [chr(i) for i in [33,35,36,38,64,95]],
	    "whitespace"    : [chr(i) for i in [32, 9, 10]],
	    "greek_upper"   : [chr(i) for i in range(0x0391, 0x03A5) if i != 0x03A2][:19],
	    "greek_lower"   : [chr(i) for i in range(0x03B1, 0x03C5) if i != 0x03C2][:19],
	    "geometric"     : [chr(i) for i in range(0x25A0, 0x2600)],
	}

	@staticmethod
	def _get( pool : str, n : int ) -> list[str] :
	    symbols = amVocabulary.symbols[ pool ]
	    if n > len( symbols ) :
	        raise ValueError( f"Requested {n} symbols from '{pool}' but only {len(symbols)} available" )
	    return symbols[ :n ]

	@staticmethod
	def letters_lower( n : int ) -> list[str] : return amVocabulary._get( 'letters_lower', n )
	@staticmethod
	def letters_upper( n : int ) -> list[str] : return amVocabulary._get( 'letters_upper', n )
	@staticmethod
	def digits( n : int ) -> list[str] :        return amVocabulary._get( 'digits', n )
	@staticmethod
	def punctuation( n : int ) -> list[str] :   return amVocabulary._get( 'punctuation', n )
	@staticmethod
	def brackets( n : int ) -> list[str] :      return amVocabulary._get( 'brackets', n )
	@staticmethod
	def math( n : int ) -> list[str] :          return amVocabulary._get( 'math', n )
	@staticmethod
	def special( n : int ) -> list[str] :       return amVocabulary._get( 'special', n )
	@staticmethod
	def whitespace( n : int ) -> list[str] :    return amVocabulary._get( 'whitespace', n )
	@staticmethod
	def greek_upper( n : int ) -> list[str] :   return amVocabulary._get( 'greek_upper', n )
	@staticmethod
	def greek_lower( n : int ) -> list[str] :   return amVocabulary._get( 'greek_lower', n )
	@staticmethod
	def geometric( n : int ) -> list[str] :     return amVocabulary._get( 'geometric', n )

	@staticmethod
	def num_letters_lower() -> int : return len( amVocabulary.symbols[ 'letters_lower' ] )
	@staticmethod
	def num_letters_upper() -> int : return len( amVocabulary.symbols[ 'letters_upper' ] )
	@staticmethod
	def num_digits() -> int :        return len( amVocabulary.symbols[ 'digits' ] )
	@staticmethod
	def num_punctuation() -> int :   return len( amVocabulary.symbols[ 'punctuation' ] )
	@staticmethod
	def num_brackets() -> int :      return len( amVocabulary.symbols[ 'brackets' ] )
	@staticmethod
	def num_math() -> int :          return len( amVocabulary.symbols[ 'math' ] )
	@staticmethod
	def num_special() -> int :       return len( amVocabulary.symbols[ 'special' ] )
	@staticmethod
	def num_whitespace() -> int :    return len( amVocabulary.symbols[ 'whitespace' ] )
	@staticmethod
	def num_greek_upper() -> int :   return len( amVocabulary.symbols[ 'greek_upper' ] )
	@staticmethod
	def num_greek_lower() -> int :   return len( amVocabulary.symbols[ 'greek_lower' ] )
	@staticmethod
	def num_geometric() -> int :     return len( amVocabulary.symbols[ 'geometric' ] )