# -*- coding: utf-8 -*-
import torch.nn as nn
from network import Decomposition,MultiscaleDiscriminator,downsample
from utils import gradient
from ssim import SSIM
import torch
import torch.optim as optim
import torchvision
import os
import torch.nn.functional as F
from contiguous_params import ContiguousParams

class Model(nn.Module):
    def __init__(self,args):
        super(Model, self).__init__()
        self.fusion = Decomposition()
        self.D = MultiscaleDiscriminator(input_nc=1)
        self.MSE_fun = nn.MSELoss()
        self.L1_loss = nn.L1Loss()
        self.SSIM_fun = SSIM()

        if args.contiguousparams==True:
            print("ContiguousParams---")
            parametersF = ContiguousParams(self.fusion.parameters())
            parametersD = ContiguousParams(self.D.parameters())
            self.optimizer_G = optim.Adam(parametersF.contiguous(), lr=args.lr)
            self.optimizer_D = optim.Adam(parametersD.contiguous(), lr=args.lr)
        else:
            self.optimizer_G = optim.Adam(self.fusion.parameters(), lr=args.lr)
            self.optimizer_D = optim.Adam(self.D.parameters(), lr=args.lr)

        self.g1 = self.g2 = self.g3 = self.s = self.img_re = None
        self.loss = torch.zeros(1)
        self.scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(self.optimizer_G , mode='min', factor=0.5, patience=2,
                                                               verbose=False, threshold=0.0001, threshold_mode='rel',
                                                               cooldown=0, min_lr=0, eps=1e-10)
        self.min_loss = 1000
        self.args = args
        self.downsample = downsample()
        self.criterionGAN = torch.nn.MSELoss()

        if args.multiGPU:
            self.mulgpus()
        self.load()
        self.load_D()

    def load_D(self,):
        if self.args.load_pt:
            print("=========LOAD WEIGHTS D=========")
            path = self.args.weights_path.replace("fusion","D")
            print(path)
            checkpoint = torch.load(path)

            if self.args.multiGPU:
                print("load D")
                self.D.load_state_dict(checkpoint['weight'])
            else:
                print("load D single")
                # 单卡模型读取多卡模型
                state_dict = checkpoint['weight']
                # create new OrderedDict that does not contain `module.`
                from collections import OrderedDict
                new_state_dict = OrderedDict()
                for k, v in state_dict.items():
                    name = k.replace('module.', '')  # remove `module.`
                    new_state_dict[name] = v
                # load params
                self.D.load_state_dict(new_state_dict)

            print("=========END LOAD WEIGHTS D=========")

    def load(self,):
        start_epoch = 0
        if self.args.load_pt:
            print("=========LOAD WEIGHTS=========")
            checkpoint = torch.load(self.args.weights_path)
            start_epoch = checkpoint['epoch'] + 1
            try:
                if self.args.multiGPU:
                    print("load G")
                    self.fusion.load_state_dict(checkpoint['weight'])
                else:
                    print("load G single")
                    # 单卡模型读取多卡模型
                    state_dict = checkpoint['weight']
                    # create new OrderedDict that does not contain `module.`
                    from collections import OrderedDict
                    new_state_dict = OrderedDict()
                    for k, v in state_dict.items():
                        name = k.replace('module.', '')  # remove `module.`
                        new_state_dict[name] = v
                    # load params
                    self.fusion.load_state_dict(new_state_dict)
            except:
                model = self.fusion
                print("weights not same ,try to load part of them")
                model_dict = model.state_dict()
                pretrained = torch.load(self.args.weights_path)['weight']
                # 1. filter out unnecessary keys
                pretrained_dict = {k: v for k, v in model_dict.items() if k in pretrained}
                left_dict = {k for k, v in model_dict.items() if k  not in pretrained}
                print(left_dict)
                # 2. overwrite entries in the existing state dict
                model_dict.update(pretrained_dict)
                # 3. load the new state dict
                model.load_state_dict(model_dict)
                print(len(model_dict),len(pretrained_dict))
                # model_dict = self.fusion.state_dict()
                # pretrained_dict = {k: v for k, v in model_dict.items() if k in checkpoint['weight'] }
                # print(len(checkpoint['weight'].items()), len(pretrained_dict), len(model_dict))
                # model_dict.update(pretrained_dict)
                # self.fusion.load_state_dict(model_dict)
            print("start_epoch:", start_epoch)
            print("=========END LOAD WEIGHTS=========")
        print("========START EPOCH: %d========="%start_epoch)
        self.start_epoch = start_epoch

    def mulGANloss(self, input_, is_real):
        if is_real:
            label = 1
        else:
            label = 0

        if isinstance(input_[0], list):
            loss = 0.0
            for i in input_:
                pred = i[-1]
                target = torch.Tensor(pred.size()).fill_(label).to(pred.device)
                loss += self.criterionGAN(pred, target)
            return loss
        else:
            target = torch.Tensor(input_[-1].size()).fill_(label).to(input_[-1].device)
            return self.criterionGAN(input_[-1], target)

    def forward(self,isTest=False):
        self.g1, self.g2, self.g3, self.s, self.img_re = self.fusion(self.img,isTest)

    def set_requires_grad(self, net, requires_grad=False):
        for param in net.parameters():
            param.requires_grad = requires_grad

    def backward_G(self):
        img = self.img
        img_re = self.img_re
        img_g = gradient(img)
        self.img_down = self.downsample(img)
        self.img_g = img_g
        # print(self.g1.sum(),self.g2.sum(),self.g3.sum(),img_g.sum())
        # print(self.g1.mean(), self.g2.mean(), self.g3.mean(), img_g.mean())
        g1 = self.MSE_fun(self.g1, img_g)
        g2 = self.MSE_fun(self.g2, img_g)
        g3 = self.MSE_fun(self.g3, img_g)
        grd_loss = g1+g2+g3
        self.lossg1 ,self.lossg2,self.lossg3 = g1,g2,g3
        # grd_loss = self.MSE_fun(self.g1, img_g) + self.MSE_fun(self.g2, img_g) + self.MSE_fun(self.g3, img_g)
        ssim_loss = 1 - self.SSIM_fun(img_re, img)
        ssim_loss = ssim_loss * 10
        pixel_loss = self.MSE_fun(img_re, img)
        pixel_loss = pixel_loss * 100

        loss_G = self.mulGANloss(self.D(self.s), is_real=True)*0.1

        # 损失求和 回传
        loss = pixel_loss + ssim_loss + grd_loss + loss_G

        loss.backward()
        self.loss,self.pixel_loss,self.ssim_loss, self.grd_loss = loss,pixel_loss,ssim_loss, grd_loss
        self.loss_G = loss_G

    def backward_D(self):
        # RealReal
        # Real
        pred_real = self.D(self.img_down.detach())
        loss_D_real = self.mulGANloss(pred_real, is_real=True)
        # Fake
        pred_fake = self.D(self.s.detach())
        loss_D_fake = self.mulGANloss(pred_fake, is_real=False)
        # Combined loss and calculate gradients
        loss_D = (loss_D_real + loss_D_fake) * 0.5
        loss_D.backward()
        self.loss_D = loss_D
        self.loss_D_real,self.loss_D_fake = loss_D_real,loss_D_fake

    def mulgpus(self):
        self.fusion= nn.DataParallel(self.fusion.cuda(), device_ids=self.args.GPUs, output_device=self.args.GPUs[0])
        self.D = nn.DataParallel(self.D.cuda(), device_ids=self.args.GPUs, output_device=self.args.GPUs[0])

    def setdata(self,img):
        img = img.to(self.args.device)
        self.img = img

    def step(self):
        self.optimizer_G.zero_grad()  # set G gradients to zero
        self.forward()

        self.set_requires_grad(self.D, False)  # D require no gradients when optimizing G

        self.backward_G()  # calculate gradients for G
        self.optimizer_G.step()  # update G weights

        # if it % 10 == 0:
        self.set_requires_grad(self.D, True)
        self.optimizer_D.zero_grad()  # set D gradients to zero
        self.backward_D()  # calculate gradients for D
        self.optimizer_D.step()  # update D weights

        self.print = 'ALL[%.5lf] pixel[%.5lf] grd[%.5lf](%.5lf %.5lf %.5lf) ssim[%.5lf] G[%.5lf]  D[%.5lf][%.5lf %.5lf ]' %\
                     (self.loss.item(), self.pixel_loss.item(), self.grd_loss.item(),self.lossg1.item() ,self.lossg2.item(),self.lossg3.item(), self.ssim_loss.item(),
                      self.loss_G.item(),self.loss_D.item(),self.loss_D_real.item(),self.loss_D_fake.item(),)

    def saveimg(self,epoch,num=0):
        img = torchvision.utils.make_grid(
            [self.img[0].cpu(), self.img_re[0].cpu(), self.img_down[0].cpu(),self.img_g[0].cpu(), self.s[0].cpu(), self.g1[0].cpu(), self.g2[0].cpu(),
             self.g3[0].cpu(), (self.g1+self.g2+self.g3)[0].cpu()], nrow=5)
        torchvision.utils.save_image(img, fp=(os.path.join('output/result_' + str(epoch) + '.jpg')))
        # torchvision.utils.save_image(img, fp=(os.path.join('output/epoch/'+str(num)+'.jpg')))

    def saveimgdemo(self):
        self.img_down = self.downsample(self.img)
        self.img_g = gradient(self.img)

        img = torchvision.utils.make_grid(
            [self.img[0].cpu(), self.img_re[0].cpu(), self.img_down[0].cpu(),self.img_g[0].cpu(), self.s[0].cpu(), self.g1[0].cpu(), self.g2[0].cpu(),
             self.g3[0].cpu(), (self.g1+self.g2+self.g3)[0].cpu()], nrow=5)
        torchvision.utils.save_image(img, fp=(os.path.join('demo_result.jpg')))
        # torchvision.utils.save_image(img, fp=(os.path.join('output/epoch/'+str(num)+'.jpg')))

    def saveimgfuse(self,name=''):
        self.img_down = self.downsample(self.img)
        self.img_g = gradient(self.img)

        img = torchvision.utils.make_grid(
            [self.img[0].cpu(), self.img_g[0].cpu(), ((self.g1+self.g2+self.g3)*1.5)[0].cpu()], nrow=3)
        torchvision.utils.save_image(img, fp=(os.path.join(name.replace('Test','demo'))))
        # torchvision.utils.save_image(img, fp=(os.path.join('output/epoch/'+str(num)+'.jpg')))

    def save(self, epoch):
        ## 保存模型和最佳模型
        if self.min_loss > self.loss.item():
            self.min_loss = self.loss.item()
            torch.save({'weight': self.fusion.state_dict(), 'epoch': epoch, },os.path.join('weights/best_fusion.pt'))
            torch.save({'weight': self.D.state_dict(), 'epoch': epoch, }, os.path.join('weights/best_D.pt'))
            print('[%d] - Best model is saved -' % (epoch))

        if epoch % 1 == 0:
            torch.save({'weight': self.fusion.state_dict(), 'epoch': epoch, },os.path.join('weights/epoch' + str(epoch) + '_fusion.pt'))
            torch.save({'weight': self.D.state_dict(), 'epoch': epoch, },os.path.join('weights/epoch' + str(epoch) + '_D.pt'))

    def getimg(self):
        return self.g1, self.g2,self.g3,self.s


from extra_streamlit_tools._logging import logging as logger
import streamlit as st
from typing import Any, Optional

def clear_cache(keep_keys: Optional[list[str]] = None) -> None:
    """
    Resets the Streamlit cache.

    Parameters
    ----------
        keep_keys:Optional[list[str]]
            Keys to not be cleared from cache
    """

    logger.debug("Clearing cache")
    for key in st.session_state.keys():
        if keep_keys is None or key not in keep_keys:
            logger.debug(f"Deleting key: {key}")
            del st.session_state[key]
        else:
            logger.debug(f"Keeping key: {key}")

def init_session_keys(key_value_pairs: dict[str, Any]) -> None:
    """
    The init_session_keys function is a helper function that initializes the session state with keys and values.

    Parameters
    ----------
        key_value_pairs:dict[str, Any]
            A dictionairy of key_value_pairs
    """  # noqa
    for key, value in key_value_pairs.items():
        if key not in st.session_state:
            st.session_state[key] = value

def change_in_session_state(key_value_pairs: dict[str, Any]):
    """
    The change_in_session_state function is a helper function that allows you to change session state values.

    Parameters
    ----------
        key_value_pairs:dict[str, Any]
            Dictionairy with the Streamlit session_state key and the its new value
    """  # noqa
    for key, value in key_value_pairs.items():
        st.session_state[key] = value

def set_selectbox_index(
    selectbox_key: str, session_state_var_name: str, values: list[Any]
) -> None:
    """
    The set_selectbox_index function is a helper function that sets the index of a selectbox to the value
    of another session state variable. This is useful when you want to set the default value of one selectbox
    to be equal to another, but you don't know what that other's default value will be until runtime.

    Parameters
    ----------
        selectbox_key:str
            Specify the key of the selectbox
        session_state_var_name:str
            Set the session state variable name
        values:list[Any]
            The list of values in the selectbox
    """  # noqa
    st.session_state[session_state_var_name] = values.index(
        st.session_state[selectbox_key]
    )


from enaml.core.enaml_compiler import EnamlCompiler
from enaml.core.parser import parse

def compile_source(source, item, filename="<test>", namespace=None):
    """Compile Enaml source code and return the target item.
    Parameters
    ----------
    source : str
        The Enaml source code string to compile.
    item : str
        The name of the item in the resulting namespace to return.
    filename : str, optional
        The filename to use when compiling the code. The default
        is '<test>'.
    namespace : dict
        Namespace in which to execute the code
    Returns
    -------
    result : object
        The named object from the resulting namespace.
    """
    ast = parse(source, filename)
    code = EnamlCompiler.compile(ast, filename)
    namespace = namespace or {}
    exec(code, namespace)
    return namespace[item]


# Code by @AmirMotefaker

# projecteuler.net
# https://projecteuler.net/problem=25

# 1000-digit Fibonacci number
# Problem 25

# The Fibonacci sequence is defined by the recurrence relation:
#        Fn = Fn−1 + Fn−2, where F1 = 1 and F2 = 1.
# Hence the first 12 terms will be:
# F1 = 1
# F2 = 1
# F3 = 2
# F4 = 3
# F5 = 5
# F6 = 8
# F7 = 13
# F8 = 21
# F9 = 34
# F10 = 55
# F11 = 89
# F12 = 144
# The 12th term, F12, is the first term to contain three digits.

# What is the index of the first term in the Fibonacci sequence to contain 1000 digits?

# Solution 1

# def fibonacci(a, b, n):
#     if n == 1:
#         return a
#     else:
#         return fibonacci(a+b, a, n-1)

# print (fibonacci(1, 0, 12))

# Solution 2
# loop instead of recursion

# def fibonacci(n):
#     a = 1
#     b = 0
#     while n > 1:
#         a, b = a+b, a
#         n = n - 1
#     return a

# print (fibonacci(12))

# Solution 3

import time
start_time = time.time()   #Time at the start of program execution

term = 2
fib = [1, 1]
while len(str(fib[1])) < 1000:
    term += 1
    fib = [fib[1], fib[0] + fib[1]]

print (term)

end_time = time.time()   #Time at the end of execution
print ("Time of program execution:", (end_time - start_time))   # Time of program execution

### Answer:  4782


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Jan 20 15:50:56 2018

@author: vitorhadad
"""
#
import numpy as np
import networkx as nx
import os

from tqdm import trange
from matching.solver.kidney_solver2 import optimal, greedy, get_two_cycles
from matching.utils.data_utils import clock_seed, evaluate_policy, get_n_matched, get_cycle_probabilities
from matching.utils.env_utils import snapshot, two_cycles
from matching.policy_function.policy_function_lstm import RNN
from matching.policy_function.policy_function_mlp import MLPNet
from matching.policy_function.policy_function_gcn import GCNet
from matching.policy_function.policy_function_rgcn import RGCNet
from matching.policy_function.policy_function_attention import AttentionRNN
from matching.environment.abo_environment import ABOKidneyExchange

#%%
def run_node2vec(G,
                 path = "",
                 input = "edges.txt",
                 output = "emb.txt",
                 d = 10):

    nx.write_edgelist(G, path + input, data = False)

    cmd = "./node2vec -i:{}{} -o:{}{} -d:{} -dr"\
            .format(path, input, path, output, d)

    os.system(cmd)

    with open("emb.txt", "r") as emb:
        lines = emb.readlines()
        n = len(lines) - 1
        features = np.zeros(shape = (n, d))
        for k, line in enumerate(lines[1:]):
            _, *xs = line.split(" ")
            try:
                features[k] = [float(x) for x in xs]
            except:
                import pdb; pdb.set_trace()
    return features

def get_features(env):
    opt= optimal(env)

    features = []
    labels = []

    for t in range(env.time_length):
        liv = np.array(env.get_living(t))
        A = env.A(t)
        has_cycle = np.diag(A @ A) > 0
        liv = liv[has_cycle]

        m = opt["matched"][t]

        Y = np.zeros(len(liv))
        Y[np.isin(liv, list(m))] = 1
        labels.append(Y)

        if len(liv) > 0:
            X = env.X(t)[has_cycle]
            subg = env.subgraph(liv)
            E = run_node2vec(subg)
            features.append(np.hstack([X, E]))

        env.removed_container[t].update()

    return np.vstack(features), np.hstack(labels)

env = ABOKidneyExchange(entry_rate=5, death_rate=.1, time_length=10, seed=clock_seed())

X, Y = get_features(env)
np.save("X.npy", X)
np.save("Y.npy", Y)

#%%

#%%
#

#

#%%
#
#env = ABOKidneyExchange(entry_rate = 5,
#                        death_rate = .1,
#                        time_length = 1500,
#                        seed = clock_seed())
#
#opt = optimal(env)
#gre = greedy(env)
#
##%%
#def evaluate(algo, env, thres):
#
#    env.removed_container.clear()
#    rewards = []
#    for t in trange(env.time_length):
#
#        liv = np.array(env.get_living(t))
#        A = env.A(t)
#        has_cycle = np.diag(A @ A) > 0
#        liv_and_cycle = liv[has_cycle]
#        yhat_full = np.zeros(len(liv), dtype=bool)
#
#        if len(liv_and_cycle) == 0:
#            continue
#
#        X = env.X(t)[has_cycle]
#        subg = env.subgraph(liv_and_cycle)
#        E = run_node2vec(subg)
#        F = np.hstack([X, E])
#
#        yhat = algo.predict_proba(F)[:,1] > thres
#        yhat_full[has_cycle] = yhat
#        potential = liv[yhat_full]
#
#        removed = optimal(env, t, t, subset=potential)["matched"][t]
#        env.removed_container[t].update(removed)
#        rewards.append(len(removed))
#
#    return rewards
#
#
#r = evaluate(pipe, env, .05)
#
#gre_n = get_n_matched(gre["matched"], 0, env.time_length)
#opt_n = get_n_matched(opt["matched"], 0, env.time_length)

#print("\nrewards\n",
#      np.sum(r[500:]),
#      np.sum(gre_n[500:]),
#      np.sum(opt_n[500:]))
#


from computer import TogglePuter

class BadSignal(Exception):
    def __init__(self, signal):
        self.message = str(signal)

class InfiniteLoop(Exception):
    pass

class SignalPuter(TogglePuter):
    def __init__(self):
        super().__init__()
        self.signal = []

    def out(self, x):
        value = self._get_value(x)
        self.signal.append(value)
        if value == len(self.signal) % 2:
            raise BadSignal(self.signal)
        if len(self.signal) > 10:
            raise InfiniteLoop
        self.pc += 1

def find_input(instructions):
    aval = 0
    while True:
        try:
            computer = SignalPuter()
            computer.a = aval
            computer.run(instructions, debug=False)
        except BadSignal:
            # print("{}: {}".format(aval, computer.signal))
            aval += 1
        except InfiniteLoop:
            return aval

if __name__ == "__main__":
    import doctest
    doctest.testmod()

    with open('25input.txt', 'r') as inputfile:
        lines = inputfile.readlines()
        print("Part 1: {}".format(find_input(lines)))


import time
import netsvc

from osv import fields,osv

class purchase_requisition(osv.osv):
    _inherit = "purchase.requisition"
    _description="Purchase Requisition"
    _columns = {

        'state': fields.selection([('draft','Draft'),('lv_approve2','Waitting Manager Approve'),('in_progress','In Progress'),('cancel','Cancelled'),('done','Done')], 'State', required=True)
    }
    _defaults = {
        'date_start': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
        'state': 'draft',
        'exclusive': 'multiple',
        'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'purchase.requisition', context=c),
        'user_id': lambda self, cr, uid, context: uid,
        'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'purchase.order.requisition'),
    }

    def copy(self, cr, uid, id, default=None, context=None):
        if not default:
            default = {}
        default.update({
            'state':'draft',
            'purchase_ids':[],
            'name': self.pool.get('ir.sequence').get(cr, uid, 'purchase.order.requisition'),
        })
        return super(purchase_requisition, self).copy(cr, uid, id, default, context)

    def tender_cancel(self, cr, uid, ids, context=None):
        purchase_order_obj = self.pool.get('purchase.order')
        for purchase in self.browse(cr, uid, ids, context=context):
            for purchase_id in purchase.purchase_ids:
                if str(purchase_id.state) in('draft','wait'):
                    purchase_order_obj.action_cancel(cr,uid,[purchase_id.id])
        self.write(cr, uid, ids, {'state': 'cancel'})
        return True

    def tender_in_progress(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state':'lv_approve2'} ,context=context)
        return True

    def manager_approve(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state':'in_progress'} ,context=context)
        return True

    def tender_reset(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state': 'draft'})
        return True

    def tender_done(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state':'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S')}, context=context)
        return True

purchase_requisition()


from __future__ import print_function
#
# -*- coding: utf-8 -*-#
# eso.org
# Copyright 2011 ESO
# Authors:
#   Lars Holm Nielsen <lnielsen@eso.org>
#   Dirk Neumayer <dirk.neumayer@gmail.com>
#
#
# Mantis 12175: Fix release dates for images and videos
#
#
# Find wrong release_dates:
# 1) Check id with release_date - e.g. opo0214a with release date in 2010 must be wrong
#    should be opoYYNNx NN is a cont. number?
# 2) Release dates with 2011-03-03 18:00-18:44 are wrong
#
# Don't bother about images connected to announcements, releases and potws.
#
# For images with long_caption_link or press_release_link follow the link and extract the date.
#
#
#*************************************************************************************************************

from future import standard_library
standard_library.install_aliases()
from djangoplicity.utils import optionparser
from djangoplicity.media.models import Image
from djangoplicity.media.models import Video

import re
import urllib.request, urllib.error, urllib.parse

import logging, sys
import socket

from datetime import datetime
import pytz

import hubblesite

def change_datetime(obj):
    '''
    follows the long_caption_link or the press_release_link to get the correct date
    '''
    # get link to image or press release
    link = None
    success = False
    if obj.long_caption_link.find('http') > -1:
        link = obj.long_caption_link
    elif obj.press_release_link.find('http') > -1:
        link = obj.press_release_link

    # follow link and get new date
    if link:
        release_date = hubblesite.get_release_date(link)
        if release_date:
            try:
                #print '-------------------------------------------------------'
                #print obj.id, obj.release_date.strftime('%Y-%B-%d %I:%M %p %Z')
                release_date = release_date.astimezone( pytz.timezone( 'Europe/Berlin' ) )
                release_date = datetime.replace(release_date, tzinfo=None)
                obj.release_date = release_date
                #print obj.id, obj.release_date.strftime('%Y-%B-%d %I:%M %p %Z')
                obj.save()
                success = True
            except:
                print(obj.id,' save failed!')
                pass
    return success

def process_objects(objs):
    '''
    find the objects that need a correction of the release_date
    '''
    pat = re.compile('[a-zA-Z]+([0-9]{2})\S+')

    count = 0
    finddate1 = datetime.strptime('2011-03-03 18:00:00','%Y-%m-%d %H:%M:%S')
    finddate2 = datetime.strptime('2011-03-03 19:00:00','%Y-%m-%d %H:%M:%S')
    for obj in objs:

        YY = None
        dt = obj.release_date
        if (dt):
            # process all objects with 2011-03-03 18:00:00 - 19:00:00
            if dt >= finddate1 and dt <= finddate2:
                if change_datetime(obj): count = count + 1
                print(obj.id, 'old: ', dt, '\t new: ', obj.release_date ,'\t\t reason: 20110303')
            # process all objects where opoYY YY does not match the year of the release_date
            else:
                #only care about opo... and heic...
                if obj.id.find('opo') == -1 and obj.id.find('heic') == -1: continue
                YY = pat.findall(obj.id)
                if len(YY) > 0:
                    YY = YY[0]
                    #print obj.id, YY, dt.strftime('%y'), dt
                    if YY != dt.strftime('%y'):
                        if change_datetime(obj): count = count + 1
                        print(obj.id, 'old: ', dt, '\t new: ', obj.release_date ,'\t\t reason: ', YY,' != ', dt.strftime('%y'))
        else:
            pass
            #print obj.id, ' no release_date'
    return count

if __name__ == '__main__':
    logger = logging.getLogger('app.' + __name__)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(logging.StreamHandler(sys.stderr))
    logger.propagate = False
    logger.info("Fix release dates for images and videos")

    # timeout in seconds
    timeout = 60
    socket.setdefaulttimeout(timeout)

    test =  '''
News Release Number: STScI-2006-25
'''
    pattern = re.compile('''h2 class="release-number".*?:.*?>\s*(.*?)<.*?h2''')

    print('videos')
    print(process_objects(Video.objects.all()), ' videos have a new release_date')
    print('images')
    print(process_objects(Image.objects.all()), ' images have a new release_date')


stones = [2, 4, 5, 3, 2, 1, 4, 2, 5, 1]
k = 3

def check(stones, k, mid):
    count = 0
    for i in stones:
        if i < mid:
            count += 1
        else:
            count = 0
        if count == k:  # 뛰어 넘어야 하는 stone의 개수가 k개가 되면 건널 수 없다.
            return 0
    return 1

def solution(stones, k):
    answer = 0
    left = 1  # 가능한 최소 인원 1명
    right = max(stones) + 1  # 가능하지 않은 최소 인원 (= 가능한 최대 인원 +1)

    # 이분 탐색
    while left <= right:
        mid = (left + right) // 2
        if check(stones, k, mid):
            left = mid + 1
        else:
            right = mid - 1
    answer = left - 1  # 마지막에 가능했던 인원
    return answer

# 정확성은 완벽 하지만 효율성은 개똥
#
# stones = [2, 4, 5, 3, 2, 1, 4, 2, 5, 1]
# k = 3
#
# result = []
# for i in range(0, len(stones)-k+1):
#     result.append(max(stones[i:i+k]))
# print(min(result))


from util.data_util import read_energy_data

# best fit algorithm, which consistently choose the least frequency if applicable.

class bestReward():
    def __init__(self, env, max_episode, ep_long):
        self.env = env
        self.last_deploy_core = 0
        self.max_episode = max_episode
        self.ep_long = ep_long

    def saveResults(self):
        self.env.saveResults()
        print(f"Overall: {self.env.overall_results}")
        print(f"Action choices: {self.env.action_choices}")

    def act(self, s):
        possible_actions = self.env.getPossibleActionGivenState(s)
        action = 0
        max_value = -100
        for test_action in possible_actions:
            if test_action == 0:
                continue
            test_value = self.env.calculateRewardOnAction(test_action)
            # print(test_value)
            if max_value < test_value:
                max_value = test_value
                action = test_action

        return action

    def test(self):
        GHI_Data = read_energy_data(is_train=False)
        done = False
        ep_num = 0
        self.env.replay(is_train=False, simulation_start=ep_num * self.ep_long,
                        simulation_end=(ep_num + 1) * self.ep_long, GHI_Data=GHI_Data)

        print('\n\n\n--------------------------------------------------')
        while ep_num < self.max_episode:
            state = self.env.reset(is_train=False, simulation_start=ep_num * self.ep_long,
                                   simulation_end=(ep_num + 1) * self.ep_long, GHI_Data=GHI_Data)
            done = False
            while not done:
                action = self.act(state)
                next_state, reward, done = self.env.step(action)
                state = next_state

            print(f'Episode test {ep_num}')
            self.saveResults()
            ep_num += 1
            # self.env.event_queue.print_queue()


import pygame
import os
from sys import exit

WIDTH, HEIGHT = 1600, 900
pygame.init()
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Buildings")
WHITE = (255, 255, 255)
FPS = 60
indx = 0
font = pygame.font.Font(None, 50)

class Building():
    def __init__(self, name, offset_x, offset_y):
        self.name = name
        self.building = pygame.image.load(os.path.join(
            "assets/buildings", self.name)).convert_alpha()
        self.offset_x = offset_x
        self.offset_y = offset_y
        self.x = offset_x
        self.y = offset_y

    def color_key(self, color):
        self.building.set_colorkey(color)

    def draw(self, WIN, camera_position):
        self.VEL = 20
        self.x = -camera_position[0]+self.offset_x
        self.y = -camera_position[1]+self.offset_y
        WIN.blit(self.building, (self.x, self.y))

    def movements(self, keys_pressed):
        if keys_pressed is None:
            return
        if keys_pressed[pygame.K_a]:
            self.x += self.VEL
            if keys_pressed[pygame.K_LSHIFT]:
                self.x += self.VEL
        elif keys_pressed[pygame.K_d]:
            self.x -= self.VEL
            if keys_pressed[pygame.K_LSHIFT]:
                self.x -= self.VEL

    def movements_updown(self, keys_pressed):
        if keys_pressed[pygame.K_w]:
            self.y += self.VEL
            if keys_pressed[pygame.K_LSHIFT]:
                self.y += self.VEL
        elif keys_pressed[pygame.K_s]:
            self.y -= self.VEL
            if keys_pressed[pygame.K_LSHIFT]:
                self.y -= self.VEL

    def collision_bound(self, camera_position, x_fac, y_fac, width_fac, height_fac, show=False):
        self.x = -camera_position[0]+self.offset_x
        self.y = -camera_position[1]+self.offset_y
        object_collision_bound = pygame.Rect(
            self.x+x_fac, self.y+y_fac, width_fac, height_fac)
        if show is True:
            pygame.draw.rect(WIN, (0, 255, 0), object_collision_bound)

def main():
    building1 = Building("4(1).png", -100, -1250)
    building2 = Building("5(1).png", 2000, -1800)
    building3 = Building("6.png", 5500, -1700)
    clock = pygame.time.Clock()

    while True:
        WIN.fill(WHITE)
        clock.tick(FPS)
        for event in pygame.event.get():
            keys_pressed = pygame.key.get_pressed()
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
        building1.draw(WIN, [0, 0])
        building1.movements(keys_pressed)
        building1.movements_updown(keys_pressed)
        building2.draw(WIN, [0, 0])
        building2.movements(keys_pressed)
        building2.movements_updown(keys_pressed)
        building3.draw(WIN, [0, 0])
        building3.movements(keys_pressed)
        building3.movements_updown(keys_pressed)
        pygame.display.update()

if __name__ == "__main__":
    main()


import logging
import json
from lxml import etree

def get_field_text(tree, path):
    nsmap = {"n1": tree.getroot().nsmap['n1']}
    node = tree.xpath(path, namespaces=nsmap)
    if len(node) > 0:
        return node[0].text
    return ''

def parse_metadata(scene, xml_filename, json_filename):
    logger = logging.getLogger(scene)
    logger.info("Parsing XML metadata from {0}".format(xml_filename))

    result = {'!scene': scene}

    tree = etree.parse(xml_filename)
    with open(json_filename, 'r') as myfile:
        tile_json = myfile.read()
    tile = json.loads(tile_json)

    scene_time = get_field_text(tree, "n1:General_Info/SENSING_TIME")
    result['acquired_date'] = scene_time.split('T')[0]
    result['acquired_time'] = scene_time.split('T')[1]

    coords = tile['tileGeometry']['coordinates'][0]
    result["#scene_corner_UL_x"] = coords[0][0]
    result["#scene_corner_UL_y"] = coords[0][1]
    result["#scene_corner_UR_x"] = coords[1][0]
    result["#scene_corner_UR_y"] = coords[1][1]
    result["#scene_corner_LR_x"] = coords[2][0]
    result["#scene_corner_LR_y"] = coords[2][1]
    result["#scene_corner_LL_x"] = coords[3][0]
    result["#scene_corner_LL_y"] = coords[3][1]

    result["#utm_zone"] = tile["utmZone"]

    return result


import unittest

from selectors.NumbersFormRangeSelector import NumbersFormRangeSelector

class TestNumbersFormRangeSelector(unittest.TestCase):
    def test_should_return_empty_sequence_when_empty_sequence_is_given(self):
        empty_sequence = []
        selector = NumbersFormRangeSelector(1, 10)

        self.assertTrue(len(selector.select(empty_sequence)) == 0)

    def test_should_return_empty_sequence_when_there_are_no_numbers_from_range(self):
        empty_sequence = [3, 5, 355, 321, 45]
        selector = NumbersFormRangeSelector(-8, 0)

        self.assertTrue(len(selector.select(empty_sequence)) == 0)

    def test_should_return_all_numbers_from_range(self):
        sequence = [1, 2, 3, 6, 4, 15, 23]
        correct_result_sequence = [2, 3, 6, 4]
        selector = NumbersFormRangeSelector(2, 6)

        self.assertEqual(correct_result_sequence, selector.select(sequence))

    def test_should_throw_exception_when_wrong_range_is_given(self):
        with self.assertRaises(ValueError):
            NumbersFormRangeSelector(100, 6)

if __name__ == '__main__':
    unittest.main()


import asyncio
import websockets

HOST  = '0.0.0.0'
WS_PORT = 3333
TCP_PORT = 8888

loop = asyncio.get_event_loop()

websocket_connections = []
tcp_connections = []

async def send_status(status: str):
	data = status.encode()
	for c in tcp_connections:
		try:
			writer = c[1]
			writer.write(data)
			await writer.drain()
		except Exception as e:
			print(e)

async def executor(command: str):
	command = command.lower()
	words = command.split(" ")
	print(words)
	if 'вправо' in words:
		await send_status('d')
	if 'право' in words:
		await send_status('d')
	if 'права' in words:
			await send_status('d')
	if 'cправа' in words:
			await send_status('d')

	if 'влево' in words:
		await send_status('a')
	if 'лево' in words:
		await send_status('a')
	if 'лего' in words:
		await send_status('a')
	if 'лева' in words:
		await send_status('a')

	if 'назад' in words:
		await send_status('s')

	if 'вперед' in words:
		await send_status('w')
	if 'перед' in words:
		await send_status('w')

async def websock_handler(websocket, path):
	print('WS connect')
	global websocket_connections
	websocket_connections.append(websocket)
	try:
		while True:
			msg = await websocket.recv()
			print('[MSG INCOMING]', msg)
			await executor(msg)
	except websockets.exceptions.ConnectionClosedOK as e:
		pass
	websocket_connections.remove(websocket)
	print('WS disc')

async def tcp_handler(reader, writer):
	print('connected to ue')
	global tcp_connections
	connection = (reader, writer)
	tcp_connections.append(connection)
	writer.write("ping".encode())
	while True:
		data = await reader.read(100)
		if len(data) == 0:
			break
		await writer.drain()
	writer.close()
	tcp_connections.remove(connection)
	print('disconnected UE')

async def run_ws():
	await websockets.serve(websock_handler, HOST, WS_PORT)

async def run_tcp():
	await asyncio.start_server(tcp_handler, HOST, TCP_PORT, loop=loop)

def main():
	loop.create_task(run_ws())
	loop.create_task(run_tcp())
	try:
		loop.run_forever()
	except KeyboardInterrupt:
		print("stoped")

if __name__ == '__main__':
	main()


# NOTE: mini function for testing your UDP connection w the computer running the server and MAX
from pythonosc import udp_client

PORT_TO_MAX = 5002
IP = "192.168.2.2"

global client
client = udp_client.SimpleUDPClient(IP, PORT_TO_MAX)
input("hello")
while True:
    print("sent")
    client.send_message("/point", 1)
    input("pause")


import random

def find_duplicate(xs):
    mini, maxi, acc = xs[0], xs[0], xs[0]
    for i in range(1, len(xs)):
        mini = min(mini, xs[i])
        maxi = max(maxi, xs[i])
        acc = acc ^ xs[i]
    mask = mini
    for i in range(mini + 1, maxi + 1):
        mask = mask ^ i
    return mask ^ acc

xs = [5, 3, 4, 1, 5, 2]
print(xs)
result = find_duplicate(xs)
print(result)


"""
Given a singly linked list, determine if it is a palindrome
"""

class Solution(object):
	def isPalindrome(self, head):
		fast = slow = head
		# Move slow to the middle of the list
		while fast and slow:
			fast = fast.next.next
			slow = slow.next
		# Reverse second half
		node = None
		while slow:
			nxt = slow.next
			# Make slow.next None/end
			slow.next = node
			node = slow
			slow = nxt

		while node:
			if node.val != head.val:
				return False
			node = node.next
			head = head.next
		return True


import numpy as np
import librosa
from typing import List
import matplotlib.pyplot as plt
from scipy import signal
from scipy.fft import rfft, rfftfreq
import os

TECHNIQUES = ['High', 'Tasto', 'Bend', 'Harm', 'Strum', 'Pont', 'Ord', 'Chord', 'Smack', 'Palm', 'TEST', 'SILENCE']
#TECHNIQUES =  os.listdir("samples/manual") + ["SILENCE"]
# ['Bend', 'Chord', 'Harm', 'High', 'Ord', 'Palm', 'Pont', 'Smack', 'Strum', 'Tasto', 'TEST', 'SILENCE']
#   high    tasto  bend     harm    strum  pont     ord     chord    smack    palm

def find_onsets(y: np.ndarray, sr: int) -> np.ndarray:
    """Takes a numpy array and returns an array of onsets, currenly using librosa"""
    #return librosa.onset.onset_detect(y, sr=sr, backtrack=True, units="samples")
    o_env = librosa.onset.onset_strength(y=y, sr=sr, max_size=8)
    samps = librosa.samples_like(o_env)
    return librosa.onset.onset_detect(onset_envelope=o_env, sr=sr, backtrack=True, units="samples",
                                          delta=4.3, hop_length=512, normalize=False,
                                          pre_max = 1.0, post_max = 1.0, pre_avg = 4.0, post_avg = 5.0, wait = 1.0)

def get_waveform_from_ndarray(audio: np.ndarray, tf):
    audio = tf.convert_to_tensor(audio)

    tf.cast(audio, tf.float32)
    return audio

def get_waveform_from_bin(wfbin, tf):
    """Returns a tf tensor float32 waveform from a binary file"""
    audio, _ = tf.audio.decode_wav(wfbin)  # somewhere here it breaks.......
    tf.cast(audio, tf.float32)
    return tf.squeeze(audio, axis=-1)

def get_waveform_from_path(path: str, tf):
    """Returns a tf tensor float32 waveform from a path"""
    wfbin = tf.io.read_file(path)
    return get_waveform_from_bin(wfbin, tf)

def get_spectrogram(waveform, tf):
    """Takes a tf.float32 waveform and returns a spectrogram.  Max size = 16000 samples"""
    if tf.shape(waveform) > 16000:
        waveform = waveform[:16000]
    zero_padding = tf.zeros([16000] - tf.shape(waveform), dtype=tf.float32) #fix this so the padding isn't huge

    waveform = tf.cast(waveform, tf.float32)
    equal_length = tf.concat([waveform, zero_padding], 0)
    spectrogram = tf.signal.stft(
        equal_length, frame_length=255, frame_step=128)

    spectrogram = tf.abs(spectrogram)
    spectrogram = tf.expand_dims(spectrogram, -1)

    return spectrogram

def numpy_to_tfdata(note: np.ndarray, tf):
    """Turn a numpy buffer note into a tensorflow dataset of the spectrogram"""
    waveform = get_waveform_from_ndarray(note, tf)
    spec = get_spectrogram(waveform, tf)
    ds = tf.data.Dataset.from_tensors([spec])
    return ds

def int_to_string_results(int_results: List[int], techniques: List[str]) -> List[str]:
    return list(map(lambda i: techniques[i], int_results))

def prediction_to_int_ranks(prediction, tf):
    sftmax = tf.nn.softmax(prediction[0])
    sorted = np.sort(sftmax)[::-1]
    index_of = lambda x: np.where(sftmax == x)[0][0]
    prediction_ranks = list(map(index_of, sorted))
    return prediction_ranks

def plot_prediction(techniques, prediction, tf):
    """view a matplotlib graph of the prediction"""
    plt.bar(techniques, tf.nn.softmax(prediction[0]))
    plt.title(f'Predictions for new note:')
    plt.show()

def note_above_threshold(note: np.ndarray) -> bool:
    """Checks if the peak of a note is above a set threshold"""
    if np.max(np.abs(note)) > 0.09:
        return True
    else:
        return False

def get_partials(waveform: np.ndarray, sr: int) -> List[float]:
    normalized_wf = np.int16((waveform / waveform.max()) * 32767)
    N = len(normalized_wf)
    yf = rfft(normalized_wf)
    xf = rfftfreq(N, 1 / sr)
    half = len(xf) // 2
    peak_sig = np.abs(yf[:half])
    peaks, d = signal.find_peaks(peak_sig, height=100000, distance=250)  # This can be tweaked for better results
    peaks_amps = np.array(list(map(lambda p: [p, peak_sig[p]], peaks)))
    sorted_peaks = peaks_amps[peaks_amps[:, 1].argsort()][::-1]
    sorted_freqs = list(map(lambda i: xf[int(i)], sorted_peaks[:, 0]))
    sorted_freqs = filter(lambda freq: freq > 80, sorted_freqs)
    return list(sorted_freqs)

if __name__ == "__main__":
    print(TECHNIQUES)


import pandas as pd
import numpy as np
from warnings import simplefilter
simplefilter(action="ignore", category=pd.errors.PerformanceWarning)

aaLi = ['A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'Y']
aaChargeDi = {'A': 0, 'C': 0, 'D': -1, 'E': -1, 'F': 0, 'G': 0, 'H': 0, 'I': 0, 'K': 1.0,
              'L': 0, 'M': 0, 'N': 0, 'P': 0, 'Q': 0, 'R': 1.0, 'S': 0, 'T': 0, 'V': 0,
              'W': 0, 'Y': 0}   # positive: R,K  negative: D,E  neutral: others
aaHydroIdxDi = {'I': 4.5, 'V': 4.2, 'L': 3.8, 'F': 2.8, 'C': 2.5, 'M': 1.9, 'A': 1.8, 'G': -0.4, 'T': -0.7, 'W': -0.9,
                'S': -0.8, 'Y': -1.3, 'P': -1.6, 'H': -3.2, 'E': -3.5, 'Q': -3.5, 'D': -3.5, 'N': -3.5, 'K': -3.9,
                'R': -4.5}   # hydropathy index (GRAVY index)
aaHyd1Di = {'A': 0.62, 'C': 0.29, 'D': -0.9, 'E': -0.74, 'F': 1.19, 'G': 0.48, 'H': -0.4, 'I': 1.38, 'K': -1.5,
              'L': 1.06, 'M': 0.64, 'N': -0.78, 'P': 0.12, 'Q': -0.85, 'R': -2.53, 'S': -0.18, 'T': -0.05, 'V': 1.08,
              'W': 0.81, 'Y': 0.26}  # hydrophobicity
aaHyd2Di = {'A': -0.5, 'C': -1, 'D': 3, 'E': 3, 'F': -2.5, 'G': 0, 'H': -0.5, 'I': -1.8, 'K': 3,
              'L': -1.8, 'M': -1.3, 'N': 2, 'P': 0, 'Q': 0.2, 'R': 3, 'S': 0.3, 'T': -0.4, 'V': -1.5,
              'W': -3.4, 'Y': -2.3}  # hydrophilicity
aaPIDi = {'A': 6, 'C': 5.07, 'D': 2.77, 'E': 3.22, 'F': 5.48, 'G': 5.97, 'H': 7.59, 'I': 6.02, 'K': 9.74,
              'L': 5.98, 'M': 5.74, 'N': 5.41, 'P': 6.3, 'Q': 5.65, 'R': 10.76, 'S': 5.68, 'T': 5.6, 'V': 5.96,
              'W': 5.89, 'Y': 5.66}   # isoelectric point
aaPKa1Di = {'A': 2.34, 'C': 1.96, 'D': 1.88, 'E': 2.19, 'F': 1.83, 'G': 2.34, 'H': 1.82, 'I': 2.36, 'K': 2.18,
              'L': 2.36, 'M': 2.28, 'N': 2.02, 'P': 1.99, 'Q': 2.17, 'R': 2.17, 'S': 2.21, 'T': 2.09, 'V': 2.32,
              'W': 2.83, 'Y': 2.2}   # pKa1: carboxyl group (-COOH)
aaPKa2Di = {'A': 9.69, 'C': 8.18, 'D': 9.6, 'E': 9.67, 'F': 9.13, 'G': 9.6, 'H': 9.17, 'I': 9.6, 'K': 8.95,
              'L': 9.6, 'M': 9.21, 'N': 8.8, 'P': 10.6, 'Q': 9.13, 'R': 9.04, 'S': 9.15, 'T': 9.1, 'V': 9.62,
              'W': 9.39, 'Y': 9.11}   # pKa2: ammonium group (NH2-)
aaVolumeDi = {'A': 91.5, 'R': 196.1, 'N': 138.3, 'D': 135.2, 'C': 102.4, 'Q': 156.4, 'E': 154.6, 'G': 67.5, 'H': 163.2,
              'I': 162.6, 'L': 163.4, 'K': 162.5, 'M': 165.9, 'F': 198.8, 'P': 123.4, 'S': 102.0, 'T': 126.0,
              'W': 237.2, 'Y': 209.8, 'V': 138.4}
aaVSCDi = {'A': 27.5, 'C': 44.6, 'D': 40, 'E': 62, 'F': 115.5, 'G': 0, 'H': 79, 'I': 93.5, 'K': 100, 'L': 93.5,
              'M': 94.1, 'N': 58.7, 'P': 41.9, 'Q': 80.7, 'R': 105, 'S': 29.3, 'T': 51.3, 'V': 71.5, 'W': 145.5, 'Y': 117.3}  # volume of side chain
aaGappDi = {'A': 0.11, 'R': 2.58, 'N': 2.05, 'D': 3.49, 'C': -0.13, 'Q': 2.36, 'E': 2.68, 'G': 0.74, 'H': 2.06, 'I': -0.6,
             'L': -0.55, 'K': 2.71, 'M': -0.1, 'F': -0.32, 'P': 2.23, 'S': 0.84, 'T': 0.52, 'W': 0.3, 'Y': 0.68, 'V': -0.31}  # free energy of transmembrane helix

aaPol1Di = {'A': 8.1, 'C': 5.5, 'D': 13, 'E': 12.3, 'F': 5.2, 'G': 9, 'H': 10.4, 'I': 5.2, 'K': 11.3, 'L': 4.9,
              'M': 5.7, 'N': 11.6, 'P': 8, 'Q': 10.5, 'R': 10.5, 'S': 9.2, 'T': 8.6, 'V': 5.9, 'W': 5.4, 'Y': 6.2}  # polarity
aaPol2Di = {'A': 0.046, 'C': 0.128, 'D': 0.105, 'E': 0.151, 'F': 0.29, 'G': 0, 'H': 0.23, 'I': 0.186, 'K': 0.219, 'L': 0.186,
              'M': 0.221, 'N': 0.134, 'P': 0.131, 'Q': 0.18, 'R': 0.291, 'S': 0.062, 'T': 0.108, 'V': 0.14, 'W': 0.409, 'Y': 0.298}  # polarizability
aaNCISDi = {'A': 0.007187, 'C': -0.03661, 'D': -0.02382, 'E': -0.006802, 'F': 0.037552, 'G': 0.179052, 'H': -0.01069,
              'I': 0.021631, 'K': 0.017708, 'L': 0.051672, 'M': 0.002683, 'N': 0.005392, 'P': 0.239531, 'Q': 0.049211,
              'R': 0.043587, 'S': 0.004627,
            'T': 0.003352, 'V': 0.057004, 'W': 0.037977, 'Y': 0.0323599} # net charge index of side chain
aaSASADi = {'A': 1.181, 'C': 1.461, 'D': 1.587, 'E': 1.862, 'F': 2.228, 'G': 0.881, 'H': 2.025, 'I': 1.81, 'K': 2.258,
              'L': 1.931, 'M': 2.034, 'N': 1.655, 'P': 1.468, 'Q': 1.932, 'R': 2.56, 'S': 1.298, 'T': 1.525, 'V': 1.645,
              'W': 2.663, 'Y': 2.368}  # solvent accessibility of surface area

## Given a dictionary of peptide sequences and a list of feature names, this function returns a feature tables for the peptides.
## The acceptable feature names include AAC, DPC, NBP, CBP, Hydro, Hyd1, Hyd2, FEtmh, Pol1, Pol2, Vol, VSC, SA, pI, Chg, NCIS, pKa1, pKa2.
def GenerateFeatureTableGivenSeqDiAndFeatureLi(seq_di, feature_list, islabeled=True):
    df = GenerateInitialSequenceDataframe(seq_di, islabeled=islabeled)
    if 'Hydro' in feature_list:
        GenerateFeature_HydropathyIndex(df)
    if 'Hyd1' in feature_list:
        GenerateFeature_Hydrophobicity(df)
    if 'Hyd2' in feature_list:
        GenerateFeature_Hydrophilicity(df)
    if 'FEtmh' in feature_list:
        GenerateFeature_FreeEnergyTMH(df)
    if 'Pol1' in feature_list:
        GenerateFeature_Polarity(df)
    if 'Pol2' in feature_list:
        GenerateFeature_Polarizability(df)
    if 'Vol' in feature_list:
        GenerateFeature_Volume(df)
    if 'VSC' in feature_list:
        GenerateFeature_VolumeSideChain(df)
    if 'SASA' in feature_list or 'SA' in feature_list:
        GenerateFeature_SolventAccessibleSurfaceArea(df)
    if 'pI' in feature_list:
        GenerateFeature_pHatIsoelectricPoint(df)
    if 'Chg' in feature_list or 'Charge' in feature_list:
        GenerateFeature_AminoAcidCharge(df)
    if 'NCIS' in feature_list:
        GenerateFeature_NetChargeIndexOfSideChain(df)
    if 'pKa2' in feature_list:
        GenerateFeature_pKaNH2(df)
    if 'pKa1' in feature_list:
        GenerateFeature_pKaCOOH(df)
    if 'AAC' in feature_list:
        GenerateFeature_AAC(df)
    if 'DPC' in feature_list:
        GenerateFeature_DPC(df)
    if 'CBP' in feature_list:
        GenerateFeature_CBP(df)
    if 'NBP' in feature_list:
        GenerateFeature_NBP(df)
    return df

def GenerateInitialSequenceDataframe(seq_dict, tag_pos ='pos_', tag_neg ='neg_', islabeled=True):
    if len(seq_dict) == 0:
        return None
    df = pd.DataFrame(list(seq_dict.items()), columns=['Name', 'Sequence'])
    if islabeled is True:
        df['TrueLabel'] = df['Name'].map(lambda x: 1 if x.startswith(tag_pos) else 0)  # assign labels according to the prefix in the entry names
    df['Length'] = df['Sequence'].map(lambda s: len(s))
    return df

## amino acid composition (dimension 20)
def GenerateFeature_AAC(df):
    if 'Sequence' not in df.columns:
        return
    for residue in aaLi:
        labelName = 'AAC_' + residue
        df[labelName] = df['Sequence'].map(lambda s: s.count(residue) / len(s))

## dipeptide composition (dimension 400)
def GenerateFeature_DPC(df):
    if 'Sequence' not in df.columns:
        return
    for residue1 in aaLi:
        for residue2 in aaLi:
            dp = residue1 + residue2
            labelName = 'DP_' + dp
            df[labelName] = df['Sequence'].map(lambda s: s.count(dp) / (len(s) - 1))

## N-terminal binary profile with k amino acids (dimension k*20)
def GenerateFeature_NBP(df, kmer=8):
    if 'Sequence' not in df.columns:
        return
    for i in range(1, kmer + 1):
        pos = i - 1
        for residue in aaLi:
            labelName = 'N' + str(kmer) + 'mer_' + str(i) + '_' + residue
            df[labelName] = df['Sequence'].map(lambda s: 1 if s[pos] == residue else 0)

## C-terminal binary profile with k amino acids (dimension k*20)
def GenerateFeature_CBP(df, kmer=8):
    if 'Sequence' not in df.columns:
        return
    for i in range(1, kmer + 1):
        pos = i - kmer - 1
        for residue in aaLi:
            labelName = 'C' + str(kmer) + 'mer_' + str(i) + '_' + residue
            df[labelName] = df['Sequence'].map(lambda s: 1 if s[pos] == residue else 0)

## The functions below create features by averaging the specific physicochemical properties of amino acids in peptide sequences
def GenerateFeature_AminoAcidCharge(df):
    if 'Sequence' not in df.columns:
        return
    df['Chg'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaChargeDi))

def GenerateFeature_NetChargeIndexOfSideChain(df):
    if 'Sequence' not in df.columns:
        return
    df['NCIS'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaNCISDi))

def GenerateFeature_HydropathyIndex(df):
    if 'Sequence' not in df.columns:
        return
    df['Hydro'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaHydroIdxDi))

def GenerateFeature_Hydrophobicity(df):
    if 'Sequence' not in df.columns:
        return
    df['Hyd1'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaHyd1Di))

def GenerateFeature_Hydrophilicity(df):
    if 'Sequence' not in df.columns:
        return
    df['Hyd2'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaHyd2Di))

def GenerateFeature_pHatIsoelectricPoint(df):
    if 'Sequence' not in df.columns:
        return
    df['pI'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaPIDi))

def GenerateFeature_pKaCOOH(df):
    if 'Sequence' not in df.columns:
        return
    df['pKa1'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaPKa1Di))

def GenerateFeature_pKaNH2(df):
    if 'Sequence' not in df.columns:
        return
    df['pKa2'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaPKa2Di))

def GenerateFeature_Volume(df):
    if 'Sequence' not in df.columns:
        return
    df['Vol'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaVolumeDi))

def GenerateFeature_VolumeSideChain(df):
    if 'Sequence' not in df.columns:
        return
    df['VSC'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaVSCDi))

def GenerateFeature_FreeEnergyTMH(df):
    if 'Sequence' not in df.columns:
        return
    df['FEtmh'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaGappDi))

def GenerateFeature_Polarity(df):
    if 'Sequence' not in df.columns:
        return
    df['Pol1'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaPol1Di))

def GenerateFeature_Polarizability(df):
    if 'Sequence' not in df.columns:
        return
    df['Pol2'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaPol2Di))

def GenerateFeature_SolventAccessibleSurfaceArea(df):
    if 'Sequence' not in df.columns:
        return
    df['SA'] = df['Sequence'].map(lambda s: ComputeAveragedIndex(s, aaSASADi))

def ComputeAveragedIndex(seq, aa_index_dict):
    index = 0
    for residue in seq:
        index += aa_index_dict[residue]
    index /= len(seq)
    return index


from os.path import join, dirname
from pandas import read_csv
from pathlib import Path

from climateeconomics.core.core_agriculture.crop import Crop
from sostrades_core.execution_engine.execution_engine import ExecutionEngine
from sostrades_core.tests.core.abstract_jacobian_unit_test import AbstractJacobianUnittest
from energy_models.core.stream_type.energy_models.biomass_dry import BiomassDry
from climateeconomics.sos_wrapping.sos_wrapping_agriculture.crop.crop_disc import CropDiscipline
import unittest
import pandas as pd
import numpy as np

class AgricultureJacobianDiscTest(AbstractJacobianUnittest):
    #AbstractJacobianUnittest.DUMP_JACOBIAN = True

    def setUp(self):

        self.name = 'Test'
        self.ee = ExecutionEngine(self.name)
        '''
        Initialize third data needed for testing
        '''
        self.year_start = 2020
        self.year_end = 2055
        self.time_step = 1
        years = np.arange(self.year_start, self.year_end + 1, 1)
        year_range = self.year_end - self.year_start + 1

        population = np.array(np.linspace(7800, 7800, year_range))
        self.population_df = pd.DataFrame(
            {"years": years, "population": population})
        self.population_df.index = years
        temperature = np.array(np.linspace(1.05, 5, year_range))
        self.temperature_df = pd.DataFrame(
            {"years": years, "temp_atmo": temperature})
        self.temperature_df.index = years

        lifetime = 50

        # Age distribution of forests in 2008 (
        initial_age_distribution = pd.DataFrame({'age': np.arange(1, lifetime),
                                                 'distrib': [0.16, 0.24, 0.31, 0.39, 0.47, 0.55, 0.63, 0.71, 0.78, 0.86,
                                                             0.94, 1.02, 1.1, 1.18, 1.26, 1.33, 1.41, 1.49, 1.57, 1.65,
                                                             1.73, 1.81, 1.88, 1.96, 2.04, 2.12, 2.2, 2.28, 2.35, 2.43,
                                                             2.51, 2.59, 2.67, 2.75, 2.83, 2.9, 2.98, 3.06, 3.14, 3.22,
                                                             3.3, 3.38, 3.45, 3.53, 3.61, 3.69, 3.77, 3.85, 3.92]})

        self.default_kg_to_m2 = {'red meat': 360,
                                 'white meat': 16,
                                 'milk': 8.95,
                                 'eggs': 6.3,
                                 'rice and maize': 2.9,
                                 'potatoes': 0.88,
                                 'fruits and vegetables': 0.8,
                                 'other': 21.4,
                                 }
        self.default_kg_to_kcal = {'red meat': 2566,
                                   'white meat': 1860,
                                   'milk': 550,
                                   'eggs': 1500,
                                   'rice and maize': 1150,
                                   'potatoes': 670,
                                   'fruits and vegetables': 624,
                                   }
        red_meat_percentage = np.linspace(6, 1, year_range)
        white_meat_percentage = np.linspace(14, 5, year_range)
        self.red_meat_percentage = pd.DataFrame({
                            'years': years,
                            'red_meat_percentage': red_meat_percentage})
        self.white_meat_percentage = pd.DataFrame({
                                'years': years,
                                'white_meat_percentage': white_meat_percentage})

        self.diet_df = pd.DataFrame({'red meat': [11.02],
                                     'white meat': [31.11],
                                     'milk': [79.27],
                                     'eggs': [9.68],
                                     'rice and maize': [97.76],
                                     'potatoes': [32.93],
                                     'fruits and vegetables': [217.62],
                                     })
        self.other = np.array(np.linspace(0.102, 0.102, year_range))

        # investment: 1Mha of crop land each year
        self.crop_investment = pd.DataFrame(
            {'years': years, 'investment': np.ones(len(years)) * 0.381})

        self.margin = pd.DataFrame(
            {'years': years, 'margin': np.ones(len(years)) * 110.0})

        # From future of hydrogen
        self.transport_cost = pd.DataFrame(
            {'years': years, 'transport': np.ones(len(years)) * 7.6})

        # bioenergyeurope.org : Dedicated energy crops
        # represent 0.1% of the total biomass production in 2018
        energy_crop_percentage = 0.005
        # ourworldindata, average cereal yield: 4070kg/ha +
        # average yield of switchgrass on grazing lands: 2565,67kg/ha
        # residue is 0.25 more than that
        density_per_ha = 2903 * 1.25
        # available ha of crop: 4.9Gha, initial prod = crop energy + residue for
        # energy of all surfaces
        self.initial_production = 4.8 * density_per_ha * 3.6 * energy_crop_percentage  # in TWh

        self.param = {'year_start': self.year_start,
                      'year_end': self.year_end,
                      'time_step': self.time_step,
                      'diet_df': self.diet_df,
                      'kg_to_kcal_dict': self.default_kg_to_kcal,
                      'population_df': self.population_df,
                      'temperature_df': self.temperature_df,
                      'kg_to_m2_dict': self.default_kg_to_m2,
                      'red_meat_percentage': self.red_meat_percentage,
                      'white_meat_percentage': self.white_meat_percentage,
                      'other_use_crop': self.other,
                      'param_a': - 0.00833,
                      'param_b': - 0.04167,
                      'crop_investment': self.crop_investment,
                      'margin': self.margin,
                      'transport_margin': self.margin,
                      'transport_cost': self.transport_cost,
                      'data_fuel_dict': BiomassDry.data_energy_dict,
                      'techno_infos_dict': CropDiscipline.techno_infos_dict_default,
                      'scaling_factor_crop_investment': 1e3,
                      'initial_age_distrib': initial_age_distribution,
                      'initial_production': self.initial_production
                      }

    def analytic_grad_entry(self):
        return [
            self.test_agriculture_discipline_analytic_grad
        ]

    def test_agriculture_discipline_analytic_grad(self):

        self.model_name = 'crop'
        ns_dict = {'ns_public': f'{self.name}',
                   'ns_witness': f'{self.name}',
                   'ns_functions': f'{self.name}',
                   'ns_biomass_dry': f'{self.name}',
                   'ns_land_use':f'{self.name}',
                   'ns_crop':f'{self.name}',
                   'ns_invest':f'{self.name}'}

        self.ee.ns_manager.add_ns_def(ns_dict)

        mod_path = 'climateeconomics.sos_wrapping.sos_wrapping_agriculture.crop.crop_disc.CropDiscipline'
        builder = self.ee.factory.get_builder_from_module(
            self.model_name, mod_path)

        self.ee.factory.set_builders_to_coupling_builder(builder)

        self.ee.configure()
        self.ee.display_treeview_nodes()

        values_dict = {f'{self.name}.year_start': self.year_start,
                       f'{self.name}.year_end': self.year_end,
                       f'{self.name}.{self.model_name}.diet_df': self.diet_df,
                       f'{self.name}.{self.model_name}.kg_to_kcal_dict': self.default_kg_to_kcal,
                       f'{self.name}.{self.model_name}.kg_to_m2_dict': self.default_kg_to_m2,
                       f'{self.name}.population_df': self.population_df,
                       f'{self.name}.temperature_df': self.temperature_df,
                       f'{self.name}.red_meat_percentage': self.red_meat_percentage,
                       f'{self.name}.white_meat_percentage': self.white_meat_percentage,
                       f'{self.name}.{self.model_name}.{Crop.OTHER_USE_CROP}': self.other,
                       f'{self.name}.crop_investment': self.crop_investment,
                       f'{self.name}.margin': self.margin,
                       f'{self.name}.transport_margin': self.margin,
                       f'{self.name}.transport_cost': self.transport_cost,
                       f'{self.name}.data_fuel_dict': BiomassDry.data_energy_dict
                       }
        self.ee.load_study_from_input_dict(values_dict)

        self.ee.execute()

        disc_techno = self.ee.root_process.proxy_disciplines[0].mdo_discipline_wrapp.mdo_discipline

        self.check_jacobian(location=dirname(__file__), filename=f'jacobian_crop_discipline.pkl', discipline=disc_techno, local_data=disc_techno.local_data,
                            step=1e-15, derr_approx='complex_step',
                            inputs=[f'{self.name}.population_df',
                                    f'{self.name}.temperature_df',
                                    f'{self.name}.red_meat_percentage',
                                    f'{self.name}.white_meat_percentage',
                                    f'{self.name}.crop_investment',
                                    ],
                            outputs=[f'{self.name}.total_food_land_surface',
                                     f'{self.name}.land_use_required',
                                     f'{self.name}.techno_prices',
                                     f'{self.name}.techno_production',
                                     f'{self.name}.techno_consumption',
                                     f'{self.name}.techno_consumption_woratio',
                                     f'{self.name}.CO2_emissions',
                                     f'{self.name}.CO2_land_emission_df',
                                     f'{self.name}.CH4_land_emission_df',
                                     f'{self.name}.N2O_land_emission_df',
                                    ])


import json
from datetime import date,timedelta
path = '/Users/evcu/GitHub/evcu.github.io//assets/nyc365blog/data.json'

data = {}
newel = {}
newel[u'date'] = str(date.today()-timedelta(days=365))
newel[u'mood'] = str(input("Enter mood -1/0/1:\n"))
print(newel)
newel[u'high'] = str(input("Highlights\n"))
newel[u'low'] = str(input("Lowlights:\n"))
newel[u'other'] = str(input("Other:\n"))
newel[u'text'] = str(input("Random Thoughts:\n"))

print(newel)
with open(path,'r') as data_file:
    print('Successfuly read')
    data = json.load(data_file)
    data.append(newel)
with open(path,'w') as data_file:
    data_file.write(json.dumps(data, sort_keys=True, indent=4))
    print('Successfuly written')


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

        #storing preprocessed nums
        nums = sorted(nums)
        hashmap = defaultdict(int)
        maxnumber = 0
        for i in nums:
            hashmap[i] +=  i
            maxnumber = max(i, maxnumber)
        @cache
        def maxProfit(i):
            if i == 0:
                return 0
            if i == 1:
                return hashmap[1]

            return max(maxProfit(i-1), maxProfit(i-2)+hashmap[i])

        return maxProfit(maxnumber)


import sieve
from typing import Dict, List
import os
from dotenv import load_dotenv

load_dotenv()
api_key = os.environ.get('SIEVE_API_KEY')
sieve.SIEVE_API_KEY = os.getenv('SIEVE_API_KEY')
sieve.SIEVE_API_URL = os.getenv('SIEVE_API_URL')

@sieve.Model(
  name="deepface-emotion-detector",
  gpu = True,
  python_packages=[
    "opencv-python==4.6.0.66",
    "tensorflow==2.11.0",
    "pandas==1.5.3",
    "numpy==1.24.2",
    "deepface==0.0.79",
    'mediapipe==0.9.0'
  ],
  python_version="3.8",
)
class EmotionDetector:
    def __setup__(self):
        from deepface import DeepFace
        self.model = DeepFace.build_model('Emotion')
        # Load the weights from the saved H5 file
        self.emotion_labels = {0: 'angry', 1: 'disgust', 2: 'fear', 3: 'happy', 4: 'neutral', 5: 'sad', 6: 'surprise'}
        import mediapipe as mp
        self.mp_face_detection = mp.solutions.face_detection
        self.face_detection = self.mp_face_detection.FaceDetection(min_detection_confidence=0.7)

    def detect_faces(self, img: sieve.Image):
        import cv2
        import numpy as np
        results = self.face_detection.process(cv2.cvtColor(img.array, cv2.COLOR_BGR2RGB))
        faces = []
        if results.detections:
            for detection in results.detections:
                bounding_box = detection.location_data.relative_bounding_box
                x = int(bounding_box.xmin * img.width)
                w = int(bounding_box.width * img.width)
                y = int(bounding_box.ymin * img.height)
                h = int(bounding_box.height * img.height)

                detected_face = img.array[y : y + h, x : x + w]
                face_array = np.array(detected_face)
                bbox = [x, y, w, h]

                faces.append({
                    "array": face_array,
                    "box": bbox,
                    "class_name": "face",
                    "score": detection.score[0],
                    "frame_number": None if not hasattr(img, "frame_number") else img.frame_number
                })

        return faces

    def __predict__(self, img: sieve.Image) -> List:
        import tensorflow as tf
        import numpy as np
        from deepface import DeepFace
        import cv2
        outputs = []
        faces = self.detect_faces(img)
        for face in faces:
            face_img = face['array']
            #preprocess the face image
            if face_img is not None and np.any(face_img):

                gray_face = cv2.cvtColor(face_img, cv2.COLOR_RGB2GRAY)
                resized_face = cv2.resize(gray_face, (48, 48))
                preprocessed_face = tf.keras.applications.resnet50.preprocess_input(resized_face)
                preprocessed_face = np.expand_dims(preprocessed_face, axis=0)

                #predict the emotion of the face image
                emotions = self.model.predict(preprocessed_face)[0]
                labels = ['angry', 'disgust', 'fear', 'happy', 'neutral', 'sad', 'surprise']
                dominant_emotion = np.argmax(emotions)
                emotion_label = self.emotion_labels[dominant_emotion]
                confidence = emotions[dominant_emotion]

                outputs.append({
                    "frame_number": face['frame_number'],
                    "class_name": "face",
                    "box": face["box"],
                    "score": face["score"],
                    "emotion": emotion_label,
                    "confidence": confidence
                })

        return outputs


'''
113

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

Note: A leaf is a node with no children.

Example:

Given the below binary tree and sum = 22,

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \    / \
7    2  5   1

Return:
[
   [5,4,11,2],
   [5,8,4,5]
]
'''

class TreeNode():
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def pathSum(root, sum, nlist, all_paths):
    if root == None:
        return all_paths

    else :

        if root.val == sum and root.left == None and root.right == None:
            return all_paths + [nlist + [root.val]]

        else :
            left = pathSum(root.left, sum - root.val, nlist + [root.val] , all_paths)
            right = pathSum(root.right, sum - root.val, nlist + [root.val] , all_paths)

        return left + right

'''
    calls        nlist + [root.val]          changes made in that call
      1            []                           [1]
      2            [1]+[2]                      [1,2]
      3            [1,2]+[3]                    [1,2,3]
      4            [1,2,3]                      [1,2]
      5            [1,2]                        [1,2,4]
      6            [1]                          []

pathSum(1,7,[],[]):------------1
    left = pathSum(2,6,[1],[])--------------2
            left = pathSum(3,4,[1,2],[])-----------3
                    pathsum(none,1,[1,2,3],[])------------4
                        left = []   # all_paths     (here we get empty path because we have not hit the right path that satisfies the condition)
        right =  pathSum(4,4,[1,2],[])--------------------5
                return all_paths + [nlist + [root.val]]
                return [] + [[1,2] + [4]]
                right = [[1,2,4]]

        return left+right = [] + [[1,2,4]] = [[1,2,4]]
    left = [[1,2,4]]
    right = pathSum(6,6,[1],[[1,2,4]])--------------6
            return all_paths + [nlist + [root.val]]
            return [] + [[1] + [6]]
            return [] + [[1,6]]
            return [] + [[1,6]]
            return [[1,6]]
    right = [[1,6]]

    return left + right
    [[1,2,4]] + [[1,6]]
    [[1,2,4],[1,6]]
'''

root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(6)
root.left.left = TreeNode(4)
root.left.right = TreeNode(3)
root.left.right.right = TreeNode(1)

print(pathSum(root,7,[], [] ))


import logging

from mmpose.apis.inference import inference_top_down_pose_model, init_pose_model, vis_pose_result
from mmpose.datasets import DatasetInfo

logger = logging.getLogger(__name__)

def loadModel(configPath, ckptPath, device, half):
  model = init_pose_model(configPath, ckptPath, str(device).lower())

  dataset = model.cfg.data['test']['type']
  dataset_info = model.cfg.data['test'].get('dataset_info', None)

  if dataset_info is None:
    logger.warning(
      'Please set `dataset_info` in the config.'
      'Check https://github.com/open-mmlab/mmpose/pull/663 for details.'
    )
  else:
    dataset_info = DatasetInfo(dataset_info)

  return model, dataset, dataset_info

def inference(model, image, plotted, bboxes, dataset, dataset_info, device, half):
  # pose estimate
  pose_results, returned_outputs = inference_top_down_pose_model(
    model,
    image,
    bboxes,
    format='xywh',
    dataset=dataset,
    dataset_info=dataset_info
  )

  points = {d['track_id']: [d['bbox'], d['keypoints']] for d in pose_results}

  # plot bboxes and skeletons
  plotted = vis_pose_result(
    model,
    plotted,
    pose_results,
    dataset=dataset,
    dataset_info=dataset_info,
    kpt_score_thr=0.3,
    radius=4,
    thickness=1,
    show=False,
    out_file=None
  )

  return points, plotted


light_matrix_string = "00000:00000:00000:00000:00000"

# Convert light matrix to a multidimensional array
def convert_light_string_to_array(array_str):
    outer_demension = array_str.split(':')
    multi_dimension_array = []

    for inner in outer_demension:
        inner_list = [int(char) for char in inner]
        multi_dimension_array.append(inner_list)

    return multi_dimension_array

# Convert Light Array to a string to pass to lego hub
def convert_matrix_to_string(matrix):
    return ':'.join([''.join(map(str, row)) for row in matrix])

# Manipulate the string directly
def toggle_light_by_index(matrix_str, row, col, brightness):
    index = row * 6 + col # 5 characters per row plus a colon
    matrix_str = matrix_str[:index] + brightness + matrix_str[index + 1:]
    return matrix_str

# for loop example

# range(start at, end before, increment)
for i in range(0,8,1):  # will count from 1-7
    print('the current index (i) is:', i)

print('\n')
print('light matrix as a string:')
print(light_matrix_string)
print('\n')
print('light matrix as a matrix:')
print (convert_light_string_to_array(light_matrix_string))


import os
import dataclasses
import unittest
import torch
import math
import copy

import numpy as np
import lpips

from dataset.co3d_dataset import Co3dDataset, FrameData
from dataset.dataset_zoo import DATASET_ROOT
from tools.utils import dataclass_to_cuda_
from evaluation.evaluate_new_view_synthesis import eval_batch
from tools.metric_utils import calc_psnr, eval_depth
from models.model_dbir import ModelDBIR

class TestEvaluation(unittest.TestCase):
    def setUp(self):
        # initialize evaluation dataset/dataloader
        torch.manual_seed(42)
        category = "skateboard"
        dataset_root = DATASET_ROOT
        frame_file = os.path.join(dataset_root, category, "frame_annotations.jgz")
        sequence_file = os.path.join(dataset_root, category, "sequence_annotations.jgz")
        self.image_size = 256
        self.dataset = Co3dDataset(
            frame_annotations_file=frame_file,
            sequence_annotations_file=sequence_file,
            dataset_root=dataset_root,
            image_height=self.image_size,
            image_width=self.image_size,
            box_crop=True,
            load_point_clouds=True,
        )
        self.bg_color = 0.0

        # init the lpips model for eval
        self.lpips_model = lpips.LPIPS(net="vgg")

    def test_eval_depth(self):
        """
        Check that eval_depth correctly masks errors and that, for get_best_scale=True,
        the error with scaled prediction equals the error without scaling the
        predicted depth. Finally, test that the error values are as expected
        for prediction and gt differing by a constant offset.
        """
        gt = (torch.randn(10, 1, 300, 400, device="cuda") * 5.0).clamp(0.0)
        mask = (torch.rand_like(gt) > 0.5).type_as(gt)

        for diff in 10 ** torch.linspace(-5, 0, 6):
            for crop in (0, 5):

                pred = gt + (torch.rand_like(gt) - 0.5) * 2 * diff

                # scaled prediction test
                mse_depth, abs_depth = eval_depth(
                    pred,
                    gt,
                    crop=crop,
                    mask=mask,
                    get_best_scale=True,
                )
                mse_depth_scale, abs_depth_scale = eval_depth(
                    pred * 10.0,
                    gt,
                    crop=crop,
                    mask=mask,
                    get_best_scale=True,
                )
                self.assertAlmostEqual(
                    float(mse_depth.sum()), float(mse_depth_scale.sum()), delta=1e-4
                )
                self.assertAlmostEqual(
                    float(abs_depth.sum()), float(abs_depth_scale.sum()), delta=1e-4
                )

                # error masking test
                pred_masked_err = gt + (torch.rand_like(gt) + diff) * (1 - mask)
                mse_depth_masked, abs_depth_masked = eval_depth(
                    pred_masked_err,
                    gt,
                    crop=crop,
                    mask=mask,
                    get_best_scale=True,
                )
                self.assertAlmostEqual(
                    float(mse_depth_masked.sum()), float(0.0), delta=1e-4
                )
                self.assertAlmostEqual(
                    float(abs_depth_masked.sum()), float(0.0), delta=1e-4
                )
                mse_depth_unmasked, abs_depth_unmasked = eval_depth(
                    pred_masked_err,
                    gt,
                    crop=crop,
                    mask=1 - mask,
                    get_best_scale=True,
                )
                self.assertGreater(
                    float(mse_depth_unmasked.sum()),
                    float(diff ** 2),
                )
                self.assertGreater(
                    float(abs_depth_unmasked.sum()),
                    float(diff),
                )

                # tests with constant error
                pred_fix_diff = gt + diff * mask
                for _mask_gt in (mask, None):
                    mse_depth_fix_diff, abs_depth_fix_diff = eval_depth(
                        pred_fix_diff,
                        gt,
                        crop=crop,
                        mask=_mask_gt,
                        get_best_scale=False,
                    )
                    if _mask_gt is not None:
                        expected_err_abs = diff
                        expected_err_mse = diff ** 2
                    else:
                        err_mask = (gt > 0.0).float() * mask
                        if crop > 0:
                            err_mask = err_mask[:, :, crop:-crop, crop:-crop]
                            gt_cropped = gt[:, :, crop:-crop, crop:-crop]
                        else:
                            gt_cropped = gt
                        gt_mass = (gt_cropped > 0.0).float().sum(dim=(1, 2, 3))
                        expected_err_abs = (
                            diff * err_mask.sum(dim=(1, 2, 3)) / (gt_mass)
                        )
                        expected_err_mse = diff * expected_err_abs
                    self.assertTrue(
                        torch.allclose(
                            abs_depth_fix_diff,
                            expected_err_abs * torch.ones_like(abs_depth_fix_diff),
                            atol=1e-4,
                        )
                    )
                    self.assertTrue(
                        torch.allclose(
                            mse_depth_fix_diff,
                            expected_err_mse * torch.ones_like(mse_depth_fix_diff),
                            atol=1e-4,
                        )
                    )

    def test_psnr(self):
        """
        Compare against opencv and check that the psnr is above
        the minimum possible value.
        """
        import cv2

        im1 = torch.rand(100, 3, 256, 256).cuda()
        for max_diff in 10 ** torch.linspace(-5, 0, 6):
            im2 = im1 + (torch.rand_like(im1) - 0.5) * 2 * max_diff
            im2 = im2.clamp(0.0, 1.0)
            # check that our psnr matches the output of opencv
            psnr = calc_psnr(im1, im2)
            psnr_cv2 = cv2.PSNR(
                im1.cpu().numpy().astype(np.float64),
                im2.cpu().numpy().astype(np.float64),
                1.0,
            )
            self.assertAlmostEqual(float(psnr), float(psnr_cv2), delta=1e-4)
            # check that all psnrs are bigger than the minimum possible psnr
            max_mse = max_diff ** 2
            min_psnr = 10 * math.log10(1.0 / max_mse)
            for _im1, _im2 in zip(im1, im2):
                _psnr = calc_psnr(_im1, _im2)
                self.assertTrue(float(_psnr) >= min_psnr)

    def _one_sequence_test(
        self,
        seq_dataset,
        n_batches=2,
        min_batch_size=5,
        max_batch_size=10,
    ):
        # form a list of random batches
        batch_indices = []
        for bi in range(n_batches):
            batch_size = torch.randint(
                low=min_batch_size, high=max_batch_size, size=(1,)
            )
            batch_indices.append(torch.randperm(len(seq_dataset))[:batch_size])

        loader = torch.utils.data.DataLoader(
            seq_dataset,
            # batch_size=1,
            shuffle=False,
            batch_sampler=batch_indices,
            collate_fn=FrameData.collate,
        )

        model = ModelDBIR(image_size=self.image_size, bg_color=self.bg_color)
        model.cuda()
        self.lpips_model.cuda()

        for frame_data in loader:
            self.assertIsNone(frame_data.frame_type)
            # override the frame_type
            frame_data.frame_type = [
                "train_unseen",
                *(["train_known"] * (len(frame_data.image_rgb) - 1)),
            ]

            # move frame_data to gpu
            frame_data = dataclass_to_cuda_(frame_data)
            preds = model(**dataclasses.asdict(frame_data))

            nvs_prediction = copy.deepcopy(preds["nvs_prediction"])
            eval_result = eval_batch(
                frame_data,
                nvs_prediction,
                bg_color=self.bg_color,
                lpips_model=self.lpips_model,
            )

            # Make a terribly bad NVS prediction and check that this is worse
            # than the DBIR prediction.
            nvs_prediction_bad = copy.deepcopy(preds["nvs_prediction"])
            nvs_prediction_bad.depth_render += (
                torch.randn_like(nvs_prediction.depth_render) * 100.0
            )
            nvs_prediction_bad.image_render += (
                torch.randn_like(nvs_prediction.image_render) * 100.0
            )
            nvs_prediction_bad.mask_render = (
                torch.randn_like(nvs_prediction.mask_render) > 0.0
            ).float()
            eval_result_bad = eval_batch(
                frame_data,
                nvs_prediction_bad,
                bg_color=self.bg_color,
                lpips_model=self.lpips_model,
            )

            lower_better = {
                "psnr": False,
                "psnr_fg": False,
                "depth_abs_fg": True,
                "iou": False,
                "rgb_l1": True,
                "rgb_l1_fg": True,
            }

            for metric in lower_better.keys():
                m_better = eval_result[metric]
                m_worse = eval_result_bad[metric]
                if m_better != m_better or m_worse != m_worse:
                    continue  # metric is missing, i.e. NaN
                _assert = (
                    self.assertLessEqual
                    if lower_better[metric]
                    else self.assertGreaterEqual
                )
                _assert(m_better, m_worse)

    def test_full_eval(self, n_sequences=5):
        """Test evaluation."""
        for seq, idx in list(self.dataset.seq_to_idx.items())[:n_sequences]:
            seq_dataset = torch.utils.data.Subset(self.dataset, idx)
            self._one_sequence_test(seq_dataset)


# -*- coding: utf-8 -*-
"""Translator module"""
from __future__ import division
from data import NUMBERS

class Translator(object):
    """Translator class"""

    @classmethod
    def translate(cls, data):
        """The method for converting a input data to number instance """
        if isinstance(data, str):
            str_result = "".join(char for char in data if char.isdigit())
            value = int(str_result) if str_result else 0
        elif isinstance(data, (int, float, long)):
            value = data
        else:
            raise TypeError("Expected {} or {} / {}. But taken {}".format(str, int, float, data))
        return value

    def __enter__(self):
        self.translate = self.context_translate
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        return True

    @classmethod
    def context_translate(cls, data):
        """TRANSLATE methodf"""
        value = cls.translate(data)
        sign = "" if value >= 0 else NUMBERS["minus"]
        abs_value = abs(value)
        if value in NUMBERS and value < 100:
            str_value = NUMBERS[abs_value]
        else:
            str_value = " ".join(cls._get_power_thousand(abs_value))
        return " ".join((sign, str_value))

    @classmethod
    def _get_power_thousand(cls, value):
        """Sort out with thousand to the power"""
        while value >= 1:
            len_value = len(str(value))
            power_thousand = 10 ** ((len_value - 1) // 3 * 3)
            value_under_thousand = value // power_thousand

            str_value_under_thousand = " ".join(cls._get_under_thousand(value_under_thousand))

            str_power_thousand = NUMBERS[power_thousand] if power_thousand > 1 else ""
            str_value = " ".join((str_value_under_thousand, str_power_thousand))
            value -= value_under_thousand * power_thousand
            yield str_value

    @classmethod
    def _get_under_thousand(cls, value):
        """Sort out with values under thousand"""
        while value >= 1:
            if value >= 100:
                quantity_hundreds = value // 100
                value -= quantity_hundreds * 100
                str_and = NUMBERS["and"] if value > 0 else ""
                str_value = " ".join((NUMBERS[quantity_hundreds], NUMBERS[100], str_and))
            elif value in NUMBERS:
                str_value = NUMBERS[value]
                value = 0
            else:
                value_tens = value // 10 * 10
                str_value = NUMBERS[value_tens]
                value = value - value_tens
            yield str_value


#!/usr/bin/python3

from models.rectangle import Rectangle

class Square(Rectangle):
    """This represents a Square, inheriting from Rectangle."""

    def __init__(personal, size, x=0, y=0, id=None):
        """This initializes a new Square.

        Args:
            size (int): The size of the Square.
            x (int): The x-coordinate of the Square's position.
            y (int): The y-coordinate of the Square's position.
            id (int): The identity of the Square.
        """
        super().__init__(size, size, x, y, id)

    @property
    def size(personal):
        """This sets the size of the Square.

        Returns:
            int: The size of the Square.
        """
        return personal.width

    @size.setter
    def size(personal, value):
        """This sets the size of the Square.

        Args:
            value (int): The size value to set.
        """
        personal.width = value
        personal.height = value

    def __str__(personal):
        """This returns a string representation of the Square.

        Returns:
            str: The string representation of the Square.
        """
        return "[Square] ({}) {}/{} - {}".format(
            personal.id, personal.x, personal.y, personal.width
        )

    def update(personal, *args, **kwargs):
        """This updates the attributes of the Square.

        Args:
            *args: List of arguments.
            **kwargs: Dictionary of keyword arguments.
        """
        if args:
            attrs = ["id", "size", "x", "y"]
            for i, value in enumerate(args):
                setattr(personal, attrs[i], value)
        else:
            for key, value in kwargs.items():
                setattr(personal, key, value)
    def to_dictionary(personal):
        """This returns the dictionary representation of the Square.

        Returns:
            dict: The dictionary representation of the Square.
        """
        return {
            "id": personal.id,
            "size": personal.size,
            "x": personal.x,
            "y": personal.y,
        }


import numpy as np
import torch
import copy
from pathlib import Path
from torch_scatter import scatter
from typing import Dict, Tuple

from pcdet.datasets.v2x_sim.v2x_sim_dataset_ego import V2XSimDataset_EGO, get_pseudo_sweeps_of_1lidar, get_nuscenes_sensor_pose_in_global, apply_se3_
from pcdet.datasets.v2x_sim.v2x_sim_utils import roiaware_pool3d_utils

class V2XSimDataset_EGO_LATE(V2XSimDataset_EGO):
    def __init__(self, dataset_cfg, class_names, training=True, root_path=None, logger=None):
        super().__init__(dataset_cfg, class_names, training, root_path, logger)
        assert self.mode == 'test', f"late fusion only support validation"

    def _get_prediction_ego(self, sample_token: str) -> np.ndarray:
        path_modar = self.exchange_database / f"{sample_token}_id1_modar.pth"
        modar = torch.load(path_modar, map_location=torch.device('cpu')).numpy() if path_modar.exists() else np.zeros(1, 9)
        return modar

    @torch.no_grad()
    def _get_prediction_agent(self, lidar_id: int, lidar_token: str, sample_token: str, exchange_setting: str) -> Tuple[np.ndarray]:
        """
        Predictions are in agent's frame
        """
        assert exchange_setting in ('now', 'prev')
        glob_se3_lidar = get_nuscenes_sensor_pose_in_global(self.nusc, lidar_token)  # (4, 4)

        path_modar = self.exchange_database / f"{sample_token}_id{lidar_id}_modar.pth"
        if path_modar.exists():
            modar = torch.load(path_modar)  # on gpu, (N_modar, 7 + 2) - box-7, score, label
            # ---
            # propagate modar forward
            path_foregr = self.exchange_database / f"{sample_token}_id{lidar_id}_foreground.pth"
            if path_foregr.exists() and exchange_setting == 'prev':
                foregr = torch.load(path_foregr)  # on gpu, (N_fore, 5 + 2 + 3 + 3) - point-5, sweep_idx, inst_idx, cls_prob-3, flow-3

                # pool
                box_idx_of_foregr = roiaware_pool3d_utils.points_in_boxes_gpu(
                    foregr[:, :3].unsqueeze(0), modar[:, :7].unsqueeze(0)
                ).squeeze(0).long()  # (N_foregr,) | == -1 mean not belong to any boxes
                mask_valid_foregr = box_idx_of_foregr > -1
                foregr = foregr[mask_valid_foregr]
                box_idx_of_foregr = box_idx_of_foregr[mask_valid_foregr]

                unq_box_idx, inv_unq_box_idx = torch.unique(box_idx_of_foregr, return_inverse=True)

                # weighted sum of foregrounds' offset; weights = foreground's prob dynamic
                boxes_offset = scatter(foregr[:, -3:], inv_unq_box_idx, dim=0, reduce='mean') * 2.  # (N_modar, 3)
                # offset modar; here, assume objects maintain the same speed
                modar[unq_box_idx, :3] += boxes_offset

            modar = modar.cpu().numpy()
        else:
            modar = np.zeros((0, 9))

        return modar, glob_se3_lidar

    def _get_lidar_token_of_present_agents(self, sample_token: str) -> Dict[int, str]:
        out = dict()
        if sample_token == '':
            return out

        sample = self.nusc.get('sample', sample_token)
        for sensor_name, sensor_token in sample['data'].items():
            if sensor_name not in self._lidars_name:
                continue
            lidar_id = int(sensor_name.split('_')[-1])
            out[lidar_id] = sensor_token

        return out

    def __getitem__(self, index):
        if self._merge_all_iters_to_one_epoch:
            index = index % len(self.infos)

        info = copy.deepcopy(self.infos[index])
        gt_boxes, gt_names = info['gt_boxes'], info['gt_names']
        # gt_boxes: (N_tot, 7)
        # gt_names: (N_tot,)

        ego_se3_glob = np.linalg.inv(get_nuscenes_sensor_pose_in_global(self.nusc, info['lidar_token']))  # (4, 4)

        sample_token = info['token']
        sample = self.nusc.get('sample', sample_token)

        # get prediction of the ego vehicle @ now
        exchange_boxes, exchange_metadata = dict(), dict()
        exchange_boxes[1] = self._get_prediction_ego(sample_token)
        exchange_metadata[1] = exchange_boxes[1].shape[0]

        if self.dataset_cfg.EXCHANGE_SETTING == 'now':
            dict_lidar_id_to_token = self._get_lidar_token_of_present_agents(sample_token)
            _token_of_sample_of_interest = sample_token
        elif self.dataset_cfg.EXCHANGE_SETTING == 'prev':
            dict_lidar_id_to_token = self._get_lidar_token_of_present_agents(sample['prev'])
            _token_of_sample_of_interest = sample['prev']
        else:
            raise NotImplementedError(f"EXCHANGE_SETTING := {self.dataset_cfg.EXCHANGE_SETTING} is unknown")

        if len(dict_lidar_id_to_token) > 0:
            for lidar_id, lidar_token in dict_lidar_id_to_token.items():
                if lidar_id == 1:
                    # ego vehicle is already handled above
                    continue

                modar, glob_se3_lidar = self._get_prediction_agent(lidar_id, lidar_token, _token_of_sample_of_interest, self.dataset_cfg.EXCHANGE_SETTING)

                # transform modar to ego frame
                ego_se3_lidar = ego_se3_glob @ glob_se3_lidar
                modar[:, :7] = apply_se3_(ego_se3_lidar, boxes_=modar[:, :7], return_transformed=True)

                # store agent's modar
                exchange_boxes[lidar_id] = modar
                exchange_metadata[lidar_id] = modar.shape[0]

        # -----------------
        # format output
        # assemble datadict
        input_dict = {
            'points': np.zeros((1, 7)),  # Dummy | (N_pts, 5 + 2) - point-5, sweep_idx, inst_idx
            'gt_boxes': gt_boxes,  # (N_inst, 7)
            'gt_names': gt_names,  # (N_inst,)
            'frame_id': Path(info['lidar_path']).stem,
            'metadata': {
                'lidar_token': info['lidar_token'],
                'num_sweeps_target': self.num_sweeps,
                'sample_token': info['token'],
                'lidar_id': 1,
                'num_original': 0,
                'exchange': exchange_metadata,
                'exchange_boxes': exchange_boxes,  # (N_boxes_tot, 7 + 2) - box-7, score, label
            }
        }

        # data augmentation & other stuff
        data_dict = self.prepare_data(data_dict=input_dict)

        return data_dict