# Path: preimage/exceptions/n_gram.py
# class InvalidNGramLengthError(ValueError):
#     def __init__(self, n, min_n=0):
#         self.n = n
#         self.min_n = min_n
# 
#     def __str__(self):
#         error_message = 'n must be greater than {:d}. Got: n={:d}'.format(self.min_n, self.n)
#         return error_message


from itertools import product
from preimage.exceptions.n_gram import InvalidNGramLengthError
import numpy
class Alphabet:
    latin = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
             'v', 'w', 'x', 'y', 'z']


def get_n_gram_to_index(alphabet, n):
    n_grams = get_n_grams(alphabet, n)
    indexes = numpy.arange(len(n_grams))
    n_gram_to_index = dict(zip(n_grams, indexes))
    return n_gram_to_index


def get_index_to_n_gram(alphabet, n):
    n_grams = get_n_grams(alphabet, n)
    indexes = numpy.arange(len(n_grams))
    index_to_n_gram = dict(zip(indexes, n_grams))
    return index_to_n_gram


def get_n_grams(alphabet, n):
    n = int(n)
    if n <= 0:
        raise InvalidNGramLengthError(n)
    n_grams = [''.join(n_gram) for n_gram in product(alphabet, repeat=n)]
    return n_grams


def transform_strings_to_integer_lists(Y, alphabet):
    letter_to_int = get_n_gram_to_index(alphabet, 1)
    n_examples = numpy.array(Y).shape[0]

# Path: preimage/exceptions/n_gram.py
# class InvalidNGramLengthError(ValueError):
#     def __init__(self, n, min_n=0):
#         self.n = n
#         self.min_n = min_n
# 
#     def __str__(self):
#         error_message = 'n must be greater than {:d}. Got: n={:d}'.format(self.min_n, self.n)
#         return error_message


# Path: preimage/utils/alphabet.py
from itertools import product
from preimage.exceptions.n_gram import InvalidNGramLengthError
import numpy

class Alphabet:
    latin = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
             'v', 'w', 'x', 'y', 'z']


def get_n_gram_to_index(alphabet, n):
    n_grams = get_n_grams(alphabet, n)
    indexes = numpy.arange(len(n_grams))
    n_gram_to_index = dict(zip(n_grams, indexes))
    return n_gram_to_index


def get_index_to_n_gram(alphabet, n):
    n_grams = get_n_grams(alphabet, n)
    indexes = numpy.arange(len(n_grams))
    index_to_n_gram = dict(zip(indexes, n_grams))
    return index_to_n_gram


def get_n_grams(alphabet, n):
    n = int(n)
    if n <= 0:
        raise InvalidNGramLengthError(n)
    n_grams = [''.join(n_gram) for n_gram in product(alphabet, repeat=n)]
    return n_grams


def transform_strings_to_integer_lists(Y, alphabet):
    letter_to_int = get_n_gram_to_index(alphabet, 1)
    n_examples = numpy.array(Y).shape[0]

    max_length = numpy.max([len(y) for y in Y])