<commit_before>#-*- coding: utf8
from __future__ import division, print_function

from node_sherlock import dataio
from node_sherlock import dynamic
from node_sherlock import learn
from node_sherlock import kernels
from node_sherlock import plearn

from mpi4py import MPI

import argparse
import multiprocessing
import numpy as np
import os

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('trace_fpath', help='The trace to learn topics from', \
            type=str)
    parser.add_argument('num_topics', help='The number of topics to learn', \
            type=int)
    parser.add_argument('model_fpath', \
            help='The name of the model file (a h5 file)', type=str)

    parser.add_argument('--num_iter', help='The number of iterations', \
            type=int, default=1000)
    parser.add_argument('--burn_in', \
            help='The burn in (ignored if using mpi)', type=int, \
            default=300)

    parser.add_argument('--dynamic', \
            help='If we should employ the dynamic strategy (only works with mpi)', \
            type=bool, default=False)
    parser.add_argument('--num_batches', \
            help='Number of batches in dynamic case', type=int, default=10)

    parser.add_argument('--alpha_zh', \
            help='Value of alpha_zh (alpha) hyper. Defaults to 50 / nz', \
            type=float, default=None)
    parser.add_argument('--beta_zs', help='Value of beta_zs (beta) hyper', \
            type=float, default=0.001)
    parser.add_argument('--beta_zd', help='Value of beta_zd (beta\') hyper', \
            type=float, default=0.001)

    parser.add_argument('--kernel', choices=kernels.names,
            help='The kernel to use', type=str, default='noop')
    parser.add_argument('--residency_priors', nargs='+',
            help='Priors for the residency time dist', type=float, default=None)

    parser.add_argument('--leaveout', \
            help='The number of transitions to leave for test', type=float, \
            default=0)

    args = parser.parse_args()

    num_lines = 0
    with open(args.trace_fpath) as trace_file:
        num_lines = sum(1 for _ in trace_file)

    if args.leaveout > 0:
        leave_out = min(1, args.leaveout)
        if leave_out == 1:
            print('Leave out is 1 (100%), nothing todo')
            return
        from_ = 0
        to = int(num_lines - num_lines * leave_out)
    else:
        from_ = 0
        to = np.inf

    if args.alpha_zh is None:
        alpha_zh = 50.0 / args.num_topics
    else:
        alpha_zh = args.alpha_zh

    kernel = kernels.names[args.kernel]()
    if args.residency_priors:
        residency_priors = np.array(args.residency_priors, dtype='d')
    else:
        residency_priors = np.zeros(shape=(0, ), dtype='d')

    if np.isinf(to):
        kernel.build(num_lines - from_, args.num_topics, residency_priors)
    else:
        kernel.build(to - from_, args.num_topics, residency_priors)

    comm = MPI.COMM_WORLD
    rank = comm.rank
    size = comm.size
    try:
        comm = MPI.COMM_WORLD
        rank = comm.rank
        size = comm.size
        single_thread = size == 1
    except:
        single_thread = True

    if single_thread:
        print('Not on MPI mode or just one MPI proc, running single thread')
        single_thread = True

    if single_thread:
        rv = learn.fit(args.trace_fpath, args.num_topics, alpha_zh, \
                args.beta_zs, args.beta_zd, kernel, residency_priors, \
                args.num_iter, args.burn_in, from_=from_, to=to)
        dataio.save_model(args.model_fpath, rv)
    else:
        comm = MPI.COMM_WORLD
        rank = comm.rank
        if rank == plearn.MASTER:
            dyn = args.dynamic
            if dyn:
                num_iter = args.num_iter // args.num_batches
                rv = dynamic.fit(args.trace_fpath, args.num_topics, alpha_zh, \
                        args.beta_zs, args.beta_zd, kernel, residency_priors, \
                        num_iter, args.num_batches, from_=from_, to=to)
            else:
                rv = plearn.fit(args.trace_fpath, args.num_topics, alpha_zh, \
                        args.beta_zs, args.beta_zd, kernel, residency_priors, \
                        args.num_iter, from_=from_, to=to)
            dataio.save_model(args.model_fpath, rv)
        else:
            plearn.work()

if __name__ == '__main__':
    main()
<commit_msg>Fixed bug in main for mpi<commit_after>#-*- coding: utf8
from __future__ import division, print_function

from node_sherlock import dataio
from node_sherlock import dynamic
from node_sherlock import learn
from node_sherlock import kernels
from node_sherlock import plearn

from mpi4py import MPI

import argparse
import multiprocessing
import numpy as np
import os

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('trace_fpath', help='The trace to learn topics from', \
            type=str)
    parser.add_argument('num_topics', help='The number of topics to learn', \
            type=int)
    parser.add_argument('model_fpath', \
            help='The name of the model file (a h5 file)', type=str)

    parser.add_argument('--num_iter', help='The number of iterations', \
            type=int, default=1000)
    parser.add_argument('--burn_in', \
            help='The burn in (ignored if using mpi)', type=int, \
            default=300)

    parser.add_argument('--dynamic', \
            help='If we should employ the dynamic strategy (only works with mpi)', \
            type=bool, default=False)
    parser.add_argument('--num_batches', \
            help='Number of batches in dynamic case', type=int, default=10)

    parser.add_argument('--alpha_zh', \
            help='Value of alpha_zh (alpha) hyper. Defaults to 50 / nz', \
            type=float, default=None)
    parser.add_argument('--beta_zs', help='Value of beta_zs (beta) hyper', \
            type=float, default=0.001)
    parser.add_argument('--beta_zd', help='Value of beta_zd (beta\') hyper', \
            type=float, default=0.001)

    parser.add_argument('--kernel', choices=kernels.names,
            help='The kernel to use', type=str, default='noop')
    parser.add_argument('--residency_priors', nargs='+',
            help='Priors for the residency time dist', type=float, default=None)

    parser.add_argument('--leaveout', \
            help='The number of transitions to leave for test', type=float, \
            default=0)

    args = parser.parse_args()

    comm = MPI.COMM_WORLD
    rank = comm.rank
    size = comm.size
    try:
        comm = MPI.COMM_WORLD
        rank = comm.rank
        size = comm.size
        single_thread = size == 1
    except:
        single_thread = True

    if not single_thread and rank != plearn.MASTER:
        plearn.work()
    else:
        num_lines = 0
        with open(args.trace_fpath) as trace_file:
            num_lines = sum(1 for _ in trace_file)

        if args.leaveout > 0:
            leave_out = min(1, args.leaveout)
            if leave_out == 1:
                print('Leave out is 1 (100%), nothing todo')
                return
            from_ = 0
            to = int(num_lines - num_lines * leave_out)
        else:
            from_ = 0
            to = np.inf

        if args.alpha_zh is None:
            alpha_zh = 50.0 / args.num_topics
        else:
            alpha_zh = args.alpha_zh

        kernel = kernels.names[args.kernel]()
        if args.residency_priors:
            residency_priors = np.array(args.residency_priors, dtype='d')
        else:
            residency_priors = np.zeros(shape=(0, ), dtype='d')

        if np.isinf(to):
            kernel.build(num_lines - from_, args.num_topics, residency_priors)
        else:
            kernel.build(to - from_, args.num_topics, residency_priors)

        if single_thread:
            print('Not on MPI mode or just one MPI proc, running single thread')
            single_thread = True

        if single_thread:
            rv = learn.fit(args.trace_fpath, args.num_topics, alpha_zh, \
                    args.beta_zs, args.beta_zd, kernel, residency_priors, \
                    args.num_iter, args.burn_in, from_=from_, to=to)
            dataio.save_model(args.model_fpath, rv)
        else:
            comm = MPI.COMM_WORLD
            rank = comm.rank
            dyn = args.dynamic
            if dyn:
                num_iter = args.num_iter // args.num_batches
                rv = dynamic.fit(args.trace_fpath, args.num_topics, alpha_zh, \
                        args.beta_zs, args.beta_zd, kernel, residency_priors, \
                        num_iter, args.num_batches, from_=from_, to=to)
            else:
                rv = plearn.fit(args.trace_fpath, args.num_topics, alpha_zh, \
                        args.beta_zs, args.beta_zd, kernel, residency_priors, \
                        args.num_iter, from_=from_, to=to)
            dataio.save_model(args.model_fpath, rv)

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import urllib
import urllib2
import json

# import the main window object (mw) from ankiqt
from aqt import mw
# import the "show info" tool from utils.py
from aqt.utils import showInfo
# import all of the Qt GUI library
from aqt.qt import *

def review_entries():
    review_images = imagesDialog()
    if not review_images.exec_():
        raise RuntimeError('User cancel')

def download_image_for_note():
    try:
        review_entries()
    except RuntimeError as rte:
        if 'cancel' in str(rte):
            # User cancelled, so close silently
            return
        else:
            #unhandled
            raise

class Browser(QWebView):

    def __init__(self):
        QWebView.__init__(self)
        self.loadFinished.connect(self._result_available)

    def _result_available(self, ok):
        frame = self.page().mainFrame()
        print unicode(frame.toHtml()).encode('utf-8')

class imagesDialog(QDialog):
    def __init__(self):
        super(imagesDialog, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle(_(u'Anki – Download images'))
        self.setWindowIcon(QIcon(":/icons/anki.png"))
        view = Browser()

        search_term = "fruit"
        url = "https://www.google.com/search?tbm=isch&q=" + search_term + "&oq=" + search_term
        view.load(QUrl(url))

        outer_layout = QVBoxLayout()
        self.setLayout(outer_layout)

        outer_layout.addWidget(view)

        # query = "sunshine"
        # search_results = bing_search(query, 'Image')

        # # Remplazar por QTreeWidget or QTableWidget
        # list = QListWidget(self)
        # #list.setDragDropMode(QAbstractItemView.NoDragDrop)
        # list.setUniformItemSizes(True)
        # list.setViewMode(1) # Set to icon view mode
        # list.setIconSize(QSize(200,200))
        # for result in search_results:
        #     item = QListWidgetItem()

        #     item.setText(result['Title'])
        #     image_data = urllib2.urlopen(result['Thumbnail']['MediaUrl']).read()
        #     qimage = QImage()
        #     qimage.loadFromData(image_data)

        #     item.setIcon(QIcon(QPixmap(qimage)))

        #     list.addItem(item)
        # outer_layout.addWidget(list)

try:
    mw.edit_media_submenu.addSeparator()
except AttributeError:
    mw.edit_media_submenu = QMenu(u"&Media", mw)
    mw.form.menuEdit.addSeparator()
    mw.form.menuEdit.addMenu(mw.edit_media_submenu)

# create a new menu item
mw.images_search_action = QAction(mw)
mw.images_search_action.setText(u"Note image")
# mw.note_download_action.setToolTip(
#     "Download images for all image fields on this note.")

# set it to call testFunction when it's clicked
mw.connect(mw.images_search_action, SIGNAL("triggered()"), download_image_for_note)

mw.edit_media_submenu.addAction(mw.images_search_action)
<commit_msg>Commit deletion of 'main.py' from commit 8c9b208a65d580e2b4a92d3e954cf4a805cfc28d<commit_after><|endoftext|>


<commit_before>from constants import IMAGE_WIDTH
from constants import IMAGE_HEIGHT
from constants import NUM_CHANNELS
from constants import NUM_ACTIONS
from constants import RESULT_DIRECTORY_NAME

import gflags
import sys
import os
import time
import re
import numpy as np
import tensorflow as tf
import a3c_network as a3c
import shared_network as shared
import actor_learner_thread as actor_thread
import ale_environment as ale

FLAGS = gflags.FLAGS
gflags.DEFINE_string('summary_dir', 'summary', 'Target summary directory')
gflags.DEFINE_string('checkpoint_dir', 'checkpoint', 'Target checkpoint directory')
gflags.DEFINE_string('rom', 'breakout.bin', 'Rom name to play')
gflags.DEFINE_integer('threads_num', 8, 'Threads to create')
gflags.DEFINE_integer('local_t_max', 20, 'batch size to use for training')
gflags.DEFINE_integer('global_t_max', 1e8, 'Max steps')
gflags.DEFINE_boolean('use_gpu', True, 'True to use gpu, False to use cpu')
gflags.DEFINE_boolean('shrink_image', False, 'Just shrink image for preprocessing')
gflags.DEFINE_boolean('life_lost_as_end', True, 'Treat live lost as end of episode')

checkpoint_dir = os.path.join(RESULT_DIRECTORY_NAME,  FLAGS.summary_dir)
summary_dir = os.path.join(RESULT_DIRECTORY_NAME,  FLAGS.checkpoint_dir)

def merged_summaries(maximum, median, average):
  max_summary = tf.scalar_summary('rewards max', maximum)
  med_summary = tf.scalar_summary('rewards med', median)
  avg_summary = tf.scalar_summary('rewards avg', average)
  return tf.merge_summary([max_summary, med_summary, avg_summary])

previous_time = time.time()
previous_step = 0
previous_evaluation_step = 0
evaluation_environment = ale.AleEnvironment(FLAGS.rom, record_display=False,
    show_display=True, id=100, shrink=FLAGS.shrink_image, life_lost_as_end=False)
def loop_listener(thread, iteration):
  global previous_time
  global previous_step
  global previous_evaluation_step
  global checkpoint_dir
  STEPS_PER_EPOCH = 1000000
  current_time = time.time()
  current_step = thread.get_global_step()
  elapsed_time = current_time - previous_time
  steps = (current_step - previous_step)
  print("itearation: %d, previous step: %d" % (iteration, previous_step))
  print("### Performance: {} steps in {:.5f} seconds. {:.0f} STEPS/s. {:.2f}M STEPS/hour".format(
    steps, elapsed_time, steps / elapsed_time, steps / elapsed_time * 3000 / 1000000.))
  previous_time = current_time
  previous_step = current_step
  if STEPS_PER_EPOCH < (current_step - previous_evaluation_step):
    previous_evaluation_step = current_step
    trials = 10
    rewards = thread.test_run(evaluation_environment, trials)
    maximum = np.max(rewards)
    median = np.median(rewards)
    average = np.average(rewards)
    epoch = current_step / STEPS_PER_EPOCH
    summary_writer.add_summary(session.run(summary_op,
      feed_dict={maximum_input: maximum, median_input: median, average_input: average}),
      epoch)
    print 'test run for epoch: %d. max: %d, med: %d, avg: %f' % (epoch, maximum, median, average)

    step = thread.get_global_step()
    print 'Save network parameters! step: %d' % step

    thread.save_parameters(checkpoint_dir + '/network_parameters', step)

def create_dir_if_not_exist(directory):
  if not os.path.exists(directory):
    os.makedirs(directory)

def remove_old_files(directory):
  for file in os.listdir(directory):
    os.remove(os.path.join(directory, file))

def write_training_settings(directory):
  file_path = os.path.join(directory, "settings.log")
  with open(file_path, "w") as f:
    flags = ['rom: ' + str(FLAGS.rom),
        'threads_num: ' + str(FLAGS.threads_num),
        'local_t_max: ' + str(FLAGS.local_t_max),
        'global_t_max: ' + str(FLAGS.global_t_max),
        'shrink_image: ' + str(FLAGS.shrink_image),
        'use_gpu: ' + str(FLAGS.use_gpu),
        'life_lost_as_end: ' + str(FLAGS.life_lost_as_end)]
    for flag in flags:
      line = f.write(flag + '\n')

if __name__ == '__main__':
  try:
    argv = FLAGS(sys.argv)
  except gflags.FlagsError:
    print 'Incompatible flags were specified'

  os.environ['OMP_NUM_THREADS'] = '1'

  graph = tf.Graph()
  config = tf.ConfigProto()

  # Output to tensorboard
  create_dir_if_not_exist(summary_dir)
  remove_old_files(summary_dir)
  summary_writer = tf.train.SummaryWriter(summary_dir, graph=graph)

  # Model parameter saving
  create_dir_if_not_exist(checkpoint_dir)
  remove_old_files(checkpoint_dir)

  write_training_settings(RESULT_DIRECTORY_NAME)

  networks = []
  shared_network = None
  summary_op = None

  with graph.as_default():
    maximum_input = tf.placeholder(tf.int32)
    median_input = tf.placeholder(tf.int32)
    average_input = tf.placeholder(tf.int32)
    summary_op = merged_summaries(maximum_input, median_input, average_input)
    device = '/gpu:0' if FLAGS.use_gpu else '/cpu:0'
    shared_network = shared.SharedNetwork(IMAGE_WIDTH, IMAGE_HEIGHT, NUM_CHANNELS, NUM_ACTIONS, 100,
        FLAGS.local_t_max, FLAGS.global_t_max, device)
    for i in range(FLAGS.threads_num):
      network = a3c.A3CNetwork(IMAGE_WIDTH, IMAGE_HEIGHT, NUM_CHANNELS, NUM_ACTIONS, i, device)
      networks.append(network)

  with tf.Session(graph=graph, config=config) as session:
    threads = []
    for thread_num in range(FLAGS.threads_num):
      show_display = True if (thread_num == 0) else False
      environment = ale.AleEnvironment(FLAGS.rom, record_display=False, show_display=show_display, id=thread_num, shrink=FLAGS.shrink_image)
      thread = actor_thread.ActorLearnerThread(session, environment, shared_network,
          networks[thread_num], FLAGS.local_t_max, FLAGS.global_t_max, thread_num)
      thread.daemon = True
      if thread_num == 0:
        thread.set_loop_listener(loop_listener)
      threads.append(thread)

    session.run(tf.initialize_all_variables())

    for i in range(FLAGS.threads_num):
      threads[i].start()

    while True:
      try:
        ts = [thread.join(10) for thread in threads if thread is not None and thread.isAlive()]
      except KeyboardInterrupt:
        print 'Ctrl-c received! Sending kill to threads...'
        for thread in threads:
          thread.kill_received = True
        break

    print 'Training finished!!'
<commit_msg>Add set saver to each thread<commit_after>from constants import IMAGE_WIDTH
from constants import IMAGE_HEIGHT
from constants import NUM_CHANNELS
from constants import NUM_ACTIONS
from constants import RESULT_DIRECTORY_NAME

import gflags
import sys
import os
import time
import re
import numpy as np
import tensorflow as tf
import a3c_network as a3c
import shared_network as shared
import actor_learner_thread as actor_thread
import ale_environment as ale

FLAGS = gflags.FLAGS
gflags.DEFINE_string('summary_dir', 'summary', 'Target summary directory')
gflags.DEFINE_string('checkpoint_dir', 'checkpoint', 'Target checkpoint directory')
gflags.DEFINE_string('rom', 'breakout.bin', 'Rom name to play')
gflags.DEFINE_integer('threads_num', 8, 'Threads to create')
gflags.DEFINE_integer('local_t_max', 20, 'batch size to use for training')
gflags.DEFINE_integer('global_t_max', 1e8, 'Max steps')
gflags.DEFINE_boolean('use_gpu', True, 'True to use gpu, False to use cpu')
gflags.DEFINE_boolean('shrink_image', False, 'Just shrink image for preprocessing')
gflags.DEFINE_boolean('life_lost_as_end', True, 'Treat live lost as end of episode')

checkpoint_dir = os.path.join(RESULT_DIRECTORY_NAME,  FLAGS.summary_dir)
summary_dir = os.path.join(RESULT_DIRECTORY_NAME,  FLAGS.checkpoint_dir)

def merged_summaries(maximum, median, average):
  max_summary = tf.scalar_summary('rewards max', maximum)
  med_summary = tf.scalar_summary('rewards med', median)
  avg_summary = tf.scalar_summary('rewards avg', average)
  return tf.merge_summary([max_summary, med_summary, avg_summary])

previous_time = time.time()
previous_step = 0
previous_evaluation_step = 0
evaluation_environment = ale.AleEnvironment(FLAGS.rom, record_display=False,
    show_display=True, id=100, shrink=FLAGS.shrink_image, life_lost_as_end=False)
def loop_listener(thread, iteration):
  global previous_time
  global previous_step
  global previous_evaluation_step
  global checkpoint_dir
  STEPS_PER_EPOCH = 1000000
  current_time = time.time()
  current_step = thread.get_global_step()
  elapsed_time = current_time - previous_time
  steps = (current_step - previous_step)
  print("itearation: %d, previous step: %d" % (iteration, previous_step))
  print("### Performance: {} steps in {:.5f} seconds. {:.0f} STEPS/s. {:.2f}M STEPS/hour".format(
    steps, elapsed_time, steps / elapsed_time, steps / elapsed_time * 3000 / 1000000.))
  previous_time = current_time
  previous_step = current_step
  if STEPS_PER_EPOCH < (current_step - previous_evaluation_step):
    previous_evaluation_step = current_step
    trials = 10
    rewards = thread.test_run(evaluation_environment, trials)
    maximum = np.max(rewards)
    median = np.median(rewards)
    average = np.average(rewards)
    epoch = current_step / STEPS_PER_EPOCH
    summary_writer.add_summary(session.run(summary_op,
      feed_dict={maximum_input: maximum, median_input: median, average_input: average}),
      epoch)
    print 'test run for epoch: %d. max: %d, med: %d, avg: %f' % (epoch, maximum, median, average)

    step = thread.get_global_step()
    print 'Save network parameters! step: %d' % step

    thread.save_parameters(checkpoint_dir + '/network_parameters', step)

def create_dir_if_not_exist(directory):
  if not os.path.exists(directory):
    os.makedirs(directory)

def remove_old_files(directory):
  for file in os.listdir(directory):
    os.remove(os.path.join(directory, file))

def write_training_settings(directory):
  file_path = os.path.join(directory, "settings.log")
  with open(file_path, "w") as f:
    flags = ['rom: ' + str(FLAGS.rom),
        'threads_num: ' + str(FLAGS.threads_num),
        'local_t_max: ' + str(FLAGS.local_t_max),
        'global_t_max: ' + str(FLAGS.global_t_max),
        'shrink_image: ' + str(FLAGS.shrink_image),
        'use_gpu: ' + str(FLAGS.use_gpu),
        'life_lost_as_end: ' + str(FLAGS.life_lost_as_end)]
    for flag in flags:
      line = f.write(flag + '\n')

if __name__ == '__main__':
  try:
    argv = FLAGS(sys.argv)
  except gflags.FlagsError:
    print 'Incompatible flags were specified'

  os.environ['OMP_NUM_THREADS'] = '1'

  graph = tf.Graph()
  config = tf.ConfigProto()

  # Output to tensorboard
  create_dir_if_not_exist(summary_dir)
  remove_old_files(summary_dir)
  summary_writer = tf.train.SummaryWriter(summary_dir, graph=graph)

  # Model parameter saving
  create_dir_if_not_exist(checkpoint_dir)
  remove_old_files(checkpoint_dir)

  write_training_settings(RESULT_DIRECTORY_NAME)

  networks = []
  shared_network = None
  summary_op = None

  with graph.as_default():
    maximum_input = tf.placeholder(tf.int32)
    median_input = tf.placeholder(tf.int32)
    average_input = tf.placeholder(tf.int32)
    summary_op = merged_summaries(maximum_input, median_input, average_input)
    device = '/gpu:0' if FLAGS.use_gpu else '/cpu:0'
    shared_network = shared.SharedNetwork(IMAGE_WIDTH, IMAGE_HEIGHT, NUM_CHANNELS, NUM_ACTIONS, 100,
        FLAGS.local_t_max, FLAGS.global_t_max, device)
    for i in range(FLAGS.threads_num):
      network = a3c.A3CNetwork(IMAGE_WIDTH, IMAGE_HEIGHT, NUM_CHANNELS, NUM_ACTIONS, i, device)
      networks.append(network)
    saver = tf.train.Saver(max_to_keep=None)

  with tf.Session(graph=graph, config=config) as session:
    threads = []
    for thread_num in range(FLAGS.threads_num):
      show_display = True if (thread_num == 0) else False
      environment = ale.AleEnvironment(FLAGS.rom, record_display=False, show_display=show_display, id=thread_num, shrink=FLAGS.shrink_image)
      thread = actor_thread.ActorLearnerThread(session, environment, shared_network,
          networks[thread_num], FLAGS.local_t_max, FLAGS.global_t_max, thread_num)
      thread.set_saver = saver
      thread.daemon = True
      if thread_num == 0:
        thread.set_loop_listener(loop_listener)
      threads.append(thread)

    session.run(tf.initialize_all_variables())

    for i in range(FLAGS.threads_num):
      threads[i].start()

    while True:
      try:
        ts = [thread.join(10) for thread in threads if thread is not None and thread.isAlive()]
      except KeyboardInterrupt:
        print 'Ctrl-c received! Sending kill to threads...'
        for thread in threads:
          thread.kill_received = True
        break

    print 'Training finished!!'
<|endoftext|>


<commit_before>#!/usr/bin/env python
#Copyright (c) 2011 Walter Bender

#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:

#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.

#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.

from taconstants import BLOCK_STYLES, BLOCK_NAMES, HELP_STRINGS, PALETTES, \
    PALETTE_NAMES, CONTENT_BLOCKS, PRIMITIVES, DEFAULTS, SPECIAL_NAMES, \
    COLORS, EXPANDABLE_STYLE, EXPANDABLE_BLOCKS
from talogo import VALUE_BLOCKS
from tautils import debug_output

class Palette():
    """ a class for defining new palettes """

    def __init__(self, name, colors=["#00FF00", "#00A000"], position=None):
        self._name = name
        self._special_name = name
        self._colors = colors
        self._help = None

    def add_palette(self, position=None):
        if self._name is None:
            debug_output('You must specify a name for your palette')
            return

        # Insert new palette just before the trash
        if 'trash' in PALETTE_NAMES:
            i = PALETTE_NAMES.index('trash')
        else:
            i = len(PALETTE_NAMES)

        if position is not None and type(position) is int and position < i:
            i = position

        if self._name not in PALETTE_NAMES:
            PALETTE_NAMES.insert(i, self._name)
            PALETTES.insert(i, [])
            COLORS.insert(i, self._colors)
        else:
            # debug_output('Palette %s already defined' % (self._name))
            return

        # Special name entry is needed for help hover mechanism
        SPECIAL_NAMES[self._name] = self._special_name
        if self._help is not None:
            HELP_STRINGS[self._name] = self._help
        else:
            HELP_STRINGS[self._name] = ''

    def set_help(self, help):
        self._help = help

    def set_special_name(self, name):
        self._special_name = name

class Primitive():
    """ a class for defining new block primitives """

    def __init__(self, name):
        self._name = name
        self._special_name = None
        self._palette = None
        self._style = None
        self._label = None
        self._default = None
        self._help = None
        self._prim_name = None
        self._value_block = False
        self._content_block = False

    def add_prim(self, position=None):
        if self._name is None:
            debug_output('You must specify a name for your block')
            return

        if self._style is None:
            debug_output('You must specify a style for your block')
            return
        else:
            BLOCK_STYLES[self._style].append(self._name)

        if self._label is not None:
            BLOCK_NAMES[self._name] = self._label

        if self._palette is not None:
            i = PALETTE_NAMES.index(self._palette)
            if position is not None and type(position) is int and \
                    position < len(PALETTES[i]):
                PALETTES[i].insert(position, self._name)
            else:
                PALETTES[i].append(self._name)
                if position is not None:
                    debug_output('Ignoring position (%s)' % (str(position)))

        if self._help is not None:
            HELP_STRINGS[self._name] = self._help
        else:
            HELP_STRINGS[self._name] = ''

        if self._value_block:
            VALUE_BLOCKS.append(self._name)

        if self._content_block:
            CONTENT_BLOCKS.append(self._name)

        if self._prim_name is not None:
            PRIMITIVES[self._name] = self._prim_name

        if self._default is not None:
            DEFAULTS[self._name] = self._default

        if self._special_name is not None:
            SPECIAL_NAMES[self._name] = self._special_name

        if self._style in EXPANDABLE_STYLE:
            EXPANDABLE_BLOCKS.append(self._name)

    def set_value_block(self, value=True):
        self._value_block = value

    def set_content_block(self, value=True):
        self._content_block = value

    def set_palette(self, palette):
        if not palette in PALETTE_NAMES:
            debug_output('Could not find palette %s' % (palette))
        else:
            self._palette = palette

    def set_help(self, help):
        self._help = help

    def set_special_name(self, name):
        self._special_name = name

    def set_label(self, label):
        if type(label) == type([]):
            self._label = label[:]
        else:
            self._label = [label]

    def set_default(self, default):
        if type(default) == type([]):
            self._default = default[:]
        else:
            self._default = [default]

    def set_style(self, style):
        if style not in BLOCK_STYLES:
            debug_output('Unknown style: %s' % (style))
        else:
            self._style = style

    def set_prim_name(self, prim_name):
        self._prim_name = prim_name

def make_prim(block_name, style='basic-block', palette=None, label=None,
              special_name=None, default=None, prim_name=None,
              help_string=None, value_block=False):
    """ Block factory """
    b = Primitive(block_name)
    b.set_style(style)
    if palette is not None:
        b.set_palette(palette)
    if label is not None:
        b.set_label(label)
    if special_name is not None:
        b.set_special_name(special_name)
    if default is not None:
        b.set_default(default)
    if prim_name is not None:
        b.set_prim_name(prim_name)
    if help_string is not None:
        b.set_help(help_string)
    b.set_value_block(value_block)
    b.add_prim()
<commit_msg>allow for setting None as default<commit_after>#!/usr/bin/env python
#Copyright (c) 2011 Walter Bender

#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:

#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.

#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.

from taconstants import BLOCK_STYLES, BLOCK_NAMES, HELP_STRINGS, PALETTES, \
    PALETTE_NAMES, CONTENT_BLOCKS, PRIMITIVES, DEFAULTS, SPECIAL_NAMES, \
    COLORS, EXPANDABLE_STYLE, EXPANDABLE_BLOCKS
from talogo import VALUE_BLOCKS
from tautils import debug_output

class Palette():
    """ a class for defining new palettes """

    def __init__(self, name, colors=["#00FF00", "#00A000"], position=None):
        self._name = name
        self._special_name = name
        self._colors = colors
        self._help = None

    def add_palette(self, position=None):
        if self._name is None:
            debug_output('You must specify a name for your palette')
            return

        # Insert new palette just before the trash
        if 'trash' in PALETTE_NAMES:
            i = PALETTE_NAMES.index('trash')
        else:
            i = len(PALETTE_NAMES)

        if position is not None and type(position) is int and position < i:
            i = position

        if self._name not in PALETTE_NAMES:
            PALETTE_NAMES.insert(i, self._name)
            PALETTES.insert(i, [])
            COLORS.insert(i, self._colors)
        else:
            # debug_output('Palette %s already defined' % (self._name))
            return

        # Special name entry is needed for help hover mechanism
        SPECIAL_NAMES[self._name] = self._special_name
        if self._help is not None:
            HELP_STRINGS[self._name] = self._help
        else:
            HELP_STRINGS[self._name] = ''

    def set_help(self, help):
        self._help = help

    def set_special_name(self, name):
        self._special_name = name

class Primitive():
    """ a class for defining new block primitives """

    def __init__(self, name):
        self._name = name
        self._special_name = None
        self._palette = None
        self._style = None
        self._label = None
        self._default = None
        self._help = None
        self._prim_name = None
        self._value_block = False
        self._content_block = False

    def add_prim(self, position=None):
        if self._name is None:
            debug_output('You must specify a name for your block')
            return

        if self._style is None:
            debug_output('You must specify a style for your block')
            return
        else:
            BLOCK_STYLES[self._style].append(self._name)

        if self._label is not None:
            BLOCK_NAMES[self._name] = self._label

        if self._palette is not None:
            i = PALETTE_NAMES.index(self._palette)
            if position is not None and type(position) is int and \
                    position < len(PALETTES[i]):
                PALETTES[i].insert(position, self._name)
            else:
                PALETTES[i].append(self._name)
                if position is not None:
                    debug_output('Ignoring position (%s)' % (str(position)))

        if self._help is not None:
            HELP_STRINGS[self._name] = self._help
        else:
            HELP_STRINGS[self._name] = ''

        if self._value_block:
            VALUE_BLOCKS.append(self._name)

        if self._content_block:
            CONTENT_BLOCKS.append(self._name)

        if self._prim_name is not None:
            PRIMITIVES[self._name] = self._prim_name

        if self._default is not None:
            DEFAULTS[self._name] = self._default

        if self._special_name is not None:
            SPECIAL_NAMES[self._name] = self._special_name

        if self._style in EXPANDABLE_STYLE:
            EXPANDABLE_BLOCKS.append(self._name)

    def set_value_block(self, value=True):
        self._value_block = value

    def set_content_block(self, value=True):
        self._content_block = value

    def set_palette(self, palette):
        if not palette in PALETTE_NAMES:
            debug_output('Could not find palette %s' % (palette))
        else:
            self._palette = palette

    def set_help(self, help):
        self._help = help

    def set_special_name(self, name):
        self._special_name = name

    def set_label(self, label):
        if type(label) == type([]):
            self._label = label[:]
        else:
            self._label = [label]

    def set_default(self, default):
        if type(default) == type([]):
            self._default = default[:]
        else:
            self._default = [default]

    def set_style(self, style):
        if style not in BLOCK_STYLES:
            debug_output('Unknown style: %s' % (style))
        else:
            self._style = style

    def set_prim_name(self, prim_name):
        self._prim_name = prim_name

def make_prim(block_name, style='basic-block', palette=None, label=None,
              special_name=None, default=None, prim_name=None,
              help_string=None, value_block=False, content_block=False):
    """ Block factory """
    b = Primitive(block_name)
    b.set_style(style)
    if palette is not None:
        b.set_palette(palette)
    if label is not None:
        b.set_label(label)
    if special_name is not None:
        b.set_special_name(special_name)
    if default is not None:
        if default == 'None':
            b.set_default(None)
        else:
            b.set_default(default)
    if prim_name is not None:
        b.set_prim_name(prim_name)
    if help_string is not None:
        b.set_help(help_string)
    b.set_value_block(value_block)
    b.set_content_block(content_block)
    b.add_prim()
<|endoftext|>


<commit_before>#! /usr/bin/env python
import os
import argparse
import datetime
import torch
import torchtext.data as data
import torchtext.datasets as datasets
import model
import train
import mydatasets
import pdb
import vpdataset

parser = argparse.ArgumentParser(description='CNN text classificer')
# learning
parser.add_argument('-lr', type=float, default=0.001, help='initial learning rate [default: 0.001]')
parser.add_argument('-l2', type=float, default=1e-6, help='l2 regularization strength [default: 1e-6]')
parser.add_argument('-epochs', type=int, default=256, help='number of epochs for train [default: 256]')
parser.add_argument('-batch-size', type=int, default=64, help='batch size for training [default: 64]')
parser.add_argument('-log-interval',  type=int, default=1, help='how many steps to wait before logging training status [default: 1]')
parser.add_argument('-log-file', type=str, default='result.txt', help='the name of the file to store results')
parser.add_argument('-verbose', action='store_true', default=False, help='logging verbose info of training process')
# parser.add_argument('-verbose-interval', type=int, default=5000, help='steps between two verbose logging')
parser.add_argument('-test-interval', type=int, default=100, help='how many steps to wait before testing [default: 100]')
parser.add_argument('-eval-on-test', action='store_true', default=False, help='run evaluation on test data?')
parser.add_argument('-save-interval', type=int, default=500, help='how many steps to wait before saving [default:500]')
parser.add_argument('-save-dir', type=str, default='snapshot', help='where to save the snapshot')
# data
parser.add_argument('-shuffle', action='store_true', default=False, help='shuffle the data every epoch' )
# model
parser.add_argument('-dropout', type=float, default=0.5, help='the probability for dropout [default: 0.5]')
parser.add_argument('-max-norm', type=float, default=0.0, help='l2 constraint of parameters [default: 0.0]')
parser.add_argument('-char-embed-dim', type=int, default=128, help='number of char embedding dimension [default: 128]')
parser.add_argument('-word-embed-dim', type=int, default=300, help='number of word embedding dimension [default: 300]')
parser.add_argument('-kernel-num', type=int, default=100, help='number of each kind of kernel')
#parser.add_argument('-kernel-sizes', type=str, default='3,4,5', help='comma-separated kernel size to use for convolution')
parser.add_argument('-char-kernel-sizes', type=str, default='3', help='comma-separated kernel size to use for char convolution')
parser.add_argument('-word-kernel-sizes', type=str, default='1', help='comma-separated kernel size to use for word convolution')
parser.add_argument('-static', action='store_true', default=False, help='fix the embedding')
# device
parser.add_argument('-device', type=int, default=-1, help='device to use for iterate data, -1 mean cpu [default: -1]')
parser.add_argument('-yes-cuda', action='store_true', default=False, help='disable the gpu' )
# option
parser.add_argument('-snapshot', type=str, default=None, help='filename of model snapshot [default: None]')
parser.add_argument('-predict', type=str, default=None, help='predict the sentence given')
parser.add_argument('-test', action='store_true', default=False, help='train or test')
parser.add_argument('-xfolds', type=int, default=10, help='number of folds for cross-validation')
parser.add_argument('-layer-num', type=int, default=2, help='the number of layers in the final MLP')
parser.add_argument('-word-vector', type=str, default='', help="use of vectors [default: None. options: 'glove' or 'w2v']")
parser.add_argument('-emb-path', type=str, default=os.getcwd(), help="the path to the w2v file")
parser.add_argument('-min-freq', type=int, default=1, help='minimal frequency to be added to vocab')
args = parser.parse_args()

if args.word_vector == 'glove':
    args.word_vector = 'glove.6B'
elif args.word_vector == 'w2v':
    if args.word_embed_dim != 300:
        raise Exception("w2v has no other kind of vectors than 300")
else: args.word_vector = None

# load SST dataset
def sst(text_field, label_field,  **kargs):
    train_data, dev_data, test_data = datasets.SST.splits(text_field, label_field, fine_grained=True)
    text_field.build_vocab(train_data, dev_data, test_data)
    label_field.build_vocab(train_data, dev_data, test_data)
    train_iter, dev_iter, test_iter = data.BucketIterator.splits(
                                        (train_data, dev_data, test_data),
                                        batch_sizes=(args.batch_size,
                                                     len(dev_data),
                                                     len(test_data)),
                                        **kargs)
    return train_iter, dev_iter, test_iter

# load MR dataset
def mr(text_field, label_field, **kargs):
    train_data, dev_data = mydatasets.MR.splits(text_field, label_field)
    text_field.build_vocab(train_data, dev_data)
    label_field.build_vocab(train_data, dev_data)
    train_iter, dev_iter = data.Iterator.splits(
                                (train_data, dev_data),
                                batch_sizes=(args.batch_size, len(dev_data)),
                                **kargs)
    return train_iter, dev_iter

#load VP dataset
def vp(text_field, label_field, foldid, **kargs):
    train_data, dev_data, test_data = vpdataset.VP.splits(text_field, label_field, foldid=foldid)
    text_field.build_vocab(train_data, wv_type=kargs["wv_type"], wv_dim=kargs["wv_dim"], wv_dir=kargs["wv_dir"], min_freq=kargs['min_freq'])
    label_field.build_vocab(train_data)
    kargs.pop('wv_type')
    kargs.pop('wv_dim')
    kargs.pop('wv_dir')
    kargs.pop("min_freq")
    train_iter, dev_iter, test_iter = data.Iterator.splits(
                                        (train_data, dev_data, test_data),
                                        batch_sizes=(args.batch_size,
                                                     len(dev_data),
                                                     len(test_data)),
                                        **kargs)
    return train_iter, dev_iter, test_iter

def char_tokenizer(mstring):
    return list(mstring)

print("Beginning {0}-fold cross-validation...".format(args.xfolds))
print("Logging the results in {}".format(args.log_file))
log_file_handle = open(args.log_file, 'w')
char_fold_accuracies = []
word_fold_accuracies = []
ensemble_fold_accuracies = []
orig_save_dir = args.save_dir
update_args = True

max_kernel_length = max([int(x) for x in args.word_kernel_sizes.split(',')])

for xfold in range(args.xfolds):
    print("Fold {0}".format(xfold))
    # load data
    print("\nLoading data...")

    #text_field = data.Field(lower=True)
    #label_field = data.Field(sequential=False)
    #train_iter, dev_iter = mr(text_field, label_field, device=-1, repeat=False)
    #train_iter, dev_iter, test_iter = sst(text_field, label_field, device=-1, repeat=False)

    text_field = data.Field(lower=True, tokenize=char_tokenizer)
    word_field = data.Field(lower=True, fix_length=max_kernel_length )

    label_field = data.Field(sequential=False)
    train_iter, dev_iter, test_iter = vp(text_field, label_field, foldid=xfold, device=args.device, repeat=False, shuffle=False, sort=False
                                         , wv_type=None, wv_dim=None, wv_dir=None, min_freq=1)
    train_iter_word, dev_iter_word, test_iter_word = vp(word_field, label_field, foldid=xfold, device=args.device,
                                                        repeat=False, shuffle=False, sort=False, wv_type=args.word_vector,
                                                        wv_dim=args.word_embed_dim, wv_dir=args.emb_path, min_freq=args.min_freq)

    args.embed_num = len(text_field.vocab)
    args.class_num = len(label_field.vocab) - 1
    args.cuda = args.yes_cuda and torch.cuda.is_available()#; del args.no_cuda
    if update_args==True:
        args.char_kernel_sizes = [int(k) for k in args.char_kernel_sizes.split(',')]
        args.save_dir = os.path.join(args.save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'CHAR')
    else:
        args.save_dir = os.path.join(orig_save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'CHAR')

    print("\nParameters:", file=log_file_handle)
    for attr, value in sorted(args.__dict__.items()):
        print("\t{}={}".format(attr.upper(), value), file=log_file_handle)

    # char CNN training and dev
    if args.snapshot is None:
        char_cnn = model.CNN_Text(args, 'char')
    else :
        print('\nLoading model from [%s]...' % args.snapshot)
        try:
            char_cnn = torch.load(args.snapshot)
        except :
            print("Sorry, This snapshot doesn't exist."); exit()

    train.train(train_iter, dev_iter, char_cnn, args, log_file_handle=log_file_handle)
    if args.eval_on_test:
        result = train.eval(test_iter, char_cnn, args, log_file_handle=log_file_handle)
        char_fold_accuracies.append(result)
        print("Completed fold {0}. Accuracy on Test: {1} for CHAR".format(xfold, result))
        print("Completed fold {0}. Accuracy on Test: {1} for CHAR".format(xfold, result), file=log_file_handle)

    # Word CNN training and dev
    args.embed_num = len(word_field.vocab)
    if update_args==True:
        # args.kernel_sizes = [int(k) for k in args.kernel_sizes.split(',')]
        args.word_kernel_sizes = [int(k) for k in args.word_kernel_sizes.split(',')]
        args.save_dir = os.path.join(args.save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'WORD')
    else:
        args.save_dir = os.path.join(orig_save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'WORD')
    # print("\nParameters:")
    # for attr, value in sorted(args.__dict__.items()):
    #     print("\t{}={}".format(attr.upper(), value))

    if args.snapshot is None:
        word_cnn = model.CNN_Text(args, 'word', vectors =word_field.vocab.vectors)
    else :
        print('\nLoading model from [%s]...' % args.snapshot)
        try:
            word_cnn = torch.load(args.snapshot)
        except:
            print("Sorry, This snapshot doesn't exist."); exit()

    train.train(train_iter_word, dev_iter_word, word_cnn, args, log_file_handle=log_file_handle)
    if args.eval_on_test:
        result = train.eval(test_iter_word, word_cnn, args, log_file_handle=log_file_handle)
        word_fold_accuracies.append(result)
        print("Completed fold {0}. Accuracy on Test: {1} for WORD".format(xfold, result))
        print("Completed fold {0}. Accuracy on Test: {1} for WORD".format(xfold, result), file=log_file_handle)

    # Ensemble training and dev
    if update_args==True:
        args.save_dir = os.path.join(args.save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'LOGIT')
    else:
        args.save_dir = os.path.join(orig_save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'LOGIT')
    update_args = False

    if args.snapshot is None:
        final_logit = model.SimpleLogistic(args)
    else :
        print('\nLoading model from [%s]...' % args.snapshot)
        try:
            final_logit = torch.load(args.snapshot)
        except:
            print("Sorry, This snapshot doesn't exist."); exit()

    # train_iter, dev_iter, test_iter = vp(text_field, label_field, foldid=xfold, device=-1, repeat=False)
    # train_iter_word, dev_iter_word, test_iter_word = vp(word_field, label_field, foldid=xfold, device=-1, repeat=False)

    train.train_logistic(train_iter, dev_iter, train_iter_word, dev_iter_word, char_cnn, word_cnn, final_logit, args, log_file_handle=log_file_handle)
    if args.eval_on_test:
        result = train.eval_logistic(test_iter, test_iter_word, char_cnn, word_cnn, final_logit, args, log_file_handle=log_file_handle)
        ensemble_fold_accuracies.append(result)

        print("Completed fold {0}. Accuracy on Test: {1} for LOGIT".format(xfold, result))
        print("Completed fold {0}. Accuracy on Test: {1} for LOGIT".format(xfold, result), file=log_file_handle)
    """
    # train or predict
    if args.predict is not None:
        label = train.predict(args.predict, cnn, text_field, label_field)
        print('\n[Text]  {}[Label] {}\n'.format(args.predict, label))
    elif args.test :
        try:
            train.eval(test_iter, cnn, args)
        except Exception as e:
            print("\nSorry. The test dataset doesn't  exist.\n")
    else :
        print()
        train.train(train_iter, dev_iter, cnn, args)
    """
    log_file_handle.flush()

average_xfold_accuracy = sum([res for res in ensemble_fold_accuracies]) / len(ensemble_fold_accuracies)
print("folds: {0}".format(len(ensemble_fold_accuracies)))
print("Average cross-fold accuracy: {0}".format(average_xfold_accuracy))
log_file_handle.close()<commit_msg>min freq<commit_after>#! /usr/bin/env python
import os
import argparse
import datetime
import torch
import torchtext.data as data
import torchtext.datasets as datasets
import model
import train
import mydatasets
import pdb
import vpdataset

parser = argparse.ArgumentParser(description='CNN text classificer')
# learning
parser.add_argument('-lr', type=float, default=0.001, help='initial learning rate [default: 0.001]')
parser.add_argument('-l2', type=float, default=1e-6, help='l2 regularization strength [default: 1e-6]')
parser.add_argument('-epochs', type=int, default=256, help='number of epochs for train [default: 256]')
parser.add_argument('-batch-size', type=int, default=64, help='batch size for training [default: 64]')
parser.add_argument('-log-interval',  type=int, default=1, help='how many steps to wait before logging training status [default: 1]')
parser.add_argument('-log-file', type=str, default='result.txt', help='the name of the file to store results')
parser.add_argument('-verbose', action='store_true', default=False, help='logging verbose info of training process')
# parser.add_argument('-verbose-interval', type=int, default=5000, help='steps between two verbose logging')
parser.add_argument('-test-interval', type=int, default=100, help='how many steps to wait before testing [default: 100]')
parser.add_argument('-eval-on-test', action='store_true', default=False, help='run evaluation on test data?')
parser.add_argument('-save-interval', type=int, default=500, help='how many steps to wait before saving [default:500]')
parser.add_argument('-save-dir', type=str, default='snapshot', help='where to save the snapshot')
# data
parser.add_argument('-shuffle', action='store_true', default=False, help='shuffle the data every epoch' )
# model
parser.add_argument('-dropout', type=float, default=0.5, help='the probability for dropout [default: 0.5]')
parser.add_argument('-max-norm', type=float, default=0.0, help='l2 constraint of parameters [default: 0.0]')
parser.add_argument('-char-embed-dim', type=int, default=128, help='number of char embedding dimension [default: 128]')
parser.add_argument('-word-embed-dim', type=int, default=300, help='number of word embedding dimension [default: 300]')
parser.add_argument('-kernel-num', type=int, default=100, help='number of each kind of kernel')
#parser.add_argument('-kernel-sizes', type=str, default='3,4,5', help='comma-separated kernel size to use for convolution')
parser.add_argument('-char-kernel-sizes', type=str, default='3', help='comma-separated kernel size to use for char convolution')
parser.add_argument('-word-kernel-sizes', type=str, default='1', help='comma-separated kernel size to use for word convolution')
parser.add_argument('-static', action='store_true', default=False, help='fix the embedding')
# device
parser.add_argument('-device', type=int, default=-1, help='device to use for iterate data, -1 mean cpu [default: -1]')
parser.add_argument('-yes-cuda', action='store_true', default=False, help='disable the gpu' )
# option
parser.add_argument('-snapshot', type=str, default=None, help='filename of model snapshot [default: None]')
parser.add_argument('-predict', type=str, default=None, help='predict the sentence given')
parser.add_argument('-test', action='store_true', default=False, help='train or test')
parser.add_argument('-xfolds', type=int, default=10, help='number of folds for cross-validation')
parser.add_argument('-layer-num', type=int, default=2, help='the number of layers in the final MLP')
parser.add_argument('-word-vector', type=str, default='', help="use of vectors [default: None. options: 'glove' or 'w2v']")
parser.add_argument('-emb-path', type=str, default=os.getcwd(), help="the path to the w2v file")
parser.add_argument('-min-freq', type=int, default=1, help='minimal frequency to be added to vocab')
args = parser.parse_args()

if args.word_vector == 'glove':
    args.word_vector = 'glove.6B'
elif args.word_vector == 'w2v':
    if args.word_embed_dim != 300:
        raise Exception("w2v has no other kind of vectors than 300")
else: args.word_vector = None

# load SST dataset
def sst(text_field, label_field,  **kargs):
    train_data, dev_data, test_data = datasets.SST.splits(text_field, label_field, fine_grained=True)
    text_field.build_vocab(train_data, dev_data, test_data)
    label_field.build_vocab(train_data, dev_data, test_data)
    train_iter, dev_iter, test_iter = data.BucketIterator.splits(
                                        (train_data, dev_data, test_data),
                                        batch_sizes=(args.batch_size,
                                                     len(dev_data),
                                                     len(test_data)),
                                        **kargs)
    return train_iter, dev_iter, test_iter

# load MR dataset
def mr(text_field, label_field, **kargs):
    train_data, dev_data = mydatasets.MR.splits(text_field, label_field)
    text_field.build_vocab(train_data, dev_data)
    label_field.build_vocab(train_data, dev_data)
    train_iter, dev_iter = data.Iterator.splits(
                                (train_data, dev_data),
                                batch_sizes=(args.batch_size, len(dev_data)),
                                **kargs)
    return train_iter, dev_iter

#load VP dataset
def vp(text_field, label_field, foldid, **kargs):
    train_data, dev_data, test_data = vpdataset.VP.splits(text_field, label_field, foldid=foldid)
    text_field.build_vocab(train_data, wv_type=kargs["wv_type"], wv_dim=kargs["wv_dim"], wv_dir=kargs["wv_dir"], min_freq=kargs['min_freq'])
    label_field.build_vocab(train_data, dev_data, test_data)
    kargs.pop('wv_type')
    kargs.pop('wv_dim')
    kargs.pop('wv_dir')
    kargs.pop("min_freq")
    train_iter, dev_iter, test_iter = data.Iterator.splits(
                                        (train_data, dev_data, test_data),
                                        batch_sizes=(args.batch_size,
                                                     len(dev_data),
                                                     len(test_data)),
                                        **kargs)
    return train_iter, dev_iter, test_iter

def char_tokenizer(mstring):
    return list(mstring)

print("Beginning {0}-fold cross-validation...".format(args.xfolds))
print("Logging the results in {}".format(args.log_file))
log_file_handle = open(args.log_file, 'w')
char_fold_accuracies = []
word_fold_accuracies = []
ensemble_fold_accuracies = []
orig_save_dir = args.save_dir
update_args = True

max_kernel_length = max([int(x) for x in args.word_kernel_sizes.split(',')])

for xfold in range(args.xfolds):
    print("Fold {0}".format(xfold))
    # load data
    print("\nLoading data...")

    #text_field = data.Field(lower=True)
    #label_field = data.Field(sequential=False)
    #train_iter, dev_iter = mr(text_field, label_field, device=-1, repeat=False)
    #train_iter, dev_iter, test_iter = sst(text_field, label_field, device=-1, repeat=False)

    text_field = data.Field(lower=True, tokenize=char_tokenizer)
    word_field = data.Field(lower=True, fix_length=max_kernel_length )

    label_field = data.Field(sequential=False)
    train_iter, dev_iter, test_iter = vp(text_field, label_field, foldid=xfold, device=args.device, repeat=False, shuffle=False, sort=False
                                         , wv_type=None, wv_dim=None, wv_dir=None, min_freq=1)
    train_iter_word, dev_iter_word, test_iter_word = vp(word_field, label_field, foldid=xfold, device=args.device,
                                                        repeat=False, shuffle=False, sort=False, wv_type=args.word_vector,
                                                        wv_dim=args.word_embed_dim, wv_dir=args.emb_path, min_freq=args.min_freq)

    args.embed_num = len(text_field.vocab)
    args.class_num = len(label_field.vocab) - 1
    args.cuda = args.yes_cuda and torch.cuda.is_available()#; del args.no_cuda
    if update_args==True:
        args.char_kernel_sizes = [int(k) for k in args.char_kernel_sizes.split(',')]
        args.save_dir = os.path.join(args.save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'CHAR')
    else:
        args.save_dir = os.path.join(orig_save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'CHAR')

    print("\nParameters:", file=log_file_handle)
    for attr, value in sorted(args.__dict__.items()):
        print("\t{}={}".format(attr.upper(), value), file=log_file_handle)

    # char CNN training and dev
    if args.snapshot is None:
        char_cnn = model.CNN_Text(args, 'char')
    else :
        print('\nLoading model from [%s]...' % args.snapshot)
        try:
            char_cnn = torch.load(args.snapshot)
        except :
            print("Sorry, This snapshot doesn't exist."); exit()

    train.train(train_iter, dev_iter, char_cnn, args, log_file_handle=log_file_handle)
    if args.eval_on_test:
        result = train.eval(test_iter, char_cnn, args, log_file_handle=log_file_handle)
        char_fold_accuracies.append(result)
        print("Completed fold {0}. Accuracy on Test: {1} for CHAR".format(xfold, result))
        print("Completed fold {0}. Accuracy on Test: {1} for CHAR".format(xfold, result), file=log_file_handle)

    # Word CNN training and dev
    args.embed_num = len(word_field.vocab)
    if update_args==True:
        # args.kernel_sizes = [int(k) for k in args.kernel_sizes.split(',')]
        args.word_kernel_sizes = [int(k) for k in args.word_kernel_sizes.split(',')]
        args.save_dir = os.path.join(args.save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'WORD')
    else:
        args.save_dir = os.path.join(orig_save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'WORD')
    # print("\nParameters:")
    # for attr, value in sorted(args.__dict__.items()):
    #     print("\t{}={}".format(attr.upper(), value))

    if args.snapshot is None:
        word_cnn = model.CNN_Text(args, 'word', vectors =word_field.vocab.vectors)
    else :
        print('\nLoading model from [%s]...' % args.snapshot)
        try:
            word_cnn = torch.load(args.snapshot)
        except:
            print("Sorry, This snapshot doesn't exist."); exit()

    train.train(train_iter_word, dev_iter_word, word_cnn, args, log_file_handle=log_file_handle)
    if args.eval_on_test:
        result = train.eval(test_iter_word, word_cnn, args, log_file_handle=log_file_handle)
        word_fold_accuracies.append(result)
        print("Completed fold {0}. Accuracy on Test: {1} for WORD".format(xfold, result))
        print("Completed fold {0}. Accuracy on Test: {1} for WORD".format(xfold, result), file=log_file_handle)

    # Ensemble training and dev
    if update_args==True:
        args.save_dir = os.path.join(args.save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'LOGIT')
    else:
        args.save_dir = os.path.join(orig_save_dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), 'LOGIT')
    update_args = False

    if args.snapshot is None:
        final_logit = model.SimpleLogistic(args)
    else :
        print('\nLoading model from [%s]...' % args.snapshot)
        try:
            final_logit = torch.load(args.snapshot)
        except:
            print("Sorry, This snapshot doesn't exist."); exit()

    # train_iter, dev_iter, test_iter = vp(text_field, label_field, foldid=xfold, device=-1, repeat=False)
    # train_iter_word, dev_iter_word, test_iter_word = vp(word_field, label_field, foldid=xfold, device=-1, repeat=False)

    train.train_logistic(train_iter, dev_iter, train_iter_word, dev_iter_word, char_cnn, word_cnn, final_logit, args, log_file_handle=log_file_handle)
    if args.eval_on_test:
        result = train.eval_logistic(test_iter, test_iter_word, char_cnn, word_cnn, final_logit, args, log_file_handle=log_file_handle)
        ensemble_fold_accuracies.append(result)

        print("Completed fold {0}. Accuracy on Test: {1} for LOGIT".format(xfold, result))
        print("Completed fold {0}. Accuracy on Test: {1} for LOGIT".format(xfold, result), file=log_file_handle)
    """
    # train or predict
    if args.predict is not None:
        label = train.predict(args.predict, cnn, text_field, label_field)
        print('\n[Text]  {}[Label] {}\n'.format(args.predict, label))
    elif args.test :
        try:
            train.eval(test_iter, cnn, args)
        except Exception as e:
            print("\nSorry. The test dataset doesn't  exist.\n")
    else :
        print()
        train.train(train_iter, dev_iter, cnn, args)
    """
    log_file_handle.flush()

average_xfold_accuracy = sum([res for res in ensemble_fold_accuracies]) / len(ensemble_fold_accuracies)
print("folds: {0}".format(len(ensemble_fold_accuracies)))
print("Average cross-fold accuracy: {0}".format(average_xfold_accuracy))
log_file_handle.close()<|endoftext|>


<commit_before>"""
DB Benchmarking Application
===========================

Main.py

This file houses the core of the application, and is where all of the read/write
commands are issued from, timed, and all data is analyzed.  Results from the
trials are printed to the console by default, but can optionally be printed to a
file to keep a record of.  This is particularly helpful when benchmarking
multiple DB's in a row to see which one is best for deployment purposes.

    Usage:
        main.py <database> [options]

    Options:
        -h --help           Show this help screen
        -v --verbose        Show verbose output from the application
        -l --list_mods      Outputs a list of available DB modules before running
        -r --report         Option to generate a report file, which will
                                OVERWRITE any existing reports from the specified
                                DB in the `generated_reports` directory

        --entry_length=<n>  Specify an entry length [default: 10]
        --trial_number=<n>  Specify the number of reads and writes to make to the
                                DB to collect data on [default: 100]

"""

from os import getcwd, listdir
import time
import string
import random
import importlib

from tabulate import tabulate
from numpy import array, average, std, max, min
from docopt import docopt

def retrieve_module_list():
    """ This function will retrieve a list of all available modules in the
    project directory and then return said list.

    :return mod_list: The list of modules in the project directory

    """
    current_dir = getcwd()
    mod_list = []

    for item in listdir(current_dir):

        if item.endswith('db'):

            mod_list.append(item)

    return mod_list

class Benchmark():

    def __init__(self):
        """ The init method is passed a single parameter upon initialization in
        order to define which database should be benchmarked.  Other important
        values are defined here, such as the entry length and the number of
        trials to execute.

        """

        self.db_name = options['<database>']
        self.verbose = options['--verbose']
        self.collection = 'test'
        self.database = self.register_module(self.db_name).Benchmark(
                    self.collection, setup=True
        )

        self.db_name = self.db_name.replace('db', '').upper()
        self.entry_length = int(options['--entry_length'])
        self.number_of_trials = int(options['--trial_number'])
        self.report = options['--report']

        #TODO - fix this
        self.number_of_nodes = 4

        self.write_times = []
        self.read_times = []

        self.sorting_index = 'ID'
        self.reports_dir = 'generated_reports/'

        self.time_and_date = time.strftime("%a, %d %b, %Y %H:%M:%S")

        # Run the benchmarks!
        self.run()

    def random_entry(self, entry_type='string'):
        """ This function generates a random string or random number depending on
        the arguments passed in.  The string is generated from all ascii letters
        and the number is generated from numbers 0-9.

        :param entry_type: the specified type of random entry, either 'string'
                    or 'number'

        :return: the random string or number that was just generated
        """

        entry = ''

        if entry_type == 'string':

            selection = string.ascii_letters

        else:

            selection = string.digits

        for x in range(self.entry_length):

            entry += random.choice(selection)

        return entry

    def run(self):
        """ This function will keep track of and call the read/ write functions
        for benchmarking.  For each iteration, a new DB entry will be created,
        written to the DB,  and then read back from it.

        """

        for index in range(self.number_of_trials):

            item_number = self.random_entry(entry_type='number')
            info = self.random_entry(entry_type='string')

            entry = {
                'Index': index,
                'Number': item_number,
                'Info': info
            }

            if not self.writes(entry):
                print 'WRITE ERROR'

            if not self.reads(index):
                print 'READ ERROR'

        self.compile_data()

    def writes(self, entry):
        """ This function handles all DB write commands, and times that action
        as well.  It takes a single parameter ('entry'), which is the data to be
        written to the DB.

        :param entry: The entry to be recorded to the DB

        :return: True, if all operations successfully completed
        """

        write_start_time = time.time()

        self.database.write(entry)

        write_stop_time = time.time()

        write_time = write_stop_time - write_start_time

        self.write_times.append(write_time)

        return True

    def reads(self, index):
        """ This function handles all DB read commands, and times that action as
        well.  It takes a single parameter, which is the index of an entry to
        retrieve from the DB.

        :param index: The index of the item to be retrieved from the DB

        :return: True, if all operations successfully completed
        """

        read_start_time = time.time()

        self.database.read(index)

        read_stop_time = time.time()

        read_time = read_stop_time - read_start_time

        self.read_times.append(read_time)

        return True

    def compile_data(self, return_results=False):
        """ This function takes all the data collected from the trials (read and
        write times) and then calculates some important statistics about said
        data.  Without altering functionality, a report will be generated upon
        completion of analysis.

        :param return_results=False: This parameter can be optionally passed as
                    True if the user wants to have the dict of results returned
                    instead of generating a report with said results

        :return results: The compiled results from the statistical analysis of
                    the trial data as a dict
        """

        self.write_times = array(self.write_times)
        self.read_times = array(self.read_times)

        write_avg = average(self.write_times)
        write_stdev = std(self.write_times)
        write_max = max(self.write_times)
        write_min = min(self.write_times)
        write_range = write_max - write_min

        read_avg = average(self.read_times)
        read_stdev = std(self.read_times)
        read_max = max(self.read_times)
        read_min = min(self.read_times)
        read_range = read_max - read_min

        if return_results:

            results = {
                'database': self.db_name,
                'trial_number': self.number_of_trials,
                'entry_length': self.entry_length,
                'node_number': self.number_of_nodes,
                'write_avg': write_avg,
                'write_stdev': write_stdev,
                'write_max': write_max,
                'write_min': write_min,
                'write_range': write_range,
                'read_avg': read_avg,
                'read_stdev': read_stdev,
                'read_max': read_max,
                'read_min': read_min,
                'read_range': read_range,
            }

            return results

        else:

            param_header = [
                'Parameter',
                'Value',
            ]

            param_values = [
                ['Database Tested', self.db_name],
                ['Number of Trials', str(self.number_of_trials)],
                ['Length of Each Entry Field', str(self.entry_length)],
                ['Number of Nodes in Cluster', str(self.number_of_nodes)],
            ]

            data_header = [
                'Operation',
                'Average',
                'St. Dev.',
                'Max Time',
                'Min Time',
                'Range',
            ]

            data_values = [
                ['Writes', write_avg, write_stdev, write_max, write_min, write_range],
                ['Reads', read_avg, read_stdev, read_max, read_min, read_range],
            ]

            param_table = tabulate(
                tabular_data=param_values,
                headers=param_header,
                tablefmt='grid',
            )

            data_table = tabulate(
                tabular_data=data_values,
                headers=data_header,
                tablefmt='grid',
                floatfmt='.5f',
            )

            param_table_md = tabulate(
                tabular_data=param_values,
                headers=param_header,
                tablefmt='pipe',
            )

            data_table_md = tabulate(
                tabular_data=data_values,
                headers=data_header,
                tablefmt='pipe',
                floatfmt='.5f',
            )

            report_info = {
                'database': self.db_name,
                'time_and_date': self.time_and_date,
                'param_table': param_table,
                'data_table': data_table,
                'param_table_md': param_table_md,
                'data_table_md': data_table_md,
            }

            self.generate_report(report_info)

    def generate_report(self, report_info):
        """ This function will take the compiled data and generated a report from
        it.  If the `--report` option was selected at runtime, a report file will
        also be saved in the `generated_reports` directory.

        :param report_info: all of the necessary information to generate the
                    benchmark report
        """

        report_name = '{parent_dir}/{db}.report.md'.format(
            parent_dir=self.reports_dir,
            db=self.db_name
        )

        with open('report_template.md', 'r') as infile:

            template = infile.read()

            report = template.format(**report_info)

            print '\n\n' + report + '\n\n'

            if self.report:

                template = template.replace('_table', '_table_md')

                report = template.format(**report_info)

                with open(report_name, 'w+') as outfile:

                    outfile.write(report)

    def register_module(self, db_mod):
        """ This function begins the process of registering a module for
        benchmarking.  The first step is to check to see if the module exists,
        and if it does, it will call `import_db_mod` to attempt the import.

        :param db_mod: The module to register

        :return mod_class: `mod_class` will ONLY BE RETURNED IF `import_db_mod`
                    runs successfully!
        """

        mod_list = retrieve_module_list()

        if db_mod in mod_list:

            return self.import_db_mod(db_mod)

        else:

            error = 'Invalid DB module!  Please be sure you are using the \n' \
                    'package name and not just the name of the database itself.\n'

            print error

    @staticmethod
    def import_db_mod(module):
        """ This function will do the actual import of the database-specific
        module.  The `try/except` format is meant to be able to attempt the
        import, but fail gracefully if for some reason the package can't be
        imported.

        :param module: The module to be imported

        :return mod_class: The `Benchmark` class of the module, if it exists
        """

        try:

            package = '{mod}.main'.format(mod=module)

            mod_class = importlib.import_module(package)

            return mod_class

        except ImportError:

            error = 'Error!  Package could not be imported!  Please make \n' \
                    'sure you are using the package name and not the name \n' \
                    'of the database itself.'

            print error

if __name__ == '__main__':

    options = docopt(__doc__)

    foo = Benchmark()
<commit_msg>adds verbose output feature<commit_after>"""
DB Benchmarking Application
===========================

Main.py

This file houses the core of the application, and is where all of the read/write
commands are issued from, timed, and all data is analyzed.  Results from the
trials are printed to the console by default, but can optionally be printed to a
file to keep a record of.  This is particularly helpful when benchmarking
multiple DB's in a row to see which one is best for deployment purposes.

    Usage:
        main.py <database> [options]

    Options:
        -h --help           Show this help screen
        -v --verbose        Show verbose output from the application
        -l --list_mods      Outputs a list of available DB modules before running
        -r --report         Option to generate a report file, which will
                                OVERWRITE any existing reports from the specified
                                DB in the `generated_reports` directory

        --entry_length=<n>  Specify an entry length [default: 10]
        --trial_number=<n>  Specify the number of reads and writes to make to the
                                DB to collect data on [default: 100]

"""

from os import getcwd, listdir
import time
import string
import random
import importlib

from tabulate import tabulate
from numpy import array, average, std, max, min
from docopt import docopt

def retrieve_module_list():
    """ This function will retrieve a list of all available modules in the
    project directory and then return said list.

    :return mod_list: The list of modules in the project directory

    """
    current_dir = getcwd()
    mod_list = []

    for item in listdir(current_dir):

        if item.endswith('db'):

            mod_list.append(item)

    return mod_list

class Benchmark():

    def __init__(self):
        """ The init method is passed a single parameter upon initialization in
        order to define which database should be benchmarked.  Other important
        values are defined here, such as the entry length and the number of
        trials to execute.

        """

        self.db_name = options['<database>']
        self.verbose = options['--verbose']
        self.collection = 'test'
        self.database = self.register_module(self.db_name).Benchmark(
                    self.collection, setup=True
        )

        self.db_name = self.db_name.replace('db', '').upper()
        self.entry_length = int(options['--entry_length'])
        self.number_of_trials = int(options['--trial_number'])
        self.report = options['--report']

        #TODO - fix this
        self.number_of_nodes = 4

        self.write_times = []
        self.read_times = []

        self.sorting_index = 'ID'
        self.reports_dir = 'generated_reports/'

        self.time_and_date = time.strftime("%a, %d %b, %Y %H:%M:%S")

        # Run the benchmarks!
        self.run()

    def random_entry(self, entry_type='string'):
        """ This function generates a random string or random number depending on
        the arguments passed in.  The string is generated from all ascii letters
        and the number is generated from numbers 0-9.

        :param entry_type: the specified type of random entry, either 'string'
                    or 'number'

        :return: the random string or number that was just generated
        """

        entry = ''

        if entry_type == 'string':

            selection = string.ascii_letters

        else:

            selection = string.digits

        for x in range(self.entry_length):

            entry += random.choice(selection)

        return entry

    def run(self):
        """ This function will keep track of and call the read/ write functions
        for benchmarking.  For each iteration, a new DB entry will be created,
        written to the DB,  and then read back from it.

        """

        for index in range(self.number_of_trials):

            item_number = self.random_entry(entry_type='number')
            info = self.random_entry(entry_type='string')

            entry = {
                'Index': index,
                'Number': item_number,
                'Info': info
            }

            if not self.writes(entry):
                print 'WRITE ERROR'

            if not self.reads(index):
                print 'READ ERROR'

        self.compile_data()

    def writes(self, entry):
        """ This function handles all DB write commands, and times that action
        as well.  It takes a single parameter ('entry'), which is the data to be
        written to the DB.

        :param entry: The entry to be recorded to the DB

        :return: True, if all operations successfully completed
        """

        write_start_time = time.time()

        self.database.write(entry)

        write_stop_time = time.time()

        write_time = write_stop_time - write_start_time

        self.write_times.append(write_time)

        return True

    def reads(self, index):
        """ This function handles all DB read commands, and times that action as
        well.  It takes a single parameter, which is the index of an entry to
        retrieve from the DB.

        :param index: The index of the item to be retrieved from the DB

        :return: True, if all operations successfully completed
        """

        read_start_time = time.time()

        read_entry = self.database.read(index)

        read_stop_time = time.time()

        read_time = read_stop_time - read_start_time

        self.read_times.append(read_time)

        if self.verbose:

            print read_entry

        return True

    def compile_data(self, return_results=False):
        """ This function takes all the data collected from the trials (read and
        write times) and then calculates some important statistics about said
        data.  Without altering functionality, a report will be generated upon
        completion of analysis.

        :param return_results=False: This parameter can be optionally passed as
                    True if the user wants to have the dict of results returned
                    instead of generating a report with said results

        :return results: The compiled results from the statistical analysis of
                    the trial data as a dict
        """

        self.write_times = array(self.write_times)
        self.read_times = array(self.read_times)

        write_avg = average(self.write_times)
        write_stdev = std(self.write_times)
        write_max = max(self.write_times)
        write_min = min(self.write_times)
        write_range = write_max - write_min

        read_avg = average(self.read_times)
        read_stdev = std(self.read_times)
        read_max = max(self.read_times)
        read_min = min(self.read_times)
        read_range = read_max - read_min

        if return_results:

            results = {
                'database': self.db_name,
                'trial_number': self.number_of_trials,
                'entry_length': self.entry_length,
                'node_number': self.number_of_nodes,
                'write_avg': write_avg,
                'write_stdev': write_stdev,
                'write_max': write_max,
                'write_min': write_min,
                'write_range': write_range,
                'read_avg': read_avg,
                'read_stdev': read_stdev,
                'read_max': read_max,
                'read_min': read_min,
                'read_range': read_range,
            }

            return results

        else:

            param_header = [
                'Parameter',
                'Value',
            ]

            param_values = [
                ['Database Tested', self.db_name],
                ['Number of Trials', str(self.number_of_trials)],
                ['Length of Each Entry Field', str(self.entry_length)],
                ['Number of Nodes in Cluster', str(self.number_of_nodes)],
            ]

            data_header = [
                'Operation',
                'Average',
                'St. Dev.',
                'Max Time',
                'Min Time',
                'Range',
            ]

            data_values = [
                ['Writes', write_avg, write_stdev, write_max, write_min, write_range],
                ['Reads', read_avg, read_stdev, read_max, read_min, read_range],
            ]

            param_table = tabulate(
                tabular_data=param_values,
                headers=param_header,
                tablefmt='grid',
            )

            data_table = tabulate(
                tabular_data=data_values,
                headers=data_header,
                tablefmt='grid',
                floatfmt='.5f',
            )

            param_table_md = tabulate(
                tabular_data=param_values,
                headers=param_header,
                tablefmt='pipe',
            )

            data_table_md = tabulate(
                tabular_data=data_values,
                headers=data_header,
                tablefmt='pipe',
                floatfmt='.5f',
            )

            report_info = {
                'database': self.db_name,
                'time_and_date': self.time_and_date,
                'param_table': param_table,
                'data_table': data_table,
                'param_table_md': param_table_md,
                'data_table_md': data_table_md,
            }

            self.generate_report(report_info)

    def generate_report(self, report_info):
        """ This function will take the compiled data and generated a report from
        it.  If the `--report` option was selected at runtime, a report file will
        also be saved in the `generated_reports` directory.

        :param report_info: all of the necessary information to generate the
                    benchmark report
        """

        report_name = '{parent_dir}/{db}.report.md'.format(
            parent_dir=self.reports_dir,
            db=self.db_name
        )

        with open('report_template.md', 'r') as infile:

            template = infile.read()

            report = template.format(**report_info)

            print '\n\n' + report + '\n\n'

            if self.report:

                template = template.replace('_table', '_table_md')

                report = template.format(**report_info)

                with open(report_name, 'w+') as outfile:

                    outfile.write(report)

    def register_module(self, db_mod):
        """ This function begins the process of registering a module for
        benchmarking.  The first step is to check to see if the module exists,
        and if it does, it will call `import_db_mod` to attempt the import.

        :param db_mod: The module to register

        :return mod_class: `mod_class` will ONLY BE RETURNED IF `import_db_mod`
                    runs successfully!
        """

        mod_list = retrieve_module_list()

        if db_mod in mod_list:

            return self.import_db_mod(db_mod)

        else:

            error = 'Invalid DB module!  Please be sure you are using the \n' \
                    'package name and not just the name of the database itself.\n'

            print error

    @staticmethod
    def import_db_mod(module):
        """ This function will do the actual import of the database-specific
        module.  The `try/except` format is meant to be able to attempt the
        import, but fail gracefully if for some reason the package can't be
        imported.

        :param module: The module to be imported

        :return mod_class: The `Benchmark` class of the module, if it exists
        """

        try:

            package = '{mod}.main'.format(mod=module)

            mod_class = importlib.import_module(package)

            return mod_class

        except ImportError:

            error = 'Error!  Package could not be imported!  Please make \n' \
                    'sure you are using the package name and not the name \n' \
                    'of the database itself.'

            print error

if __name__ == '__main__':

    options = docopt(__doc__)

    foo = Benchmark()
<|endoftext|>