# Path: preimage/utils/alphabet.py
# 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
# 
# Path: preimage/exceptions/n_gram.py
# class InvalidNGramError(ValueError):
#     def __init__(self, n, n_gram):
#         self.n = n
#         self.n_gram = n_gram
# 
#     def __str__(self):
#         error_message = "{} is not a possible {:d}_gram for this alphabet".format(self.n_gram, self.n)
#         return error_message


from collections import Counter
from scipy.sparse import csr_matrix
from preimage.utils.alphabet import get_n_gram_to_index
from preimage.exceptions.n_gram import InvalidNGramError
import numpy
    return feature_space


def __initialize_pointers_indexes_data(n_examples):
    index_pointers = numpy.empty(n_examples + 1, dtype=numpy.int)
    index_pointers[0] = 0
    indexes = []
    data = []
    return index_pointers, indexes, data


def __build_y_pointers_indexes_data(index_pointers, indexes, data, n, n_gram_to_index, Y):
    for y_index, y in enumerate(Y):
        y_column_indexes = __get_y_indexes(y, n, n_gram_to_index)
        y_unique_column_indexes = list(numpy.unique(y_column_indexes))
        index_pointers[y_index + 1] = __get_y_index_pointer(y_index, index_pointers, y_unique_column_indexes)
        indexes += y_unique_column_indexes
        data += __get_y_data(y_column_indexes, y_unique_column_indexes)


def __get_y_index_pointer(y_index, index_pointers, y_unique_column_indexes):
    index_pointer = index_pointers[y_index] + len(y_unique_column_indexes)
    return index_pointer


def __get_y_indexes(y, n, n_gram_to_index):
    y_n_gram_count = len(y) - n + 1
    try:
        column_indexes = [n_gram_to_index[y[i:i + n]] for i in range(y_n_gram_count)]
    except KeyError as key_error:

# Path: preimage/utils/alphabet.py
# 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
# 
# Path: preimage/exceptions/n_gram.py
# class InvalidNGramError(ValueError):
#     def __init__(self, n, n_gram):
#         self.n = n
#         self.n_gram = n_gram
# 
#     def __str__(self):
#         error_message = "{} is not a possible {:d}_gram for this alphabet".format(self.n_gram, self.n)
#         return error_message


# Path: preimage/features/string_feature_space.py
from collections import Counter
from scipy.sparse import csr_matrix
from preimage.utils.alphabet import get_n_gram_to_index
from preimage.exceptions.n_gram import InvalidNGramError
import numpy

    return feature_space


def __initialize_pointers_indexes_data(n_examples):
    index_pointers = numpy.empty(n_examples + 1, dtype=numpy.int)
    index_pointers[0] = 0
    indexes = []
    data = []
    return index_pointers, indexes, data


def __build_y_pointers_indexes_data(index_pointers, indexes, data, n, n_gram_to_index, Y):
    for y_index, y in enumerate(Y):
        y_column_indexes = __get_y_indexes(y, n, n_gram_to_index)
        y_unique_column_indexes = list(numpy.unique(y_column_indexes))
        index_pointers[y_index + 1] = __get_y_index_pointer(y_index, index_pointers, y_unique_column_indexes)
        indexes += y_unique_column_indexes
        data += __get_y_data(y_column_indexes, y_unique_column_indexes)


def __get_y_index_pointer(y_index, index_pointers, y_unique_column_indexes):
    index_pointer = index_pointers[y_index] + len(y_unique_column_indexes)
    return index_pointer


def __get_y_indexes(y, n, n_gram_to_index):
    y_n_gram_count = len(y) - n + 1
    try:
        column_indexes = [n_gram_to_index[y[i:i + n]] for i in range(y_n_gram_count)]
    except KeyError as key_error:

        raise InvalidNGramError(n, key_error.args[0])