# Path: utils/ops.py
# def multi_filter_conv_block(input, n_filters, reuse=False,
#                             dropout_keep_prob=0.5, activation='relu',
#                             padding='same', name='mfcb'):
# def lstm_block(input, hidden_units=128, dropout=0.5, reuse=False, layers=1,
#                            dynamic=True, return_seq=False, bidirectional=False):
# def embedding_layer(metadata_path=None, embedding_weights=None,
#                     name='W_embedding', trainable=True, vocab_size=None,
#                     embedding_shape=300):
# def get_regularizer(beta=0.001):
# def get_optimizer(name='adam'):
#     W = None
#         W = tf.Variable(w2v_init, trainable=trainable, name=name)
#         W = tf.get_variable(name, [vocab_size, embedding_shape],
#                         trainable=trainable)


import os
import pickle
import tensorflow as tf
from utils import ops
from abc import abstractmethod, ABC

    ###########################################################################
    #                         CONCRETE IMPLEMENTATIONS                        #
    ###########################################################################

    def __init__(self, train_options):
        """
        This constructs a Model Object and sets some training options,
        which is a dictionary of hyper parameters.
        E.g., train_options = {"num_layers": 4, "rnn_size: 128}.
        It is recommended to always use default parameters for train_options

        :param train_options: This is a dictionary of training options and
        hyperparameters that will be required to train and evaluate the model
        """
        self.args = train_options
        self.create_experiment_dirs()
        self.load_train_options()
        self.save_train_options()
        self.create_placeholders()
        self.create_scalars()

    def create_optimizer(self):
        """
        Create your optimizer here. You can choose from an exhaustive list
        of Optimizers that Tensorflow provides. This is a link to the
        available optimizers
        https://www.tensorflow.org/api_guides/python/train
        :return:
        """

# Path: utils/ops.py
# def multi_filter_conv_block(input, n_filters, reuse=False,
#                             dropout_keep_prob=0.5, activation='relu',
#                             padding='same', name='mfcb'):
# def lstm_block(input, hidden_units=128, dropout=0.5, reuse=False, layers=1,
#                            dynamic=True, return_seq=False, bidirectional=False):
# def embedding_layer(metadata_path=None, embedding_weights=None,
#                     name='W_embedding', trainable=True, vocab_size=None,
#                     embedding_shape=300):
# def get_regularizer(beta=0.001):
# def get_optimizer(name='adam'):
#     W = None
#         W = tf.Variable(w2v_init, trainable=trainable, name=name)
#         W = tf.get_variable(name, [vocab_size, embedding_shape],
#                         trainable=trainable)


# Path: models/model.py
import os
import pickle
import tensorflow as tf
from utils import ops
from abc import abstractmethod, ABC


    ###########################################################################
    #                         CONCRETE IMPLEMENTATIONS                        #
    ###########################################################################

    def __init__(self, train_options):
        """
        This constructs a Model Object and sets some training options,
        which is a dictionary of hyper parameters.
        E.g., train_options = {"num_layers": 4, "rnn_size: 128}.
        It is recommended to always use default parameters for train_options

        :param train_options: This is a dictionary of training options and
        hyperparameters that will be required to train and evaluate the model
        """
        self.args = train_options
        self.create_experiment_dirs()
        self.load_train_options()
        self.save_train_options()
        self.create_placeholders()
        self.create_scalars()

    def create_optimizer(self):
        """
        Create your optimizer here. You can choose from an exhaustive list
        of Optimizers that Tensorflow provides. This is a link to the
        available optimizers
        https://www.tensorflow.org/api_guides/python/train
        :return:
        """

        self.optimizer = ops.get_optimizer(self.args["optimizer"]) \