def make_subsequences(x, y, step=1, max_len=2 ** 31):
    """
    Creates views to all subsequences of the sequence x. For example if
    x = [1,2,3,4]
    y = [1,1,0,0]
    step = 1
    the result is a tuple a, b, where:
    a = [[1],
    [1,2],
    [1,2,3],
    [1,2,3,4]
    ]
    b = [1,1,0,0]

    Note that only a view into x is created, but not a copy of elements of x.

    Parameters
    ----------
    X : array [seq_length, n_features]

    y : numpy array of shape [n_samples]
        Target values. Can be string, float, int etc.

    step : int
        Step with which to subsample the sequence.

    max_len : int, default 2 ** 31
        Step with which to subsample the sequence.

    Returns
    -------
    a, b : a is all subsequences of x taken with some step, and b is labels assigned to these sequences.
    """

    r = range(step-1, len(x), step)

    X = []
    Y = []

    for i in r:
        start = max(0, i - max_len)
        stop = i+1
        X.append(x[start:stop])
        Y.append(y[i])

    return X, Y