# Path: hamaa/utils/np_utils.py
# def to_one_hot(y, nb_class):
# def to_categorical(y):
# def split_training_data(data, nb_validation=None, split_ratio=None):
# def padding(images, pad_size):
# def rot180(images):
# def eval_numerical_gradient_array(f, x, df=None, verbose=False, h=1e-4):
# def sum_abs_err(u, v):
# 
# Path: hamaa/utils/time_utils.py
# class ProgressBar:
#     """控制台进度条类"""
# 
#     def __init__(self, total=0, width=20):
#         """
#         :param total: 进度最大值，整数类型
#         :param width: 进图条显示宽度，单位为一个字符占位格
#         """
#         # 当前轮数，类型为整数值
#         self.current = 0
#         self.total = total
#         self.width = width
#         self.timestamp = None
#         self.one_move_time = 0
# 
#     def move(self, step=1):
#         self.current += step
#         if self.timestamp:
#             self.one_move_time = (time.time() - self.timestamp) / step
#         self.timestamp = time.time()
# 
#     def clear(self):
#         """清空进度条"""
#         sys.stdout.write('\r')
#         sys.stdout.write(' ' * (100))
#         sys.stdout.write('\r')
#         sys.stdout.flush()
# 
#     def reset(self):
#         """重置进度条进度"""
#         self.current = 0
# 
#     def show(self, head='', message=''):
#         self.clear()
#         # 计算当前进度百分比
#         percent = self.current * 1.0 / self.total
#         # 根据百分比以及进度条总长度，计算当前进度的占位符宽度
#         progress = int(math.ceil(self.width * percent))
#         if progress == self.width:
#             progress -= 1
#         # 估计剩余耗时
#         remaining_time = (self.total - self.current) * self.one_move_time
#         # 打印进度条头
#         sys.stdout.write(head + ',  {0:3}/{1}: '.format(self.current, self.total))
#         # 打印进度条
#         sys.stdout.write('[' + '='*progress + '>' + ' '*(self.width - progress - 1) + '] remaining time: %.2fs' % remaining_time)
#         # 打印尾随信息
#         sys.stdout.write(message)
#         sys.stdout.flush()
# 
#         # 如果进度完成，则输出换行符（永久打印在控制台上）
#         # if self.current == self.total:
#         #     sys.stdout.write('\n')
#         #     sys.stdout.flush()


import sys
import time
import warnings
import matplotlib.pyplot as plt
import numpy as np
from .utils import np_utils
from .utils.time_utils import ProgressBar
            for i in xrange(batch_times):  # 对于每次批量计算
                batch_range = random_idx[i * mini_batch_size:(i + 1) * mini_batch_size]
                batch_training_x = training_x[batch_range]
                batch_training_y = training_y[batch_range]
                self.train_by_batch(model, (batch_training_x, batch_training_y))
            print 'epoch:{}, loss:{}'.format(epoch, model.evaluate_loss(training_x, training_y))

    def train(self, model, training_data, nb_epochs, mini_batch_size, verbose=1, log_epoch=1,
              validation_data=None, shuffle=True, evaluate_batch_size=100, **kwargs):
        """训练模型.TODO"""

        assert log_epoch > 0, 'log_epoch:{} must be larger than zero!'.format(log_epoch)
        assert verbose in [0, 1, 2], 'invalid verbose:{}'.format(verbose)

        # 当log_epoch不为1时，不推荐使用进度条功能。
        if log_epoch != 1 and verbose == 2:
            raise Exception('Invalid log_epoch and verbose: verbose为2时log_epoch只能为1!\n'
                            '原因：进图条功能用于在控制台显示每个epoch的完成进度，\n'
                            '如果log_epoch > 1，说明控制台每隔log_epoch个epoch才显示一次，\n'
                            '会和进图条的显示功能产生冲突。')

        training_x, training_y = training_data
        n = training_x.shape[0]
        random_idx = range(n)
        batch_times = np.ceil(n * 1.0 / mini_batch_size).astype(np.int32)

        # logger负责记录训练过程，同时统计两次log之间的时间间隔
        self.reset_logger()
        self.logger['need_to_refresh_start_time'] = True


# Path: hamaa/utils/np_utils.py
# def to_one_hot(y, nb_class):
# def to_categorical(y):
# def split_training_data(data, nb_validation=None, split_ratio=None):
# def padding(images, pad_size):
# def rot180(images):
# def eval_numerical_gradient_array(f, x, df=None, verbose=False, h=1e-4):
# def sum_abs_err(u, v):
# 
# Path: hamaa/utils/time_utils.py
# class ProgressBar:
#     """控制台进度条类"""
# 
#     def __init__(self, total=0, width=20):
#         """
#         :param total: 进度最大值，整数类型
#         :param width: 进图条显示宽度，单位为一个字符占位格
#         """
#         # 当前轮数，类型为整数值
#         self.current = 0
#         self.total = total
#         self.width = width
#         self.timestamp = None
#         self.one_move_time = 0
# 
#     def move(self, step=1):
#         self.current += step
#         if self.timestamp:
#             self.one_move_time = (time.time() - self.timestamp) / step
#         self.timestamp = time.time()
# 
#     def clear(self):
#         """清空进度条"""
#         sys.stdout.write('\r')
#         sys.stdout.write(' ' * (100))
#         sys.stdout.write('\r')
#         sys.stdout.flush()
# 
#     def reset(self):
#         """重置进度条进度"""
#         self.current = 0
# 
#     def show(self, head='', message=''):
#         self.clear()
#         # 计算当前进度百分比
#         percent = self.current * 1.0 / self.total
#         # 根据百分比以及进度条总长度，计算当前进度的占位符宽度
#         progress = int(math.ceil(self.width * percent))
#         if progress == self.width:
#             progress -= 1
#         # 估计剩余耗时
#         remaining_time = (self.total - self.current) * self.one_move_time
#         # 打印进度条头
#         sys.stdout.write(head + ',  {0:3}/{1}: '.format(self.current, self.total))
#         # 打印进度条
#         sys.stdout.write('[' + '='*progress + '>' + ' '*(self.width - progress - 1) + '] remaining time: %.2fs' % remaining_time)
#         # 打印尾随信息
#         sys.stdout.write(message)
#         sys.stdout.flush()
# 
#         # 如果进度完成，则输出换行符（永久打印在控制台上）
#         # if self.current == self.total:
#         #     sys.stdout.write('\n')
#         #     sys.stdout.flush()


# Path: hamaa/trainers.py
import sys
import time
import warnings
import matplotlib.pyplot as plt
import numpy as np
from .utils import np_utils
from .utils.time_utils import ProgressBar

            for i in xrange(batch_times):  # 对于每次批量计算
                batch_range = random_idx[i * mini_batch_size:(i + 1) * mini_batch_size]
                batch_training_x = training_x[batch_range]
                batch_training_y = training_y[batch_range]
                self.train_by_batch(model, (batch_training_x, batch_training_y))
            print 'epoch:{}, loss:{}'.format(epoch, model.evaluate_loss(training_x, training_y))

    def train(self, model, training_data, nb_epochs, mini_batch_size, verbose=1, log_epoch=1,
              validation_data=None, shuffle=True, evaluate_batch_size=100, **kwargs):
        """训练模型.TODO"""

        assert log_epoch > 0, 'log_epoch:{} must be larger than zero!'.format(log_epoch)
        assert verbose in [0, 1, 2], 'invalid verbose:{}'.format(verbose)

        # 当log_epoch不为1时，不推荐使用进度条功能。
        if log_epoch != 1 and verbose == 2:
            raise Exception('Invalid log_epoch and verbose: verbose为2时log_epoch只能为1!\n'
                            '原因：进图条功能用于在控制台显示每个epoch的完成进度，\n'
                            '如果log_epoch > 1，说明控制台每隔log_epoch个epoch才显示一次，\n'
                            '会和进图条的显示功能产生冲突。')

        training_x, training_y = training_data
        n = training_x.shape[0]
        random_idx = range(n)
        batch_times = np.ceil(n * 1.0 / mini_batch_size).astype(np.int32)

        # logger负责记录训练过程，同时统计两次log之间的时间间隔
        self.reset_logger()
        self.logger['need_to_refresh_start_time'] = True


        bar = ProgressBar(total=n, width=20)