import numpy as np
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout

def visualize_training_results(results):
    """
    Plots the loss and accuracy for the training and testing data
    """
    history = results.history
    plt.figure(figsize=(12,4))
    plt.plot(history['val_loss'])
    plt.plot(history['loss'])
    plt.legend(['val_loss', 'loss'])
    plt.title('Loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.show()
    
    plt.figure(figsize=(12,4))
    plt.plot(history['val_accuracy'])
    plt.plot(history['accuracy'])
    plt.legend(['val_accuracy', 'accuracy'])
    plt.title('Accuracy')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.show()
    
    
def split_sequence(seq, n_steps_in, n_steps_out):
    """
    Splits the univariate time sequence
    """
    X, y = [], []
    
    for i in range(len(seq)):
        end = i + n_steps_in
        out_end = end + n_steps_out
        
        if out_end > len(seq):
            break
        
        seq_x, seq_y = seq[i:end], seq[end:out_end]
        
        X.append(seq_x)
        y.append(seq_y)
    
    return np.array(X), np.array(y)


def layer_maker(n_layers, n_nodes, activation, drop=None, d_rate=.5):
    """
    Create a specified number of hidden layers for an RNN
    Optional: Adds regularization option, dropout layer to prevent potential overfitting if necessary
    """
    model = Sequential()
    # Creating the specified number of hidden layers with the specified number of nodes
    for x in range(1,n_layers+1):
        model.add(LSTM(n_nodes, activation=activation, return_sequences=True))

        # Adds a Dropout layer after every Nth hidden layer (the 'drop' variable)
        try:
            if x % drop == 0:
                model.add(Dropout(d_rate))
        except:
            pass

[((55, 12, 55, 24), 'keras.models.Sequential', 'Sequential', ({}, {}), '()', False, 'from keras.models import Sequential\n'), ((47, 11, 47, 22), 'numpy.array', 'np.array', ({(47, 20, 47, 21): 'X'}, {}), '(X)', True, 'import numpy as np\n'), ((47, 24, 47, 35), 'numpy.array', 'np.array', ({(47, 33, 47, 34): 'y'}, {}), '(y)', True, 'import numpy as np\n'), ((58, 18, 58, 77), 'keras.layers.LSTM', 'LSTM', (), '', False, 'from keras.layers import LSTM, Dense, Dropout\n'), ((63, 26, 63, 41), 'keras.layers.Dropout', 'Dropout', ({(63, 34, 63, 40): 'd_rate'}, {}), '(d_rate)', False, 'from keras.layers import LSTM, Dense, Dropout\n')]