import json
import math
import os
from statistics import mean

import matplotlib
import matplotlib.patches as patches
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats
from matplotlib import cm
from matplotlib.colors import Normalize
from scipy.stats import gaussian_kde

class NgsData:
    def __init__(self, file):
        self.data = []
        self.genes = []
        with open(file) as fs:
            header = fs.readline()
            spl = header.rstrip().split('\t')
            data_index = spl.index("Mean")
            gene_index = spl.index("Gene name")
            for line in fs:
                if len(line) == 0 or line[0] == '#':
                    continue
                spl = line.rstrip().split('\t')
                self.data.append(float(spl[data_index]))
                self.genes.append(spl[gene_index])

class ProteinGroup:
    def __init__(self, file, type, pg2gene, mergeGenes=True, makeLog2=True):
        self.files = []
        self.lfq = None
        self.ibaq = None
        self.genes = []
        if type == "MaxQuant":
            with open(file) as fs:
                header = fs.readline()
                spl = header.rstrip().split('\t')
                pg_index = spl.index("Protein IDs")
                files = []
                lfq_indexes = []
                ibaq_indexes = []
                for i in range(len(spl)):
                    if spl[i].startswith("LFQ intensity "):
                        lfq_indexes.append(i)
                        files.append(int(spl[i].split()[-1]))
                    if spl[i].startswith("iBAQ ") and spl[i] != "iBAQ peptides":
                        ibaq_indexes.append(i)
                tuples = sorted(enumerate(files), key=lambda x: x[1])
                self.files = [t[1] for t in tuples]
                order = [t[0] for t in tuples]
                self.lfq = [[] for i in self.files]
                self.ibaq = [[] for i in self.files]
                reject_names = ["Only identified by site", "Reverse", "Potential contaminant"]
                reject_indexes = [spl.index(i) for i in reject_names]
                for line in fs:
                    spl = line.rstrip().split('\t')
                    if sum([spl[reject_index] == '+' for reject_index in reject_indexes]):
                        continue
                    genes = list(set([pg2gene[pg] for pg in spl[pg_index].split(';') if pg in pg2gene]))
                    if len(genes) == 0:
                        continue
                    genes.sort()
                    self.genes.append(genes[0])
                    for i in range(len(lfq_indexes)):
                        self.lfq[i].append(float(spl[lfq_indexes[order[i]]]))
                    for i in range(len(ibaq_indexes)):
                        self.ibaq[i].append(float(spl[ibaq_indexes[order[i]]]))
        elif type == "Spectronaut":
            with open(file) as fs:
                header = fs.readline()
                spl = header.rstrip().split('\t')
                pg_index = spl.index("PG.ProteinGroups")
                indexes = []
                files = []
                for i in range(len(spl)):
                    if spl[i].endswith(".raw.PG.Quantity"):
                        indexes.append(i)
                        files.append(int(spl[i].split('.')[0].split('_')[-1]))
                tuples = sorted(enumerate(files), key=lambda x: x[1])
                self.files = [t[1] for t in tuples]
                order = [t[0] for t in tuples]
                self.ibaq = [[] for i in self.files]
                for line in fs:
                    spl = line.rstrip().split('\t')
                    genes = list(set([pg2gene[pg] for pg in spl[pg_index].split(';') if pg in pg2gene]))
                    if len(genes) == 0:
                        continue
                    genes.sort()
                    self.genes.append(genes[0])
                    for i in range(len(indexes)):
                        k = spl[indexes[order[i]]]
                        if k == "Filtered":
                            self.ibaq[i].append(0.0)
                        else:
                            self.ibaq[i].append(float(k))
        if mergeGenes:
            genes = list(set(self.genes))
            gene2idx = {genes[i]: i for i in range(len(genes))}
            ibaq = [[0.0 for j in range(len(genes))] for i in range(len(self.files))]
            for i in range(len(self.files)):
                for j in range(len(self.genes)):
                    ibaq[i][gene2idx[self.genes[j]]] += self.ibaq[i][j]
            self.ibaq = ibaq
            if type == "MaxQuant":
                lfq = [[0.0 for j in range(len(genes))] for i in range(len(self.files))]
                for i in range(len(self.genes)):
                    for j in range(len(self.files)):
                        lfq[j][gene2idx[self.genes[i]]] += self.lfq[j][i]
                self.lfq = lfq
            self.genes = genes
        if makeLog2:
            for i in range(len(self.ibaq)):
                for j in range(len(self.ibaq[i])):
                    self.ibaq[i][j] = np.log2(self.ibaq[i][j])
            if type == "MaxQuant":
                for i in range(len(self.lfq)):
                    for j in range(len(self.lfq[i])):
                        self.lfq[i][j] = np.log2(self.lfq[i][j])

def getProteinGroup2Gene(fastaFiles):
    pg2gene = {}
    pname = ""
    gname = []
    for file in fastaFiles:
        with open(file) as fs:
            for line in fs:
                if line[0] == '>':
                    if len(gname) == 1:
                        pg2gene[pname] = gname[0]
                    pname = line.split('|')[1]
                    gname = [i[3:] for i in line.split(" ") if i.startswith("GN=")]
    if len(gname) == 1:
        pg2gene[pname] = gname[0]
    return pg2gene

def makeColours(vals):
    norm = Normalize(vmin=vals.min(), vmax=vals.max())
    colours = [cm.ScalarMappable(norm=norm, cmap='jet').to_rgba(val) for val in vals]
    return colours

def plot3ef(maxquant_data, maxquant_selection, spectronaut_data, spectronaut_selection, figSize, dotSize, outputFolder):
    for k, data, selection, title, measure, file_name in \
            [
                (0, maxquant_data.lfq, maxquant_selection, "MaxDIA", "LFQ intensity", "e"),
                (1, spectronaut_data.ibaq, spectronaut_selection, "Spectronaut", "Intensity", "f")
            ]:
        fig, ax = plt.subplots(1, 1, figsize=(figSize, figSize))
        yx = [(data[selection[0]][i], data[selection[1]][i])
              for i in range(len(data[selection[0]]))
              if not np.isinf(data[selection[0]][i]) and not np.isinf(data[selection[1]][i])]
        minv = yx[0][0]
        maxv = yx[0][0]
        for y, x in yx:
            minv = min(minv, min(x, y))
            maxv = max(maxv, max(x, y))
        xs = [x for x, y in yx]
        ys = [y for x, y in yx]
        values = np.vstack([xs, ys])
        z = gaussian_kde(values)(values)
        idx = z.argsort()
        ax.scatter(np.array(xs)[idx], np.array(ys)[idx], color=makeColours(z[idx]), s=dotSize)
        ax.set_title(title)
        ax.set_xlim((minv, maxv))
        ax.set_ylim((minv, maxv))
        ax.set_ylabel("Replicate {}, log2 {}".format(str(selection[0] + 1), measure))
        ax.set_xlabel("Replicate {}, log2 {}".format(str(selection[1] + 1), measure))
        r = list(range(math.ceil(minv), math.floor(maxv), 3))
        ax.set_xticks(r)
        ax.set_yticks(r)
        # ax.axline((1, 1), slope=1, ls="--", color="black", lw=1)
        # a, b = np.polyfit(xs, ys, 1)
        # X_plot = np.linspace(minv, maxv, 100)
        # plt.plot(X_plot, a * X_plot + b, '-')
        ax.text(minv + 0.1 * (maxv - minv), maxv - 0.1 * (maxv - minv),
                "Pearson $R$={:.3f}".format(scipy.stats.pearsonr(xs, ys)[0]), verticalalignment='top')
        fig.tight_layout()
        file = os.path.join(outputFolder, f"{file_name}.pdf")
        if os.path.isfile(file):
            os.remove(file)
        plt.savefig(file)

def plot3g(corr_table, selections, figSize, file):
    fig, ax = plt.subplots(1, 1, figsize=(figSize, figSize))
    cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["white", "darkblue"])
    im = ax.imshow(corr_table, cmap=cmap)
    for x, y in selections:
        rect = patches.Rectangle((x - 0.5, y - 0.5), 1, 1, linewidth=1, edgecolor='r', facecolor='none')
        ax.add_patch(rect)
    cbar = ax.figure.colorbar(im, ax=ax)
    cbar.ax.set_ylabel("Pearson $R^2$", rotation=-90, va="bottom")
    ax.set_axis_off()
    kw = dict(horizontalalignment="center",
              verticalalignment="center")
    for i in range(corr_table.shape[0]):
        im.axes.text(i, i, str(i + 1), **kw)
    ax.arrow(-1, -1, 0, 5, head_width=0.5, head_length=0.5, fc='k', ec='k')
    ax.text(-1, 5.5, 'Spectronaut', verticalalignment='top', horizontalalignment='center', fontsize=12, rotation=90)
    ax.arrow(-1, -1, 5, 0, head_width=0.5, head_length=0.5, fc='k', ec='k')
    ax.text(5.5, -1, 'MaxDIA', verticalalignment='center', horizontalalignment='left', fontsize=12)
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_xticklabels([])
    ax.set_yticklabels([])
    fig.tight_layout()
    if os.path.isfile(file):
        os.remove(file)
    plt.savefig(file)

def printDots(xs, ys, genes):
    for x, y, gene in zip(xs, ys, genes):
        if x > 37 and 20 < y < 24:
            print("First dot: {}".format(gene))
    for x, y, gene in zip(xs, ys, genes):
        if x < 26 and 26 < y:
            print("Second dot: {}".format(gene))

def plot3h(maxquant_data, spectronaut_data, min_count, figSize, dotSize, file):
    data = {}
    names = ["MaxDIA", "Spectronaut"]
    labels = ["log2 mean iBAQ intensity", "log2 mean intensity"]
    for name, raw_data, raw_genes in \
            [
                (names[0], maxquant_data.ibaq, maxquant_data.genes),
                (names[1], spectronaut_data.ibaq, spectronaut_data.genes)
            ]:
        data[name] = {}
        for i in range(len(raw_genes)):
            values = [raw_data[j][i] for j in range(len(raw_data)) if
                      not np.isinf(raw_data[j][i])]
            if len(values) < min_count:
                continue
            data[name][raw_genes[i]] = values
    xs = []
    ys = []
    genes = []
    for gene, values in data[names[0]].items():
        if gene in data[names[1]]:
            xvalues = data[names[0]][gene]
            yvalues = data[names[1]][gene]
            x0 = mean(xvalues)
            y0 = mean(yvalues)
            xs.append(x0)
            ys.append(y0)
            genes.append(gene)
    fig, ax = plt.subplots(1, 1, figsize=(figSize, figSize))
    values = np.vstack([xs, ys])
    z = gaussian_kde(values)(values)
    idx = z.argsort()
    ax.scatter(np.array(xs)[idx], np.array(ys)[idx], color=makeColours(z[idx]), s=dotSize)
    ax.set_title("Pearson R={:.3f}".format(scipy.stats.pearsonr(xs, ys)[0]))
    ax.set_xlabel("{}, {}".format(names[0], labels[0]))
    ax.set_ylabel("{}, {}".format(names[1], labels[1]))
    quantile = 0.005
    minx, maxx = sorted(xs)[int(quantile * len(xs))], sorted(xs)[int((1 - quantile) * len(xs))]
    ax.set_xlim(minx, maxx)
    ax.set_xticks(list(range(math.ceil(minx), math.floor(maxx), 3)))
    fig.tight_layout()
    if os.path.isfile(file):
        os.remove(file)
    plt.savefig(file)

def plot3ij(maxquant_data, spectronaut_data, min_count, ngs_data, figSize, dotSize, out_folder):
    data = {}
    raws = [maxquant_data, spectronaut_data]
    names = ["MaxDIA", "Spectronaut"]
    labels = ["log2 mean LFQ intensity", "log2 mean intensity"]
    for name, raw_data, genes in [(names[0], maxquant_data.ibaq, maxquant_data.genes),
                                  (names[1], spectronaut_data.ibaq, spectronaut_data.genes)]:
        data[name] = {}
        for i in range(len(genes)):
            values = [raw_data[j][i] for j in range(len(raw_data)) if
                      not np.isinf(raw_data[j][i])]
            if len(values) < min_count:
                continue
            data[name][genes[i]] = values
    MaxDIA = []
    Spectronaut = []
    ngs = []
    genes = []
    ngs_gene2idx = {ngs_data.genes[i]: i for i in range(len(ngs_data.genes))}
    for gene, values in data[names[0]].items():
        if gene in data[names[1]] and gene in ngs_gene2idx:
            xvalues = data[names[0]][gene]
            yvalues = data[names[1]][gene]
            MaxDIA.append(mean(xvalues))
            Spectronaut.append(mean(yvalues))
            ngs.append(ngs_data.data[ngs_gene2idx[gene]])
            genes.append(gene)
    for xs, ys, i, file_name in [(MaxDIA, ngs, 0, 'i'), (Spectronaut, ngs, 1, 'j')]:
        fig, ax = plt.subplots(1, 1, figsize=(figSize, figSize))
        values = np.vstack([xs, ys])
        z = gaussian_kde(values)(values)
        idx = z.argsort()
        ax.scatter(np.array(xs)[idx], np.array(ys)[idx], color=makeColours(z[idx]), s=dotSize)
        ax.set_xlabel("{}, {}".format(names[i], labels[i]))
        ax.set_ylabel("Caltech_HepG2_cell_PE_i200, RPKM")
        quantile = 0.01
        minx, maxx = sorted(xs)[int(quantile * len(xs))], sorted(xs)[int((1 - quantile) * len(xs))]
        ax.set_title("Pearson R={:.3f}".format(scipy.stats.pearsonr(xs, ys)[0]))
        fig.tight_layout()
        file = os.path.join(out_folder, f"{file_name}.pdf")
        if os.path.isfile(file):
            os.remove(file)
        plt.savefig(file)

def plot(params):
    ngsData = NgsData(params["NgsDataFile"])
    pg2gene = getProteinGroup2Gene(params["fastaFiles"])
    mqData = ProteinGroup(params["MaxQuantFile"], "MaxQuant", pg2gene)
    snData = ProteinGroup(params["SpectronautFile"], "Spectronaut", pg2gene)

    n = len(mqData.files)
    corr = [[0 for j in range(n)] for i in range(n)]
    minx = 1.0
    maxquant_corr = []
    spectronaut_corr = []
    for i in range(n):
        for j in range(i + 1, n):
            xy = [(mqData.lfq[i][k], mqData.lfq[j][k]) for k in range(len(mqData.lfq[i])) if
                  not np.isinf(mqData.lfq[i][k]) and not np.isinf(mqData.lfq[j][k])]
            corr[i][j] = scipy.stats.pearsonr([x for x, y in xy], [y for x, y in xy])[0] ** 2
            minx = min(corr[i][j], minx)
            maxquant_corr.append((i, j, corr[i][j]))
    maxquant_med_corr = sorted(maxquant_corr, key=lambda x: x[2])[len(maxquant_corr) // 2]
    for i in range(1, n):
        for j in range(0, i):
            xy = [(snData.ibaq[i][k], snData.ibaq[j][k]) for k in
                  range(len(snData.ibaq[i])) if
                  not np.isinf(snData.ibaq[i][k]) and not np.isinf(snData.ibaq[j][k])]
            corr[i][j] = scipy.stats.pearsonr([x for x, y in xy], [y for x, y in xy])[0] ** 2
            minx = min(corr[i][j], minx)
            spectronaut_corr.append((i, j, corr[i][j]))
    spectronaut_med_corr = sorted(spectronaut_corr, key=lambda x: x[2])[len(spectronaut_corr) // 2]
    for i in range(n):
        corr[i][i] = minx
    plot3ef(mqData, (maxquant_med_corr[0], maxquant_med_corr[1]), snData,
            (spectronaut_med_corr[0], spectronaut_med_corr[1]),
            params["figSize"], params["dotSize"], params["outputFolder"])
    plot3g(np.array(corr),
           [(maxquant_med_corr[1], maxquant_med_corr[0]), (spectronaut_med_corr[1], spectronaut_med_corr[0])],
           params["figSize"], os.path.join(params["outputFolder"], "g.pdf"))
    plot3h(mqData, snData, params["minCount"], params["figSize"], params["dotSize"], os.path.join(params["outputFolder"], "i.pdf"))
    plot3ij(mqData, snData, params["minCount"], ngsData, params["figSize"], params["dotSize"], params["outputFolder"])

if __name__ == "__main__":
    with open("parameters.json", 'r') as parameters_fs:
        plot(json.loads(parameters_fs.read()))


"""
    surabayapy-facebook-bot
    oleh Christoforus Surjoputro
    ~~~~~~~~~
    Modul ini berisi servis-servis yang tersedia untuk modul chat messenger.

    :license: MIT, see LICENSE for more details.
"""

from datetime import timedelta
from mimetypes import guess_type

from wheezy.caching.patterns import Cached
from wheezy.core.comp import json_dumps
from wheezy.core.comp import json_loads
from wheezy.core.httpclient import HTTPClient

from config import cache
from config import config

cached = Cached(cache, time=timedelta(minutes=15))

class ChatService():

    def callUserProfileAPI(self, userID):
        ''' Getting user's first name by user ID. '''
        first_name = cached.get(userID)
        if not first_name:
            token = config.get('chatmodule', 'token')
            messenger_link = config.get('chatmodule', 'messenger_link')

            MESSENGER_PATH = '/v2.6/{}?fields=first_name&access_token={}'.format(userID, token)
            CONTENT_TYPE = 'application/json'

            client = HTTPClient(messenger_link)
            if 200 != client.get(MESSENGER_PATH):
                print('Error callUserProfileAPI: {}'.format(client.headers))
                return None
            first_name = json_loads(client.content)['first_name']
            cached.set(userID, first_name)
        return first_name

    def callSendAPI(self, messageData):
        ''' Handling sending text message to messenger. '''
        token = config.get('chatmodule', 'token')
        messenger_link = config.get('chatmodule', 'messenger_link')

        MESSENGER_PATH = '/v2.6/me/messages?access_token={}'.format(token)
        CONTENT_TYPE = 'application/json'

        client = HTTPClient(messenger_link)
        if 200 != client.post(MESSENGER_PATH, body=messageData, content_type=CONTENT_TYPE):
            print('Error callSendAPI: {}'.format(client.headers))
            return None
        return True

    def _encode_multipart_formdata(self, messageData):
        ''' Preparing the body of html to send attachment message as multipart
            form data. Convert mesasge data and atachment to binary.
        '''
        BOUNDARY = b'----------ThIs_Is_tHe_bouNdaRY_$'
        CRLF = b'\r\n'
        body = b''
        for key in messageData:
            body += b'--' + BOUNDARY + CRLF
            if not isinstance(messageData[key], bytes):
                body += b'Content-Disposition: form-data; name="%s"' % key.encode('utf-8')
                body += CRLF + CRLF
                if isinstance(messageData[key], str):
                    body += messageData[key].encode('utf-8')
                    body += CRLF
                else:
                    body += json_dumps(messageData[key]).encode('utf-8')
                    body += CRLF
            else:
                body += b'Content-Disposition: form-data; name="%s"; filename="%s"' % (key.encode('utf-8'), b'speech.mp3')
                body += CRLF
                body += b'Content-Type: %s' % b'audio/mp3'
                body += CRLF
                body += CRLF
                body += messageData[key]
                body += CRLF
        body += b'--' + BOUNDARY + b'--'
        body += CRLF
        body += CRLF
        content_type = 'multipart/form-data; boundary=%s' % BOUNDARY.decode('utf-8')
        return content_type, body

    def callSendFileAPI(self, messageData):
        ''' Handling sending attachment message to messenger. '''
        CONTENT_TYPE, body = self._encode_multipart_formdata(messageData)
        token = config.get('chatmodule', 'token')
        messenger_link = config.get('chatmodule', 'messenger_link')

        MESSENGER_PATH = '/v2.6/me/messages?access_token={}'.format(token)

        client = HTTPClient(messenger_link)
        if 200 != client.post(MESSENGER_PATH, body=body, content_type=CONTENT_TYPE):
            print('Error callSendAPI: {}'.format(client.headers))
            return None
        return True


import traceback

from ....utils.MessageUtils import multiPage
from ..functions.HelpGenerator import getHelpForAllCommands, getHelpForCommand

async def run(plugin, ctx, query):
    if query is None:
        pages = await getHelpForAllCommands(plugin, ctx)
        msg = await ctx.send(embed=pages[0])
        while True:
            res = await multiPage(plugin, ctx, msg, pages)
            if res is None:
                break
    else:
        query = "".join(query.splitlines())

        help_message = await getHelpForCommand(plugin, ctx, query)
        if help_message is None:
            return await ctx.send(plugin.t(ctx.guild, "invalid_command"))
        else:
            return await ctx.send(embed=help_message)


# Start Logging
import qlogger as ql
ql.start_logging(__file__)

# Run Code
try:

    from itertools import permutations

    S,k = input().split()
    #my solution:
    for pm in sorted(permutations(S,int(k))):
        print(''.join(list(pm)))

    #best practice:
    # print(*[''.join(i) for i in permutations(sorted(S),int(k))],sep='\n')

    #modified:
    # print(*[''.join(list(i)) for i in sorted(permutations(S,int(k)))],sep='\n')

    # print(*[1,2,3],sep='\n') # spart den for-loop

# Errors will be logged here
except Exception as e:
    ql.logger.exception(e)


import onnxruntime
import numpy as np

if __name__ == '__main__':
    onnx_path = "./export/damo/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727/model.onnx"
    sess = onnxruntime.InferenceSession(onnx_path)
    input_name = [nd.name for nd in sess.get_inputs()]
    output_name = [nd.name for nd in sess.get_outputs()]

    def _get_feed_dict(text_length):
        return {'inputs': np.ones((1, text_length), dtype=np.int64),
                'text_lengths': np.array([text_length,], dtype=np.int32),
                'vad_masks': np.ones((1, 1, text_length, text_length), dtype=np.float32),
                'sub_masks': np.ones((1, 1, text_length, text_length), dtype=np.float32),
                }

    def _run(feed_dict):
        output = sess.run(output_name, input_feed=feed_dict)
        for name, value in zip(output_name, output):
            print('{}: {}'.format(name, value))
    _run(_get_feed_dict(10))


#
# @lc app=leetcode.cn id=123 lang=python3
#
# [123] 买卖股票的最佳时机 III
#

# @lc code=start
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        length= len(prices)
        if length==0:
            return 0
        dp=[[0]*5 for _ in range(length)]
        dp[0][0]=0
        dp[0][1]=-prices[0]
        dp[0][2]=0
        dp[0][3]=-prices[0]
        # 第二次买入依赖于第一次卖出的状态，其实相当于第0天第一次买入了，第一次卖出了，然后在买入一次（第二次买入），那么现在手头上没有现金，只要买入，现金就做相应的减少。
        dp[0][4]=0
        for i in range(1,length):
            dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i])
            dp[i][2]=max(dp[i-1][2],dp[i-1][1]+prices[i])
            dp[i][3]=max(dp[i-1][3],dp[i-1][2]-prices[i])
            dp[i][4]=max(dp[i-1][4],dp[i-1][3]+prices[i])
        return dp[-1][4]
# @lc code=end

'''
这里设置了5个
0：没有操作
1：第一次买入
2：第一次卖出
3：第二次买入
4：第二次卖出
dp[i][j]中 i表示第i天，j为 [0 - 4] 五个状态，dp[i][j]表示第i天状态j所剩最大现金。
'''


'''
    * Capítulo 05: Pré-processamento

        5.3  Transformações Geométricas
            > Ajuste de escala
'''

# Parâmetros:
    # fx: Fator de escala horizontal;
    # fy: Fator de escala vertical.
    # cv2.INTER_CUBIC: Interpolação

import cv2

imagemOriginal = cv2.imread("folha.jpeg")

imagemModificada = cv2.resize(
    imagemOriginal, None, fx = 0.5, fy = 0.5,
    interpolation = cv2.INTER_CUBIC
)

cv2.imshow("Resultado", imagemModificada)

cv2.waitKey(0)
cv2.destroyAllWindows()


import pandas as pd

xls = pd.ExcelFile("E:\Week7Challenge.xlsx")

dept = pd.read_excel(xls,"Departure Details")
allc = pd.read_excel(xls,"Allocation Details")

dept["Departure ID"]=dept["Ship ID"].map(str)+dept["Departure Date"].apply(lambda x: x.strftime('-%d-%m-%Y'))
dept["Departure Date"] = dept["Departure Date"].dt.strftime('%d/%m/%Y')

temp = dept.merge(allc, on="Departure ID", how='inner')

aggr = {
    'Max Weight':'max',
    'Max Volume':'max',
    'Weight Allocated':'sum',
    'Volume Allocated':'sum'
}

final = temp.groupby(["Ship ID","Departure Date"], as_index=False).agg(aggr)
final["Weight Exceeded"] = final.apply(lambda x: x['Weight Allocated']>x['Max Weight'],axis=1)
final["Volume Exceeded"] = final.apply(lambda x: x['Volume Allocated']>x['Max Volume'],axis=1)


from numpy import *
def classify0(inX,dataSet,labels,k):
    dataSize=dataSet.shape[0]
    diffMat=tile(inX,(dataSize,1))-dataSet#在列方向上重复inX次，行dataSize次
    sqDiffMat=diffMat**2
    sqDistances=sqDiffMat.sum(axis=1)#同一行相加
    distances=sqDistances**0.5
    sortedDistIndicies=distances.argsort()
    classCount={}
    for i in range(k):
        voteIlabel=labels[sortedDistIndicies[i]];
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
    sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]

def file2matrix(filename):
    fr=open(filename)
    arrayOLines=fr.readlines()
    numberOfLines=len(arrayOLines)
    returnMat=zeros((numberOfLines,3))
    classLabelVector=[]
    index=0
    for line in arrayOLines:
        line=line.strip()#去除首尾的空白字符
        listFromLine=line.split('\t')
        returnMat[index,:]=listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index+=1
    return returnMat,classLabelVector

def autoNorm(dataSet):
    minVals=dataSet.min(0)
    maxVals=dataSet.max(0)
    ranges=maxVals-minVals
    normDataSet=zeros(shape(dataSet))
    m=dataSet.shape[0]
    normDataSet=dataSet-tile(minVals,(m,1))
    normDataSet=normDataSet/tile(ranges,(m,1))
    return normDataSet,ranges,minVals


import argparse
import cv2

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())

detector = cv2.SIFT_create()
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# This is where the code messes up.
kps = detector.detect(gray)
(kps, descs) = detector.compute(gray, kps)

detImg = cv2.drawKeypoints(gray, kps, image)

print("Number of keypoints detected : {}".format(len(kps)))
print("feature vector shape : {}".format(descs.shape))

cv2.imshow('Detected Image', detImg)
cv2.waitKey(0)


from lnn import Predicate, And, Model, Variable, World, Fact

TRUE = Fact.TRUE
FALSE = Fact.FALSE

model = Model()
x, y, z = map(Variable, ("x", "y", "z"))
P = Predicate()
B = Predicate()
_And = And(P(x), B(x), world=World.AXIOM)

P.add_data({"Jon": TRUE, "Bob": TRUE})
B.add_data({("James", "Date1"): 0.4, ("Bob", "Date2"): TRUE, ("Jon", "Date1"): TRUE})
model.print()
model.add_knowledge(_And)


notebook = 1200000
camera = 400000
print("*****상품 정보*****")
print(f"1 노트북 : {notebook:,} 원")
print(f"2 카메라 : {camera:,} 원")
print("*****상품 정보*****")
num = int(input("상품 번호 입력 : "))

if num != 1 and num != 2:
    print("잘못 입력하였습니다. 종료합니다.")

else:
    num2 = int(input("주문 수량 입력 : "))
    print("***** 주문 내용 *****")

    if num == 1:
        product = "노트북"
        price = notebook

    elif num == 2:
        product = "디지털카메라"
        price = camera

    # 주문액 계산
    amount = num2 * price
    # 할인액 계산
    if amount >= 1000000 :
        discount = int(amount * 0.1)
    elif amount > 500000 :
        discount = int(amount * 0.05)

    total = amount - discount

    print(f"상품명 : {product}")
    print(f"가격 : {price:,} 원")
    print(f"주문 수량 : {num2}")
    print(f"주문액 : {amount:,} 원")
    print(f"할인액 : {discount:,} 원")
    print(f"총 지불액 : {total:,} 원")


import argparse
import errno
import os
import sys

from klever.deploys.local.local import Klever, KleverDevelopment, KleverProduction, KleverTesting
from klever.deploys.utils import check_deployment_configuration_file, get_logger, get_cgroup_version

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('action', choices=['install', 'update', 'reinstall', 'uninstall'],
                        help='Action to be executed.')
    parser.add_argument('mode', choices=['development', 'production', 'testing'], nargs='?', default='production',
                        help='Mode for which action to be executed (default: "%(default)s").')
    parser.add_argument('--non-interactive', default=False, action='store_true',
                        help='Install/update packages non-interactively (default: "%(default)s"). ' +
                             'This option has no effect for mode "testing".')
    parser.add_argument('--deployment-configuration-file',
                        default=os.path.join(os.path.dirname(__file__), os.path.pardir, 'conf', 'klever.json'),
                        help='Path to Klever deployment configuration file (default: "%(default)s").')
    parser.add_argument('--source-directory', default=os.getcwd(),
                        help='Path to Klever source directory (default: "%(default)s").')
    parser.add_argument('--deployment-directory', required=True, help='Path to Klever deployment directory.')
    parser.add_argument('--data-directory', help='Path to directory where Klever will search for build bases. Please,' +
                                                 ' use this option carefully since it will abandon any deployed build' +
                                                 ' bases if so.')
    parser.add_argument('--update-packages', default=False, action='store_true',
                        help='Update packages for action "update" (default: "%(default)s"). ' +
                             'This option has no effect for action "install".')
    parser.add_argument('--update-python3-packages', default=False, action='store_true',
                        help='Update Python3 packages for action "update" (default: "%(default)s"). ' +
                             'This option has no effect for action "install".')
    parser.add_argument('--allow-symbolic-links', default=False, action='store_true',
                        help='Use symbolic links to directories (Klever addons and build bases) rather than copy them' +
                             ' (default: "%(default)s"). Please, use this option very carefully to avoid dangling' +
                             ' symbolic links as well as unexpected changes in their targets. Indeed this option is' +
                             ' intended to update Klever addons and build bases silently without using deployment' +
                             ' scripts.')
    parser.add_argument('--log-level', default='INFO', metavar='LEVEL',
                        help='Set logging level to LEVEL (INFO or DEBUG).')
    parser.add_argument('--install-only-klever-addons', default=False, action='store_true',
                        help='Install only Klever addons and skip most parts of deployment (default: "%(default)s"). ' +
                             'This option may be necessary for very specific conditions, e.g. for generating build' +
                             ' bases using Dockerfile.build-bases.')
    args = parser.parse_args()

    logger = get_logger(__name__, args.log_level)

    check_deployment_configuration_file(logger, args.deployment_configuration_file)

    if get_cgroup_version() != "v1":
        logger.error('It appears that you are using cgroup v2, which is not supported by Klever')
        logger.error('To revert the systemd configuration to use cgroup v1 run the following command and reboot:')
        logger.error('\tsudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"')
        sys.exit(-1)

    # Returns either mode of previous deployment or unchanged value of args.mode
    args.mode = Klever(args, logger).get_deployment_mode()

    logger.info('Start execution of action "%s" in "%s" mode', args.action, args.mode)

    try:
        if args.mode == 'development':
            getattr(KleverDevelopment(args, logger), args.action)()
        elif args.mode == 'production':
            getattr(KleverProduction(args, logger), args.action)()
        elif args.mode == 'testing':
            getattr(KleverTesting(args, logger), args.action)()
        else:
            logger.error('Mode "%s" is not supported', args.mode)
            sys.exit(errno.ENOSYS)
    except SystemExit:
        logger.error('Could not execute action "%s" in "%s" mode (analyze error messages above for details)',
                     args.action, args.mode)
        raise

    logger.info('Finish execution of action "%s" in "%s" mode', args.action, args.mode)


from time import localtime, strftime
import re

from VerilogModule import VerilogModule
from VerilogCodeGen_Helper import *

class VerilogFile():

    """represents a Verilog file"""

    def __init__(self, verilogModule: VerilogModule, s_timescale="", s_author="", s_creationDate="", includeGuards: bool=False, indentObj: IndentObj=IndentObj(tabwidth=4, desiredIndentation=24), language: HDL_Enum=HDL_Enum.VERILOG ):

        self.verilogModule  = verilogModule
        self.s_timescale    = s_timescale
        self.s_author       = s_author
        self.includeGuards  = includeGuards
        self.indentObj      = indentObj
        self.language       = language
        self.s_creationDate = s_creationDate if s_creationDate else strftime("%Y-%m-%d", localtime())

    def __str__(self):
        l_print = []
        l_print.extend( ["language: ", str(self.language), "\n"] )
        l_print.extend( ["timescale: ", self.s_timescale, "\n"] )
        l_print.extend( ["author: ", self.s_author, "\n"] )
        l_print.extend( ["include guards: ", str(self.includeGuards), "\n"] )
        # append module printing
        l_print.extend( [str(self.verilogModule), "\n"] )

        return "".join( l_print )

    @classmethod
    def scan(cls, s_fileIn):
        """scan s_fileIn for a Verilog module declaration and file properties (timescale, language).
        As I assume that scanning a file will be used to generate a testbench or a module instantiation, the method does not scan for the properties s_author and includeGuards (same with VerilogModule.outputReg). They are not practical to match and not needed in those applications.

        :s_fileIn: string representing Verilog/Systemverilog source file to be scanned (gets opened)
        :returns: VerilogFile object if successful, otherwise None
        """
        # determine language from file ending (or exit if no known ending)
        mo_fileEnding = re.search(r"\.(v|sv)$", s_fileIn)
        if mo_fileEnding:
            s_fileEnding = mo_fileEnding.group(1)
#             if s_fileEnding == "v":
            if s_fileEnding == HDL_Enum.VERILOG.get_fileEnding():
                language = HDL_Enum.VERILOG
            else:
                language = HDL_Enum.SYSTEMVERILOG
        else:
            print("no valid input file ending!")
            return None

        # regular expression to match timescale definition
        __re_timescaleDefintion = r"\s*`timescale\s*(\w+\s*/\s*\w+)"

        with open(s_fileIn, "r") as file_in:
            # scan for module declaration
            verilogModule = VerilogModule.scan( file_in )

            # if module declaration found, rescan file for timescale definition, else return None
            if verilogModule:
                # reset read pointer
                file_in.seek(0)

                currentLine = file_in.readline()
                while currentLine:

                    matchObj = re.match( __re_timescaleDefintion , currentLine)
                    if  matchObj:
                        # remove whitespaces from identified timescale string
                        s_timescale = (matchObj.group(1)).replace(" ","")
                        return cls( verilogModule=verilogModule, s_timescale=s_timescale, language=language)
                    else:
                        currentLine = file_in.readline()

                # return VerilogFile object without timescale definition
                return cls( verilogModule=verilogModule, language=language)

            else:
                return None

    def write_moduleFile(self, s_fileOut=""):
        """writes a complete code body to the specified output file

        :s_fileOut: string identifying output file; if empty, s_fileOut will be set to <verilogModule.moduleName>.v/sv depending on self.language
        """
        # determine s_fileOut if not passed
        if not s_fileOut:
            s_fileOut = self.verilogModule.moduleName + "." + self.language.get_fileEnding()

        # check for file existance
        try:
            with open(s_fileOut, "r") as file_out:
                # file exists -> query for overwriting
                overwrite = input("File " + s_fileOut + " exists! Are you sure you want to overwrite it? [y/n]")

                if overwrite == 'y':
                    print("File " + s_fileOut + " will be overwritten...")
                else :
                    print("File " + s_fileOut + " will not be overwritten. Exiting...")
                    return None
        except FileNotFoundError:
            pass

        ##############################
        #### write to output file ####
        ##############################
        with open(s_fileOut, "w") as file_out:

            #### timescale ####
            self.write_timescale(file_out)
            writeBlankLines(file_out, 1)

            #### include guards ####
            if self.includeGuards:
                self.verilogModule.write_includeGuards(file_out, "top")
                writeBlankLines(file_out, 1)

            #### file description commentary ####
            file_out.write("""/*
* company:
* author/engineer:\t""" + self.s_author + """
* creation date:\t""" + self.s_creationDate + """
* project name:
* target devices:
* tool versions:
*
*
* * description:
* [module description]
*
* * interface:
* [interfacing description]
*
*
""")
            # fetch port dictionary
            d_ports = self.verilogModule.ports

            # TODO: maybe use get_tabbedString function to align port/parameter commentaries...
            # write example line
            file_out.write("*\t\t[port name]\t\t- [port description]\n")
            # input ports
            file_out.write("* * inputs:\n" if d_ports["input"] else "")
            for port in d_ports["input"]:
                file_out.write("*\t\t" + port.get_identifier() + "\t\n")

            # output ports
            file_out.write("* * outputs:\n" if d_ports["output"] else "")
            for port in d_ports["output"]:
                file_out.write("*\t\t" + port.get_identifier() + "\t\n")

            # inout ports
            file_out.write("* * inout:\n" if d_ports["inout"] else "")
            for port in d_ports["inout"]:
                file_out.write("*\t\t" + port.get_identifier() + "\t\n")

            # fetch parameter list
            l_parameters = self.verilogModule.l_parameters

            # parameters
            if l_parameters:
                writeBlankLines(file_out,2,leading_string="*")
                file_out.write("* * parameters:\n")
                for parameter in l_parameters:
                    file_out.write("*\t\t" + parameter.identifier + "\t\n")

            file_out.write("*/\n")

            writeBlankLines(file_out,2)

            #### module declaration ####
            self.verilogModule.write_declaration(file_out, indentObj=self.indentObj, language=self.language)

            # end if
            if self.includeGuards:
                writeBlankLines(file_out,1)
                self.verilogModule.write_includeGuards(file_out, "bottom")

    def write_testbenchFile(self, s_fileOut="", b_removeIOSuffix=True):
        """generates a testbench file for self.verilogModule

        :s_fileOut: string identifying output file; if empty, s_fileOut will be set to <verilogModule.moduleName>.v/sv depending on self.language
        """
        # determine s_fileOut if not passed
        if not s_fileOut:
            s_fileOut = "tb_" + self.verilogModule.moduleName + "." + self.language.get_fileEnding()

        # check for file existance
        try:
            with open(s_fileOut, "r") as file_out:
                # file exists -> query for overwriting
                overwrite = input("File " + s_fileOut + " exists! Are you sure you want to overwrite it? [y/n]")

                if overwrite == 'y':
                    print("File " + s_fileOut + " will be overwritten...")
                else:
                    print("File " + s_fileOut + " will not be overwritten. Exiting...")
                    return None
        except FileNotFoundError:
            pass

        ##############################
        #### write to output file ####
        ##############################
        with open(s_fileOut, "w") as file_out:

            #### timescale ####
            self.write_timescale(file_out)
            writeBlankLines(file_out, 1)

            #### file description commentary ####
            file_out.write("""/*
* testbench for """ + self.verilogModule.moduleName + """
*
* company:
* author/engineer:\t""" + self.s_author + """
* creation date:\t""" + self.s_creationDate + """
* project name:
* tool versions:
*/
""")

            writeBlankLines(file_out, 1)

            #### tb module generation ####
            file_out.write("module tb_" + self.verilogModule.moduleName + ";\n")
            writeBlankLines(file_out, 1)

            ## variable declarations ##
            # fetch port dictionary
            d_ports = self.verilogModule.ports

            # input ports
            file_out.write("\t// dut inputs\n" if d_ports["input"] else "")
            for port in d_ports["input"]:
                file_out.write("\t")
                port.write_connectedVariable(file_out, self.indentObj, self.language, b_removeIOSuffix=b_removeIOSuffix)
                file_out.write(";\n")
            if d_ports["input"]: writeBlankLines(file_out, 1)
            # output ports
            file_out.write("\t// dut outputs\n" if d_ports["output"] else "")
            for port in d_ports["output"]:
                file_out.write("\t")
                port.write_connectedVariable(file_out, self.indentObj, self.language, b_removeIOSuffix=b_removeIOSuffix)
                file_out.write(";\n")
            if d_ports["output"]: writeBlankLines(file_out, 1)
            # inout ports
            file_out.write("\t// dut inouts\n" if d_ports["inout"] else "")
            for port in d_ports["inout"]:
                file_out.write("\t")
                port.write_connectedVariable(file_out, self.indentObj, self.language, b_removeIOSuffix=b_removeIOSuffix)
                file_out.write(";\n")

            writeBlankLines(file_out, 2)

            ## clock initialization ##
            # TODO: maybe deactivate by a parameter
            # search for clock signal and set up clock
            # (I know it may not always be switching at 5 time units, but better that writing nothing)
            re_clk = r"(clk|CLK|clock|Clock)"
            for port in d_ports["input"]:
                mo_clk = re.search(re_clk, port.get_identifier() )
                if mo_clk:
                    file_out.writelines(["\talways begin\n", "\t\t #5 "])
                    s_variableIdentifier = port.get_identifier() if not b_removeIOSuffix else removeIOSuffix(port.get_identifier())
                    file_out.write( "\t\t" + s_variableIdentifier + " <= ~" + s_variableIdentifier+ ";\n")
                    file_out.write("\tend\n")
                    writeBlankLines(file_out, 1)

            writeBlankLines(file_out, 1)

            ## empty initial block (with clock initialized to 1 if exists) ##
            file_out.write("\tinitial begin\n")

            # initialize clock if found
            for port in d_ports["input"]:
                mo_clk = re.search(re_clk, port.get_identifier() )
                if mo_clk:
                    s_variableIdentifier = port.get_identifier() if not b_removeIOSuffix else removeIOSuffix(port.get_identifier())
                    file_out.write("\t\t" + s_variableIdentifier + " <= 1;\n")

            writeBlankLines(file_out, 2)
            file_out.writelines(["\t\t$finish\n", "\tend\n"])

            writeBlankLines(file_out, 2)

            ## dut instantiation
            # TODO: will not be indented
            self.verilogModule.write_instantiation(file_out, self.indentObj)

            writeBlankLines(file_out, 1)

            ## end module ##
            file_out.write("endmodule")

    def write_timescale(self, file_out):
        """writes a timescale definition to fileOut_Descriptor if self.s_timescale is not empty

        :file_out: output file object
        """
        if file_out.closed:
            print("file_out must be open!")
            return None

        if self.s_timescale:
            file_out.write("`timescale " + self.s_timescale + "\n")


class Solution:
    def rob(self, nums: List[int]) -> int:

        def rob1(nums):
            dp=nums
            if len(nums)>=3:
                for i in range(len(nums)-3,-1,-1):
                    dp[i]=dp[i]+max(dp[i+2:])
            return max(dp)
        n=len(nums)
        if n<=2:
            return max(nums)
        max1=rob1(nums[:-1])
        max2=rob1(nums[1:])
        return(max(max1,max2))


import  torch
from    torch import nn
from model.my_vit import ViT

class VAE(nn.Module):

    def __init__(self):
        super(VAE, self).__init__()

        self.dropout = nn.Dropout(p=0.5)

        # [b, 784] => [b, 20]
        # u: [b, 10]
        # sigma: [b, 10]
        self.vit = ViT(
                        image_size = 64,
                        patch_size = 16,
                        num_classes = 20,
                        dim = 1024,
                        depth = 6,
                        heads = 16,
                        mlp_dim = 2048,
                        dropout = 0.1,
                        emb_dropout = 0.1
        )

        self.linear_down = nn.Sequential(
            nn.Linear(1000,256),
            nn.BatchNorm1d(256),
            nn.GELU(),
            nn.Linear(256,10),
            nn.Dropout(p=0.1),
        )
        self.linear_up = nn.Sequential(
            nn.Linear(10, 512),
            nn.BatchNorm1d(512),
            nn.GELU(),
            nn.Linear(512, 1000),
            nn.BatchNorm1d(1000),
            nn.GELU(),
            nn.Linear(1000, 3*64*64),

        )

    def forward(self, noise):
        """

        :param x: [b, 1, 28, 28]
        :return:
        """
        # noise = torch.concat((noise,noise,noise),dim=1)
        m = noise.size(-1)

        batchsz = noise.size(0)
        out = self.vit(noise)
        # out = self.linear_down(out)

        mu, sigma = out.chunk(2, dim=1)

        # print(sigma)
        h = mu + sigma * torch.randn_like(sigma)
        # h = mu + torch.exp(sigma) * torch.randn_like(sigma)
        # if mode == 'train':
        #     h = mu + torch.exp(sigma) * torch.randn_like(sigma)
        # else:
        #     h = mu

        # print(mu.shape)
        x_hat = self.linear_up(h)
        x_hat = x_hat.reshape(batchsz,3,m,m)
        #
        kld = 0.5 * torch.sum(
            torch.pow(mu, 2) +
            torch.pow(sigma, 2) -
            torch.log(1e-8 + torch.pow(sigma, 2)) - 1
        ) / (batchsz * m * m)

        return x_hat,kld
if __name__ == '__main__':
    img = torch.randn(2, 3, 64, 64).cuda()
    model = VAE().cuda()
    out = model(img)
    print(out[0].shape)


from .directory_layout import DirectoryLayout
from .dpkg import *
from .cmake_builder import *
from .qt6_base import VERSION, PKGNAME as BASE_PKGNAME, URL as BASE_URL

NAME = 'qt6-svg'
DESCRIPTION = 'Classes for displaying the contents of SVG files (mingw-w64)'
PKGNAME = pkgname(NAME, dev=True)
URL = BASE_URL.replace('qtbase-', 'qtsvg-')

def build():
    if not DPKG.check(BASE_PKGNAME):
        raise RuntimeError(f'requiring {BASE_PKGNAME}')
    if DPKG.installed(PKGNAME):
        print('INSTALLED', PKGNAME)
        return
    cache = DirectoryLayout.download(NAME, URL)
    dpkg = DPKG(PKGNAME, version=VERSION, description=DESCRIPTION,
                depends=[BASE_PKGNAME])
    dirs = Directories(source=cache.src_dir, build=DirectoryLayout.get_build_root() / NAME,
                       installation=dpkg.pkg_root)
    builder = CMakeBuilder(
        name=NAME, dirs=dirs,
    )
    builder.build()
    builder.install()
    dpkg.build_and_install(NAME)


import pygame
class Button(object):

    def __init__(self, image_filename, position):
        self.position = position
        self.image = pygame.image.load(image_filename)

    def render(self, surface):
        x, y = self.position
        w, h = self.image.get_size()
        x -= w / 2
        y -= h / 2
        surface.blit(self.image, (x, y))

    def is_over(self, point):
        # 如果point在自身范围内，返回True
        point_x, point_y = point
        x, y = self.position
        w, h = self.image.get_size()
        x -= w /2
        y -= h / 2
        in_x = point_x >= x and point_x < x + w
        in_y = point_y >= y and point_y < y + h
        return in_x and in_y

    def transform(self,sizex,sizey):
        self.image = pygame.transform.scale(self.image, (sizex, sizey))


import pycuda.driver as cuda
import json
from types import SimpleNamespace
import torch
import cvcuda
import os
import sys
from pathlib import Path

# Import Triton modules
import triton_python_backend_utils as pb_utils

# Bring module folders from the samples directory into our path so that
# we can import modules from it.
samples_dir = Path(os.path.abspath(__file__)).parents[5]  # samples/
segmentation_dir = Path(os.path.abspath(__file__)).parents[
    3
]  # samples/segmentation/python
sys.path.insert(0, os.path.join(samples_dir, ""))
sys.path.insert(0, os.path.join(segmentation_dir, ""))

from model_inference import SegmentationPyTorch, SegmentationTensorRT  # noqa: E402
from pipelines import PreprocessorCvcuda, PostprocessorCvcuda  # noqa: E402

from common.python.perf_utils import CvCudaPerf  # noqa: E402

# docs_tag: end_python_imports

# Triton Python Model
class TritonPythonModel:
    def initialize(self, args):
        # docs_tag: begin_init_model
        self.model_config = json.loads(args["model_config"])
        params = self.model_config["parameters"]
        self.max_batch_size = self.model_config["max_batch_size"]
        self.device_id = int(params["device_id"]["string_value"])
        self.network_width = int(params["network_width"]["string_value"])
        self.network_height = int(params["network_height"]["string_value"])
        self.visualization_class_name = params["visualization_class_name"][
            "string_value"
        ]
        self.inference_backend = params["inference_backend"]["string_value"]
        cuda_device = cuda.Device(self.device_id)
        self.cuda_ctx = cuda_device.retain_primary_context()
        self.cuda_ctx.push()
        self.cvcuda_stream = cvcuda.Stream()
        self.torch_stream = torch.cuda.ExternalStream(self.cvcuda_stream.handle)

        # Use CvCudaPerf class to record performance of various portions of code
        # It reports the data back to nvtx internally.
        # Since it requires a minimal object with certain properties passed in it
        # we will create it here. SimpleNamespace is used to create an object
        # with arbitrary attributes.
        args = SimpleNamespace()
        args.output_dir = "/tmp"
        args.device_id = self.device_id
        self.cvcuda_perf = CvCudaPerf("segmentation_triton_server", default_args=args)

        if self.inference_backend == "tensorrt":
            self.inference = SegmentationTensorRT(
                output_dir="/tmp",
                seg_class_name=self.visualization_class_name,
                batch_size=self.max_batch_size,
                image_size=(self.network_width, self.network_height),
                device_id=self.device_id,
                cvcuda_perf=self.cvcuda_perf,
            )
        else:
            self.inference = SegmentationPyTorch(
                output_dir="/tmp",
                seg_class_name=self.visualization_class_name,
                batch_size=1,
                image_size=(self.network_width, self.network_height),
                device_id=self.device_id,
                cvcuda_perf=self.cvcuda_perf,
            )

        self.input_tensor_name = "inputrgb"
        self.output_tensor_name = "outputrgb"

        self.preprocess = PreprocessorCvcuda(self.device_id, self.cvcuda_perf)
        self.postprocess = PostprocessorCvcuda(
            "NCHW",
            gpu_output=True,
            device_id=self.device_id,
            cvcuda_perf=self.cvcuda_perf,
        )

        self.logger = pb_utils.Logger

        # docs_tag: end_init_model

    # docs_tag: begin_execute_model
    def execute(self, requests):
        responses = []
        # Every Python backend must iterate over everyone of the requests
        # and create a pb_utils.InferenceResponse for each of them.
        try:
            with self.cvcuda_stream, torch.cuda.stream(self.torch_stream):
                for idx, request in enumerate(requests):
                    self.cvcuda_perf.push_range("request", batch_idx=idx)

                    self.cvcuda_perf.push_range("preprocess")
                    in_0 = pb_utils.get_input_tensor_by_name(
                        request, self.input_tensor_name
                    )
                    in_0_numpy = in_0.as_numpy()
                    image_tensors = torch.from_numpy(in_0_numpy)

                    orig_tensor, resized_tensor, normalized_tensor = self.preprocess(
                        image_tensors.cuda(),
                        out_size=(self.network_width, self.network_height),
                    )
                    self.cvcuda_perf.pop_range()

                    self.cvcuda_perf.push_range("inference")
                    probabilities = self.inference(normalized_tensor)
                    self.cvcuda_perf.pop_range()

                    self.cvcuda_perf.push_range("postprocess")
                    blurred_frame = self.postprocess(
                        probabilities,
                        orig_tensor,
                        resized_tensor,
                        self.inference.class_index,
                    )
                    # Get Triton output tensor
                    out_tensor_0 = pb_utils.Tensor(
                        "outputrgb", blurred_frame.cpu().numpy()
                    )
                    # Create inference response
                    inference_response = pb_utils.InferenceResponse(
                        output_tensors=[out_tensor_0]
                    )
                    responses.append(inference_response)
                    self.cvcuda_perf.pop_range()

                    self.cvcuda_perf.pop_range(total_items=in_0_numpy.shape[0])

            # You should return a list of pb_utils.InferenceResponse. Length
            # of this list must match the length of `requests` list.

            return responses
        except Exception as e:
            print(e)
        # docs_tag: end_execute_model

    # docs_tag: begin_finalize_model
    def finalize(self):
        self.cvcuda_perf.finalize()
        self.cuda_ctx.pop()

    # docs_tag: end_finalize_model


s="abcef"

def permutations(s):
    l=[]
    perm(s,"",l)
    print(l)

def perm(s,prefix,l):
    if(s==""):
        l.append(prefix)

    for i in range(len(s)):
        remaning=s[0:i]+s[i+1:]
        perm(remaning,prefix+s[i],l)

permutations(s)


class Solution:

    def shortform(self, nums: List[int]) -> int:
        n = len(nums)
        if n <= 1: return n

        maxSum, curSum = nums[0], nums[0]

        for n in nums[1:]:
            curSum = max(n, curSum + n)
            maxSum = max(maxSum, curSum)

        return maxSum

    def bruteforce(self, nums: List[int]) -> int:
        maxSum = -math.inf

        for i in range(len(nums)):
            curSum = 0
            for j in range(i, len(nums)):
                curSum += nums[j]
                maxSum = max(max_subarray, current_subarray)
        return maxSum

    def maxSubArray(self, nums: List[int]) -> int:
        maxsum, cursum = nums[0], nums[0]

        for i in range(1, len(nums)):
            if cursum < 0:
                cursum = nums[i]
            else:
                cursum += nums[i]
            maxsum = max(cursum, maxsum)
        return maxsum


def third_max(nums):
	if len(nums) < 3:
		return max(nums)

	small, middle, large = -float('inf'), -float('inf'), -float('inf')
	for num in nums:
		if num <= small or num == middle or num == large:
			continue

		if num < middle:
			small = num
		elif num < large:
			small = middle
			middle = num
		elif num > large:
			small = middle
			middle = large
			large = num

	if small != -float('inf'):
		return small
	else:
		return large


#!/usr/bin/env python3

import os
import argparse
from embedding_evaluation.evaluate_similarity import EvaluationSimilarity

import json as jsonmod
import numpy as np

def emb_name(emb_path):
    bname = os.path.basename(emb_path)
    return os.path.splitext(bname)[0]

def load_embeddings(path):
    try:
        with open(path) as fh:
            E = jsonmod.load(fh)
    except IOError as e:
        print("Can not load embeddings: {}".format(e))
        exit(1)
    embeddings = {}
    for word, v in E.items():
        embeddings[word] = np.array(v)
    return embeddings

def load_glove_embeddings(emb_path, vocab):
    embeddings = {}
    try:
        for line in open(emb_path, 'r', encoding='utf-8', errors='surrogateescape'):
            auxV = line.strip().split(' ')
            if auxV[0] not in vocab:
                continue
            embeddings[auxV[0]] = np.array([ float(x) for x in auxV[1:] ])
    except IOError as e:
        print(e)
        exit(1)
    return embeddings

def main():
    os.environ["EMBEDDING_EVALUATION_DATA_PATH"] = "/tartalo03/users/muster/embedding_evaluation_paper/EloiZ/embedding_evaluation/data"
    parser = argparse.ArgumentParser()
    # Hyper Parameters
    parser = argparse.ArgumentParser()
    parser.add_argument('wemb',
                        help = "Word embeddings", nargs='+')
    parser.add_argument('--nofallback', action='store_true',
                        help = "Set for no glove fallback")
    parser.add_argument('--dataset',
                        help = "Give details of dataset")
    opt = parser.parse_args()
    print(opt)
    total_results = {}
    eval_object = EvaluationSimilarity() # use EloiZ to evaluate embeddings

    E_fallback = None
    if not opt.nofallback:
        for emb_path in opt.wemb:
            bname = os.path.basename(emb_path)
            emb_name = os.path.splitext(bname)[0]
            if emb_name != 'glove':
                continue
            E_fallback = load_glove_embeddings(emb_path, eval_object.words_in_benchmarks())
        if E_fallback is None:
            import sys
            print('No glove embeddings (use --nofallback for no glove)', file=sys.stderr)
            exit(0)

    for emb_path in opt.wemb:
        bname = os.path.basename(emb_path)
        emb_name = os.path.splitext(bname)[0]
        if emb_name == 'glove':
            # load only vocab words
            if E_fallback is not None:
                E = E_fallback
            else:
                E = load_glove_embeddings(emb_path, eval_object.words_in_benchmarks())
        else:
            E = load_embeddings(emb_path)
        total_results[emb_name] = eval_object.evaluate(E, E_fallback)
    columns = []
    for emb_name, results in total_results.items():
        if len(columns) == 0:
            columns = [ ['datasets'] + sorted([ r for r in results.keys() ]) ] # first column are the datasets
        c = [ emb_name ]
        for d in columns[0][1:]:
            r = results.get(d, None)
            if r is None:
                c.append('--')
                continue
            if r['total_pairs'] == 0:
                c.append('--')
                continue
            coverage = 100 * r['used_pairs'] / r['total_pairs']
            c.append("{:.2f} : {:.2f}".format(r['all_entities'] * 100, coverage))
        columns.append(c)
    rows = list(map(list, zip(*columns))) # transpose
    print("|" + "|".join(rows[0]) + "|")
    print("|-")
    for r in rows[1:]:
        print("|" + "|".join(r) + "|")

if __name__ == '__main__':
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tues 14 Dec 15:40:20 2021.

@author: floracharbonnier
"""

import copy

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from matplotlib import gridspec

class Action_translator:
    """
    Manage computations of the RL flexibilitiy action variable.

    k  - line coefficients per interval
    xs - intervals
    dp - positive import, negative export (after fixed consumption)
    ds - change in storage
    l  - losses
    fl - flexible load consumed
    """

    def __init__(self, prm, env):
        """Initialise action_translator object and add relevant properties."""
        self.name = 'action translator'
        self.entries = ['dp', 'ds', 'charge_losses', 'discharge_losses', 'c']
        self.plotting = prm['save']['plotting_action']
        self.colours = [(0, 0, 0)] + prm['save']['colours']
        self.n_homes = env.n_homes
        self.N = env.N
        self.labels = [r'$\Delta$p', r'$\Delta$s', 'Losses', 'Consumption']
        self.z_orders = [1, 3, 2, 0, 4]
        self.H = prm['syst']['H']

        type_action = env.spaces.space_info['name'].map(
            lambda x: x[- min(len(x), len('action')):] == 'action'
        )
        self.action_info = env.spaces.space_info[type_action]
        for info in [
            'aggregate_actions', 'dim_actions_1', 'low_action',
            'high_action', 'type_env', 'no_flex_action'
        ]:
            setattr(self, info, prm['RL'][info])
        for info in [
            'dep', 'max_apparent_power_car'
        ]:
            setattr(self, info, prm['car'][info])
        for info in [
            'export_C', 'reactive_power_for_voltage_control'
        ]:
            setattr(self, info, prm['grd'][info])

    def optimisation_to_rl_env_action(self, time_step, date, netp, loads, home_vars, res):
        """
        From home energy values, get equivalent RL flexibility actions.

        Given home consumption and import variables,
        compute equiavalent RL flexibility action values.
        """
        self.car.min_max_charge_t(time_step, date)
        self.initial_processing(loads, home_vars)
        error = np.zeros(self.n_homes, dtype=bool)

        if self.aggregate_actions:
            actions, bool_flex = self.get_aggregate_actions(netp)
        else:
            actions, bool_flex = self._get_disaggregated_actions(res, loads, time_step)

        for home in range(self.n_homes):
            error = self._check_action_errors(
                actions, error, res, loads, home, time_step, bool_flex
            )

        return bool_flex, actions, error

    def initial_processing(self, loads, home_vars):
        """Compute current flexibility variables."""
        # inputs
        # loads: l_flex, l_fixed
        # home_vars: gen0
        eta_dis, eta_ch = self.car.eta_dis, self.car.eta_ch
        homes = range(self.n_homes)

        s_avail_dis, s_add_0, s_remove_0, potential_charge = self.car.initial_processing()

        self._check_input_types(
            loads, home_vars, s_add_0, s_avail_dis, potential_charge, s_remove_0
        )

        # translate inputs into relevant quantities
        self.tot_l_fixed = loads['l_fixed'] + self.heat.E_heat_min
        tot_l_flex = loads['l_flex'] + self.heat.potential_E_flex()

        # gen to min charge
        g_to_add0 = np.minimum(home_vars['gen'], s_add_0 / eta_dis)

        # gen left after contributing to reaching min charge
        g_net_add0 = home_vars['gen'] - g_to_add0

        # required addition to storage for min charge left
        # after contribution from gen
        s_add0_net = s_add_0 - g_to_add0 * eta_ch
        assert np.all(s_add0_net <= self.car.c_max + 1e-2), \
            f"s_add0_net {s_add0_net} > self.car.c_max {self.car.c_max}"
        # gen to fixed consumption
        g_to_fixed = np.minimum(g_net_add0, self.tot_l_fixed)

        # gen left after contributing to fixed consumption
        gnet_fixed = g_net_add0 - g_to_fixed

        # fixed load left after contribution from gen
        lnet_fixed = self.tot_l_fixed - g_to_fixed

        # prof to flex consumption
        g_to_flex = np.minimum(gnet_fixed, tot_l_flex)

        # gen left after contributing to flex consumption
        gnet_flex = gnet_fixed - g_to_flex

        # flex load left after contribution from gen
        lnet_flex = tot_l_flex - g_to_flex

        # gen that can be put in store
        g_to_store = np.minimum(gnet_flex, potential_charge / eta_ch)

        # How much generation left after storing as much as possible
        gnet_store = gnet_flex - g_to_store
        self.k = {home: {} for home in homes}

        # get relevant points in graph
        d = {entry: {} for entry in self.entries}
        action_points, xs = [{} for _ in range(2)]

        d['ds']['A'] = - s_avail_dis + s_add_0
        dsB = np.maximum(- s_avail_dis + s_add_0, - lnet_fixed / eta_dis)
        d['ds']['B'] = np.where(
            s_remove_0 > 1e-2, np.minimum(dsB, - s_remove_0), dsB
        )

        d['ds']['C'] = s_add_0 - s_remove_0
        d['ds']['D'] = s_add_0 - s_remove_0
        dsE = np.maximum(np.minimum(gnet_flex * eta_ch, potential_charge), s_add_0)
        d['ds']['E'] = [min(dsE[home], - s_remove_0[home])
                        if s_remove_0[home] > 1e-2 else dsE[home] for home in homes]
        d['ds']['F'] = np.where(s_remove_0 > 1e-2, - s_remove_0, potential_charge)
        d['dp']['A'] = - s_avail_dis * eta_dis - g_net_add0 \
            + s_add0_net / eta_ch + self.tot_l_fixed

        dspB = np.where(
            d['ds']['B'] > 0, s_add0_net / eta_ch, d['ds']['B'] * eta_dis
        )

        d['dp']['B'] = - g_net_add0 + dspB + self.tot_l_fixed
        d['dp']['C'] = - gnet_fixed + lnet_fixed \
            + s_add0_net / eta_ch - eta_dis * s_remove_0
        d['dp']['D'] = - gnet_flex + lnet_fixed + lnet_flex \
            + s_add0_net / eta_ch - eta_dis * s_remove_0
        dpE_dspos = (dsE - eta_ch * (g_to_store + g_to_add0)) / eta_ch \
            + lnet_fixed + lnet_flex - gnet_store
        dpE_dsneg = lnet_fixed + lnet_flex - gnet_flex - eta_dis * s_remove_0
        d['dp']['E'] = np.where(dsE > 0, dpE_dspos, dpE_dsneg)

        dpF_dspos = (potential_charge - eta_ch * (g_to_add0 + g_to_store)) / eta_ch \
            + lnet_fixed + lnet_flex - gnet_store
        dpF_dsneg = - s_remove_0 * eta_dis + lnet_fixed + lnet_flex - gnet_flex
        d['dp']['F'] = np.where(d['ds']['F'] >= 0, dpF_dspos, dpF_dsneg)

        for i in ['A', 'B', 'C']:
            d['c'][i] = self.tot_l_fixed
        for i in ['D', 'E', 'F']:
            d['c'][i] = self.tot_l_fixed + tot_l_flex
        a_dp = d['dp']['F'] - d['dp']['A']
        a_dp = np.where((- 5e-2 < a_dp) & (a_dp < 0), 0, a_dp)
        assert len(np.where(a_dp < 0)[0]) == 0, f"a_dp {a_dp}"

        b_dp = d['dp']['A']

        action_points['A'], action_points['F'] = np.zeros(self.n_homes), np.ones(self.n_homes)
        for i in ['B', 'C', 'D', 'E']:
            action_points[i] = np.zeros(self.n_homes)
            mask = a_dp > 5e-3
            action_points[i][mask] = (d['dp'][i][mask] - b_dp[mask]) / a_dp[mask]
            for home in homes:
                assert action_points[i][home] > - 5e-3, \
                    f"action_points[{i}][{home}] {action_points[i][home]} < 0"
                if action_points[i][home] > 1 + 5e-3 and self.car.time_step == self.N:
                    action_points[i][home] = 1
                if action_points[i][home] > 1 + 1e-2:
                    print(
                        f"ERROR: action_points[{i}][{home}] {action_points[i][home]} > 1 "
                        f"mask {mask[home]} "
                        f"d['dp'][i][mask] {d['dp'][i][mask][home]} "
                        f"a_dp {a_dp[home]} b_dp {b_dp[home]} "
                        f"self.heat.E_heat_min[home] {self.heat.E_heat_min[home]} "
                        f"self.heat.potential_E_flex()[home] {self.heat.potential_E_flex()[home]}"
                        f"s_avail_dis {s_avail_dis[home]}, "
                        f"s_add_0 {s_add_0[home]}, "
                        f"s_remove_0 {s_remove_0[home]}, "
                        f"potential_charge {potential_charge[home]} "
                        f"self.car.avail_car[home] {self.car.avail_car[home]}"
                        f"loads['l_flex'] {loads['l_flex'][home]}"
                    )
                    np.save('loads_error', loads)
                    np.save('home_vars_error', home_vars)
                    action_points[i][home] = 1

                # assert action_points[i][home] < 1 + 5e-3, \
                #     f"action_points[{i}][{home}] {action_points[i][home]} > 1 " \
                #     f"mask {mask[home]} d['dp'][i][mask] {d['dp'][i][mask][home]}
                #     a_dp {a_dp[home]} b_dp {b_dp[home]}"
                if - 1e-4 < action_points[i][home] < 0:
                    action_points[i][home] = 0
                if 1 < action_points[i][home] < 1 + 5e-3:
                    action_points[i][home] = 1
        self.d = d
        self.k, self.action_intervals = [[] for _ in range(2)]

        for home in homes:
            self._compute_k(home, a_dp, b_dp, action_points, d)
            assert self.heat.E_heat_min[home] + loads['l_fixed'][home] \
                   <= self.k[home]['c'][0][1] + 1e-3,\
                   "min c smaller than min required"
        self.k_dp = np.array([self.k[home]['dp'][0] for home in range(self.n_homes)])

        # these variables are useful in optimisation_to_rl_env_action and actions_to_env_vars
        # in the case where action variables are not aggregated
        min_val_ds = np.array(
            [(self.k[home]['ds'][0][0] * 0 + self.k[home]['ds'][0][1]) for home in homes]
        )
        max_val_ds = np.array(
            [self.k[home]['ds'][-1][0] * 1 + self.k[home]['ds'][-1][1] for home in homes]
        )
        self.min_charge = np.where(min_val_ds > 0, min_val_ds, 0)
        assert all(self.min_charge <= self.car.c_max + 1e-3), \
            f"self.min_charge {self.min_charge} self.car.c_max {self.car.c_max}"
        self.max_discharge = np.where(min_val_ds < 0, min_val_ds, 0)
        self.max_charge = np.where(max_val_ds > 0, max_val_ds, 0)
        self.min_discharge = np.where(max_val_ds < 0, max_val_ds, 0)

    def test_adjust_disaggregated_actions(self, charge, discharge, res, flexible_q_car_action):
        assert not np.isnan(charge), f"{charge}"
        assert not np.isnan(discharge), f"{discharge}"
        assert not np.isnan(res['charge_losses']), f"{res['charge_losses']}"
        if self.reactive_power_for_voltage_control:
            apparent_power_car = abs(charge - discharge + res['charge_losses'])
            assert not np.isnan(flexible_q_car_action), f"{flexible_q_car_action}"
            delta = apparent_power_car - self.max_apparent_power_car
            assert delta <= 1e-3, \
                f"(charge - discharge + res['charge_losses']) {apparent_power_car} " \
                f"self.max_apparent_power_car {self.max_apparent_power_car}"
            if 0 < delta < 1e-3:
                if charge > 0:
                    charge -= delta
                elif discharge > 0:
                    discharge -= delta

    def actions_to_env_vars(self, loads, home_vars, action, date, time_step):
        """Update variables after non flexible consumption is met."""
        # other variables
        self.error = False
        homes = range(self.n_homes)

        # problem variables
        bool_penalty = self.car.min_max_charge_t(time_step, date)
        for e in ['netp', 'tot_cons']:
            home_vars[e] = np.zeros(self.n_homes)

        self.initial_processing(loads, home_vars)

        # check initial errors
        self.res = {}
        [home_vars['bool_flex'], loads['flex_cons'],
         loads['tot_cons_loads'], self.heat.tot_E] \
            = [[] for _ in range(4)]
        self.l_flex = loads['l_flex']
        flex_heat = np.zeros(self.n_homes)
        flexible_q_car = np.zeros(self.n_homes)
        for home in homes:
            # boolean for whether we have flexibility
            home_vars['bool_flex'].append(abs(self.k[home]['dp'][0][0]) > 1e-2)
            if len(np.shape(action)) != 2:
                action = np.reshape(action, (self.n_homes, -1))
            if self.aggregate_actions:
                flex_heat = None
                # update variables for given action
                # obtain the interval in which action_points lies
                ik = [
                    i for i in range(len(self.action_intervals[home]) - 1)
                    if action[home][0] >= self.action_intervals[home][i]
                ][-1]
                res = {}  # resulting values (for dp, ds, fl, l)
                for e in self.entries:
                    ik_ = 0 if e == 'dp' else ik
                    # use coefficients to obtain value
                    res[e] = self.k[home][e][ik_][0] * action[home][0] \
                        + self.k[home][e][ik_][1]

                home_vars['tot_cons'][home] = res['c']
                home_vars['netp'][home] = res['dp']
                if res['c'] > loads['l_flex'][home] + self.tot_l_fixed[home]:
                    loads['flex_cons'].append(loads['l_flex'][home])
                else:
                    loads['flex_cons'].append(res['c'] - self.tot_l_fixed[home])
                    assert loads['flex_cons'][-1] > - 1e-2, \
                        f"loads['flex_cons'][-1] {loads['flex_cons'][-1]} < 0"
                    if - 1e-2 < loads['flex_cons'][-1] < 0:
                        loads['flex_cons'][-1] = 0
            else:
                if not self.reactive_power_for_voltage_control:
                    flexible_cons_action, flexible_heat_action, \
                        flexible_store_action = action[home]
                    flexible_q_car[home] = None
                    flexible_q_car_action = None
                else:
                    flexible_cons_action, flexible_heat_action, \
                        flexible_store_action, flexible_q_car_action = action[home]
                # flex cons between 0 and 1
                # flex heat between 0 and 1
                # charge between -1 and 1 where
                # -1 max discharge
                # 0 nothing (or just minimum)
                # 1 max charge
                res = {}
                flexible_cons_action_ = 0 if flexible_cons_action is None else flexible_cons_action
                loads['flex_cons'].append(flexible_cons_action_ * loads['l_flex'][home])
                flex_heat[home] = flexible_heat_action * self.heat.potential_E_flex()[home]
                home_vars['tot_cons'][home] = self.tot_l_fixed[home] \
                    + loads['flex_cons'][home] \
                    + flex_heat[home]
                res['c'] = home_vars['tot_cons'][home]
                res = self._flexible_store_action_to_ds(home, flexible_store_action, res)

                discharge = - res['ds'] * self.car.eta_dis \
                    if res['ds'] < 0 else 0
                charge = res['ds'] if res['ds'] > 0 else 0
                home_vars['netp'][home] = loads['flex_cons'][home] \
                    + loads['l_fixed'][home] \
                    + self.heat.E_heat_min[home] \
                    + flex_heat[home] \
                    + charge - discharge + res['charge_losses'] \
                    - home_vars['gen'][home]
                self.test_adjust_disaggregated_actions(
                    charge, discharge, res, flexible_q_car_action
                )
                if self.reactive_power_for_voltage_control:
                    # based on flexible store actions, calculate flexible q_car action
                    # reactive power battery between -1 and 1 where
                    # -1 max export
                    # 1 max import
                    res['q'] = flexible_q_car_action * np.sqrt(
                        (self.max_apparent_power_car + 1e-6) ** 2
                        - (charge - discharge + res['charge_losses']) ** 2
                    )
                    flexible_q_car[home] = res['q']

                res['dp'] = home_vars['netp'][home]

            loads['tot_cons_loads'].append(
                loads['flex_cons'][home] + loads['l_fixed'][home])
            self.res[home] = copy.copy(res)

        self.car.actions_to_env_vars(self.res)
        self.heat.actions_to_env_vars(
            self.res, loads['l_flex'], self.tot_l_fixed, E_flex=flex_heat
        )

        # check for errors
        for home in homes:
            # energy balance
            e_balance = abs((self.res[home]['dp'] + home_vars['gen'][home]
                             + self.car.discharge[home] - self.car.charge[home]
                             - self.car.loss_ch[home] - home_vars['tot_cons'][home]))
            assert e_balance <= 1e-2, f"energy balance {e_balance}"
            assert abs(loads['tot_cons_loads'][home] + self.heat.tot_E[home]
                   - home_vars['tot_cons'][home]) <= 1e-3, \
                f"tot_cons_loads {loads['tot_cons_loads'][home]}, "\
                f"self.heat.tot_E[home] {self.heat.tot_E[home]}, " \
                f"home_vars['tot_cons'][home] {home_vars['tot_cons'][home]}"

        bool_penalty = self.car.check_errors_apply_step(
            homes, bool_penalty, action, self.res
        )
        if sum(bool_penalty) > 0:
            self.error = True
        if not self.error and self.plotting:
            self._plot_graph_actions()
        # outputs
        # loads: flex_cons, tot_cons_loads
        # home_vars: netp, bool_flex, tot_cons
        # bool_penalty
        # flexible_q_car

        return loads, home_vars, bool_penalty, flexible_q_car

    def _flexible_store_action_to_ds(self, home, flexible_store_action, res):
        """Convert flexible store action to change in storage level ds."""
        if flexible_store_action is None:
            assert abs(self.min_charge[home] - self.max_charge[home]) <= 1e-3, \
                "flexible_store_action is None but " \
                "self.min_charge[home] != self.max_charge[home]"
            if self.min_charge[home] > 1e-3:
                res['ds'] = self.min_charge[home]
            elif self.min_discharge[home] < - 1e-3:
                res['ds'] = self.min_discharge[home]
            else:
                res['ds'] = 0
        elif flexible_store_action < 0:
            if self.min_charge[home] > 0:
                res['ds'] = self.min_charge[home]
            elif self.min_discharge[home] <= 0:
                res['ds'] = self.min_discharge[home] + abs(flexible_store_action) \
                    * (self.max_discharge[home] - self.min_discharge[home])
        elif flexible_store_action >= 0:
            if self.min_discharge[home] < 0:
                res['ds'] = self.min_discharge[home]
            elif self.max_charge[home] >= 0:
                res['ds'] = self.min_charge[home] + flexible_store_action \
                    * (self.max_charge[home] - self.min_charge[home])
        res['charge_losses'] = 0 if res['ds'] < 0 \
            else (1 - self.car.eta_ch) / self.car.eta_ch * res['ds']
        res['discharge_losses'] = - res['ds'] * (1 - self.car.eta_dis) if res['ds'] < 0 else 0

        return res

    def _plot_graph_actions(self, save_fig=False, name_fig='action_points', legend=False):
        line_width = 2.5
        font_size = 15
        sns.set_palette("bright")
        ymin = 0
        ymax = 0
        fig = plt.figure(figsize=(2, 3))
        ax1 = fig.add_subplot(111)
        gs = gridspec.GridSpec(4, 1)
        ax1.set_position(gs[0:3].get_position(fig))
        ax1.set_subplotspec(gs[0:3])  # only necessary if using tight_layout()

        entries_plot = ['Losses' if e == 'charge_losses' else e
                        for e in self.entries if e != 'discharge_losses']
        ys = {}
        for ie in range(len(entries_plot)):
            e = entries_plot[ie]
            e0 = 'charge_losses' if e == 'Losses' else e
            wd = line_width * 1.5 if e == 'dp' else line_width
            col, zo, label = \
                [self.colours[ie], self.z_orders[ie], self.labels[ie]]
            n = len(self.k[0][e0])
            xs = [0, 1] if e == 'dp' else self.action_intervals[0]
            if e == 'Losses':
                ys[e] = [
                    sum(self.k[0][e_][i][0] * xs[i] + self.k[0][e_][i][1]
                        for e_ in ['charge_losses', 'discharge_losses']) for i in range(n)]
                ys[e].append(
                    sum(self.k[0][e_][-1][0] * xs[-1] + self.k[0][e_][-1][1]
                        for e_ in ['charge_losses', 'discharge_losses']))
            else:
                ys[e] = [self.k[0][e][i][0] * xs[i] + self.k[0][e][i][1]
                         for i in range(n)]
                ys[e].append(
                    self.k[0][e][-1][0] * xs[-1] + self.k[0][e][-1][1])
            ax1.plot(xs, ys[e], label=label, linewidth=wd,
                     color=col, zorder=zo)
            if min(ys[e]) < ymin:
                ymin = min(ys[e])
            if max(ys[e]) > ymax:
                ymax = max(ys[e])
        print(f'name_fig {name_fig}, ymin {ymin}, ymax {ymax}')
        y_bottom = - 56
        y_top = 60
        x_left = - 0.02
        x_right = 1.02
        for e in self.action_intervals.keys():
            ax1.vlines(
                x=self.action_intervals[e][0],
                ymin=y_bottom,
                ymax=y_top,
                color='gray',
                linestyle='--',
                linewidth=0.5
            )
        ax1.hlines(
            y=0,
            xmin=x_left,
            xmax=x_right,
            linestyle='--',
            linewidth=0.5
        )
        ax1.set_ylim([y_bottom, y_top])
        ax1.set_xlim([x_left, x_right])
        ax1.set_xlim([x_left, x_right])
        ax1.set_yticks([0])
        ax1.set_yticklabels([0], fontsize=font_size)
        ax1.set_xticks([])
        ax1.set_xticklabels([])
        if legend:
            ax1.legend(loc='right', bbox_to_anchor=(2, 0), fancybox=True)
        ax2 = fig.add_subplot(gs[3])
        discharge = [abs(ds) if ds < 0 else 0 for ds in ys['ds']]
        all_dps = [x * self.k[0]['dp'][0][0] + self.k[0]['dp'][0][1]
                   for x in self.action_intervals[0]]
        export = [abs(dp) if dp < 0 else 0 for dp in all_dps]
        costs = [loss * 0.1 + self.bat_dep * d + e * self.export_C
                 for loss, d, e in zip(ys['Losses'], discharge, export)]
        ax2.plot(self.action_intervals[0], costs,
                 color=self.colours[len(entries_plot)],
                 linewidth=line_width,
                 label='Battery, loss & export costs')
        ax2.set_yticks([0])
        ax2.set_yticklabels([0], fontsize=font_size)
        ax2.set_xticks([0, 1])
        if legend:
            ax2.legend(loc='right', bbox_to_anchor=(2, -2), fancybox=True)
        ax2.set_ylim([-0.05 * max(costs), max(costs)])
        ax2.set_xticklabels([0, 1], fontsize=font_size)
        # ax2.set_ylabel('Cost', fontsize=font_size)
        # ax2.set_xlabel('Action variable '+ r'$\mu$ [-]',
        # fontsize=font_size)

        fig.tight_layout()

        plt.show()
        if save_fig:
            fig.save_fig(name_fig + '.svg',
                         bbox_inches='tight', format='svg', dpi=1200)

    def _compute_k(self, home, a_dp, b_dp, action_points, d):
        """Get the coefficients of the linear function for the action variable."""
        letters = ['A', 'B', 'C', 'D', 'E', 'F']

        self.k.append({entry: [] for entry in self.entries})
        # reference line - dp

        self.k[home]['dp'] = [[a_dp[home], b_dp[home]]]
        self.action_intervals.append([0])

        for e in ['ds', 'c', 'charge_losses', 'discharge_losses']:
            self.k[home][e] = []
        for z in range(5):
            l1, l2 = letters[z: z + 2]
            if action_points[l2][home] > action_points[l1][home]:
                self.action_intervals[home].append(action_points[l2][home])
                for e in ['ds', 'c', 'losses']:
                    if e == 'losses':
                        self.k = self.car.k_losses(
                            home,
                            self.k,
                            action_points[l1][home],
                            action_points[l2][home]
                        )
                    else:
                        ad = (d[e][l2][home] - d[e][l1][home]) / \
                             (action_points[l2][home] - action_points[l1][home])
                        bd = d[e][l2][home] - action_points[l2][home] * ad
                        self.k[home][e].append([ad, bd])

    def _check_input_types(
            self, loads, home_vars, s_add_0, s_avail_dis, potential_charge, s_remove_0
    ):
        """Check the input types."""
        assert isinstance(loads['l_fixed'], np.ndarray), \
            f"type(loads['l_fixed']) {type(loads['l_fixed'])}"
        assert isinstance(loads['l_flex'], np.ndarray), \
            f"type(loads['l_flex']) {type(loads['l_flex'])}"
        assert isinstance(self.heat.E_heat_min, np.ndarray), \
            f"type(self.heat.E_heat_min) {type(self.heat.E_heat_min)}"
        assert isinstance(home_vars['gen'], np.ndarray), \
            f"type(home_vars['gen']) = {type(home_vars['gen'])}"
        assert isinstance(s_add_0, np.ndarray), \
            f"type(s_add_0) = {type(s_add_0)}"
        assert isinstance(s_avail_dis, np.ndarray), \
            f"type(s_avail_dis) = {type(s_avail_dis)}"
        assert isinstance(potential_charge, np.ndarray), \
            f"type(potential_charge) = {type(potential_charge)}"
        assert isinstance(s_remove_0, np.ndarray), \
            f"type(s_remove_0) = {type(s_remove_0)}"

    def get_flexibility(self):
        """Compute total flexibility between minimum and maximum possible imports/exports."""
        return self.k_dp[:, 0]

    def get_store_bool_flex(self):
        """Check that there is flexibility over the storage sub-action."""
        return [
            abs(self.k[home]['ds'][0][1] - sum(self.k[home]['ds'][-1])) > 1e-3
            for home in range(self.n_homes)
        ]

    def _get_no_flex_action(self, action_type):
        if self.no_flex_action == 'one':
            action = 1
        elif self.no_flex_action == 'random' or self.type_env == 'discrete':
            action = np.random.rand()
        elif self.no_flex_action == 'None':
            action = None

        min_action, max_action = [
            self.action_info.loc[self.action_info["name"] == action_type, col].values[0]
            for col in ['min', 'max']
        ]

        action = action * (max_action - min_action) + min_action

        return action

    def _check_action_errors(
            self, actions, error, res, loads, home, time_step, bool_flex
    ):
        """Check assertion errors for the translation of optimisation results into rl actions."""
        for i in range(self.dim_actions_1):
            if actions[home][i] is not None \
                    and actions[home][i] < self.low_action[i]:
                if actions[home][i] < self.low_action[i] - 1e-2:
                    error[home] = True
                else:
                    actions[home][i] = 0

            if actions[home][i] is not None \
                    and actions[home][i] > self.high_action[i]:
                if actions[home][i] > self.high_action[i] + 1e-2:
                    error[home] = True
                else:
                    actions[home][i] = self.high_action[i]

            if error[home]:
                print(f"time_step {time_step} action[{home}] = {actions[home]}")
                np.save('res_error', res)
                np.save('loads', loads)
                np.save('E_heat_min', self.heat.E_heat_min)
                np.save('E_heat_max', self.heat.E_heat_max)
                np.save('action_error', actions)

        actions_none = (self.aggregate_actions and actions[home] is None) \
            or (not self.aggregate_actions
                and all(action is None for action in actions[home]))
        assert not (bool_flex[home] is True and actions_none), \
            f"actions[{home}] are none whereas there is flexibility"

        return error

    def _get_disaggregated_actions(self, res, loads, time_step):
        flexible_cons_action, loads_bool_flex = self._flex_loads_actions(loads, res, time_step)
        flexible_heat_action, heat_bool_flex = self._flex_heat_actions(res, time_step)
        flexible_store_action, store_bool_flex = self._flex_store_actions(res, time_step)
        if self.reactive_power_for_voltage_control:
            flexible_q_car_action, q_car_bool_flex = self._flex_q_car_actions(res, time_step)
            actions = np.stack(
                (flexible_cons_action, flexible_heat_action, flexible_store_action,
                    flexible_q_car_action), axis=1
            )
            bool_flex = loads_bool_flex | heat_bool_flex | store_bool_flex | q_car_bool_flex
        else:
            actions = np.stack(
                (flexible_cons_action, flexible_heat_action, flexible_store_action), axis=1
            )
            bool_flex = loads_bool_flex | heat_bool_flex | store_bool_flex

        return actions, bool_flex

    def _flex_loads_actions(self, loads, res, time_step):
        no_flex_actions = self._get_no_flex_actions('flexible_cons_action')

        cons = res['house_cons'][:, time_step]
        cons[cons < 1e-3] = 0
        flex_cons = cons - loads['l_fixed']
        flex_cons[flex_cons < 1e-3] = 0
        flex_cons = np.where(
            abs(loads['l_flex'] - flex_cons) < 1e-2,
            loads['l_flex'],
            flex_cons
        )
        loads_bool_flex = loads['l_flex'] > 1e-3
        flexible_cons_action = no_flex_actions
        flexible_cons_action[loads_bool_flex] \
            = flex_cons[loads_bool_flex] / loads['l_flex'][loads_bool_flex]
        flexible_cons_action[abs(flex_cons - loads['l_flex']) < 5e-3] = 1

        if any(flexible_cons_action > 1 + 1e-3):
            print(
                f"flexible_cons_action {flexible_cons_action} "
                f"loads['l_flex'][home] {loads['l_flex']}"
            )

        return flexible_cons_action, loads_bool_flex

    def _flex_heat_actions(self, res, time_step):
        """Compute the flexible heat energy consumption action from the optimisation result."""
        no_flex_actions = self._get_no_flex_actions('flexible_heat_action')

        E_heat = res['E_heat'][:, time_step]
        E_heat[E_heat < 1e-3] = 0
        E_heat = np.where(
            abs(E_heat - self.heat.E_heat_min) < 1e-3,
            self.heat.E_heat_min,
            E_heat
        )
        potential_E_flex = self.heat.potential_E_flex()
        heat_bool_flex = potential_E_flex > 1e-3
        heat_actions = no_flex_actions
        heat_actions[heat_bool_flex] = (
            E_heat[heat_bool_flex] - self.heat.E_heat_min[heat_bool_flex]
        ) / potential_E_flex[heat_bool_flex]

        return heat_actions, heat_bool_flex

    def _flex_store_actions(self, res, time_step):
        """Compute the flexible storage action from the optimisation result."""
        no_flex_actions = self._get_no_flex_actions('battery_action')
        no_flex_charge = abs(self.max_charge - self.min_charge) < 1e-3
        no_flex_discharge = abs(self.min_discharge - self.max_discharge) < 1e-3
        store_bool_flex = ~ (
            (no_flex_charge & no_flex_discharge)
            | (no_flex_discharge & (res['discharge_other'][:, time_step] > 1e-3))
            | (no_flex_charge & (res['charge'][:, time_step] > 1e-3))
        )

        assert all(
            store_bool_flex | (abs(self.min_charge - self.max_charge) <= 1e-3)
        ), "flexible_store_action is None but self.min_charge[home] != self.max_charge[home]"

        assert all(
            (~ store_bool_flex)
            | (
                (self.min_charge - 1e-3 <= res['charge'][:, time_step])
                & (res['charge'][:, time_step] <= self.max_charge + 1e-3)
            )
        ), f"res charge {res['charge'][:, time_step]} " \
           f"self.min_charge[home] {self.min_charge} " \
           f"self.max_charge[home] {self.max_charge}"

        efficiency_corrected_discharge = res['discharge_other'][:, time_step] / self.car.eta_dis
        assert all(
            (~ store_bool_flex)
            | (
                (self.max_discharge - 1e-3 <= - efficiency_corrected_discharge)
                & (- efficiency_corrected_discharge <= self.min_discharge + 1e-3)
            )
        ), f"res efficiency_corrected_discharge {efficiency_corrected_discharge} " \
           f"self.min_discharge] {- self.min_discharge} " \
           f"self.max_discharge] {- self.max_discharge}"
        flexible_store_actions = np.zeros(self.n_homes)
        for home in range(self.n_homes):
            if store_bool_flex[home]:
                if abs(res['discharge_other'][home, time_step]) < 1e-3 \
                        and abs(res['charge'][home, time_step]) < 1e-3:
                    flexible_store_actions[home] = 0
                elif res['discharge_other'][home, time_step] > 1e-3:
                    flexible_store_actions[home] = \
                        (self.min_discharge[home] - res['discharge_other'][home, time_step]) \
                        / (self.min_discharge[home] - self.max_discharge[home])
                else:
                    if abs(res['charge'][home, time_step] - self.max_charge[home]) < 1e-3:
                        flexible_store_actions[home] = 1
                    else:
                        flexible_store_actions[home] = (
                            res['charge'][home, time_step] - self.min_charge[home]
                        ) / (self.max_charge[home] - self.min_charge[home])

        store_actions = np.where(
            store_bool_flex,
            flexible_store_actions,
            no_flex_actions
        )

        return store_actions, store_bool_flex

    def _flex_q_car_actions(self, res, time_step):
        """Compute the flexible battery reactive power action from the optimisation result."""
        no_flex_actions = self._get_no_flex_actions('flexible_q_car_action')
        flexible_q_car_actions = np.zeros(self.n_homes)
        for home in range(self.n_homes):
            active_power = res['charge'][home, time_step] / self.car.eta_ch \
                - res['discharge_other'][home, time_step]
            max_q_car_flexibility = np.sqrt(self.max_apparent_power_car ** 2 - active_power ** 2)
            flexible_q_car_actions[home] = \
                res['q_car_flex'][home, time_step] / max_q_car_flexibility
        # if action is close to zero, consider it to be zero
        flexible_q_car_actions[home] = \
            0 if abs(res['q_car_flex'][home, time_step]) < 1e-3 else flexible_q_car_actions[home]
        q_car_bool_flex = \
            (max_q_car_flexibility > 1e-3) | (max_q_car_flexibility < - 1e-3)

        q_car_actions = np.where(
            q_car_bool_flex,
            flexible_q_car_actions,
            no_flex_actions
        )

        return q_car_actions, q_car_bool_flex

    def _get_no_flex_actions(self, action_type):
        if self.no_flex_action == 'one':
            action = np.ones(self.n_homes)
        elif self.no_flex_action == 'random' or self.type_env == 'discrete':
            action = np.random.rand(self.n_homes)
        elif self.no_flex_action == 'None':
            action = np.full(self.n_homes, None)

        min_action, max_action = [
            self.action_info.loc[self.action_info["name"] == action_type, col].values[0]
            for col in ['min', 'max']
        ]

        action = action * (max_action - min_action) + min_action

        return action

    def aggregate_action_bool_flex(self):
        return self.k_dp[:, 0] > 0

    def get_aggregate_actions(self, netp):
        self.k_dp[:, 0][abs(self.k_dp[:, 0]) < 1e-2] = 0
        bool_flex = self.aggregate_action_bool_flex()
        assert all(bool_flex | (netp - self.k_dp[:, 1] > - 1e-2)), \
            "netp smaller than k['dp'][0]"

        delta = np.where(
            abs(netp - self.k_dp[:, 1]) < 1e-2,
            0,
            netp - self.k_dp[:, 1]
        )
        no_flex_actions = self._get_no_flex_actions('action')
        actions = no_flex_actions
        actions[bool_flex] = delta[bool_flex] / self.k_dp[bool_flex, 0]
        assert all(
            action is None or ((action >= 0) & (action <= 1 + 1e-3))
            for action in actions
        ), f"action should be between 0 and 1 but is {actions}"

        actions = np.reshape(actions, (self.n_homes, 1))

        return actions, bool_flex

# figs1
# env.action_translator.mincharge=[7.5, 7.5]
# env.action_translator.maxcharge=[75,75]
# env.action_translator.initial_processing(
# [45,45], [10, 10], [10,10], [1,1], [5,5],[20, 20],[5, 5],[0, 1])
# env.action_translator._plot_graph_actions(True, 'mu_smallgen')

# env.action_translator.mincharge=[7.5,7.5]
# env.action_translator.maxcharge=[30,30]
# env.action_translator.store0=[37.5,37.5]
# env.action_translator.initial_processing(
# [20,20], [10, 10], [15,15], [1,1], [0,0],[10, 10],[0, 0],[0, 1])
# env.action_translator._plot_graph_actions(True, 'mu_midgen')

# env.action_translator.mincharge=[7.5,7.5]
# env.action_translator.maxcharge=[75,75]
# env.action_translator.store0=[37.5,37.5]
# env.action_translator.initial_processing(
# [20,20], [10, 10], [30,30], [1,1], [0,0],[10, 10],[0, 0],[0, 1])
# env.action_translator._plot_graph_actions(True, 'mu_largegen')

# figs2
# def initial_processing(self, store0, l_flex, gen0,
# avail_EV, E_flex, l_fixed, E_heat_min, homes):

# env.action_translator.mincharge=[7.5,7.5]
# env.action_translator.maxcharge=[75,75]
# env.action_translator.initial_processing(
# [35,35], [20, 20], [5,5], [1,1], [0,0],[20, 20],[0, 0],[0, 1])
# env.action_translator._plot_graph_actions(True, 'mu_smallgen')

# env.action_translator.mincharge=[7.5,7.5]
# env.action_translator.maxcharge=[75,75]
# env.action_translator.initial_processing(
# [35,35], [20, 20], [5,5], [1,1], [0,0],[20, 20],[0, 0],[0, 1])
# env.action_translator._plot_graph_actions(True, 'mu_legend', legend=True)

# env.action_translator.mincharge=[7.5,7.5]
# env.action_translator.maxcharge=[75,75]
# env.action_translator.initial_processing(
# [35,35], [20, 20], [30,30], [1,1], [0,0],[20, 20],[0, 0],[0, 1])
# env.action_translator._plot_graph_actions(True, 'mu_midgen')

# env.action_translator.mincharge=[7.5,7.5]
# env.action_translator.maxcharge=[75,75]
# env.action_translator.initial_processing(
# [35,35], [20, 20], [50,50], [1,1], [0,0],[20, 20],[0, 0],[0, 1])
# env.action_translator._plot_graph_actions(True, 'mu_largegen')