# -*- coding: utf-8 -*-
# Copyright 2010 Thamini S.à.R.L    This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

import time
import xlwt
from ad_account_optimization.report.report_engine_xls import report_xls
from ad_report_sales.report.sale_order_item import ReportStatus
import cStringIO
from xlwt import Workbook, Formula
from tools.translate import _

class report_sales_order_xls(report_xls):
    no_ind = 0

    def get_no_index(self):
        self.set_no_index()
        return self.no_ind
    def set_no_index(self):
        self.no_ind += 1
        return True

    def create_source_xls(self, cr, uid, ids, data, report_xml, context=None):
        if not context:
            context = {}
        context = context.copy()
        rml_parser = self.parser(cr, uid, self.name2, context=context)
        objs = self.getObjects(cr, uid, ids, context=context)
        rml_parser.set_context(objs, data, ids, 'xls')

        n = cStringIO.StringIO()
        wb = xlwt.Workbook(encoding='utf-8')
        self.generate_xls_report(rml_parser, data, rml_parser.localcontext['objects'], wb)
        wb.save(n)
        n.seek(0)
        return (n.read(), 'xls')

    def generate_xls_report(self, parser, data, obj, wb):
        c = parser.localcontext['company']
        ws = wb.add_sheet(('Sale Order Report'))#- %s - %s' % (c.partner_id.ref, c.currency_id.name))[:31])
        ws.panes_frozen = True
        ws.remove_splits = True
        ws.portrait = 0 # Landscape
        ws.fit_width_to_pages = 1
        ws.col(0).width = len("ABCD")*1024
        ws.col(1).width = len("ABCDEFG")*1024
        ws.col(2).width = len("ABCDEFGHI")*1024
        ws.col(3).width = len("ABC")*1024
        ws.col(4).width = len("AB")*1024
        ws.col(5).width = len("ABCD")*1024
        ws.col(6).width = len("ABCD")*1024
        ws.col(7).width = len("ABCDC")*1024
        ws.col(8).width = len("ABCD")*1024

        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
        #         Spesifikasi Kolom                                                         #
        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
        cols_specs = [
                # Headers data
                ('Title',  13, 0, 'text',
                    lambda x, d, p: 'Sale Order Report'),
                ('Kosong', 13, 0, 'text',
                    lambda x, d, p: ""),
                ('Space', 1, 0, 'text',
                    lambda x, d, p: ""),
                ('Space2', 9, 0, 'text',
                    lambda x, d, p: ""),

                # Balance column
                #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
                #        Kolom Text                                                                 #
                #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

                ('Date', 1, 200, 'text',
                    lambda x, d, p: 'Date'),
                ('Reference', 1, 200, 'text',
                    lambda x, d, p: 'Reference'),
                ('Order No.', 1, 200, 'text',
                    lambda x, d, p: 'Order No.'),
                ('Customer', 1, 200, 'text',
                    lambda x, d, p: 'Customer'),
                ('Curr', 1, 200, 'text',
                    lambda x, d, p: 'Curr'),
                ('Sub Total', 1, 200, 'text',
                    lambda x, d, p: 'Sub Total'),
                ('Discount', 1, 200, 'text',
                    lambda x, d, p: 'Discount'),
                ('Tax', 1, 200, 'text',
                    lambda x, d, p: 'Tax'),
                ('Sales Total', 1, 200, 'text',
                    lambda x, d, p: 'Sales Total'),
                ('Payment', 1, 200, 'text',
                    lambda x, d, p: 'Payment'),
                ('Balance', 1, 200, 'text',
                    lambda x, d, p: 'Balance'),
                #'Date','Reference','Order No.','Customer','Curr','Sub Total','Discount','Tax','Sales Total','Payment','Balance'
                ('Date1', 1, 200, 'text',
                    lambda x, d, p: x['date_order']),
                ('Reference1', 1, 200, 'text',
                    lambda x, d, p: x['client_order_ref']),
                ('Order No.1', 1, 200, 'text',
                    lambda x, d, p: x['name']),
                ('Customer1', 1, 200, 'text',
                    lambda x, d, p: x['partner_id']['name']),
                ('Curr1', 1, 200, 'text',
                    lambda x, d, p: x['pricelist_id']['currency_id']['name']),
                ('Sub Total1', 1, 200, 'number',
                    lambda x, d, p: x['amount_undiscount']),
                ('Discount1', 1, 200, 'number',
                    lambda x, d, p: x['add_disc_amt']),
                ('Tax1', 1, 200, 'number',
                    lambda x, d, p: x['amount_tax']),
                ('Sales Total1', 1, 200, 'number',
                    lambda x, d, p: x['amount_total']),
                ('Payment1', 1, 200, 'number',
                    lambda x, d, p: 0),
                ('Balance1', 1, 200, 'number',
                    lambda x, d, p: 0),
                #item
                ('CodeItem', 1, 200, 'text',
                    lambda x, d, p: x['product_id']['default_code']),
                ('NameItem', 1, 200, 'text',
                    lambda x, d, p: x['product_id']['name']),
                ('Quantity', 1, 200, 'number',
                    lambda x, d, p: x['product_uom_qty']),
                ('PriceItem', 1, 200, 'number',
                    lambda x, d, p: x['price_unit']),
                ('DiscItem', 1, 200, 'number',
                    lambda x, d, p: x['discount']),
                ('SubtotalItem', 1, 200, 'number',
                    lambda x, d, p: x['price_subtotal']),

        ]
        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
        #         ISI KOLOM                                                                 #
        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
        row_hdr0 = self.xls_row_template(cols_specs, ['Space','Title'])
        row_hdr1 = self.xls_row_template(cols_specs, ['Date','Order No.','Customer',
                                                      'Curr','Sub Total','Discount','Tax','Sales Total',
                                                      #'Payment','Balance'
                                                      ])
        row_hdr2 = self.xls_row_template(cols_specs, ['Date1','Order No.1','Customer1',
                                                      'Curr1','Sub Total1','Discount1','Tax1','Sales Total1',
                                                      #'Payment1','Balance1'
                                                      ])
        row_hdr3 = self.xls_row_template(cols_specs, ['Space','CodeItem','NameItem',
                                                      'Quantity','PriceItem','DiscItem','SubtotalItem',
                                                      #'Space'
                                                      ])

        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
        #         ####ISI KOLOM####                                                         #
        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

        ## Style variable Begin
        hdr_style = xlwt.easyxf('pattern: pattern solid, fore_color sky_blue;')
        row_normal_style=  xlwt.easyxf(num_format_str='#,##0.00;(#,##0.00)')
        row_bold_style = xlwt.easyxf('font: bold on;pattern: pattern solid, fore_color ice_blue;',num_format_str='#,##0.00;(#,##0.00);')
        row_bold_style_line = xlwt.easyxf('font: bold on;pattern: pattern solid, fore_color ice_blue;',num_format_str='#,##0.00;(#,##0.00);')
        row_bold_bottom_style = xlwt.easyxf('font: bold on;borders: bottom thin;',num_format_str='#,##0.00;(#,##0.00)')

        tittle_style = xlwt.easyxf('font: height 240, name Arial Black, colour_index black, bold on; align: wrap on, vert centre, horiz left; pattern: pattern solid, fore_color white;')
        subtittle_left_style = xlwt.easyxf('font: name Arial, colour_index brown, bold on, italic on; align: wrap on, vert centre, horiz right; pattern: pattern solid, fore_color white;')
        subtittle_right_style = xlwt.easyxf('font: name Arial, colour_index brown, bold on, italic on; align: wrap on, vert centre, horiz left; pattern: pattern solid, fore_color white;')
        subtittle_top_and_bottom_style = xlwt.easyxf('font: height 240, name Arial, colour_index black, bold off, italic on; align: wrap on, vert centre, horiz left; pattern: pattern solid, fore_color white;')
        blank_style = xlwt.easyxf('font: height 650, name Arial, colour_index brown, bold off; align: wrap on, vert centre, horiz left; pattern: pattern solid, fore_color white;')
        normal_style = xlwt.easyxf('font: height 240, name Arial, colour_index black, bold off; align: wrap on, vert centre, horiz left;')
        total_style = xlwt.easyxf('font: height 200, name Arial, colour_index black, bold on, italic on; align: wrap on, vert centre;pattern: pattern solid, fore_color gray25;', num_format_str='#,##0.00;(#,##0.00)')
        ## Style variable End

        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
        #         Write To Excel                                                            #
        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
        self.xls_write_row(ws, None, data, parser, 1, row_hdr0, tittle_style)
        self.xls_write_row(ws, None, data, parser, 2, row_hdr1, row_bold_style)
        row_count=3
        for inv in parser._get_basedon(data):
            self.xls_write_row(ws, inv, data, parser, row_count, row_hdr2, row_normal_style)
            row_count+=1
            if data['form']['with_item']:
                for line in inv.order_line:
                    self.xls_write_row(ws, line, data, parser, row_count, row_hdr3, row_normal_style)
                    row_count+=1
            row_count+=1
        pass

report_sales_order_xls(
        'report.sale.order.form.xls',
        'sale.line.report',
        'addons/ad_report_sales/report/report_sales_webkit.mako',
        parser=ReportStatus,       header=False)


#%%
import numpy as np
import os
import matplotlib.pyplot as plt

def plot_data(val_acc_history, loss_acc_history):
    plt.plot(loss_acc_history, label = 'Validation')
    plt.title('Loss per epoch')
    plt.legend()
    plt.show()
    plt.plot(val_acc_history, label = 'Validation')
    plt.title('Accuracy per epoch')
    plt.legend()
    plt.show()
#%%
acc = np.load('GoogLeNet_val_acc_history.npy', allow_pickle=True)
loss = np.load('GoogLeNet_loss_history.npy', allow_pickle=True)

plot_data(acc, loss)

# %%


import math

def solution(fees, records):
    bt, bf, ut, uf = fees
    answer = {}
    temp = []
    result = []
    for r in records:
        # 시간을 :로 분리
        time = r.split()[0].split(":")
        # 시간을 분 단위로 변형
        minutes = int(time[0]) * 60 + int(time[1])
        if r.split()[2] == "IN":
            temp.append([minutes, r.split()[1]])
        else:
            for t in temp:
                if t[1] == r.split()[1]:
                    times = minutes - t[0]
                    if t[1] in answer:
                        answer[t[1]] += times
                    else:
                        answer[t[1]] = times
                    temp.remove(t)
    for t2 in temp:
        times = 1439 - t2[0]
        if t2[1] in answer:
            answer[t2[1]] += times
        else:
            answer[t2[1]] = times

    answer = sorted(answer.items())

    for a in answer:
        fee = bf + uf * math.ceil((a[1] - bt if a[1] - bt > 0 else 0) / ut)
        result.append(fee)
    return result

print(solution([180, 5000, 10, 600], ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"]))


from Glucose import Glucose
import random

class GlucoseSystem:
    def __init__(self, glut_threshold = 200, glu_stored = 3000):  #glut_threshold:The distance threshold of directed search for glut_protein
        self.glut_threshold = glut_threshold
        self.glu_stored = glu_stored
        self.gluList = []

    def display(self):
        for glu in self.gluList:
            glu.display()

    def update(self):
        for glu in self.gluList:
            glu.update()

    def check(self, cell, glut_list):
        num = self.count_num(in_cell = 1)
        for glu in self.gluList:
            glu.check_in_cell(cell, glut_list) # Check to see if it's inside the cell
            # try to find the glut
            if PVector.dist(glu.position, cell.position) >= cell.r - 30 and glu.through_glut == False:
                glu.follow(glut_list, self.glut_threshold)
                glu.check_edge()
                # not find glut or close enough to the glut yet
                if glu.dist_target >= 100:
                    glu.check_cell_out_edge(cell)
            elif glu.in_cell == 1:
                # avoid to find the glut again
                glu.through_glut = True
                if glu.change_state == False:
                    glu.velocity.x *= random.uniform(0, 5)
                    glu.velocity.y *= random.uniform(0, 5)
                    glu.change_state = True
                glu.check_cell_edge(cell)

            if glu.gluDead():
                self.gluList.remove(glu)

        return num

    def count_num(self, in_cell):
        num = 0
        for glu in self.gluList:
            if glu.in_cell == in_cell:
                num += 1
        return num

    def add(self, num, in_cell):
        self.glu_stored -= num
        for i in range(num):
            if in_cell:
                glu = Glucose(position = PVector(mouseX, mouseY), velocity = PVector(random.uniform(-1.0,1.0),random.uniform(-1.0,1.0)),
                        acceleration = PVector(0,0), mass = 0, top_speed = 1, maxforce = 0, r = 5, in_cell = 1, lifespan = 100,spin = 100)
            else:
                glu = Glucose(position = PVector(random.randint(0,250), random.randint(0,800)), velocity = PVector(random.uniform(-1.0,1.0),random.uniform(-1.0,1.0)),
                    acceleration = PVector(0,0), mass = 0, top_speed = 1, maxforce = 0, r = 5, in_cell = 0, lifespan = 100,spin = 100)
            self.gluList.append(glu)


# Time:  O(n)
# Space: O(h)

# 1026
# Given the root of a binary tree, find the maximum value V for which there exists
# different nodes A and B where V = |A.val - B.val| and A is an ancestor of B.
#
# (A node A is an ancestor of B if either: any child of A is equal to B, or any
# child of A is an ancestor of B.)

# Solution: We pass the minimum and maximum values to the children,
# At the leaf node, we calculate max - min.

# Definition for a binary tree node.
class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution(object):
# Time:  O(n)
# Space: O(h)
# recursive solution
    def maxAncestorDiff(self, root): # USE THIS
        """
        :type root: TreeNode
        :rtype: int
        """
        def dfs(node, minn, maxx):
            if not node: # an empty subtree
                return 0

            # update minn/maxx
            minn = min(minn, node.val)
            maxx = max(maxx, node.val)
            if not node.left and not node.right: # leaf
                return abs(maxx - minn)

            return max(dfs(node.left, minn, maxx),
                       dfs(node.right, minn, maxx))

        return dfs(root, float('inf'), float('-inf'))

    # iterative stack solution
    def maxAncestorDiff_iter(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        result = 0
        stack = [(root, 0, float("inf"))]
        while stack:
            node, mx, mn = stack.pop()
            if not node:
                continue
            result = max(result, mx-node.val, node.val-mn)
            mx = max(mx, node.val)
            mn = min(mn, node.val)
            stack.append((node.left, mx, mn))
            stack.append((node.right, mx, mn))
        return result

# use global var, no return from helper func.
class Solution2:
    def maxAncestorDiff(self, root: TreeNode) -> int:
        def dfs(node, minn, maxx):
            if node:
                minn = min(minn, node.val)
                maxx = max(maxx, node.val)
                dfs(node.left, minn, maxx)
                dfs(node.right, minn, maxx)
            else:
                self.ans = max(self.ans, abs(maxx - minn))

        self.ans = 0
        dfs(root, float('inf'), float('-inf'))
        return self.ans

    # The following way is worse maintaining a path, as in the end we need to traverse the path
    # to find min/max. Much better if pass min/max along the way.
    def maxAncestorDiff_maintainPath(self, root):
        def dfs(n, path):
            if n:
                path.append(n.val)
                if not n.left and not n.right:
                    self.ans = max(self.ans, max(path) - min(path))
                dfs(n.left, path)
                dfs(n.right, path)
                path.pop()

        self.ans = 0
        dfs(root, [])
        return self.ans

r = TreeNode(8)
r.left, r.right = TreeNode(3), TreeNode(10)
r.left.left, r.left.right = TreeNode(1), TreeNode(6)
r.left.right.left, r.left.right.right = TreeNode(4), TreeNode(7)
r.right.right = TreeNode(14)
r.right.right.left = TreeNode(13)

print(Solution2().maxAncestorDiff_recur(r)) # 7


from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap
from mpl_toolkits.axes_grid1 import make_axes_locatable
import matplotlib
matplotlib.rcParams.update({'font.sans-serif' : 'Helvetica',
                            'axes.labelsize': 9,
                            'xtick.labelsize' : 9,
                            'ytick.labelsize' : 9,
                            'axes.titlesize' : 9})

from hips.plotting.layout import create_figure, create_axis_at_location

from pypolyagamma.pypolyagamma import psi_n
from scipy.special import gamma, gammaln
from scipy.integrate import cumtrapz
plt.ion()

def invgamma_envelope(xs, b):
    # Compute the density of an inverse gamma kernel
    alpha = 0.5
    beta = b**2 / 2.
    iglogpdf = b*np.log(2) + alpha * np.log(beta) - gammaln(alpha) + -(alpha+1) * np.log(xs) - beta/xs
    igpdf = np.exp(iglogpdf)
    igcdf = cumtrapz(igpdf / 2.0**b, xs) if np.size(xs) > 1 else None
    return igpdf, iglogpdf, igcdf

def gamma_envelope(xs, b):
    # Compute a gamma distribution envelope
    alpha = b
    beta = np.pi**2 / 8.
    glogpdf = b * np.log(6./np.pi) + alpha * np.log(beta) - gammaln(alpha) + (alpha-1) * np.log(xs) - beta*xs
    gpdf = np.exp(glogpdf)
    gcdf = cumtrapz(gpdf / (6/np.pi)**b, xs) if np.size(xs) > 1 else None
    return gpdf, glogpdf, gcdf

# Compute an inverse Gaussian envelope
def invgauss_envelope(xs, b):
    z = 1.
    mu = b / z
    lam = b**2
    igausslogpdf = b * np.log(2.) + 0.5 * np.log(lam) -0.5*np.log(2*np.pi*xs**3) - lam * (xs-mu)**2 / (2*mu**2 * xs)
    igausspdf = np.exp(igausslogpdf)
    igausscdf = cumtrapz(igausspdf / (2**b), xs) if np.size(xs) > 1 else None
    return igausspdf, igausslogpdf, igausscdf

def plot_psi(bs=[0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0], oneminus=False,
             varname="\\omega"):
    """
    In the draft we show that
    the J^*(x | b) density is well approximated by an
    inverse gamma distribution times a scaling factor,
    [1-(2+b)exp{-(4+4b)/2x} + (1+b)(4+b)/2 exp{-(16+8b)/2x} - o(1)]

    We know this factor (if it included its infinitely many terms)
    would have to be a number between 0 and 1. Empirically, it
    seems to decay approximately exponentially. Let's try to come
    up with a parametric approximation for this term.
    """

    xmax = 10.
    xs = np.linspace(0.001, xmax, 1000)

    Nmax = 20
    ns = np.arange(Nmax)

    import palettable
    fig = create_figure(figsize=(3,2), transparent=True)
    ax = create_axis_at_location(fig, 0.6, 0.5, 2., 1.3)
    ax.set_color_cycle(palettable.colorbrewer.sequential.BuGn_9.mpl_colors)
    for b in bs:
        y = 0
        Z = b * gamma(b) * np.exp(-b**2/(2*xs)) * 2**b / gamma(b) / np.sqrt(2*np.pi*xs**3)
        Sns = np.array([psi_n(xs,n,b) for n in ns])
        for trmn in Sns:
            y += trmn / Z

        if oneminus:
            y = 1-y
        ln = ax.plot(xs, y, lw=2, label="b=%.2f" % b)[0]

    ax.set_ylim(-1e-3, 1+1e-3)
    ax.set_xlabel("$%s$" % varname)
    if oneminus:
        ax.set_ylabel("$1-\Psi(%s \\, | \\,  b)$" % varname)
    else:
        ax.set_ylabel("$\Phi(%s \\, | \\,  b)$" % varname)
    plt.legend(loc="upper right", fontsize=8, frameon=False)
    plt.savefig("phi.pdf")

    plt.show()

def fit_psi_cdf(bs=[ 0.1, 0.25, 0.5, 0.75, 0.9, 1.0]):
    xmax = 10.
    xs = np.linspace(0.001, xmax, 1000)

    Nmax = 20
    ns = np.arange(Nmax)

    # gparams = []
    # igparams = []
    params = []
    plt.figure()
    for b in bs:
        print("b=", b)
        y = 0
        Z = b * gamma(b) * np.exp(-b**2/(2*xs)) * 2**b / gamma(b) / np.sqrt(2*np.pi*xs**3)
        Sns = np.array([psi_n(xs,n,b) for n in ns])
        for trmn in Sns:
            y += trmn / Z

        ln = plt.plot(xs,(y), label="b=%.2f" % b)[0]
        col = ln.get_color()

        # Make a distribution object for this cdf\
        import scipy.stats as stats
        cdf = 1-y
        # class theoretical_dist(stats.rv_continuous):
        #     def _cdf(self, x, *args):
        #         return np.interp(x, xs, cdf, left=0., right=1.)
        #
        # dist = theoretical_dist()
        # samples = dist.rvs(size=(10000,))

        # Define an objective for fitting a cdf
        def gamma_obj(logprms):
            prms = np.exp(logprms)
            shape, scale = prms[0], prms[1]
            gdist = stats.gamma(shape, scale=scale)
            return gdist.cdf(xs) - cdf

        def invgamma_obj(logprms):
            prms = np.exp(logprms)
            shape, scale = prms[0], prms[1]
            gdist = stats.invgamma(shape, scale=scale)
            return gdist.cdf(xs) - cdf

        def gengamma_obj(logprms):
            prms = np.exp(logprms)
            shape, shape2, scale = prms[0], prms[1], prms[2]
            dist = stats.gengamma(shape, shape2, scale=scale)
            return dist.cdf(xs) - cdf

        def weibull_obj(logprms):
            prms = np.exp(logprms)
            shape, scale = prms[0], prms[1]
            dist = stats.weibull_min(shape, scale=scale)
            return dist.cdf(xs) - cdf

        def exp_obj(logprms):
            prms = np.exp(logprms)
            scale = prms[0]
            dist = stats.expon(scale=scale)
            return dist.cdf(xs) - cdf

        def tanh_obj(prms):
            a,b = prms[0], prms[1]
            f =  (1+ np.tanh(a+b*xs))/2.
            return f - cdf

        # Now fit a few distributions to this and see how well they work
        from scipy.optimize import leastsq
        # gparam = stats.gamma.fit(samples)
        # gparam, _ = leastsq(gamma_obj, np.zeros(2))
        # gparam = np.exp(gparam)
        # gparams.append(gparam)
        # gdist = stats.gamma(gparam[0], scale=gparam[1])
        # plt.plot(xs, 1-gdist.cdf(xs), '--', color=col)

        # igparam = stats.invgamma.fit(samples)
        # igparam, _ = leastsq(invgamma_obj, np.zeros(2))
        # igparam = np.exp(igparam)
        # igparams.append(igparam)
        # igdist = stats.invgamma(igparam[0], scale=igparam[1])
        # plt.plot(xs, 1-igdist.cdf(xs), '-.', color=col)

        # param, _ = leastsq(gengamma_obj, np.zeros(3))
        # param = np.exp(param)
        # params.append(param)
        # dist = stats.gengamma(param[0], param[1], scale=param[2])
        # plt.plot(xs, 1-dist.cdf(xs), '-.', color=col)

        # param, _ = leastsq(weibull_obj, np.zeros(2))
        # param = np.exp(param)
        # params.append(param)
        # dist = stats.weibull_min(param[0], scale=param[1])
        # plt.plot(xs, 1-dist.cdf(xs), '-.', color=col)

        # param, _ = leastsq(exp_obj, np.zeros(1))
        # param = np.exp(param)
        # params.append(param)
        # dist = stats.expon(scale=param[0])
        # plt.plot(xs, 1-dist.cdf(xs), '-.', color=col)

        import ipdb; ipdb.set_trace()
        param, _ = leastsq(tanh_obj, np.zeros(2))
        params.append(param)
        f = (1 + np.tanh(param[0]+param[1]*xs))/2.
        plt.plot(xs, 1-f, '-.', color=col)

    plt.xlabel("x")
    plt.legend(loc="upper right")
    plt.show()

    # Plot the shapes and scales vs b
    # shapes = [gp[0] for gp in gparams]
    # scales = [gp[1] for gp in gparams]
    # plt.figure()
    # plt.subplot(221)
    # plt.plot(bs, shapes)
    # plt.ylabel("shape(b)")
    #
    # plt.subplot(222)
    # plt.plot(bs, scales)
    # plt.ylabel("scale(b)")
    #
    # ishapes = [gp[0] for gp in igparams]
    # iscales = [gp[1] for gp in igparams]
    #
    # plt.subplot(223)
    # plt.plot(bs, ishapes)
    # plt.ylabel("ishape(b)")
    #
    # plt.subplot(224)
    # plt.plot(bs, iscales)
    # plt.ylabel("iscale(b)")

    # ggshapes = [gp[0] for gp in params]
    # ggshapes2 = [gp[1] for gp in params]
    # ggscales = [gp[2] for gp in params]
    # plt.figure()
    # plt.subplot(131)
    # plt.plot(bs, ggshapes)
    # plt.ylabel("GG shape(b)")
    #
    # plt.subplot(132)
    # plt.plot(bs, ggshapes2)
    # plt.ylabel("GG shape2(b)")
    #
    # plt.subplot(133)
    # plt.plot(bs, ggscales)
    # plt.ylabel("GG scale(b)")

def plot_partial_sums(b=0.5):
    xmax = 5.
    xs = np.linspace(1e-3, xmax, 1000)

    Nmax = 5
    ns = np.arange(Nmax)
    Sns = np.array([psi_n(xs,n,b) for n in ns])

    # Check if partial sums are decreasing
    pgpdf = np.sum(Sns, axis=0)
    pgcdf = cumtrapz(pgpdf, xs)
    def _check_decreasing(X):
        # Make sure each row is smaller than the one before
        N,T = X.shape
        dec = np.ones(T, dtype=np.bool)
        for n in xrange(1,N):
            dec &= (X[n] <= X[n-1])
        return dec

    isdec = _check_decreasing(np.abs(Sns))
    print("Decreasing until cdf = ", pgcdf[np.amin(np.where(~isdec)[0])])

    # Plot the partial sums
    plt.figure()
    cm = get_cmap("Greys")
    for n in xrange(1,Nmax):
        plt.plot(xs, np.sum(Sns[:n], axis=0),
                 color=cm(np.clip(float(n)/Nmax, 0.3, 0.7)),
                 label="n=%d" % n)
    plt.legend()

    plt.figure()
    cm = get_cmap("Greys")
    for n in xrange(Nmax):
        plt.plot(xs, Sns[n],
                 color=cm(np.clip(1-float(n)/Nmax, 0.3, 0.7)),
                 label="n=%d" % n)
    plt.legend()

def approx_threshold(b):
    # b=0.10, thr=0.2
    # b=1.00, thr=2.0
    # thr = mb + c
    # m = (2-0.2) / (1-0.1)
    m = 2.0
    # c = thr - m*b = 2.0 - m * 1.0 = 0.0
    c = 0.0
    return m*b + c

def plot_envelopes():

    xmax = 5.
    xs = np.linspace(1e-3, xmax, 1000)
    bs = np.linspace(1e-1, 1.00, 10)
    ints = []

    def _find_intersect(y1,y2,start=0,stop=-1):
        return start + np.argmin((y1[start:stop]-y2[start:stop])**2)

    plt.figure()
    for i,b in enumerate(bs):
        # Get envelopes
        igpdf, iglogpdf, igcdf = invgamma_envelope(xs, b)
        igausspdf, igausslogpdf, igausscdf = invgauss_envelope(xs, b)
        int = _find_intersect(igpdf, igausspdf,
                              start=np.argmin((xs-0.05)**2),
                              stop=np.argmin((xs-2.0)**2))
        ints.append(int)
        # alpha = 0.1 + (0.9 * i)/len(bs)
        alpha = 0.5
        plt.plot(xs, igpdf, '-b', alpha=alpha)
        plt.plot(xs, igausspdf, '-r', alpha=alpha)
        plt.plot(xs[int], igpdf[int], 'ko')

    # Plot the approximate thresholds
    bbs = np.linspace(bs[0], bs[-1])
    thr = approx_threshold(bbs)
    ythr = np.array([invgauss_envelope(t,b) for t,b in zip(thr,bbs)])
    plt.plot(thr, ythr, '-k' )

    plt.ylim(0,1)
    plt.ylabel("l(x | b) and r(x|b)")
    plt.xlabel("x")
    plt.savefig("smallb_envelopes.png")
    plt.show()

    plt.figure()
    plt.plot(bs, xs[ints], 'ok')
    plt.plot(bbs, thr, '-k')
    plt.show()

    plt.savefig("smallb_crossover.png")

def plot_pdf_and_envelope():
    xmax = 5.
    xs = np.linspace(1e-3, xmax, 1000)
    Nmax = 20
    ns = np.arange(Nmax)
    B = 5
    bs = np.linspace(0.1, 0.95, B)

    plt.figure(figsize=(12,12))
    for i,b in enumerate(bs):
        # Get the terms of the sum
        Sns = np.array([psi_n(xs,n,b) for n in ns])

        # Plot the pdf and the envelopes
        pgpdf = np.sum(Sns, axis=0)
        pgcdf = cumtrapz(pgpdf, xs)
        pglogpdf = np.log(pgpdf)

        # Find the threshold
        # thr = approx_threshold(b)
        # ithr = np.argmin((xs-thr)**2)

        # Get envelopes
        igpdf, iglogpdf, igcdf = invgamma_envelope(xs, b)
        # igausspdf, igausslogpdf, igausscdf = invgauss_envelope(xs[ithr:], b)

        plt.subplot(B,2,2*i+1)
        plt.plot(xs, pgpdf, 'k')
        plt.plot(xs, igpdf, 'b')
        # plt.plot(xs[ithr:], igausspdf,  'r')
        plt.ylabel("p(x | b=%.1f)" % b)
        if i == B-1:
            plt.xlabel("x")

        plt.subplot(B,2,2*i+2)
        plt.plot(xs, pglogpdf, 'k')
        plt.plot(xs, iglogpdf, 'b')
        # plt.plot(xs[ithr:], igausslogpdf, 'r')
        plt.ylim(pglogpdf[-1],5)
        plt.ylabel("log p(x | b=%.1f)" % b)
        if i == B-1:
            plt.xlabel("x")

    # plt.savefig("smallb_pdf_and_envelopes.png")

def plot_acceptance_probability():
    zmin, zmax = -1.5, 1.5
    bmin, bmax = 0, 1
    zs = np.linspace(zmin,zmax,100)
    bs = np.linspace(bmin,bmax,50)
    Zs, Bs = np.meshgrid(zs, bs)
    c = (1+np.exp(-2*abs(Zs)))**Bs
    p = 1./c

    from palettable.colorbrewer.sequential import BuGn_5
    cmap = BuGn_5.mpl_colormap
    #fig = create_figure(figsize=(3,1.5), transparent=True)
    #ax = create_axis_at_location(fig, 0.6, 0.4, 1.8, .8)

    fig = create_figure(figsize=(3.,2.), transparent=True)
    ax = create_axis_at_location(fig, 0.6, 0.5, 1.8, 1.3)

    # ax = fig.add_subplot(111)
    im = ax.imshow(p, cmap=cmap, vmin=0.5, vmax=1., extent=(zmin,zmax,bmax,bmin), aspect=2.15)
    ax.set_xlabel("$\psi$")
    ax.set_ylabel("$b$")
    ax.set_yticks((0, 0.25, 0.5, 0.75, 1.0))
    ax.set_title("Acceptance Probability")

    # create an axes on the right side of ax. The width of cax will be 5%
    # of ax and the padding between cax and ax will be fixed at 0.05 inch.
    # divider = make_axes_locatable(plt.gca())
    # cax = divider.append_axes("right", size="5%", pad=0.05)
    cax = create_axis_at_location(fig, 2.5, 0.5, .1, 1.3)
    cbar = plt.colorbar(im, cax=cax, ticks=(0.5, 0.75, 1.0))

    plt.savefig("acceptance.pdf")
    plt.show()

def quantile_comparison(b):
    """
    Compare our rejection sampling algorithm with the truncated
    sum of gammas algorithm.
    """
    n = 10000
    zs = 1.0 * np.ones(n, dtype=np.float)

    from pypolyagamma import pypolyagamma
    x_rej = pypolyagamma.sample_pg_small_b(b, zs)

    # Sample with the sum of gammas approach
    ppg = pypolyagamma.PyPolyaGamma(np.random.randint(2**16), trunc=200)
    x_sum = np.zeros(n)
    ppg.pgdrawv(b * np.ones(n, dtype=np.float), zs, x_sum)

    from scipy.stats.mstats import mquantiles
    quantiles = np.arange(0.1, 1.0, 0.1)
    q_rej = mquantiles(x_rej, quantiles, alphap=0., betap=1.)
    q_sum = mquantiles(x_sum, quantiles, alphap=0., betap=1.)
    lim = max(q_rej.max(), q_sum.max())

    plt.figure()
    plt.plot(q_rej, q_sum, lw=2)
    plt.plot([0, 1.1*lim], [0, 1.1*lim], '--k')
    plt.show()

# bs = np.linspace(0.05,1.0,9)
# plot_partial_sums(b=0.9)
# plot_envelopes()
# plot_pdf_and_envelope()
# fit_psi_cdf(bs)
plot_psi()
#plot_acceptance_probability()
# quantile_comparison(0.5)


import sys, os
# Tell script directiory of HPC input gen module
gmxModDir = os.path.join('..', '..', 'gromacs_hpc_input_gen')
sys.path.append(gmxModDir)

# Load default mdp dictionaries, simulation class
import default_mdp_dicts as mdp
from sim_class import SimGromacs, finalize_simulation

outputDir = os.getcwd()

shellName = 'run_gromacs.sh'
currentCoords = '1024xC15-AA_12nsEq_L-OPLS.gro'
hpcHeader = os.path.join(gmxModDir, 'MMM_header_2016-3.sh')
mdrunCmd = 'gerun mdrun_mpi'

# Strings to replace in shell header
pbsVars = {'ncpus': '96', 'walltime': '48:00:00', 'budgetname': 'QMUL_BURROWS'}

# Set force field parameters
mdpFF = dict(mdp.L_OPLS)
mdpFF['tau-p'] = '4.0' # Add mdpFF after ensemble in mdp list to overwrite e.g. [mdp.NPT_eq, mdpFF]

# Open shell script for writing
shellFile = open(os.path.join(outputDir, shellName), 'w', newline='\n') # Must use unix line endings

# Write HPC header file (with job description)
for line in open(hpcHeader):
	for var, rep in pbsVars.items():
		line = line.replace(var, rep)

	shellFile.write(line)

# Wesbarnett, 2fs ts
newSim = SimGromacs([mdp.NPT, dict(mdpFF)], shellFile,
			mdrun=mdrunCmd,
			suffix='NPT_wb_2fs',
			topol='wb_topol.top',
			coords=currentCoords)
newSim.set_param('nsteps', 2000000) # 4ns
newSim.set_param('dt', 0.002)
newSim.set_param('define', '-DLOPLS')
finalize_simulation(newSim, shellFile, outputDir)

# Wesbarnett, 1fs ts
newSim = SimGromacs([mdp.NPT, dict(mdpFF)], shellFile,
			mdrun=mdrunCmd,
			suffix='NPT_wb_1fs',
			topol='wb_topol.top',
			coords=currentCoords)
newSim.set_param('nsteps', 4000000) # 4ns
newSim.set_param('dt', 0.001)
newSim.set_param('define', '-DLOPLS')
finalize_simulation(newSim, shellFile, outputDir)

# Minimal, 2fs ts
newSim = SimGromacs([mdp.NPT, dict(mdpFF)], shellFile,
			mdrun=mdrunCmd,
			suffix='NPT_minimal_2fs',
			topol='minimal_topol.top',
			coords=currentCoords)
newSim.set_param('nsteps', 2000000) # 4ns
newSim.set_param('dt', 0.002)
finalize_simulation(newSim, shellFile, outputDir)

# Minimal, 1fs ts
newSim = SimGromacs([mdp.NPT, dict(mdpFF)], shellFile,
			mdrun=mdrunCmd,
			suffix='NPT_minimal_1fs',
			topol='minimal_topol.top',
			coords=currentCoords)
newSim.set_param('nsteps', 4000000) # 4ns
newSim.set_param('dt', 0.001)
finalize_simulation(newSim, shellFile, outputDir)


# -*- coding: utf-8 -*-
# See LICENSE file for full copyright and licensing details.

"""
Added class and
"""

import html
import math
import time
from datetime import datetime, timedelta

from odoo import models, fields, api, _
from odoo.addons.iap.tools import iap_tools
from odoo.exceptions import UserError

from ..endpoint import DEFAULT_ENDPOINT

class AmazonProductEpt(models.Model):
    _name = "amazon.product.ept"
    _description = "Amazon Product Mapping with Odoo Products"

    name = fields.Char()
    product_id = fields.Many2one('product.product', string='Odoo Product', ondelete="cascade",
                                 help="ERP Product Reference")
    instance_id = fields.Many2one('amazon.instance.ept', string='Instance', required=True,
                                  copy=False, help="Recognise Products to unique Amazon Instances")
    product_asin = fields.Char(copy=False, help="Amazon Product ASIN")
    asin_qty = fields.Integer("Number Of Items In One Package", default=1,
                              help="Amazon Product's Number of Quantity in One Packet")
    product_upc = fields.Char("UPC", copy=False)
    fulfillment_by = fields.Selection(
        [('FBM', 'Manufacturer Fulfillment Network'), ('FBA', 'Amazon Fulfillment Network')],
        default='FBM', help="Amazon Fulfillment Type")
    fix_stock_type = fields.Selection([('fix', 'Fix'), ('percentage', 'Percentage')])
    fix_stock_value = fields.Float(digits="Product UoS")
    exported_to_amazon = fields.Boolean(default=False, copy=False,
                                        help="True:Product exported to Amazon or False: "
                                             "Product is not exported to Amazon.")
    seller_sku = fields.Char(help="Amazon Seller SKU")
    barcode = fields.Char(related="product_id.barcode")
    long_description = fields.Text("Product Description", help="Long description of the product")
    active = fields.Boolean("Active", related="product_id.active")
    fulfillment_channel_sku = fields.Char()
    last_feed_submission_id = fields.Char(readonly=True, copy=False)
    error_in_export_product = fields.Boolean(default=False, copy=False)
    _sql_constraints = [('amazon_instance_seller_sku_unique_constraint',
                         'unique(instance_id,seller_sku,fulfillment_by)',
                         "Seller sku must be unique per instance & Fulfillment By")]

    @api.model
    def search_product(self, seller_sku):
        product_obj = self.env['product.product']
        if self.env.ref('product.product_comp_rule').active:
            cur_usr = self.env.user
            company_id = cur_usr.company_id.id or False
            product = product_obj.search(
                ['|', ('company_id', '=', False), ('company_id', '=', company_id),
                 ('default_code', '=', seller_sku)])
            if len(product) > 1:
                raise UserError(_('Duplicate Product Found For Sku (%s)' % seller_sku))
            if not product:
                product = product_obj.search( \
                    ['|', ('company_id', '=', False), ('company_id', '=', company_id),
                     ('default_code', '=', seller_sku), ('active', '=', False)])
                if len(product) > 1:
                    raise UserError(_('Duplicate Product Found For Sku (%s)' % seller_sku))
                if product and not product.active:
                    product.write({'active': True})
            return product or False
        product = product_obj.search([('default_code', '=', seller_sku)])
        if len(product) > 1:
            raise UserError(_('Duplicate Product Found For Sku (%s)' % seller_sku))
        if not product:
            product = product_obj.search( \
                [('default_code', '=', seller_sku), ('active', '=', False)])
            if len(product) > 1:
                raise UserError(_('Duplicate Product Found For Sku (%s)' % seller_sku))
            if product and not product.active:
                product.write({'active': True})
        return product or False

    @api.model
    def search_amazon_product(self, instance_id, seller_sku, fulfillment_by='FBM'):
        """
        This method will find the amazon product
        """
        seller_sku = seller_sku.strip()
        product = self.search( \
            ['|', ('active', '=', False), ('active', '=', True), ('seller_sku', '=', seller_sku),
             ('instance_id', '=', instance_id), ('fulfillment_by', '=', fulfillment_by)], limit=1)
        if not product:
            return False
        if not product.active:
            product.write({'active': True})
        return product[0]

    standard_product_id_type = fields.Selection(
        [('EAN', 'EAN'), ('ASIN', 'ASIN'), ('GTIN', 'GTIN'), ('UPC', 'UPC')],
        string="Standard Product ID", default='ASIN')
    related_product_type = fields.Selection([('UPC', 'UPC'), ('EAN', 'EAN'), ('GTIN', 'GTIN')])
    related_product_value = fields.Char()
    launch_date = fields.Datetime(help="Controls when the product appears in search and "
                                       "browse on the Amazon website")
    release_date = fields.Datetime(help="The date a product is released for sale")
    discontinue_date = fields.Datetime(help="The date a product is Discontinue for sale")
    condition = fields.Selection([('New', 'New'),
                                  ('UsedLikeNew', 'UsedLikeNew'),
                                  ('UsedVeryGood', 'UsedVeryGood'),
                                  ('UsedGood', 'UsedGood'),
                                  ('CollectibleLikeNew', 'CollectibleLikeNew'),
                                  ('CollectibleVeryGood', 'CollectibleVeryGood'),
                                  ('CollectibleGood', 'CollectibleGood'),
                                  ('CollectibleAcceptable', 'CollectibleAcceptable'),
                                  ('Club', 'Club')], default='New', copy=False)

    item_package_qty = fields.Integer(string="Package Quantity", default=1,
                                      help="Number of the same product contained within"
                                           "one package. "
                                           "For example, "
                                           "if you are selling a case of 10 packages of socks, "
                                           "ItemPackageQuantity would be 10.")

    brand = fields.Char(string="Product Brand",
                        related='product_id.product_tmpl_id.product_brand_id.name', readonly=True)
    designer = fields.Char(help="Designer of the product")

    bullet_point_ids = fields.One2many('amazon.product.bullet.description', 'amazon_product_id',
                                       string="Bullet Point Description")

    package_weight = fields.Float(help="Weight of the package", digits="Stock Weight")
    shipping_weight = fields.Float(help="Weight of the product when packaged to ship",
                                   digits="Stock Weight")
    max_order_quantity = fields.Integer("Maximum Order Quantity",
                                        help="Maximum quantity of the product that a customer can "
                                             "order")

    manufacturer = fields.Char(related='product_id.product_tmpl_id.product_brand_id.partner_id.name',
                               readonly=True)

    search_term_ids = fields.One2many('amazon.product.search.term', 'amazon_product_id',
                                      string="Search Term")
    is_gift_wrap_available = fields.Boolean("Is Gift Wrap Available ?",
                                            help="Indicates whether gift wrapping is available for "
                                                 "the product")

    is_gift_message_available = fields.Boolean("Is Gift Message Available ?",
                                               help="Indicates whether gift messaging is available "
                                                    "for the product")
    gtin_exemption_reason = fields.Selection([('bundle', 'Bundle'), ('part', 'Part')],
                                             string="GtinExemptionReason")
    package_weight_uom = fields.Selection(
        [('GR', 'GR'), ('KG', 'KG'), ('OZ', 'OZ'), ('LB', 'LB'), ('MG', 'MG')], default='KG')

    shipping_weight_uom = fields.Selection(
        [('GR', 'GR'), ('KG', 'KG'), ('OZ', 'OZ'), ('LB', 'LB'), ('MG', 'MG')], default='KG')
    item_dimensions_uom = fields.Selection(
        [('CM', 'CM'), ('FT', 'FT'), ('M', 'M'), ('IN', 'IN'), ('MM', 'MM')],
        string="Item Dimension", default='CM')

    item_height = fields.Float(help="Height of the item dimension", digits="Stock Height")
    item_length = fields.Float(help="Length of the item dimension", digits="Stock Height")
    item_width = fields.Float(help="Width of the item dimension", digits="Stock Height")

    package_dimensions_uom = fields.Selection(
        [('CM', 'CM'), ('FT', 'FT'), ('M', 'M'), ('IN', 'IN'), ('MM', 'MM')],
        string="Package Dimension", default='CM')
    package_height = fields.Float(help="Height of the package dimension", digits="Stock Height")
    package_length = fields.Float(help="Length of the package dimension", digits="Stock Height")
    package_width = fields.Float(help="Width of the package dimension", digits="Stock Height")
    allow_package_qty = fields.Boolean(default=False)
    fulfillment_latency = fields.Integer()

    def get_amazon_product_request_data_ept(self, instance, data, emipro_api):
        """
        Defined common method to prepare the amazon product request data
        """
        account = self.env['iap.account'].search([('service_name', '=', 'amazon_ept')])
        dbuuid = self.env['ir.config_parameter'].sudo().get_param('database.uuid')

        kwargs = {'merchant_id': instance.merchant_id and str(instance.merchant_id) or False,
                  'auth_token': instance.auth_token and str(instance.auth_token) or False,
                  'app_name': 'amazon_ept',
                  'account_token': account.account_token,
                  'emipro_api': emipro_api,
                  'dbuuid': dbuuid,
                  'amazon_marketplace_code': instance.country_id.amazon_marketplace_code or
                                             instance.country_id.code,
                  'data': data,
                  'instance_id': instance.id, }
        return kwargs

    def export_product_amazon(self, instance):
        """
        This Method Relocates export amazon product listing in amazon.
        :param instance:This argument relocates instance of amazon.
        :return: This Method return Boolean(True/False).
        """
        data = self.create_product_envelope(instance)

        kwargs = self.get_amazon_product_request_data_ept(instance, data,
                                                          'export_product_amazon_v13')
        response = iap_tools.iap_jsonrpc(DEFAULT_ENDPOINT + '/iap_request', params=kwargs)
        if response.get('reason'):
            raise UserError(_(response.get('reason')))
        results = response.get('result')
        self.process_export_product_amazon_result(instance, data, results)
        return True

    def process_export_product_amazon_result(self, instance, data, results):
        feed_submission_obj = self.env['feed.submission.history']
        if results.get('FeedSubmissionInfo', {}).get('FeedSubmissionId', {}).get('value', False):
            last_feed_submission_id = results.get(
                'FeedSubmissionInfo', {}).get('FeedSubmissionId', {}).get('value', False)
            for amazon_product in self:
                amazon_product.write( \
                    {'exported_to_amazon': True, 'last_feed_submission_id': last_feed_submission_id, \
                     'error_in_export_product': False})

            vals = {'message': data, 'feed_result_id': last_feed_submission_id,
                    'feed_submit_date': time.strftime("%Y-%m-%d %H:%M:%S"),
                    'instance_id': instance.id, 'user_id': self._uid,
                    'feed_type': 'export_product',
                    'seller_id': instance.seller_id.id}
            feed_submission_obj.create(vals)
        return True

    def create_product_envelope(self, instance):
        """
        This Method relocates prepare envelope for amazon.
        :param amazon_products: This arguments relocates product listing of amazon.
        :param instance: This argument relocates instance of amazon.
        :return: This argument return envelope of amazon.
        """
        message_id = 0
        messages = ''
        for product in self:
            message_id = message_id + 1
            messages = "%s %s" % (messages, self.get_message(message_id, product))
        header = self.get_header(instance)
        data = "%s %s %s" % (header, messages, '</AmazonEnvelope>')
        return data

    def get_message(self, message_id, product):
        """
        This Method relocates prepare envelop message for amazon product.
        :param message_id:This argument relocates message id of amazon because of amazon
        depends on message id.
        :param product:This arguments relocates product listing of amazon
        :return: This Method return amazon envelope message.
        """
        message = """
                <MessageID>%s</MessageID>
                <OperationType>PartialUpdate</OperationType>
                <Product>""" % (message_id)
        message = "%s %s" % (message, self.standard_product_code(product))
        if product.standard_product_id_type == 'GTIN':
            message = "%s %s" % (message, "<GtinExemptionReason>%s</GtinExemptionReason>" % ( \
                product.gtin_exemption_reason))
        if product.related_product_type:
            message = "%s %s" % (message, self.get_related_product_type(product))

        luanch_date = self.get_lanuch_date(product)
        if luanch_date:
            message = "%s %s" % (message, luanch_date)
        discontinue_date = self.get_discontinue_date(product)
        if discontinue_date:
            message = "%s %s" % (message, discontinue_date)
        release_date = self.get_release_date(product)
        if release_date:
            message = "%s %s" % (message, release_date)
        condition = self.get_condition(product)
        if condition:
            message = "%s %s" % (message, condition)
        message = "%s %s" % (message, self.item_package_qty_and_no_of_items(product))
        description_data = self.get_description_data(product)
        message = "%s %s" % (message, description_data)

        item_dimension = self.get_item_dimension(product)
        if item_dimension:
            message = "%s %s" % (message, item_dimension)

        package_dimension = self.get_package_dimension(product)
        if package_dimension:
            message = "%s %s" % (message, package_dimension)

        amazon_only = "<Amazon-Only>"
        if len(amazon_only) > 14:
            amazon_only = "%s %s" % (amazon_only, "</Amazon-Only>")
            message = "%s %s" % (message, amazon_only)
        message = "%s </Product>" % (message)
        return "<Message>%s</Message>" % (message)

    def get_header(self, instnace):
        """
        This Method relocates prepare header of envelope for amazon product listing.
        :param instnace: This argument relocates instance of amazon.
        :return: This Method return header of envelope for amazon product listing.
        """
        return """<?xml version="1.0"?>
            <AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
            <Header>
                <DocumentVersion>1.01</DocumentVersion>
                <MerchantIdentifier>%s</MerchantIdentifier>
            </Header>
            <MessageType>Product</MessageType>
            <PurgeAndReplace>false</PurgeAndReplace>
         """ % (instnace.merchant_id)

    def standard_product_code(self, product):
        """
        This Method prepare envelope message of standard product type for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return standard product type envelope message for amazon.
        """
        product_code, product_type = '', ''
        if product.standard_product_id_type in ['GTIN']:
            return """<SKU>%s</SKU>""" % product.seller_sku
        if product.standard_product_id_type == 'ASIN':
            product_code, product_type = product.product_asin, 'ASIN'
        elif product.standard_product_id_type == 'EAN':
            product_code, product_type = product.barcode, 'EAN'
        elif product.standard_product_id_type == 'GTIN':
            product_code, product_type = product.product_upc, 'GTIN'
        elif product.standard_product_id_type == 'UPC':
            product_code, product_type = product.product_upc, 'UPC'
        return """<SKU>%s</SKU>
                         <StandardProductID>
                             <Type>%s</Type>
                             <Value>%s</Value>
                         </StandardProductID>
                       """ % (product.seller_sku, product_type, product_code)

    def get_lanuch_date(self, product):
        """
        This Method prepare envelope message of lunch date for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return lunch date envelope message for amazon.
        """
        launch_date = product.launch_date and datetime.strftime(product.launch_date,
                                                                "%Y-%m-%d %H:%M:%S") or False
        return launch_date and " <LaunchDate>%s</LaunchDate>" % (launch_date) or False

    def get_related_product_type(self, product):
        """
        This Method prepare envelope message of related product type for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return related product type envelope message for amazon.
        """
        return """<RelatedProductID>
                          <Type>%s</Type>
                          <Value>%s</Value>
                      </RelatedProductID>""" % ( \
            product.related_product_type, product.related_product_value)

    def get_discontinue_date(self, product):
        """
        This Method prepare envelope message of discontinue date for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return discontinue date envelope message for amazon.
        """
        discontinue_date = product.discontinue_date and datetime.strftime( \
            product.discontinue_date, "%Y-%m-%d %H:%M:%S") or False
        return discontinue_date and " <DiscontinueDate>%s</DiscontinueDate>" % ( \
            discontinue_date) or False

    def get_release_date(self, product):
        """
        This Method prepare envelope message of release date for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return release date envelope message for amazon.
        """
        release_date = product.release_date and datetime.strftime( \
            product.release_date, "%Y-%m-%d %H:%M:%S") or False
        return release_date and " <ReleaseDate>%s</ReleaseDate>" % release_date or False

    def get_item_dimension(self, product):
        """
        This Method prepare envelope message of item dimension for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return item dimension envelope message for amazon.
        """
        if product.item_dimensions_uom:
            return """
                    <ItemDimensions>
                        <Length unitOfMeasure='%s'>%s</Length>
                        <Width unitOfMeasure='%s'>%s</Width>
                        <Height unitOfMeasure='%s'>%s</Height>

                    </ItemDimensions>
                    """ % ( \
                product.item_dimensions_uom, str(round(float(product.item_length), 2)),
                product.item_dimensions_uom, \
                str(round(float(product.item_width), 2)), product.item_dimensions_uom, \
                str(round(float(product.item_width), 2)))

    def get_package_dimension(self, product):
        """
        This Method prepare envelope message of package dimension for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return package dimension envelope message for amazon.
        """
        if product.package_dimensions_uom:
            return """
                    <PackageDimensions>
                        <Length unitOfMeasure='%s'>%s</Length>
                        <Width unitOfMeasure='%s'>%s</Width>
                        <Height unitOfMeasure='%s'>%s</Height>

                    </PackageDimensions>
                    """ % ( \
                product.package_dimensions_uom, str(round(float(product.package_length), 2)),
                product.item_dimensions_uom,
                str(round(float(product.package_width), 2)), product.item_dimensions_uom,
                str(round(float(product.package_width), 2)))

    def get_condition(self, product):
        """
        This Method prepare envelope message of condition for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return condition envelope message for amazon.
        """
        if product.condition:
            return """<Condition>
                            <ConditionType>%s</ConditionType>
                      </Condition>""" % product.condition
        return False

    def item_package_qty_and_no_of_items(self, product):
        """
        This Method prepare envelope message of item package qty and no of items for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return item package qty and no of items envelope message for amazon.
        """
        item_pack = ''
        if product.item_package_qty > 0:
            item_pack = "%s %s" % (
                item_pack,
                "<ItemPackageQuantity>%s</ItemPackageQuantity>" % (product.item_package_qty))
        if product.asin_qty > 0:
            item_pack = "%s %s" % (
                item_pack, "<NumberOfItems>%s</NumberOfItems>" % (product.asin_qty))
        return item_pack

    def get_description_data(self, product):
        """
        This Method prepare envelope message of description data for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return description data envelope message for amazon.
        """
        data = []
        if product.name:
            data.append("<Title>%s</Title>" % (html.escape(product.name)))  # .encode("utf-8")
        else:
            data.append("<Title>%s</Title>" % (
                html.escape(product.name)))  # .encode("utf-8")
        product.brand and data.append(
            "<Brand>%s</Brand>" % (html.escape(product.brand)))  # .encode("utf-8")
        product.designer and data.append(
            "<Designer>%s</Designer>" % (html.escape(product.designer)))  # .encode("utf-8")
        description = product.long_description or False
        description and data.append("<Description>%s</Description>" % (html.escape(description)))

        product.bullet_point_ids and data.append(self.get_bullet_points(product))
        if product.package_weight > 0.0:
            data.append("""<PackageWeight unitOfMeasure='%s'>%s</PackageWeight>""" % (
                product.package_weight_uom, str(round(float(product.package_weight), 2))))

        if product.shipping_weight > 0.0:
            data.append("""<ShippingWeight unitOfMeasure='%s'>%s</ShippingWeight>""" % ( \
                product.shipping_weight_uom, str(round(float(product.shipping_weight), 2))))
        if product.max_order_quantity > 0:
            data.append("<MaxOrderQuantity>%s</MaxOrderQuantity>" % product.max_order_quantity)
        product.manufacturer and data.append(
            "<Manufacturer>%s</>" % (html.escape(product.manufacturer)))
        product.search_term_ids and data.append(self.get_search_terms(product))
        data.append("<IsGiftWrapAvailable>%s</IsGiftWrapAvailable>" % (
            str(product.is_gift_wrap_available).lower()))
        data.append("<IsGiftMessageAvailable>%s</IsGiftMessageAvailable>" % (
            str(product.is_gift_message_available).lower()))

        description_data = ''
        for tag in data:
            description_data = "%s %s" % (description_data, tag)
        return "<DescriptionData>%s</DescriptionData>" % (str(description_data))

    def get_search_terms(self, product):
        """
        This Method prepare envelope message of search term for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return search term envelope message for amazon.
        """
        search_terms = ''
        for search_term in product.search_term_ids:
            search_term = """<SearchTerms>%s</SearchTerms>""" % (html.escape(search_term.name))
            search_terms = "%s %s" % (search_terms, search_term)
        return search_terms

    def get_bullet_points(self, product):
        """
        This Method prepare envelope message of bullet points description for amazon.
        :param product: This arguments relocates product of amazon.
        :return: This method return bullet points description envelope message for amazon.
        """
        bullet_points = ''
        for bullet in product.bullet_point_ids:
            bullet_point = """<BulletPoint>%s</BulletPoint>""" % (html.escape(bullet.name))
            bullet_points = '%s %s' % (bullet_points, bullet_point)
        if product.bullet_point_ids:
            return bullet_points

    def export_stock_levels(self, instance):
        """
        This method used to export product stock to amazon
        """
        warehouse_ids = instance.warehouse_id.ids
        if instance.stock_update_warehouse_ids:
            warehouse_ids += instance.stock_update_warehouse_ids.ids
            warehouse_ids = list(set(warehouse_ids))

        product_ids = self.mapped('product_id')
        amazon_products = self.ids
        self.process_export_stock_message_info_ept( \
            instance, product_ids.ids, amazon_products, warehouse_ids)
        return True

    def export_amazon_stock_levels_operation(self, instance):
        """
        This Method relocates prepare envelop for inventory.
        :return: This Method return Boolean(True/False).
        """
        prod_obj = self.env['product.product']
        from_datetime = instance.inventory_last_sync_on
        company = instance.company_id

        warehouse_ids = instance.warehouse_id.ids
        warehouse_ids += instance.stock_update_warehouse_ids.ids if \
            instance.stock_update_warehouse_ids else []
        warehouse_ids = list(set(warehouse_ids))

        if not from_datetime:
            from_datetime = datetime.today() - timedelta(days=365)
        product_ids = prod_obj.get_products_based_on_movement_date_ept(from_datetime, company)
        amazon_products = self.env['amazon.product.ept'].search([('exported_to_amazon', '=', True),
                                                                 ('instance_id', '=', instance.id),
                                                                 ('fulfillment_by', '=', 'FBM'),
                                                                 ('product_id', 'in', product_ids)])
        product_ids = amazon_products.mapped('product_id')
        self.process_export_stock_message_info_ept( \
            instance, product_ids.ids, amazon_products.ids, warehouse_ids)
        return True

    def process_export_stock_message_info_ept(self, instance, product_ids, amazon_products_ids,
                                              warehouse_ids):
        product_listing_stock = self.check_stock_type(instance, product_ids, warehouse_ids)
        if product_listing_stock:
            message_information = ''
            message_id = 1
            for amazon_product_id in amazon_products_ids:
                amazon_product = self.browse(amazon_product_id)
                stock = product_listing_stock.get(amazon_product.product_id.id)
                message_information = self.prepare_export_stock_level_dict_operation( \
                    amazon_product, instance, stock, message_information, message_id)
                message_id += 1
            if message_information:
                self.process_amazon_export_stock_dict_ept(instance, message_information)
        return True

    def process_amazon_export_stock_dict_ept(self, instance, message_information):
        """
        This method will prepare the message information
        """
        merchant_string = "<MerchantIdentifier>%s</MerchantIdentifier>" % ( \
            instance.merchant_id)
        data = """<?xml version="1.0" encoding="utf-8"?><AmazonEnvelope xmlns:xsi=
        "http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
        <Header><DocumentVersion>1.01</DocumentVersion>""" + merchant_string + """</Header>
        <MessageType>Inventory</MessageType>""" + message_information + """</AmazonEnvelope>"""
        kwargs = self.get_amazon_product_request_data_ept(instance, data,
                                                          'export_stock_levels_v13')
        kwargs.update({'marketplaceids': [instance.market_place_id]})

        response = iap_tools.iap_jsonrpc(DEFAULT_ENDPOINT + '/iap_request', params=kwargs)
        self.process_amazon_export_stock_response_ept(instance, data, response)
        return True

    def process_amazon_export_stock_response_ept(self, instance, data, response):
        amazon_process_job_log_obj = self.env['common.log.book.ept']
        amazon_feed_submit_history = self.env['feed.submission.history']

        if response.get('reason'):
            amazon_process_job_log_obj.create({
                'module': 'amazon_ept',
                'type': 'export',
                'res_id': self.id,
                'model_id': self.env['ir.model']._get('amazon.product.ept').id,
                'active': True,
                'log_lines': [(0, 0, {'message': response.get('reason')})]
            })
        else:
            result = response.get('result')
            seller_id = self._context.get('seller_id', False) or instance.seller_id
            if seller_id:
                last_feed_submission_id = result.get('FeedSubmissionInfo', {}).get( \
                    'FeedSubmissionId', {}).get('value', False)
                vals = {'message': data, 'feed_result_id': last_feed_submission_id,
                        'feed_submit_date': time.strftime("%Y-%m-%d %H:%M:%S"),
                        'instance_id': instance.id, 'user_id': self._uid,
                        'feed_type': 'export_stock',
                        'seller_id': instance.seller_id.id}
                amazon_feed_submit_history.create(vals)
        return True

    def check_stock_type(self, instance, product_ids, warehouse_ids):
        """
        This Method relocates check type of stock.
        :param instance: This arguments relocates instance of amazon.
        :param product_ids: This arguments product listing id of odoo.
        :param warehouse_ids:This arguments relocates warehouses of amazon.
        :return: This Method return product listing stock.
        """
        product_listing_stock = []
        prod_obj = self.env['product.product']
        ware_obj = self.env['stock.warehouse']
        if product_ids:
            warehouses = ware_obj.browse(warehouse_ids)
            if instance.stock_field == 'free_qty':
                product_listing_stock = prod_obj.get_free_qty_ept(warehouses, product_ids)
            elif instance.stock_field == 'virtual_available':
                product_listing_stock = prod_obj.get_forecasted_qty_ept(warehouses, product_ids)
        return product_listing_stock

    def prepare_export_stock_level_dict_operation(self, amazon_product, instance, actual_stock,
                                                  message_information, message_id):

        """
        This Method relocates prepare envelope of export stock value.
        :param amazon_product: This arguments relocates product of amazon.
        :param instance: This arguments relocates instance of amazon.
        :param actual_stock : stock
        :param message_information: This arguments relocates message information.
        :param message_id: This arguments relocates message id of amazon envelope.
        :return: This method return message envelope for amazon.
        """
        seller_sku = html.escape(amazon_product['seller_sku'])
        stock = self.stock_ept_calculation(actual_stock,
                                           amazon_product['fix_stock_type'],
                                           amazon_product['fix_stock_value'])

        if amazon_product['allow_package_qty']:
            asin_qty = amazon_product['asin_qty']
            stock = math.floor(stock / asin_qty) if asin_qty > 0.0 else stock

        stock = 0 if int(stock) < 1 else int(stock)
        fullfillment_latency = amazon_product['fulfillment_latency'] or \
                               instance.seller_id.fulfillment_latency
        message_information += """<Message><MessageID>%s</MessageID><OperationType>Update
        </OperationType> <Inventory><SKU>%s</SKU><Quantity>%s</Quantity><FulfillmentLatency>%s
        </FulfillmentLatency> </Inventory></Message>""" % (message_id, seller_sku, stock,
                                                           fullfillment_latency)
        return message_information

    def stock_ept_calculation(self, actual_stock, fix_stock_type=False, fix_stock_value=0):
        """
        This mehod relocates calculate stock.
        :param actual_stock: This arguments relocates actual stock.
        :param fix_stock_type: This arguments relocates type of stock type.
        :param fix_stock_value: This arguments relocates value of stock value.
        :return:
        """
        try:
            if actual_stock >= 1.00:
                if fix_stock_type == 'fix':
                    if fix_stock_value >= actual_stock:
                        return actual_stock
                    return fix_stock_value

                if fix_stock_type == 'percentage':
                    quantity = int((actual_stock * fix_stock_value) / 100.0)
                    if quantity >= actual_stock:
                        return actual_stock
                    return quantity
            return actual_stock
        except Exception as e:
            raise UserError(e)

    def update_price(self, instance):
        """
        This Method relocates create envelope for update price in amazon.
        :param instance: This arguments relocates instance of amazon.
        :return:This Method return boolean(True/False).
        """
        message_id = 1
        message_information = ''
        merchant_string = "<MerchantIdentifier>%s</MerchantIdentifier>" % instance.merchant_id
        message_type = """<MessageType>Price</MessageType>"""
        for amazon_products in self:
            message_information = self.update_price_dict(instance, amazon_products,
                                                         message_information, message_id)
            message_id += 1
        if message_information:
            data = """<?xml version="1.0" encoding="utf-8"?><AmazonEnvelope xmlns:xsi=
            "http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
            <Header><DocumentVersion>1.01</DocumentVersion>""" + merchant_string + """
            </Header>""" + message_type + """""" + message_information + """</AmazonEnvelope>"""
            kwargs = self.get_amazon_product_request_data_ept(instance, data,
                                                              'update_price_v13')
            kwargs.update({'marketplaceids': [instance.market_place_id]})
            response = iap_tools.iap_jsonrpc(DEFAULT_ENDPOINT + '/iap_request', params=kwargs)
            if response.get('reason'):
                raise UserError(_(response.get('reason')))
            results = response.get('result')
            self.process_amazon_update_price_result(instance, data, results)
        return True

    def process_amazon_update_price_result(self, instance, data, results):
        amazon_feed_submit_history = self.env['feed.submission.history']

        if results.get('FeedSubmissionInfo', {}).get('FeedSubmissionId', \
                                                     {}).get('value', False):
            last_feed_submission_id = results.get('FeedSubmissionInfo', {}).get( \
                'FeedSubmissionId', {}).get('value', False)
            self.write({'last_feed_submission_id': last_feed_submission_id,
                        'error_in_export_price': False})
            vals = {'message': data, 'feed_result_id': last_feed_submission_id,
                    'feed_submit_date': time.strftime("%Y-%m-%d %H:%M:%S"),
                    'instance_id': instance.id, 'user_id': self._uid,
                    'feed_type': 'export_price',
                    'seller_id': instance.seller_id.id}
            amazon_feed_submit_history.create(vals)
        return True

    def update_price_dict(self, instance, amazon_product, message_information, message_id):
        """
        This Method relocates Prepare price dictionary for amazon.
        :param instance: This arguments relocates instance of amazon.
        :param amazon_product: This arguments relocates product listing of amazon.
        :param message_information: This arguments prepare message envelope of amazon.
        :param message_id: This arguments relocates message of amazon.
        :return:This Method return envelope message of amazon.
        """
        price = instance.pricelist_id.get_product_price_ept(amazon_product.product_id)
        price = price and round(price, 2) or 0.0
        seller_sku = html.escape(amazon_product.seller_sku)
        price_string = """<Message><MessageID>%(message_id)s</MessageID><Price><SKU>%(sku)s</SKU>
        <StandardPrice currency="%(currency)s">%(price)s</StandardPrice></Price></Message>"""
        price_string = price_string % {'currency': instance.pricelist_id.currency_id.name,
                                       'message_id': message_id, 'sku': seller_sku, 'price': price}
        message_information += price_string
        return message_information

    def update_images(self, instance):
        """
        This Method relocates prepare image envelope for amazon.
        :param instance: This arguments relocates instance of amazon.
        :return: This Method return boolean(True/False).
        """
        message_id = 1
        merchant_string = "<MerchantIdentifier>%s</MerchantIdentifier>" % (instance.merchant_id)
        message_information = ''
        for amazon_product in self:
            if not amazon_product.exported_to_amazon:
                continue
            for image_obj in amazon_product.product_id.ept_image_ids:
                message_information = self.create_image_dict(amazon_product, image_obj,
                                                             message_information, message_id)
                message_id += 1
        if message_information:
            data = """<?xml version="1.0" encoding="utf-8"?>
            <AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="amzn-envelope.xsd"><Header><DocumentVersion>1.01
            </DocumentVersion>""" + merchant_string + """</Header><MessageType>
            ProductImage</MessageType>""" + message_information + """</AmazonEnvelope>"""
            kwargs = self.get_amazon_product_request_data_ept(instance, data, 'update_images_v13')
            kwargs.update({'marketplaceids': [instance.market_place_id]})

            response = iap_tools.iap_jsonrpc(DEFAULT_ENDPOINT + '/iap_request', params=kwargs)
            if response.get('reason'):
                raise UserError(_(response.get('reason')))
            results = response.get('result')
            self.process_amazon_update_image_result(instance, results, data)

        return True

    def process_amazon_update_image_result(self, instance, results, data):
        amazon_process_job_log_obj = self.env['common.log.book.ept']
        feed_submission_obj = self.env['feed.submission.history']

        if results.get('FeedSubmissionInfo', {}).get('FeedSubmissionId', {}).get('value', False):
            last_feed_submission_id = results.get('FeedSubmissionInfo', {}).get( \
                'FeedSubmissionId', {}).get('value', False)
            self.write({'error_in_export_image': False,
                        'last_feed_submission_id': last_feed_submission_id})

            vals = {'message': data, 'feed_result_id': last_feed_submission_id,
                    'feed_submit_date': time.strftime("%Y-%m-%d %H:%M:%S"),
                    'instance_id': instance.id, 'user_id': self._uid,
                    'feed_type': 'export_image',
                    'seller_id': instance.seller_id.id}
            feed = feed_submission_obj.create(vals)
            amazon_process_job_log_obj.create({
                'module': 'amazon_ept',
                'type': 'import',
                'res_id': self.id,
                'model_id': self.env['ir.model']._get('amazon.product.ept').id,
                'active': True,
                'log_lines': [(0, 0, {'message': 'Requested Feed Id' + feed and feed.id or False})]
            })
        return True

    def create_image_dict(self, amazon_product, image_obj, message_information, message_id):
        """
        This Method relocates prepare image envelope for amazon.
        :param amazon_product: This arguments relocates product listing of amazon.
        :param image_obj: This arguments relocates image object of amazon.
        :param message_information: This arguments prepare message envelope of amazon.
        :param message_id:This arguments relocates message of amazon.
        :return: This Method return envelope message of amazon.
        """
        seller_sku = amazon_product.seller_sku
        amazon_image_type = 'Main'
        amazon_image_url = image_obj.url

        message_information += """<Message><MessageID>%s</MessageID><OperationType>Update
        </OperationType><ProductImage><SKU>%s</SKU><ImageType>%s</ImageType><ImageLocation>%s
        </ImageLocation></ProductImage></Message>""" % ( \
            message_id, seller_sku, amazon_image_type, amazon_image_url)
        return message_information

    def name_get(self):
        """
        Use: Display Product title
        Added By: Dhaval Sanghani [@Emipro Technologies]
        Added On: 17-Jun-2020
        @param: {}
        @return: {}
        """
        if self._context.get('show_product_title', False):
            res = []
            for product in self:
                name = product.name or False
                res.append((product.id, name))
            return res
        return super(AmazonProductEpt, self).name_get()


# TODO: Wrap it as a class and connect it to GUI
# A script to transform anomaly data to d3m format
import pandas as pd
import numpy as np
import os
import json

##############################
# Some information for the dataset to be transformed
# Designed for time series data
name = 'yahoo_sub_5'
src_path = './raw_data/yahoo_sub_5.csv'
label_name = 'anomaly'
timestamp_name = 'timestamp'
value_names = ['value_{}'.format(i) for i in range(5)]
ratio = 0.9 # Ratio of training data, the rest is for testing

###############################

dst_root = './' + name
dirs = ['./', 'SCORE', 'TEST', 'TRAIN']
maps = {'./': None, 'SCORE': 'TEST', 'TEST': 'TEST', 'TRAIN': 'TRAIN'}

# Create the corresponding directories
for d in dirs:
    if maps[d] is not None:
        dataset_name = 'dataset_' + maps[d]
        problem_name = 'problem_' + maps[d]
    else:
        dataset_name = name + '_dataset'
        problem_name = name + '_problem'
    tables_dir = os.path.join(dst_root, d, dataset_name, 'tables')
    if not os.path.exists(tables_dir):
        os.makedirs(tables_dir)
    problem_dir = os.path.join(dst_root, d, problem_name)
    if not os.path.exists(problem_dir):
        os.makedirs(problem_dir)

# Process data
_df = pd.DataFrame()
df = pd.read_csv(src_path)
_df['d3mIndex'] = df.index
_df['timestamp'] = df[timestamp_name]
for value_name in value_names:
    _df[value_name] = df[value_name]
_df['ground_truth'] = df[label_name]
df = _df
cols = df.columns.tolist()

# Save all the data
df.to_csv(os.path.join(dst_root, name+'_dataset', 'tables', 'learningData.csv'), index=False)

# Save training and testing data
train_df, test_df = df[:int(df.shape[0]*ratio)], df[int(df.shape[0]*ratio):]

train_df.to_csv(os.path.join(dst_root, 'TRAIN', 'dataset_TRAIN', 'tables', 'learningData.csv'), index=False)
test_df.to_csv(os.path.join(dst_root, 'TEST', 'dataset_TEST', 'tables', 'learningData.csv'), index=False)
test_df.to_csv(os.path.join(dst_root, 'SCORE', 'dataset_TEST', 'tables', 'learningData.csv'), index=False)

# Data splits
row_0 = train_df.shape[0]
row_1 = train_df.shape[0]
row = row_0 + row_1
df = pd.DataFrame(np.array([[i for i in range(row)], ['TRAIN' for _ in range(row_0)] + ['TEST' for _ in range(row_1)], [0 for _ in range(row)], [0 for _ in range(row)]]).transpose(), columns = ['d3mIndex', 'type', 'repeat', 'fold'])

# Save data splits for all data
train_df.to_csv(os.path.join(dst_root, name+'_problem', 'dataSplits.csv'), index=False)

# Save training and testing splits
train_df, test_df = df[:row_0], df[row_0:]
train_df.to_csv(os.path.join(dst_root, 'TRAIN', 'problem_TRAIN', 'dataSplits.csv'), index=False)
test_df.to_csv(os.path.join(dst_root, 'TEST', 'problem_TEST', 'dataSplits.csv'), index=False)
test_df.to_csv(os.path.join(dst_root, 'SCORE', 'problem_TEST', 'dataSplits.csv'), index=False)

# Dataset JSON files
# Load template
with open('template/datasetDoc.json') as json_file:
    data = json.load(json_file)
columns = []
for i in range(len(cols)):
    c = {}
    c['colIndex'] = i
    c['colName'] = cols[i]
    if i == 0:
        c['colType'] = 'integer'
        c['role'] = ['index']
    elif i == 1:
        c['colType'] = 'integer'
        c['role'] = ['attribute']
    elif i == len(cols)-1:
        c['colType'] = 'integer'
        c['role'] = ['suggestedTarget']
    else:
        c['colType'] = 'real'
        c['role'] = ['attribute']
    columns.append(c)
data['dataResources'][0]['columns'] = columns
data['dataResources'][0]['columnsCount'] = len(cols)

data['about']['datasetID'] = name + '_dataset'
data['about']['datasetName'] = name
with open(os.path.join(dst_root, name+'_dataset', 'datasetDoc.json'), 'w') as outfile:
    json.dump(data, outfile, indent=4)

data['about']['datasetID'] = name +'_dataset_TRAIN'
data['about']['datasetName'] = "NULL"
with open(os.path.join(dst_root, 'TRAIN', 'dataset_TRAIN', 'datasetDoc.json'), 'w') as outfile:
    json.dump(data, outfile, indent=4)

data['about']['datasetID'] = name + '_dataset_TEST'
data['about']['datasetName'] = 'NULL'
with open(os.path.join(dst_root, 'TEST', 'dataset_TEST', 'datasetDoc.json'), 'w') as outfile:
    json.dump(data, outfile, indent=4)

data['about']['datasetID'] = name + '_dataset_TEST'
data['about']['datasetName'] = 'NULL'
with open(os.path.join(dst_root, 'SCORE', 'dataset_TEST', 'datasetDoc.json'), 'w') as outfile:
    json.dump(data, outfile, indent=4)

# Problem JSON files
# Load template
with open('template/problemDoc.json') as json_file:
    data = json.load(json_file)

data['about']['problemID'] = name+'_problem'
data['about']['problemName'] = name+'_problem'
data['about']['problemDescription'] = 'Anomaly detection'
data['about']['taskKeywords'] = ['classification', 'binary', 'tabular']
data['inputs']['data'][0]['datasetID'] = name + '_dataset'
data['inputs']['data'][0]['targets'][0]['colIndex'] = len(cols)-1
data['inputs']['data'][0]['targets'][0]['colName'] = cols[-1]
data['inputs']['dataSplits']['datasetViewMaps']['train'][0]['from'] = name+'_dataset'
data['inputs']['dataSplits']['datasetViewMaps']['test'][0]['from'] = name+'_dataset'
data['inputs']['dataSplits']['datasetViewMaps']['score'][0]['from'] = name+'_dataset'
data['inputs']['dataSplits']['datasetViewMaps']['train'][0]['to'] = name+'_dataset_TRAIN'
data['inputs']['dataSplits']['datasetViewMaps']['test'][0]['to'] = name+'_dataset_TEST'
data['inputs']['dataSplits']['datasetViewMaps']['score'][0]['to'] = name+'_dataset_SCORE'

with open(os.path.join(dst_root, name+'_problem', 'problemDoc.json'), 'w') as outfile:
    json.dump(data, outfile, indent=4)

with open(os.path.join(dst_root, 'TRAIN', 'problem_TRAIN', 'problemDoc.json'), 'w') as outfile:
    json.dump(data, outfile, indent=4)

with open(os.path.join(dst_root, 'TEST', 'problem_TEST', 'problemDoc.json'), 'w') as outfile:
    json.dump(data, outfile, indent=4)

with open(os.path.join(dst_root, 'SCORE', 'problem_TEST', 'problemDoc.json'), 'w') as outfile:
    json.dump(data, outfile, indent=4)

# Make an empty targets.csv
with open(os.path.join(dst_root, 'SCORE', 'targets.csv'), 'w') as outfile:
    outfile.write('')


import matplotlib.pyplot as plt

lines = plt.plot([0, 1, 2, 3], [1, 2, 3, 5], 'b-', linewidth=2.0)
# plot返回一个线对象(line_2d)列表
# 填入的是x,y轴坐标，对应的x值为[0, 1, 2, 3]
# 如果只有一个参数，则为y轴坐标
# 第三个参数为点格式
# linewidth 控制线的宽度

lines[0].set_antialiased(False)
# set_antialiased方法实现开启/去除平滑

plt.setp(lines, color='r', linewidth=2.0)
plt.setp(lines, 'color', 'r', 'linewidth', 2.0)  # matlab风格
# setp()可以作用于一个列表对象或者是一个单一的对象。
# 你可以使用python风格的关键字参数或者是MATLAB风格的string/value对为参数
# line_2d对象具有的属性和取值,见OneNote:人工智能-数据挖掘

plt.ylabel("First numbers")
# 添加y轴标签

plt.axis([0, 6, 0, 10])
# axis规定 x 轴显示范围为 0-6  规定y轴显示范围为 0-10

plt.show()


import time
from collections import OrderedDict
from datetime import datetime

import pymysql
import pytz
import rethinkdb as rdb

class ZabbixAlert(object):
    """ Zabbix alert object used to push alerts to the db"""

    def __init__(self, event_id, event_time=None, event_date=None, event_name='', priority=10, db_connection=True):
        self.timezone = pytz.timezone('UTC')
        self.database = None
        self.db_table = None
        self.event_id = event_id
        if event_date and event_time:
            self.event_datetime = self.timezone.localize(
                datetime.strptime('{0} {1}'.format(event_date, event_time), '%Y.%m.%d %H:%M:%S'))
            self.event_ts = self.event_datetime.strftime('%H:%M:%S %d-%m-%Y')
        else:
            self.event_ts = None
            self.event_datetime = None

        self.priority = priority
        self.event_name = event_name
        self.alert_entry = {'event_id': self.event_id, 'ts': self.event_datetime,
                            'priority': priority, 'name': self.event_name}
        if db_connection:
            self.connect_db()

    def connect_db(self, host='rdb', port='28015', database='monitoring', db_table='alerts'):
        """ Initialise connection to Rethink"""
        self.database = database
        self.db_table = db_table
        rdb.connect(host, port, ).repl()

    def exist(self):
        cursor = rdb.db(self.database).table(self.db_table).filter(
            rdb.row['event_id'] == self.alert_entry['event_id']).run()
        results = list(cursor)

        if len(results) == 1:
            return True

        return False

    def push(self):
        if not self.exist():
            rdb.db(self.database).table(self.db_table).insert(self.alert_entry).run()
        else:
            self.update()

    def pop(self):
        if self.exist():
            rdb.db(self.database).table(self.db_table).filter(
                rdb.row['event_id'] == self.alert_entry['event_id']).delete().run()

    def update(self):
        if self.exist():
            rdb.db(self.database).table(self.db_table).filter(
                rdb.row['event_id'] == self.alert_entry['event_id']).update(self.alert_entry).run()

def get_alerts(count=None, index='ts', order='desc', host='rdb', port='28015', database='monitoring',
               db_table='alerts'):
    """ Function to get specific number of current alerts ordered by 'index'"""
    alerts = []
    rdb.connect(host, port, ).repl()
    if count:
        if order == 'desc':
            cursor = rdb.db(database).table(db_table).order_by(rdb.desc(index)).limit(count).run()
        elif order == 'asc':
            cursor = rdb.db(database).table(db_table).order_by(rdb.acs(index)).limit(count).run()
        else:
            cursor = rdb.db(database).table(db_table).limit(count).run()
    else:
        if order == 'desc':
            cursor = rdb.db(database).table(db_table).order_by(rdb.desc(index)).run()
        elif order == 'asc':
            cursor = rdb.db(database).table(db_table).order_by(rdb.acs(index)).run()
        else:
            cursor = rdb.db(database).table(db_table).run

    for alert in cursor:
        alerts.append(alert)

    return alerts

def find_parent_id_db(child_id, db_connection):
    cursor = db_connection.cursor()
    cursor.execute('SELECT templateid FROM triggers WHERE triggerid={}'.format(child_id))
    record = cursor.fetchall()
    if len(record) != 1:
        return None

    parent_id = record[0][0]
    if not parent_id:
        return child_id

    return find_parent_id_db(parent_id, db_connection)

def fetch_parents_tree(db_connection):
    cursor = db_connection.cursor()
    cursor.execute('SELECT triggerid, templateid FROM triggers')
    data = cursor.fetchall()

    return data

def find_parent_id_cache(child_id, parents_data):
    parent_id = None
    for pair in parents_data:
        if pair[0] == child_id:
            parent_id = pair[1]

            break

    if not parent_id:
        return child_id

    return find_parent_id_cache(parent_id, parents_data)

def stats(limit=100):
    db = pymysql.connect('mysql', 'root', 'secret', 'zabbix')
    child_parent = dict()
    event_stats = dict()
    statistics = list()
    start_time = int(time.time()) - 2592000
    cursor = db.cursor()
    cursor.execute('SELECT objectid FROM events WHERE clock>{}'.format(start_time))
    data = cursor.fetchall()
    # parents_tree = fetch_parents_tree(db)
    for zabbix_event in data:
        child_id = zabbix_event[0]
        if child_id in child_parent.keys():
            parent_id = child_parent[child_id]
        else:
            parent_id = find_parent_id_db(child_id, db)
            # parent_id = find_parent_id_cache(int(child_id), parents_tree)
            child_parent[child_id] = parent_id

        if parent_id in event_stats.keys():
            event_stats[parent_id] += 1
        else:
            event_stats[parent_id] = 1

    event_stats = OrderedDict(reversed(sorted(event_stats.items(), key=lambda t: t[1])))

    for event in event_stats:
        if event == None:
            continue

        cursor = db.cursor()
        cursor.execute('SELECT description FROM triggers WHERE triggerid={}'.format(event))
        data = cursor.fetchall()
        description = str(data[0][0])
        record = {'description': description, 'count': event_stats[event]}
        statistics.append(record)

    db.close()
    return statistics[:limit]


#!/usr/bin/python
import math
import numpy as np

def dist(x, y):
    return math.sqrt(sum([(x[i] - y[i]) ** 2 for i in range(max(len(x), len(y)))]))

def bourgain_embedding(elements, dist):
    np.random.seed(123)
    distort_elements = []
    r = range(len(elements))
    n = len(elements)
    k = int(math.ceil(math.log(n) / math.log(2) - 1))
    t = int(math.ceil(math.log(n)))
    counter = 0
    for i in range(0, k + 1):
        for t in range(t):
            s = np.random.choice(r, 2 ** i)
            for j in r:
                x = elements[j]
                d = min([dist(x, elements[s]) for s in s])
                counter += len(s)
                if i == 0 and t == 0:
                    distort_elements.append([d])
                else:
                    distort_elements[j].append(d)
    return np.array(distort_elements)

if __name__ == "__main__":
    print(dist([1, 2], [3, 4]))
    X = [[(i + j) * (i + j + 1) / 2 + j for j in range(0, 10)] for i in range(0, 50)]
    print(X)
    X_emb = bourgain_embedding(X, dist)
    l = []
    for x in range(len(X)):
        for y in range(len(X)):
            if x != y:
                d1 = dist(X[x], X[y])
                d2 = dist(X_emb[x], X_emb[y])
                l.append(d2 * 1.0 / (d1 * 1.0))
                # print x,y,d1,d2
    print("distortion = %s" % (max(l) / min(l)))
    print("upper bound for distortion = %s " % math.log(len(X)))
    # print "\n".join([str(x) for x in X_emb])
    # print "\n".join([",".join([str(a) for a in X_emb[i]]) for i in range(len(X))])

def vector_distance(a, b):
    a = np.array(a)
    b = np.array(b)
    return np.linalg.norm(a - b)

def bourgain_embedding_matrix(distance_matrix):
    np.random.seed(123)
    distort_elements = []
    r = range(len(distance_matrix))
    n = len(distance_matrix)
    k = int(math.ceil(math.log(n) / math.log(2) - 1))
    t = int(math.ceil(math.log(n)))
    counter = 0
    for i in range(0, k + 1):
        for t in range(t):
            s = np.random.choice(r, 2 ** i)
            for j in r:
                d = min([distance_matrix(j, s) for s in s])
                counter += len(s)
                if i == 0 and t == 0:
                    distort_elements.append([d])
                else:
                    distort_elements[j].append(d)
    distort_matrix = np.zeros((n, n))
    for i in range(n):
        for j in range(i + 1, n):
            distort_matrix[i][j] = distance_matrix[j][i] = vector_distance(distort_elements[i], distort_elements[j])
    return np.array(distort_elements)


import os
import sys
import logging
import datetime

class mylog(object):
    '''
    # ERROR
    # WARNING
    # INFO
    # DEBUG
    '''

    def __init__(self):
        path = os.path.dirname(os.path.dirname(__file__))
        version = datetime.datetime.now().strftime("%Y-%m-%dH%H")
        self.logname = 'all_%s.log' % version  # all.log
        self.log_path = "temp"
        self.logger = logging.getLogger("logger")
        self.tem_path = os.path.join(path, self.log_path)
        self.log_path = os.path.join(self.tem_path, self.logname)

    def log_name(self):
        return self.log_path

    def log(self):
        formatter = logging.Formatter(
            "%(asctime)s %(levelname)-8s: %(message)s")
        #tem_path  = os.path.join(os.path.dirname(os.getcwd()),self.log_path)
        #log_path = os.path.join(self.tem_path,self.logname)
        if not os.path.isdir(self.tem_path) or not os.path.isfile(self.log_path):
            try:
                os.mkdir(self.tem_path)
            except FileExistsError as e:
                pass
            with open(self.log_path, 'w', encoding='utf-8') as f:
                pass

        if not self.logger.handlers:
            # 文件日志
            file_handler = logging.FileHandler(self.log_path)
            file_handler.setLevel(logging.INFO)  # 指定日志的最低输出级别，默认为WARN级别
            file_handler.setFormatter(formatter)  # 可以通过setFormatter指定输出格式

            # 控制台日志
            console_handler = logging.StreamHandler(sys.stdout)
            console_handler.setLevel(logging.DEBUG)  # 指定日志的最低输出级别，默认为WARN级别
            console_handler.formatter = formatter  # 也可以直接给formatter赋值

            # 为logger添加的日志处理器
            self.logger.addHandler(file_handler)
            self.logger.addHandler(console_handler)

            # 指定日志的最低输出级别，默认为WARN级别
            self.logger.setLevel(logging.INFO)

        return self.logger

if __name__ == '__main__':
    # l = log()
    # l.info('1234566789')
    m = mylog()
    m.log().info('8888888888888')
    # for i in range(0,500):
    #     m.info(i)
    print(m.log_name())


from django.conf.urls import url
from . import views
app_name = "art"
urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^errorlogin$', views.error, name='error'),
    url(r'^produits$', views.produits_view, name='produits_view'),
    url(r'^logout$', views.logout_view, name='logout_view'),
    url(r'^tunisie$', views.tunisie_view, name='tunisie_view'),
    url(r'^about$', views.about_view, name='about_view'),
    url(r'^contact$', views.contact_view, name='contact_view'),
    url(r'^event$', views.event_view, name='event_view'),
    url(r'^produit/tapis/$', views.cat_view_tapis, name='cat_view_tapis'),
    url(r'^produit/habits/$', views.cat_view_habits, name='cat_view_habits'),
    url(r'^produit/posaique/$', views.cat_view_mosaique, name='cat_view_mosaique'),
    url(r'^produit/bijoux/$', views.cat_view_bijoux, name='cat_view_bijoux'),
    url(r'^produit/cuterie/$', views.cat_view_poterie, name='cat_view_poterie'),
    url(r'^produit/moivre/$', views.cat_view_cuivre, name='cat_view_cuivre'),
    url(r'^produit/ceramique/$', views.cat_view_ceramique, name='cat_view_ceramique'),
    url(r'^produit/tapis/(?P<id>\w{0,50})/$', views.single_view, name='single_view'),
    url(r'^produit/habits/(?P<id>\w{0,50})/$', views.single_view, name='single_view'),
    url(r'^produit/poterie/(?P<id>\w{0,50})/$', views.single_view, name='single_view'),
    url(r'^produit/mosaique/(?P<id>\w{0,50})/$', views.single_view, name='single_view'),
    url(r'^produit/bijoux/(?P<id>\w{0,50})/$', views.single_view, name='single_view'),
    url(r'^produit/cuivre/(?P<id>\w{0,50})/$', views.single_view, name='single_view'),
    url(r'^produit/ceramique/(?P<id>\w{0,50})/$', views.single_view, name='single_view'),
    url(r'^produit/(?P<id>\w{0,50})/$', views.single_view, name='single_view'),
    url(r'^savePanier$', views.savePanier, name='savePanier'),
    url(r'^reclamation$', views.reclamation, name='reclamation'),
    url(r'^facture$', views.facture, name='facture'),
]


from django import forms
from sales.utils import PRODRECWIDGETS, MINIPRODWIDGETS
from survey.forms import ProdRecCreateForm
from trapTransmitter.models import Traptransmitterordermodel, SalesSalesinputtraptransmitter

class TrapTransmitterUpdateForm(forms.ModelForm):
    class Meta:
        model = Traptransmitterordermodel
        fields = ('number_of_collars',
                  'vhf_beacon_frequency', 'notification_mail', 'notification_sms',
                  'vhf_beacon_schedule', 'id_tag', 'globalstar', 'iridium', 'contact_name_airtime_fee',
                  'contact_mail_airtime_fee', 'world_location', 'interval', 'comment', 'delivery_time',
                  'payment_option', 'operation_number')

class TrapTransmitterProdRecForm(ProdRecCreateForm):
    class Meta:
        model = SalesSalesinputtraptransmitter
        fields = ('co_worker',
                  'further_instructions_programming',
                  'path_customer_folder',
                  'order')

        widgets = PRODRECWIDGETS

class SalesInputTrapTransCreateForm(forms.ModelForm):
    class Meta:
        model = SalesSalesinputtraptransmitter
        # exclude = ('order',)
        fields = ('further_instructions_programming',)

        widgets = MINIPRODWIDGETS

        labels = {
            'gl_no_of_attempts': 'GLOBALSTAR no of attempts',
            'gl_fixes_per_message': 'GLOBALSTAR fixes per message',
        }


# Default Imports
import pandas as pd
import matplotlib.pyplot as plt
from greyatomlib.descriptive_stats.q01_calculate_statistics.build import calculate_statistics

dataframe = pd.read_csv('data/house_prices_multivariate.csv')
sale_price = dataframe.loc[:, 'SalePrice']

def plot():
    mean = sale_price.mean()
    median = sale_price.median()
    mode = np.int64(sale_price.mode())

    plt.axvline(x=mean)
    plt.axvline(x=median)
    plt.axvline(x=mode)

   # plt.hist(median, bins=10)

plt.show()


"""
Find the last ten digits of the series 1**1 + 2**2 + 3**3 + ... + 1000**1000
"""

if __name__ == "__main__":
    total = 0

    for i in range(1, 1001):
        total += i ** i

    last_10_digits = str(total)[len(str(total)) - 10:]
    print(last_10_digits)