# -*- coding: utf-8 -*-
"""
Created on Thu Apr 12 18:08:53 2018

@author: Edward
"""

import numpy as np
from matplotlib import pyplot as plt
import cv2
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon
import os
import csv
from lineManager import lineMgr
from commonFunctions import distance, extendList

def drawLine(pic,pt1,pt2,rgb=(255,255,255)):
    cv2.line(pic, (pt1[1],pt1[0]), (pt2[1],pt2[0]), rgb)

def drawRect(pic,x,y,rgb=(0,0,255),L=10):
    if isinstance(pic,list)==True:
        for k in pic:
            cv2.line(k,(y-L,x+L),(y+L,x+L),rgb)
            cv2.line(k,(y-L,x-L),(y+L,x-L),rgb)
            cv2.line(k,(y-L,x-L),(y-L,x+L),rgb)
            cv2.line(k,(y+L,x-L),(y+L,x+L),rgb)
    else:
        cv2.line(pic,(y-L,x+L),(y+L,x+L),rgb)
        cv2.line(pic,(y-L,x-L),(y+L,x-L),rgb)
        cv2.line(pic,(y-L,x-L),(y-L,x+L),rgb)
        cv2.line(pic,(y+L,x-L),(y+L,x+L),rgb)

"""
    This class manager several polygons in an image
"""
class PolyManager:
    def __init__(self):
        self.polygonsList = []
        self.polyPoints = []
        self.gDataDir = None
        self.font = cv2.FONT_HERSHEY_SIMPLEX
        self.polyMaskList = []
        self.polyMaskPointsList = []
        self.polyIntensities = []

    def addPolyPoint(self, point):
        self.polyPoints.append(np.array(point,dtype=int))

    def removePolyPoint(self, location):
        for i in range(0,len(self.polyPoints)):
            if i>=len(self.polyPoints):
                break;
            if distance(self.polyPoints[i],location)<=10:
                del self.polyPoints[i];
        pass;

    def clearCurrentPoly(self):
        self.polyPoints = []

    """
        Close the polygon by making the first point also the last point
    """
    def closePoly(self):
        if len(self.polyPoints)>1:
            self.addPolyPoint(self.polyPoints[0])

    """
        Returns the polygon the user is working on right now
    """
    def getCurrentPoly(self):
        return self.polyPoints

    def addPolygon(self, points):
        self.polygonsList.append(points)

    """
        Remove the last (added) polygon
    """
    def removeLastPolygon(self):
        del self.polygonsList[-1]

    """
        Remove all polygons that the point falls inside.
    """
    def removePolygon(self, point):
        for i in range(0,len(self.polygonsList)):
            if i>=len(self.polygonsList):
                break

            polygon = Polygon(self.polygonsList[i]);
            if polygon.contains(Point(point[0],point[1])):
                del self.polygonsList[i]
                i = i-1

    def showAllPolygons(self, img):
        for i in range(len(self.polygonsList)):
            self.showPolygon(img, self.polygonsList[i], i)

        # Show the one we are working on right now
        self.showPolygon(img, self.polyPoints, len(self.polygonsList))

    def showPolygon(self, img ,polyPoints, index):
        if len(polyPoints)==0:
            return

        # Draw the lines
        prevPt = None
        for pt in polyPoints:
            if prevPt is not None:
                drawLine(img,prevPt,pt)
            prevPt = pt

        # Draw the rectangles
        for pt in polyPoints:
            drawRect(img,pt[0],pt[1],L=2)

        # Draw the circle number
        cv2.putText(img,'#'+str(index),(polyPoints[0][1]+10,polyPoints[0][0]), self.font, 0.5,(100,255,0),1)

    """
        Return the area of the current / last polygon. This area depends on the factor
        of by how much the pixels were inflated (hight and width was multiplied by).

        The area returned is in [pixel * pixel] units.
    """
    def getPolyArea(self, factor):
        x = np.array([pt[0] for pt in self.polygonsList[-1]],dtype=float)
        y = np.array([pt[1] for pt in self.polygonsList[-1]],dtype=float)
        x = x * 1/factor
        y = y * 1/factor
        return 0.5*np.abs(np.dot(x,np.roll(y,1))-np.dot(y,np.roll(x,1)))

    def measureAveragePolyIntensity(self, grayImg, img, frame, polyPoints, index):
        global polyMaskList,polyMaskPointsList;#polyPoints,polyMask,polyMaskPoints;

        if len(polyPoints)<2:
            return;

        flagMask = False;
        if len(self.polyMaskPointsList)>index and len(self.polyMaskList)>index:
            if np.array_equal(np.array(polyPoints),np.array(self.polyMaskPointsList[index])):
                mask = self.polyMaskList[index];
                flagMask = True;
        if flagMask==False:
            mask = np.array(grayImg,dtype=bool);
            mask[:] = False;

            xpoints = [pt[0] for pt in polyPoints];
            ypoints = [pt[1] for pt in polyPoints];
            xmin = np.min(xpoints);
            xmax = np.max(xpoints);
            ymin = np.min(ypoints);
            ymax = np.max(ypoints);

            polygon = Polygon(polyPoints);
            for x in range(xmin,xmax+1):
                for y in range(ymin,ymax+1):
                    if polygon.contains(Point(x, y)):
                        mask[x,y] = True;

            self.polyMaskList = extendList(self.polyMaskList,index);
            self.polyMaskList[index] = mask;
            self.polyMaskPointsList = extendList(self.polyMaskPointsList,index);
            self.polyMaskPointsList[index] = np.copy(polyPoints);
        avgIntensity = np.mean(grayImg[mask]);

        # This test works:
        #img[mask] = (0,0,255);

        self.addPolyIntensity(index,frame,avgIntensity);
        #print('avgIntensity: ',avgIntensity);
        #return avgIntensity;

    def addPolyIntensity(index,frame,avgIntensity):
        global polyIntensities
        polyIntensities = extendList(polyIntensities,index)
        polyIntensities[index] = extendList(polyIntensities[index],frame)
        polyIntensities[index][frame] = avgIntensity

    def savePolyIntensities(self, filename):
        if filename is not None:
            csvOutputFile = filename + "polyIntensities.csv"
        else:
            csvOutputFile = "polyIntensities.csv"

        # In case we didn't start at the first frame
        for i in range(0,len(self.polyIntensities)):
            for frame in range(0,len(self.polyIntensities[i])):
                if self.polyIntensities[i][frame]==[]:
                    self.polyIntensities[i][frame] = -1

        for i in range(0,len(self.polyIntensities)):
            #
            # Output graph
            ##########################################
            fig = plt.figure(100)
            plt.plot(range(0,len(self.polyIntensities[i])),self.polyIntensities[i],'b')
            plt.xlabel('time [frame]')
            plt.ylabel('Poly Average Intenisty')
            plt.title('Poly Average Intensity as a Function of Time')
            fig.savefig(filename+"polyIntenistyPlot["+str(i)+"].jpeg")
            fig.clf()
            plt.close(fig)

        #
        # Output to *.CSV
        ##########################################
        if len(self.polyIntensities)>0:
            print('Writing to CSV file: ',csvOutputFile);
            with open(csvOutputFile, 'w') as csvfile:
                writer = csv.writer(csvfile, delimiter=',',\
                    quotechar='|', quoting=csv.QUOTE_MINIMAL,lineterminator='\n')

                # Write header row
                row1 = ['Frame #'];
                for i in range(0,len(self.polyIntensities)):
                    row1.append('poly '+str(i))
                writer.writerow(row1)

                # Write data rows
                rows = [];
                for frame in range(0,len(self.polyIntensities[0])):
                    row = []
                    row.append(str(frame));
                    for i in range(0,len(self.polyIntensities)):
                        if polyIntensities[i][frame]==-1:
                            row.append("")
                        else:
                            row.append(str(self.polyIntensities[i][frame]))
                    rows.append(row)

                for i in range(0,len(rows)):
                    writer.writerow(rows[i])

    def clearPolyIntensities(self):
        self.polyIntensities = []

    def measureAveragePolyIntensityForAllPolys(self, grayImg, img, frame):
        for i in range(0,len(self.polygonsList)):
            #measureAveragePolyIntensity(grayImg,img,frame,polygonsList[i],i);
            selectedPixels = []
            selectedPixelsCoord = []
            linePoints = []
            for j in range(0,len(self.polygonsList[i])-1):
                selectedPixelsNew,selectedPixelsCoordNew = lineMgr.measureIntensityForLine(grayImg,img,frame,self.polygonsList[i][j],self.polygonsList[i][j+1],j)
                #print('selectedPixelsCoordNew: ',selectedPixelsCoordNew)
                if len(selectedPixels)==0:
                    selectedPixels = np.array(selectedPixelsNew);
                    selectedPixelsCoord = np.array(selectedPixelsCoordNew)
                    #linePoints = np.array([polygonsList[i][j]])
                else:
                    selectedPixels = np.concatenate((selectedPixels,selectedPixelsNew))
                    selectedPixelsCoord = np.concatenate((selectedPixelsCoord,selectedPixelsCoordNew))
                    #linePoints = np.concatenate(linePoints,np.array([polygonsList[i][j]]))
            linePoints = np.array(self.polygonsList[i])
            if self.gDataDir is None:
                folderNum = 0

                if os.path.exists('selectedPixels/'+str(folderNum)):
                    print('Checking for folder: '+'selectedPixels/'+str(folderNum)+' = folder exists')
                    folderNum = folderNum + 1
                dataDir = 'selectedPixels/'+str(folderNum)
                print('Creating folder: '+dataDir)

                #cwd = os.getcwd()
                #print('cwd = ',cwd)
                #os.sys.exit()

                while True:
                    try:
                        os.mkdir(dataDir)
                    except:
                        folderNum = folderNum + 1
                        dataDir = 'selectedPixels/'+str(folderNum)
                        continue
                    break
                self.gDataDir = dataDir
                print('Folder created!')

            # Save plot
            fig = plt.figure(100)
            plt.plot(range(0,len(selectedPixels)),selectedPixels)
            fig.savefig(self.gDataDir+'/selectedPixels['+str(frame)+'].png')
            fig.clf();
            plt.close(fig);

            # Save data
            np.save(self.gDataDir+'/selectedPixels['+str(frame)+']',selectedPixels)

            # Save line pts
            if os.path.exists(self.gDataDir+'/selectedPixels[points]')==False:
                np.save(self.gDataDir+'/selectedPixels[points]',linePoints)

            # Save coordinates for line
            if os.path.exists(self.gDataDir+'/selectedPixels[coord]')==False:
                np.save(self.gDataDir+'/selectedPixels[coord]',selectedPixelsCoord)

            if False:
                #
                # Test coord.
                x,y = [],[]
                for c in selectedPixelsCoord:
                    x.append(c[1])
                    y.append(-c[0])
                fig = plt.figure(1010)
                plt.plot(x[:np.int(len(x)/2)],y[:np.int(len(x)/2)],'ro')
                plt.plot(x[np.int(len(x)/2):],y[np.int(len(x)/2):],'ko')
                fig.savefig(self.gDataDir+'/pixelsCoord.png')
                fig.clf()
                plt.close(fig)


from math import sin, cos
from dataclasses import dataclass, field
from typing import Tuple

import numpy as np
from gym import spaces

Vec2D = Tuple[float, float]
PolarVec2D = Tuple[float, float]
RobotPose = Tuple[Vec2D, float]
WheelSpeedState = Tuple[float, float] # tuple of (left, right) speeds

@dataclass
class DifferentialDriveSettings:
    radius: float = 1.0
    max_linear_speed: float = 2.0
    max_angular_speed: float = 0.5
    wheel_radius: float = 0.05
    interaxis_length: float = 0.3

    def __post_init__(self):
        if self.radius <= 0:
            raise ValueError("Robot's radius mustn't be negative or zero! Needs to model a corps!")
        if self.wheel_radius <= 0:
            raise ValueError("Robot's wheel radius mustn't be negative or zero! Needs to model a corps!")
        if self.max_linear_speed <= 0 or self.max_angular_speed <= 0:
            raise ValueError("Robot's max. linear / angular speed mustn't be negative or zero!")
        if self.interaxis_length <= 0:
            raise ValueError("Robot's interaxis length mustn't be negative or zero!")

@dataclass
class DifferentialDriveState:
    pose: RobotPose
    velocity: PolarVec2D = field(default=(0, 0))
    last_wheel_speeds: WheelSpeedState = field(default=(0, 0))
    wheel_speeds: WheelSpeedState = field(default=(0, 0))

DifferentialDriveAction = Tuple[float, float] # (linear velocity, angular velocity)

@dataclass
class DifferentialDriveMotion:
    config: DifferentialDriveSettings

    def move(self, state: DifferentialDriveState, action: PolarVec2D, d_t: float):
        robot_vel = self._robot_velocity(state.velocity, action)
        new_wheel_speeds = self._resulting_wheel_speeds(robot_vel)
        distance = self._covered_distance(state.wheel_speeds, new_wheel_speeds, d_t)
        new_orient = self._new_orientation(state.pose[1], state.wheel_speeds, new_wheel_speeds, d_t)
        state.pose = self._compute_odometry(state.pose, (distance, new_orient))
        state.last_wheel_speeds = state.wheel_speeds
        state.wheel_speeds = new_wheel_speeds
        state.velocity = robot_vel

    def _robot_velocity(self, velocity: PolarVec2D, action: PolarVec2D) -> PolarVec2D:
        dot_x = velocity[0] + action[0]
        dot_orient = velocity[1] + action[1]
        dot_x = np.clip(dot_x, 0, self.config.max_linear_speed)
        angular_max = self.config.max_angular_speed
        dot_orient = np.clip(dot_orient, -angular_max, angular_max)
        return dot_x, dot_orient

    def _resulting_wheel_speeds(self, movement: PolarVec2D) -> WheelSpeedState:
        dot_x, dot_orient = movement
        diff = self.config.interaxis_length * dot_orient / 2
        new_left_wheel_speed = (dot_x - diff) / self.config.wheel_radius
        new_right_wheel_speed = (dot_x + diff) / self.config.wheel_radius
        return new_left_wheel_speed, new_right_wheel_speed

    def _covered_distance(
            self, last_wheel_speeds: WheelSpeedState,
            new_wheel_speeds: WheelSpeedState, d_t: float) -> float:
        last_wheel_speed_left, last_wheel_speed_right = last_wheel_speeds
        wheel_speed_left, wheel_speed_right = new_wheel_speeds

        velocity = ((last_wheel_speed_left + wheel_speed_left) / 2 \
            + (last_wheel_speed_right + wheel_speed_right) / 2)
        distance_covered = self.config.wheel_radius / 2 * velocity * d_t
        return distance_covered

    def _new_orientation(
            self, robot_orient: float, last_wheel_speeds: WheelSpeedState,
            wheel_speeds: WheelSpeedState, d_t: float) -> float:
        last_wheel_speed_left, last_wheel_speed_right = last_wheel_speeds
        wheel_speed_left, wheel_speed_right = wheel_speeds

        right_left_diff = (last_wheel_speed_right + wheel_speed_right) / 2 \
            - (last_wheel_speed_left + wheel_speed_left) / 2
        diff = self.config.wheel_radius / self.config.interaxis_length * right_left_diff * d_t
        new_orient = robot_orient + diff
        return new_orient

    def _compute_odometry(self, old_pose: RobotPose, movement: PolarVec2D) -> RobotPose:
        distance_covered, new_orient = movement
        (robot_x, robot_y), old_orient = old_pose
        rel_rotation = (old_orient + new_orient) / 2
        new_x = robot_x + distance_covered * cos(rel_rotation)
        new_y = robot_y + distance_covered * sin(rel_rotation)
        return (new_x, new_y), new_orient

@dataclass
class DifferentialDriveRobot():
    """Representing a robot with differential driving behavior"""

    config: DifferentialDriveSettings
    state: DifferentialDriveState = field(default=DifferentialDriveState(((0, 0), 0)))
    movement: DifferentialDriveMotion = field(init=False)

    def __post_init__(self):
        self.movement = DifferentialDriveMotion(self.config)

    @property
    def observation_space(self) -> spaces.Box:
        high = np.array([self.config.max_linear_speed, self.config.max_angular_speed], dtype=np.float32)
        low = np.array([0.0, -self.config.max_angular_speed], dtype=np.float32)
        return spaces.Box(low=low, high=high, dtype=np.float32)

    @property
    def action_space(self) -> spaces.Box:
        high = np.array([self.config.max_linear_speed, self.config.max_angular_speed], dtype=np.float32)
        low = np.array([0.0, -self.config.max_angular_speed], dtype=np.float32)
        return spaces.Box(low=low, high=high, dtype=np.float32)

    @property
    def pos(self) -> Vec2D:
        return self.state.pose[0]

    @property
    def pose(self) -> RobotPose:
        return self.state.pose

    @property
    def current_speed(self) -> PolarVec2D:
        return self.state.velocity

    def apply_action(self, action: DifferentialDriveAction, d_t: float):
        self.movement.move(self.state, action, d_t)

    def reset_state(self, new_pose: RobotPose):
        self.state = DifferentialDriveState(new_pose)

    def parse_action(self, action: np.ndarray) -> DifferentialDriveAction:
        return (action[0], action[1])


# -*- coding: utf-8 -*-
# @Date    : 2018-05-17 16:29:32
# @Author  : Light (halysl0817@gmail.com)
# @Link    : ${link}
# @Version : $Id$

import socket
import random
import argparse
import sys

MAX_BYTES = 65535

def server(interface, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind((interface, port))
    print('listening at', sock.getsockname())
    while True:
        data, address = sock.recvfrom(MAX_BYTES)
        if random.random() < 0.5:
            print('Pretending to drop packet from {}'.format(address))
            continue
        text = data.decode('ascii')
        print('The clent at {} says {!r}'.format(address, text))
        message = 'Your data was {} bytes long'.format(len(data))
        sock.sendto(message.encode('ascii'), address)

def client(hostname, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    hostname = sys.argv[2]
    # connect方法有多种好处，最直观的在于之后的send及recv方法不需要手动指定ip+port
    # 也可以有效抵御网络攻击，但只适用于一个套接字连接一个服务器情况，多次连接会覆盖设置
    sock.connect((hostname, port))
    print('Client socket name is {}'.format(sock.getsockname()))

    delay = 0.1
    text = 'This is another message.'
    data = text.encode('ascii')
    while True:
        sock.send(data)
        print('Waiting up to {} seconds for a reply'.format(delay))
        sock.settimeout(delay)
        try:
            data = sock.recv(MAX_BYTES)
        except socket.timeout:
            # 超时重新设置delay，当delay大于2时，视为服务器无响应
            delay *= 2
            if delay > 2.0:
                raise RuntimeError('I think the server is down.')
        else:
            break

    print('The server say {!r}'.format(data.decode('ascii')))

if __name__ == "__main__":
    choices = {'client':client, 'server':server}
    parse = argparse.ArgumentParser(description='Send and receive UDP,'
                                                ' pretending packets are often dropped')
    parse.add_argument('role', choices=choices, help='which role to take')
    parse.add_argument('host', help='interface the server listens at;'
                                    'host the clent sends to')
    parse.add_argument('-p', metavar='PORT', type=int, default=1060,help='UDP port (default 1060)')

    args = parse.parse_args()
    function = choices[args.role]
    function(args.host, args.p)


#　ワインに含まれる成分を入力として、ワインのおいしさを正解ラベルに学習を行い、おいしさを判定する。

from sklearn import svm, metrics
from sklearn.model_selection import train_test_split

# ワインデータを読み込む
wine_csv = []
with open("winequality-white.csv", "r", encoding="utf-8") as fp:
    no = 0
    for line in fp:
	    # 一行づつ読み込んでいく
	    line = line.strip()
		# セミコロンで行を区切って格納していく
	    cols = line.split(";")
	    wine_csv.append(cols)

# 1行目はヘッダ行なので削除
wine_csv = wine_csv[1:]

# CSVの各データを数値に変換する
labels = []
data = []
for cols in wine_csv:
    # map関数でリストの各要素を数値に変換
    cols = list(map(lambda n: float(n), cols))
    # ワインの評価数値を格納
    grade = int(cols[11])
	# 評価数値の調整
    if grade == 9: grade = 8
    if grade < 4: grade = 5
	# 正解ラベルとしてワインの評価数値を格納
    labels.append(grade)
	# 成分値を配列として格納
    data.append( cols[0:11])

# 訓練用データとテストデータに分ける
data_train, data_test, label_train, label_test = train_test_split(data, labels)

# ランダムフォレストのアルゴリズムを使用してモデルを作成
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier()
clf.fit(data_train, label_train)
# SVMのアルゴリズムを使用したモデルの作成
#clf = svm.SVC()
#clf.fit(data_train, label_train)

# 予測の実行
predict = clf.predict(data_test)
# 正解データをもとに正答率を算出
ac_score = metrics.accuracy_score(label_test, predict)
cl_report = metrics.classification_report(label_test, predict)
print("正解率=", ac_score)
print("レポート=\n",cl_report)


# we are using virtual enviornment that means that most of the librabry we are using we need to install them first before we start using thempr
import pickle as pkl
import pandas as pd
import streamlit as st
import requests

def fetch_poster(movie_id):
    response = requests.get("https://api.themoviedb.org/3/movie/{}?api_key=2234cda012e52526ee792fda591639f4&language=en-US".format(movie_id))
    data = response.json()
    return  "https://image.tmdb.org/t/p/w500/"+data['poster_path']

def recommend(movie):
    movie_index = df[df['title'] == movie].index[0]
    distances = similarity[movie_index]
    movie_list = sorted(list(enumerate(similarity[movie_index])), reverse=True, key=lambda x: x[1])[1:6]
    recommended_movies=[]
    recommended_movies_poster=[]
    for i in movie_list:
        movie_id=df.iloc[i[0]].movie_id
        recommended_movies.append(df.iloc[i[0]].title)
        recommended_movies_poster.append(fetch_poster(movie_id))
    return recommended_movies,recommended_movies_poster

st.title("Movie Recommender System")

# we have transfer our data frame from jupyter notebook to here in form of pickle format
with open("C:/Users/rani/Movie_Recommendation_System/my_data.pkl", "rb") as f:
    file = pkl.load(f)
df = pd.DataFrame(file)

with open("C:/Users/rani/Movie_Recommendation_System/similarity.pkl", "rb") as ff:
    similarity = pkl.load(ff)

selected_movie_name = st.selectbox("what do you like ?",df['title'].values)

if st.button("Recommend"):
    name,posters = recommend(selected_movie_name)
    st.title("Here are some recommendation based on your likes : ")
    st.header(name[0])
    st.image(posters[0])
    st.header(name[1])
    st.image(posters[1])
    st.header(name[2])
    st.image(posters[2])
    st.header(name[3])
    st.image(posters[3])
    st.header(name[4])
    st.image(posters[4])

st.header("Enjoy your day !!!")


from dataclasses import dataclass, field
from datetime import datetime
from decimal import Decimal
from typing import List

from bolsaprov.constants import (
    ASSET_EVENT_TYPE_MAPPER,
    ASSET_ESPECIF_TYPE_MAPPER,
    BrokerAssetExtractEspecif,
    BrokerAssetExtractEventType
)

@dataclass
class BrokerParseExtraData():
    data: str

@dataclass
class Broker():
    value: str
    name: str
    parse_extra_data: BrokerParseExtraData
    accounts: List = field(default_factory=lambda: [])

@dataclass
class BrokerAccountParseExtraData():
    """ Essential data to do other requests using account information. """

    view_state: str
    view_state_generator: str
    event_validation: str

@dataclass
class BrokerAccount():
    id: str
    parse_extra_data: BrokerAccountParseExtraData

@dataclass
class BrokerAssetExtract():
    raw_negotiation_name: str
    asset_specification: str
    raw_negotiation_code: str
    operation_date: datetime
    event_type: str
    unit_amount: Decimal
    quotation_factor: int
    bruto_price: Decimal
    liquido_price: Decimal

    @classmethod
    def create_from_response_fields(
        cls,
        raw_negotiation_name,
        asset_specification,
        raw_negotiation_code,
        operation_date,
        event_type,
        unit_amount,
        quotation_factor,
        bruto_price,
        liquido_price,
    ):
        operation_date = datetime.strptime(operation_date, '%d/%m/%Y').date()
        # asset_specification = ASSET_ESPECIF_TYPE_MAPPER[asset_specification]
        # event_type = ASSET_EVENT_TYPE_MAPPER[event_type]
        unit_amount = cls._format_string_to_decimal(unit_amount)
        quotation_factor = int(quotation_factor)
        bruto_price = cls._format_string_to_decimal(bruto_price)
        liquido_price = cls._format_string_to_decimal(liquido_price)

        return cls(
            raw_negotiation_name=raw_negotiation_name,
            asset_specification=asset_specification,
            raw_negotiation_code=raw_negotiation_code,
            operation_date=operation_date,
            event_type=event_type,
            unit_amount=unit_amount,
            quotation_factor=quotation_factor,
            bruto_price=bruto_price,
            liquido_price=liquido_price
        )

    @staticmethod
    def _format_string_to_decimal(value):
        value = value.replace(',', '').replace('.', '')
        value = f'{value[:-2]}.{value[-2:]}'
        return Decimal(value)


from django.conf import settings
from django.utils.translation import activate
from telegram.ext import CallbackContext, ExtBot, Application

from ...models import TelegramUser

class L10nContext(CallbackContext[ExtBot, dict, dict, dict]):
    def __init__(self, application: Application, chat_id: int = None, user_id: int = None):
        super().__init__(application=application, chat_id=chat_id, user_id=user_id)
        self.user_id: int | None = user_id
        self.language: str = settings.DEFAULT_LANGUAGE

    async def refresh_data(self) -> None:
        user = await TelegramUser.objects.filter(id=self.user_id).afirst()
        if user:
            self.language = user.language

        activate(self.language)
        return await super().refresh_data()


from ..core import Object
from PyQt5.QtCore import QObject
from PyQt5.QtWidgets import QWidget
from janus.widgets.ui.scan_ui import Ui_Scan
from ..actions.gridscanaction import GridScanAction

class ScanControls(QObject, Object):

    def __init__(self, parent=None, grid_controller=None, grid_axis_controller=None, raw_tango_devices=None):
        Object.__init__(self)
        QObject.__init__(self)
        self.parent = parent
        self.grid_controller = grid_controller
        self.grid_axis_controller = grid_axis_controller
        self.raw_tango_devices = raw_tango_devices
        self.setup_ui()
        self.connect_signals()

    def start_scan(self):
        if "grid_scan" not in self.janus.actions or self.janus.actions["grid_scan"] is None:
            action = GridScanAction(self.grid_controller, self.grid_axis_controller, self.raw_tango_devices)
            action.progress_signal.connect(self.action_progress)
            action.done_signal.connect(self.action_done)
            self.janus.actions["grid_scan"] = action
            action.start()

    def action_progress(self, progress_data):
        print("progress: {}".format(progress_data["progress"]))

    def action_done(self):
        self.janus.actions["grid_scan"] = None

    def connect_signals(self):
        self.ui.startScan.clicked.connect(self.start_scan)

    def setup_ui(self):
        self.widget = QWidget(self.parent)
        self.ui = Ui_Scan()
        self.ui.setupUi(self.widget)


import humanize

from analyse_data import analyse_data as anda

def get_drawdowns_tables(portoflio_name, drawdowns):
    drawdowns_df = anda.drawdown_summary(drawdowns)
    drawdowns_formated = format_summary(drawdowns_df)
    no_records = 10 if 10 < len(drawdowns_df) else len(drawdowns_df)
    table_data = drawdowns_formated.to_dict("records")[:no_records]

    table_name = f"{portoflio_name} Top Drawdowns"
    table_visibility = {"display": "block"}

    return [table_name, table_data, table_visibility]

def format_summary(drawdowns):
    drawdowns = drawdowns.head(10)
    return drawdowns.apply(format_row, axis=1, result_type="broadcast")

def format_row(row):
    return [
        round(row["Drawdown"], 2),
        row["Start"].strftime("%d/%m/%Y"),
        row["End"].strftime("%d/%m/%Y"),
        row["Recovery"].strftime("%d/%m/%Y"),
        humanize.naturaldelta(row["Length"]),
        humanize.naturaldelta(row["Recovery Time"]),
        humanize.naturaldelta(row["Underwater Period"]),
    ]


from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm
from .models import SiteUser

class SiteUserAdmin(UserAdmin):
  model = SiteUser

  def get_fieldsets(self, request, obj=None):
    if obj:
      current_fieldsets = []
      for item in UserAdmin.fieldsets:
        field_options = dict(item[1])

        if item[0] == None:
          fields = list(item[1]["fields"])
          fields.append("profile_image")
          field_options.update({"fields": tuple(fields)})

        current_fieldsets.append((item[0], field_options,))
    else:
      current_fieldsets = self.add_fieldsets + (
        ("Other", {"fields": ["profile_image"]}),
      )

    return current_fieldsets

admin.site.register(SiteUser, SiteUserAdmin)


import copy
from .util import reify

import requests
from requests_oauthlib import OAuth2Session
from .resource import Resource

class Connection:

    def __init__(self, service_root, session=None, client_secret=None):
        self.service_root = service_root.rstrip('/')
        if session is None:
            session = OAuth2Session()
        self.session = session
        self.client_secret = client_secret
        self.session.headers['Accept'] = 'application/json'

    def __repr__(self):
        return f'<Connection {self.service_root}>'

    @classmethod
    def from_token(cls, service_root, token):
        session = OAuth2Session(token=token)
        self = cls(service_root, session=session)

    @reify
    def metadata(self):
        url = self.service_root + '/metadata'
        resp = requests.get(url, headers={'Accept': 'application/json'})
        resp.raise_for_status()
        return resp.json()

    def service(self, rest_id=0):
        return Resource.from_dict(
            self.metadata['rest'][rest_id],
            resourceType='_Service',
            bind=self)

    def get(self, path):
        url = self.service_root + path
        resp = self.session.get(url)
        resp.raise_for_status()
        return resp.json()

    def clone(self, **kwargs):
        result = copy.copy(self)
        for k, v in kwargs.items():
            setattr(result, k, v)
        return result


import setuptools

BASE_REQUIREMENTS = []
SERVER_REQUIREMENTS = []
CLIENT_REQUIREMENTS = []

with open("README.md", "r") as fh:
    long_description = fh.read()
setuptools.setup(
     name='easyschedule',
     version='NEXTVERSION',
     packages=setuptools.find_packages(include=['easyschedule'], exclude=['build']),
     author="Joshua Jamison",
     author_email="joshjamison1@gmail.com",
     description="Easily schedule single or recurring sync/async tasks",
     long_description=long_description,
   long_description_content_type="text/markdown",
     url="https://github.com/codemation/easyschedule",
     classifiers=[
         "Programming Language :: Python :: 3",
         "License :: OSI Approved :: MIT License",
         "Operating System :: OS Independent",
     ],
     python_requires='>=3.7, <4',
     install_requires=BASE_REQUIREMENTS
 )


import functools
from typing import Any, Mapping, Optional, Tuple

import gin
import haiku as hk
import jax
from jax import core
import jax.numpy as jnp
from learned_optimization import circular_buffer
from learned_optimization import profile
from learned_optimization import summary
from learned_optimization import tree_utils
from learned_optimization.outer_trainers import common
from learned_optimization.outer_trainers import gradient_learner
from learned_optimization.outer_trainers import truncated_pes
from learned_optimization.outer_trainers import truncated_step as truncated_step_mod

PRNGKey = jnp.ndarray
MetaParams = Any
TruncatedUnrollState = Any

@gin.configurable
class TruncatedPESNoHystSameData(gradient_learner.GradientEstimator):
  """PES with no hysteresis by spending a lot more compute and storing data."""

  def __init__(
      self,
      truncated_step: truncated_step_mod.VectorizedTruncatedStep,
      data_buffer_size: int,
      trunc_length=10,
      std=0.01,
      steps_per_jit=10,
      stack_antithetic_samples: bool = False,
      sign_delta_loss_scalar: Optional[float] = None,
  ):
    self.steps_per_jit = steps_per_jit
    self.stack_antithetic_samples = stack_antithetic_samples
    self.sign_delta_loss_scalar = sign_delta_loss_scalar
    self.std = std
    self.truncated_step = truncated_step
    self.trunc_length = trunc_length
    self.grad_est = truncated_pes.TruncatedPES(truncated_step, trunc_length,
                                               std, steps_per_jit,
                                               stack_antithetic_samples,
                                               sign_delta_loss_scalar)
    self.data_buffer_size = data_buffer_size

    self.step_abstract_shape = jax.tree_util.tree_map(
        lambda x: core.ShapedArray(x.shape, x.dtype),
        self.truncated_step.get_batch(self.steps_per_jit),
    )

    # The shape of theta is not known at gradient estimator initialization time
    # as such we cannot initialize the circular buffer here.
    self.circular_buffer = None

  @profile.wrap()
  def init_worker_state(self, worker_weights: gradient_learner.WorkerWeights,
                        key: PRNGKey):
    nt = self.truncated_step.num_tasks
    theta = worker_weights.theta
    epsilon = jax.tree_util.tree_map(
        lambda x: core.ShapedArray([nt] + list(x.shape), x.dtype), theta
    )
    state = self.grad_est.init_worker_state(worker_weights, key)

    self.circular_buffer = circular_buffer.CircularBuffer(
        {
            "data": self.step_abstract_shape,
            "epsilon": epsilon,
            "key": jax.tree_util.tree_map(
                lambda x: core.ShapedArray(x.shape, x.dtype), key
            ),
            "p_state": jax.tree_util.tree_map(
                lambda x: core.ShapedArray(x.shape, x.dtype), state.pos_state
            ),
        },
        self.data_buffer_size,
    )

    # fill the buffer with a single epsilon and data.
    p_state = state.pos_state
    buffer_state = self.circular_buffer.init()
    for _ in range(self.data_buffer_size):
      key, key1, key2 = jax.random.split(key, 3)
      data = self.truncated_step.get_batch(self.steps_per_jit)
      eps, _, _ = common.vector_sample_perturbations(theta, key1, self.std, nt)

      buffer_state = self.circular_buffer.add(buffer_state, {
          "data": data,
          "epsilon": eps,
          "key": key2,
          "p_state": p_state,
      })

      (p_state, _), _ = common.truncated_unroll(self.truncated_step,
                                                self.steps_per_jit, False,
                                                theta, key, p_state, data, None)
    return state, buffer_state

  @profile.wrap()
  def compute_gradient_estimate(
      self,
      worker_weights: gradient_learner.WorkerWeights,
      key: PRNGKey,
      state,
      with_summary: bool = False,
      datas_list: Any = None,
  ) -> Tuple[gradient_learner.GradientEstimatorOut, Mapping[str, jnp.ndarray]]:
    del datas_list
    state, buffer_state = state

    rng = hk.PRNGSequence(key)

    # train on the circular buffer's data.
    reordered_data, unused_mask = self.circular_buffer.stack_reorder(
        buffer_state)

    # The first iterations on this loop are computing the wrong thing
    # (by intention). This is fine, as eventualy the inner problem will reset
    # and start computing the right thing. If we really wanted we could re-init
    # the state here.
    p_state = jax.tree_util.tree_map(lambda x: x[0], reordered_data["p_state"])
    n_state = p_state

    def sliced(i, dat):
      return dat[i]

    for i in range(self.data_buffer_size):
      elements_from_buffer = jax.tree_util.tree_map(
          functools.partial(sliced, i), reordered_data)
      datas = elements_from_buffer["data"]
      epsilon = elements_from_buffer["epsilon"]
      key = elements_from_buffer["key"]

      vec_p_theta = tree_utils.tree_add(worker_weights.theta, epsilon)
      vec_n_theta = tree_utils.tree_sub(worker_weights.theta, epsilon)

      p_state, n_state, p_ys, n_ys, m = common.maybe_stacked_es_unroll(
          self.truncated_step,
          self.steps_per_jit,
          self.stack_antithetic_samples,
          vec_p_theta,
          vec_n_theta,
          p_state,
          n_state,
          key,
          datas,
          worker_weights.outer_state,
          with_summary=False,
          sample_rng_key=next(rng))

    # Now, we compute the actual PES update for this step.
    # each iteration, we add the eps and data to the buffer.
    theta = worker_weights.theta

    vec_pos, vec_p_theta, vec_n_theta = common.vector_sample_perturbations(
        theta, next(rng), self.std, self.truncated_step.num_tasks)

    p_yses = []
    n_yses = []
    metrics = []

    for i in range(self.trunc_length // self.steps_per_jit):
      print("inner step", i)
      datas = self.truncated_step.get_batch(self.steps_per_jit)
      key = next(rng)
      buffer_state = self.circular_buffer.add(buffer_state, {
          "data": datas,
          "epsilon": vec_pos,
          "key": key,
          "p_state": p_state,
      })

      p_state, n_state, p_ys, n_ys, m = common.maybe_stacked_es_unroll(
          self.truncated_step,
          self.steps_per_jit,
          self.stack_antithetic_samples,
          vec_p_theta,
          vec_n_theta,
          p_state,
          n_state,
          key,
          datas,
          worker_weights.outer_state,
          with_summary=with_summary,
          sample_rng_key=next(rng))

      metrics.append(m)
      p_yses.append(p_ys)
      n_yses.append(n_ys)

    # Compute PES gradient and outputs just based on this last short unroll.
    loss, es_grad, new_accumulator, p_ys, delta_loss = truncated_pes.compute_pes_grad(
        p_yses,
        n_yses,
        state.accumulator,
        vec_pos,
        self.std,
        sign_delta_loss_scalar=self.sign_delta_loss_scalar)

    unroll_info = gradient_learner.UnrollInfo(
        loss=p_ys.loss,
        iteration=p_ys.iteration,
        task_param=p_ys.task_param,
        is_done=p_ys.is_done)

    unroll_state = (truncated_pes.PESWorkerState(p_state, n_state,
                                                 new_accumulator), buffer_state)
    output = gradient_learner.GradientEstimatorOut(
        mean_loss=loss,
        grad=es_grad,
        unroll_state=unroll_state,  # pytype: disable=wrong-arg-types
        unroll_info=unroll_info)

    metrics = summary.aggregate_metric_list(metrics)
    if with_summary:
      metrics["sample||delta_loss_sample"] = summary.sample_value(
          key, jnp.abs(delta_loss))
      metrics["mean||delta_loss_mean"] = jnp.abs(delta_loss)
      if hasattr(p_state, "inner_step"):
        metrics["sample||inner_step"] = p_state.inner_step[0]
        metrics["sample||end_inner_step"] = p_state.inner_step[0]

    return output, metrics


"""Lighting Functional Domain"""

from __future__ import annotations

from typing import Final

import zigpy.types as t
from zigpy.zcl import Cluster, foundation
from zigpy.zcl.foundation import (
    BaseAttributeDefs,
    BaseCommandDefs,
    ZCLAttributeDef,
    ZCLCommandDef,
)

class ColorMode(t.enum8):
    Hue_and_saturation = 0x00
    X_and_Y = 0x01
    Color_temperature = 0x02

class EnhancedColorMode(t.enum8):
    Hue_and_saturation = 0x00
    X_and_Y = 0x01
    Color_temperature = 0x02
    Enhanced_hue_and_saturation = 0x03

class ColorCapabilities(t.bitmap16):
    Hue_and_saturation = 0b00000000_00000001
    Enhanced_hue = 0b00000000_00000010
    Color_loop = 0b00000000_00000100
    XY_attributes = 0b00000000_00001000
    Color_temperature = 0b00000000_00010000

class Direction(t.enum8):
    Shortest_distance = 0x00
    Longest_distance = 0x01
    Up = 0x02
    Down = 0x03

class MoveMode(t.enum8):
    Stop = 0x00
    Up = 0x01
    Down = 0x03

class StepMode(t.enum8):
    Up = 0x01
    Down = 0x03

class ColorLoopUpdateFlags(t.bitmap8):
    Action = 0b0000_0001
    Direction = 0b0000_0010
    Time = 0b0000_0100
    Start_Hue = 0b0000_1000

class ColorLoopAction(t.enum8):
    Deactivate = 0x00
    Activate_from_color_loop_hue = 0x01
    Activate_from_current_hue = 0x02

class ColorLoopDirection(t.enum8):
    Decrement = 0x00
    Increment = 0x01

class DriftCompensation(t.enum8):
    NONE = 0x00
    Other_or_unknown = 0x01
    Temperature_monitoring = 0x02
    Luminance_monitoring = 0x03
    Color_monitoring = 0x03

class Options(t.bitmap8):
    Execute_if_off = 0b00000001

class Color(Cluster):
    """Attributes and commands for controlling the color
    properties of a color-capable light
    """

    ColorMode: Final = ColorMode
    EnhancedColorMode: Final = EnhancedColorMode
    ColorCapabilities: Final = ColorCapabilities
    Direction: Final = Direction
    MoveMode: Final = MoveMode
    StepMode: Final = StepMode
    ColorLoopUpdateFlags: Final = ColorLoopUpdateFlags
    ColorLoopAction: Final = ColorLoopAction
    ColorLoopDirection: Final = ColorLoopDirection
    DriftCompensation: Final = DriftCompensation
    Options: Final = Options

    cluster_id: Final = 0x0300
    name: Final = "Color Control"
    ep_attribute: Final = "light_color"

    class AttributeDefs(BaseAttributeDefs):
        current_hue: Final = ZCLAttributeDef(id=0x0000, type=t.uint8_t, access="rp")
        current_saturation: Final = ZCLAttributeDef(
            id=0x0001, type=t.uint8_t, access="rps"
        )
        remaining_time: Final = ZCLAttributeDef(id=0x0002, type=t.uint16_t, access="r")
        current_x: Final = ZCLAttributeDef(id=0x0003, type=t.uint16_t, access="rps")
        current_y: Final = ZCLAttributeDef(id=0x0004, type=t.uint16_t, access="rps")
        drift_compensation: Final = ZCLAttributeDef(
            id=0x0005, type=DriftCompensation, access="r"
        )
        compensation_text: Final = ZCLAttributeDef(
            id=0x0006, type=t.CharacterString, access="r"
        )
        color_temperature: Final = ZCLAttributeDef(
            id=0x0007, type=t.uint16_t, access="rps"
        )
        color_mode: Final = ZCLAttributeDef(
            id=0x0008, type=ColorMode, access="r", mandatory=True
        )
        options: Final = ZCLAttributeDef(
            id=0x000F, type=Options, access="rw", mandatory=True
        )
        # Defined Primaries Information
        num_primaries: Final = ZCLAttributeDef(id=0x0010, type=t.uint8_t, access="r")
        primary1_x: Final = ZCLAttributeDef(id=0x0011, type=t.uint16_t, access="r")
        primary1_y: Final = ZCLAttributeDef(id=0x0012, type=t.uint16_t, access="r")
        primary1_intensity: Final = ZCLAttributeDef(
            id=0x0013, type=t.uint8_t, access="r"
        )
        primary2_x: Final = ZCLAttributeDef(id=0x0015, type=t.uint16_t, access="r")
        primary2_y: Final = ZCLAttributeDef(id=0x0016, type=t.uint16_t, access="r")
        primary2_intensity: Final = ZCLAttributeDef(
            id=0x0017, type=t.uint8_t, access="r"
        )
        primary3_x: Final = ZCLAttributeDef(id=0x0019, type=t.uint16_t, access="r")
        primary3_y: Final = ZCLAttributeDef(id=0x001A, type=t.uint16_t, access="r")
        primary3_intensity: Final = ZCLAttributeDef(
            id=0x001B, type=t.uint8_t, access="r"
        )
        # Additional Defined Primaries Information
        primary4_x: Final = ZCLAttributeDef(id=0x0020, type=t.uint16_t, access="r")
        primary4_y: Final = ZCLAttributeDef(id=0x0021, type=t.uint16_t, access="r")
        primary4_intensity: Final = ZCLAttributeDef(
            id=0x0022, type=t.uint8_t, access="r"
        )
        primary5_x: Final = ZCLAttributeDef(id=0x0024, type=t.uint16_t, access="r")
        primary5_y: Final = ZCLAttributeDef(id=0x0025, type=t.uint16_t, access="r")
        primary5_intensity: Final = ZCLAttributeDef(
            id=0x0026, type=t.uint8_t, access="r"
        )
        primary6_x: Final = ZCLAttributeDef(id=0x0028, type=t.uint16_t, access="r")
        primary6_y: Final = ZCLAttributeDef(id=0x0029, type=t.uint16_t, access="r")
        primary6_intensity: Final = ZCLAttributeDef(
            id=0x002A, type=t.uint8_t, access="r"
        )
        # Defined Color Point Settings
        white_point_x: Final = ZCLAttributeDef(id=0x0030, type=t.uint16_t, access="r")
        white_point_y: Final = ZCLAttributeDef(id=0x0031, type=t.uint16_t, access="r")
        color_point_r_x: Final = ZCLAttributeDef(id=0x0032, type=t.uint16_t, access="r")
        color_point_r_y: Final = ZCLAttributeDef(id=0x0033, type=t.uint16_t, access="r")
        color_point_r_intensity: Final = ZCLAttributeDef(
            id=0x0034, type=t.uint8_t, access="r"
        )
        color_point_g_x: Final = ZCLAttributeDef(id=0x0036, type=t.uint16_t, access="r")
        color_point_g_y: Final = ZCLAttributeDef(id=0x0037, type=t.uint16_t, access="r")
        color_point_g_intensity: Final = ZCLAttributeDef(
            id=0x0038, type=t.uint8_t, access="r"
        )
        color_point_b_x: Final = ZCLAttributeDef(id=0x003A, type=t.uint16_t, access="r")
        color_point_b_y: Final = ZCLAttributeDef(id=0x003B, type=t.uint16_t, access="r")
        color_point_b_intensity: Final = ZCLAttributeDef(
            id=0x003C, type=t.uint8_t, access="r"
        )
        # ...
        enhanced_current_hue: Final = ZCLAttributeDef(
            id=0x4000, type=t.uint16_t, access="rs"
        )
        enhanced_color_mode: Final = ZCLAttributeDef(
            id=0x4001, type=EnhancedColorMode, access="r", mandatory=True
        )
        color_loop_active: Final = ZCLAttributeDef(
            id=0x4002, type=t.uint8_t, access="rs"
        )
        color_loop_direction: Final = ZCLAttributeDef(
            id=0x4003, type=t.uint8_t, access="rs"
        )
        color_loop_time: Final = ZCLAttributeDef(
            id=0x4004, type=t.uint16_t, access="rs"
        )
        color_loop_start_enhanced_hue: Final = ZCLAttributeDef(
            id=0x4005, type=t.uint16_t, access="r"
        )
        color_loop_stored_enhanced_hue: Final = ZCLAttributeDef(
            id=0x4006, type=t.uint16_t, access="r"
        )
        color_capabilities: Final = ZCLAttributeDef(
            id=0x400A, type=ColorCapabilities, access="r", mandatory=True
        )
        color_temp_physical_min: Final = ZCLAttributeDef(
            id=0x400B, type=t.uint16_t, access="r"
        )
        color_temp_physical_max: Final = ZCLAttributeDef(
            id=0x400C, type=t.uint16_t, access="r"
        )
        couple_color_temp_to_level_min: Final = ZCLAttributeDef(
            id=0x400D, type=t.uint16_t, access="r"
        )
        start_up_color_temperature: Final = ZCLAttributeDef(
            id=0x4010, type=t.uint16_t, access="rw"
        )
        cluster_revision: Final = foundation.ZCL_CLUSTER_REVISION_ATTR
        reporting_status: Final = foundation.ZCL_REPORTING_STATUS_ATTR

    class ServerCommandDefs(BaseCommandDefs):
        move_to_hue: Final = ZCLCommandDef(
            id=0x00,
            schema={
                "hue": t.uint8_t,
                "direction": Direction,
                "transition_time": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        move_hue: Final = ZCLCommandDef(
            id=0x01,
            schema={
                "move_mode": MoveMode,
                "rate": t.uint8_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        step_hue: Final = ZCLCommandDef(
            id=0x02,
            schema={
                "step_mode": StepMode,
                "step_size": t.uint8_t,
                "transition_time": t.uint8_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        move_to_saturation: Final = ZCLCommandDef(
            id=0x03,
            schema={
                "saturation": t.uint8_t,
                "transition_time": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        move_saturation: Final = ZCLCommandDef(
            id=0x04,
            schema={
                "move_mode": MoveMode,
                "rate": t.uint8_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        step_saturation: Final = ZCLCommandDef(
            id=0x05,
            schema={
                "step_mode": StepMode,
                "step_size": t.uint8_t,
                "transition_time": t.uint8_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        move_to_hue_and_saturation: Final = ZCLCommandDef(
            id=0x06,
            schema={
                "hue": t.uint8_t,
                "saturation": t.uint8_t,
                "transition_time": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        move_to_color: Final = ZCLCommandDef(
            id=0x07,
            schema={
                "color_x": t.uint16_t,
                "color_y": t.uint16_t,
                "transition_time": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        move_color: Final = ZCLCommandDef(
            id=0x08,
            schema={
                "rate_x": t.uint16_t,
                "rate_y": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        step_color: Final = ZCLCommandDef(
            id=0x09,
            schema={
                "step_x": t.uint16_t,
                "step_y": t.uint16_t,
                "duration": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        move_to_color_temp: Final = ZCLCommandDef(
            id=0x0A,
            schema={
                "color_temp_mireds": t.uint16_t,
                "transition_time": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        enhanced_move_to_hue: Final = ZCLCommandDef(
            id=0x40,
            schema={
                "enhanced_hue": t.uint16_t,
                "direction": Direction,
                "transition_time": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        enhanced_move_hue: Final = ZCLCommandDef(
            id=0x41,
            schema={
                "move_mode": MoveMode,
                "rate": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        enhanced_step_hue: Final = ZCLCommandDef(
            id=0x42,
            schema={
                "step_mode": StepMode,
                "step_size": t.uint16_t,
                "transition_time": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        enhanced_move_to_hue_and_saturation: Final = ZCLCommandDef(
            id=0x43,
            schema={
                "enhanced_hue": t.uint16_t,
                "saturation": t.uint8_t,
                "transition_time": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        color_loop_set: Final = ZCLCommandDef(
            id=0x44,
            schema={
                "update_flags": ColorLoopUpdateFlags,
                "action": ColorLoopAction,
                "direction": ColorLoopDirection,
                "time": t.uint16_t,
                "start_hue": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        stop_move_step: Final = ZCLCommandDef(
            id=0x47,
            schema={
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        move_color_temp: Final = ZCLCommandDef(
            id=0x4B,
            schema={
                "move_mode": MoveMode,
                "rate": t.uint16_t,
                "color_temp_min_mireds": t.uint16_t,
                "color_temp_max_mireds": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )
        step_color_temp: Final = ZCLCommandDef(
            id=0x4C,
            schema={
                "step_mode": StepMode,
                "step_size": t.uint16_t,
                "transition_time": t.uint16_t,
                "color_temp_min_mireds": t.uint16_t,
                "color_temp_max_mireds": t.uint16_t,
                "options_mask?": t.bitmap8,
                "options_override?": t.bitmap8,
            },
            direction=False,
        )

class BallastStatus(t.bitmap8):
    Non_operational = 0b00000001
    Lamp_failure = 0b00000010

class LampAlarmMode(t.bitmap8):
    Lamp_burn_hours = 0b00000001

class Ballast(Cluster):
    """Attributes and commands for configuring a lighting
    ballast
    """

    BallastStatus: Final = BallastStatus
    LampAlarmMode: Final = LampAlarmMode

    cluster_id: Final = 0x0301
    ep_attribute: Final = "light_ballast"

    class AttributeDefs(BaseAttributeDefs):
        physical_min_level: Final = ZCLAttributeDef(
            id=0x0000, type=t.uint8_t, access="r", mandatory=True
        )
        physical_max_level: Final = ZCLAttributeDef(
            id=0x0001, type=t.uint8_t, access="r", mandatory=True
        )
        ballast_status: Final = ZCLAttributeDef(
            id=0x0002, type=BallastStatus, access="r"
        )
        # Ballast Settings
        min_level: Final = ZCLAttributeDef(
            id=0x0010, type=t.uint8_t, access="rw", mandatory=True
        )
        max_level: Final = ZCLAttributeDef(
            id=0x0011, type=t.uint8_t, access="rw", mandatory=True
        )
        power_on_level: Final = ZCLAttributeDef(id=0x0012, type=t.uint8_t, access="rw")
        power_on_fade_time: Final = ZCLAttributeDef(
            id=0x0013, type=t.uint16_t, access="rw"
        )
        intrinsic_ballast_factor: Final = ZCLAttributeDef(
            id=0x0014, type=t.uint8_t, access="rw"
        )
        ballast_factor_adjustment: Final = ZCLAttributeDef(
            id=0x0015, type=t.uint8_t, access="rw"
        )
        # Lamp Information
        lamp_quantity: Final = ZCLAttributeDef(id=0x0020, type=t.uint8_t, access="r")
        # Lamp Settings
        lamp_type: Final = ZCLAttributeDef(
            id=0x0030, type=t.LimitedCharString(16), access="rw"
        )
        lamp_manufacturer: Final = ZCLAttributeDef(
            id=0x0031, type=t.LimitedCharString(16), access="rw"
        )
        lamp_rated_hours: Final = ZCLAttributeDef(
            id=0x0032, type=t.uint24_t, access="rw"
        )
        lamp_burn_hours: Final = ZCLAttributeDef(
            id=0x0033, type=t.uint24_t, access="rw"
        )
        lamp_alarm_mode: Final = ZCLAttributeDef(
            id=0x0034, type=LampAlarmMode, access="rw"
        )
        lamp_burn_hours_trip_point: Final = ZCLAttributeDef(
            id=0x0035, type=t.uint24_t, access="rw"
        )
        cluster_revision: Final = foundation.ZCL_CLUSTER_REVISION_ATTR
        reporting_status: Final = foundation.ZCL_REPORTING_STATUS_ATTR


from django.core.management.base import BaseCommand
from shop.models import Host
from itertools import chain
from rest_framework.authtoken.models import Token

class Command(BaseCommand):
    """
    List the string of Host IDs and Tokens that will be needed in the environment variables of the Host
        Examples:
        # To get the Host IDs and Tokens under of one or more IPs (separated by comma)
        python3 manage.py get_host_ids_and_tokens --ips=192.88.99.10
        python3 manage.py get_host_ids_and_tokens --ips=192.88.99.10,123.45.67.89,82.158.0.2

        # To get ALL stored Host IDs and Tokens
        python3 manage.py get_host_ids_and_tokens
    """

    def add_arguments(self, parser):
        parser.add_argument("--ips", required=False)

    def handle(self, *args, **options):

        ips = options["ips"]
        suffix_text = ""

        registered_ip_list = list(Host.objects.values_list('ip', flat=True).distinct())
        self.stdout.write(f'==============================================================')
        self.stdout.write(f'Registered IPs: {registered_ip_list}')

        if not None == ips:
            ips_list = ips.split(',')
            # here we limit the list of registered_ip_list to the ones passed in the argument
            registered_ip_list = [x for x in registered_ip_list if x in ips_list]
            pass

        self.stdout.write(f'Processing these IPs: {registered_ip_list}')

        hosts_active = []
        hosts_all = []

        for ip in registered_ip_list:
            hosts_active = chain(hosts_active, Host.active.filter(ip=ip))
            hosts_all = chain(hosts_all, Host.objects.filter(ip=ip))

            host_active_string = ""
            for host in hosts_active:
                token = Token.objects.filter(user=host.token_user).first()
                host_active_string = host_active_string + str(host.id) + ',' + token.key + ':'

            host_all_string = ""
            for host in hosts_all:
                token = Token.objects.filter(user=host.token_user).first()
                host_all_string = host_all_string + str(host.id) + ',' + token.key + ':'

            self.stdout.write(f'--------------------------------------------------------------')
            self.stdout.write(f'IP ' + ip + ' - Host IDs and Token only for ACTIVE hosts:')
            self.stdout.write(host_active_string.strip(':'))
            self.stdout.write(f'IP ' + ip + ' - Host IDs and Token for ALL hosts:')
            self.stdout.write(host_all_string.strip(':'))

        self.stdout.write(f'==============================================================')

        return


from typing import Union

import torch

class ReplayBuffer:
    def __init__(self, state_dim: int, action_dim: int, max_size: int = int(1e6),
                 training_device: Union[str, torch.device] = "cpu", storage_device: Union[str, torch.device] = "cpu"):
        self.__max_size = max_size
        self.__ptr = 0
        self.__size = 0

        self.__training_device = training_device if isinstance(training_device, torch.device) else torch.device(
            training_device)
        self.__storage_device = storage_device if isinstance(storage_device, torch.device) else torch.device(
            storage_device)

        self.__state = torch.zeros((max_size, state_dim), device=self.__storage_device)
        self.__action = torch.zeros((max_size, action_dim), device=self.__storage_device)
        self.__next_state = torch.zeros((max_size, state_dim), device=self.__storage_device)
        self.__reward = torch.zeros((max_size, 1), device=self.__storage_device)
        self.__not_done = torch.zeros((max_size, 1), device=self.__storage_device)

    def add(self, state: torch.Tensor, action: torch.Tensor, next_state: torch.Tensor, reward: torch.Tensor,
            done: torch.Tensor):
        self.__state[self.__ptr] = state.to(self.__storage_device)
        self.__action[self.__ptr] = action.to(self.__storage_device)
        self.__next_state[self.__ptr] = next_state.to(self.__storage_device)
        self.__reward[self.__ptr] = reward.to(self.__storage_device)
        self.__not_done[self.__ptr] = torch.logical_not(done).to(self.__storage_device)

        self.__ptr = (self.__ptr + 1) % self.__max_size
        self.__size = min(self.__size + 1, self.__max_size)

    def sample(self, batch_size: int):
        idx = torch.randint(low=0, high=self.__size, device=self.__storage_device, size=(batch_size, ))

        return (
            torch.FloatTensor(self.__state[idx]).to(self.__training_device),
            torch.FloatTensor(self.__action[idx]).to(self.__training_device),
            torch.FloatTensor(self.__next_state[idx]).to(self.__training_device),
            torch.FloatTensor(self.__reward[idx]).to(self.__training_device),
            torch.FloatTensor(self.__not_done[idx]).to(self.__training_device)
        )

    @property
    def size(self) -> int:
        return self.__size


import numpy
import math
from PIL import Image

import matplotlib.pyplot as plt
import matplotlib.patches as patches

def ck(x,y):
    i=x;
    j=y;
    sum=0.0

    for a in range (0,gm.size[0]):
        for b in range (0,gm.size[1]):
            #0.2989, 0.5870, 0.1140.
            p=rr[a][b]
            q=tt[i][j]
            sum=sum+(p-q)*(p-q)
            j=j+1

        i=i+1
        j=y
    return sum

im = Image.open('test.jpg') # Can be many different formats.
test = im.load()

gm = Image.open('ref.jpg') # Can be many different formats.
ref = gm.load()
#print (im.size[0] )
#print pix[x,y]
ans_pixel=numpy.zeros(3, dtype=int)
ans_val=-1
tt=numpy.ones((im.size[0],im.size[1]))
rr=numpy.ones((gm.size[0],gm.size[1]))

for i in range(0,im.size[0]):
    for j in range(0, im.size[1]):
        tt[i][j]=.2989*test[i,j][0]+.5870*test[i,j][1]+.1140*test[i,j][2]

for i in range(0,gm.size[0]):
    for j in range(0, gm.size[1]):
        rr[i][j]=.2989*ref[i, j][0]+.5870*ref[i,j][1]+.1140*ref[i,j][2]

for i in range (0,im.size[0]-(gm.size[0]-1)):
    for j in range (0,im.size[1]-(gm.size[1]-1)):
        temp=ck(i , j)
        #print(i,j)
        if ans_val==-1:
            ans_val=temp
            ans_pixel[0]=i;
            ans_pixel[1]=j;
        elif ans_val>temp:
            ans_val = temp
            ans_pixel[0] = i;
            ans_pixel[1] = j;

im = numpy.array(Image.open('test.png'), dtype=numpy.uint8)
fig,ax = plt.subplots(1)
ax.imshow(im)
rect = patches.Rectangle((ans_pixel[0],ans_pixel[1]),gm.size[0],gm.size[1],linewidth=1,edgecolor='r',facecolor='none')

ax.add_patch(rect)

plt.show()

print(ans_pixel)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Sep 30 11:53:43 2020

@author: zzhajun
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.spatial.distance import cdist
from sklearn.metrics import make_scorer, roc_curve
from scipy.optimize import brentq
from scipy.interpolate import interp1d

#Problem 1.a
train=pd.read_csv("train.csv")
x_test_image=pd.read_csv("test.csv")

#Problem 1.b
x_train_image=train.drop('label',axis=1)#dataframe with index
y_train_label=train.label

X_train=x_train_image.values.reshape(42000,28,28).astype('float32')
X_test=x_test_image.values.reshape(28000,28,28).astype('float32')

x_train_data = np.array(x_train_image)#array 42000*784

images=[]
labels=[]
num=[1,0,16,7,3,8,21,6,10,11]
for i in range(10):
    images.append(X_train[num[i]])
    labels.append(y_train_label[num[i]])

def plot_images_labels(images,labels,idx,num=10):
    fig=plt.gcf()
    fig.set_size_inches(12,14)
    for i in range(0,10):
        ax=plt.subplot(5,5,i+1)
        ax.imshow(images[idx],cmap='binary')
        title='label='+str(labels[idx])

        ax.set_title(title,fontsize=10)
        ax.set_xticks([]);ax.set_yticks([])
        idx+=1
    plt.show()

plot_images_labels(images,labels,idx=0)

#Problem 1.c
count=np.zeros((10,), dtype=np.int)
prob=np.zeros((10,))
for i in range(len(y_train_label)):
    for j in range(10):
        if y_train_label[i]==j:
            count[j]+=1
print(count)

for i in range(10):
    prob[i]=count[i]/42000
    print(prob[i])
plt.hist(x = y_train_label, density=True, bins = 10, color = 'steelblue', edgecolor = 'black' )

plt.xlabel('number')
plt.ylabel('probability')
plt.title('prior probability')
plt.show()

#Problem 1d
a=0
dist=[10000,10000,10000,10000,10000,10000,10000,10000,10000,10000]
match=np.zeros(10)
for i in range(10):
    for j in range(42000):
        if j!=num[i]:
            a=np.linalg.norm(images[i]-X_train[j])
            if dist[i]>a:
                dist[i]=a
                match[i]=y_train_label[j]

print(dist)
print(match)

#Problem 1.e
num0=[]
image0=[]
total0=0
num1=[]
image1=[]
total1=0
for i in range(42000):
    if y_train_label[i]==0:
        num0.append(y_train_label[i])
        image0.append(x_train_data[i])
        total0+=1
    elif y_train_label[i]==1:
        num1.append(y_train_label[i])
        image1.append(x_train_data[i])
        total1+=1
#print(total0,total1)
dist00=cdist(image0,image0,'euclidean')
dist11=cdist(image1,image1,'euclidean')
dist01=cdist(image0,image1,'euclidean')

dist00=dist00.reshape(1,4132*4132)
dist11=dist11.reshape(1,4684*4684)
dist01=dist01.reshape(1,4132*4684)

dist00=np.array(dist00)
dist00=dist00.tolist()

dist11=np.array(dist11)
dist11=dist11.tolist()

dist01=np.array(dist01)
dist01=dist01.tolist()

dist_genu=dist00[0]+dist11[0]
dist_impo=dist01[0]+dist01[0]

sns.distplot(dist_genu, bins = 100, kde = False, hist_kws = {'color':'steelblue'}, label = 'genuine')
sns.distplot(dist_impo, bins = 100, kde = False, hist_kws = {'color':'purple'}, label = 'impostor')
plt.title('distance')
plt.legend()
plt.show()

#Problem 1.f

genu_min=min(dist_genu)
genu_max=max(dist_genu)
impo_min=min(dist_impo)
impo_max=max(dist_impo)
dist_max=max(genu_max,impo_max)
distmax=[]
distmax.append(dist_max)
print(dist_max)#max distance

inter=60
count_tp=np.zeros(60)
count_fp=np.zeros(60)

#TPR
for j in range(60):
    for i in range(39013280):
        if dist_genu[i]<distmax[0]-inter*j:
            count_tp[j]+=1
count_tp=count_tp/ 39013280

#FPr
for j in range(60):
    for i in range(38708576):
        if dist_impo[i]<distmax[0]-inter*j:
            count_fp[j]+=1
count_fp=count_fp/ 38708576
e=0.001
for i in range(60):
    if (abs(count_tp[i]+count_fp[i]-1)<e):
        print('ERR=',count_tp[i])

plt.plot(count_fp,count_tp,label='ROC')
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.legend()
plt.show()


# -*- encoding=utf-8 -*-

import sys

args = sys.argv[1:]

if len(args)>=2 :
  width =int(args[0])
  height=int(args[1])
  if width <640 :
      width=640
  if width >7680:
      width=7680
  if height<480:
      height=480
  if height>4320:
      height=4320
else:
  width  = 1200
  height =  720

g_topic_h =20
g_char_h  =17
g_scr_h   =17
g_bt_h    =20

g_lines= int((height -g_topic_h -g_scr_h -g_bt_h)/g_char_h -1 +0.5)

g_char_w=15
g_tr_w  = int(width/g_char_w +0.5)
g_probar2_w= int(200/g_char_w +0.5)

g_pbar1=1.0             # 16  minutes
g_pbar2=g_pbar1*0.7     # 32  minutes
g_pbar3=g_pbar2*0.49    # 64  minutes
g_pbar4=g_pbar3*0.343   # 128 minutes

g_bt_init=0
g_bt_step=0
g_bt_y1=0
g_bt_y2=0
g_bt_y3=0
g_bt_adj=0

g_bt_y1=height

import os
import time
import pygame
from tkinter   import *
from tkinter   import ttk
from tkinter   import messagebox
from threading import Thread

global mainw

mainw = Tk()

mainw.title('Purpose Player 4')
mainw.geometry('{}x{}+{}+{}'.format(width, height, 0, 0))

mainw.grid_rowconfigure(0, weight=1)
mainw.grid_columnconfigure(2, weight=1)

columns = ['Type', 'Size', 'Date' ]

global tr

scr1=Scrollbar(mainw,orient='vertical')

tr = ttk.Treeview(
           mainw,
           height=g_lines,
           columns=columns,
           show='tree headings',
           selectmode='browse',
           yscrollcommand=scr1.set,
                 )

s = ttk.Style()
s.configure('Treeview', rowheight=17)

tr.heading('#0'  , text='Name')
tr.heading('Type', text='Type')
tr.heading('Size', text='Size')
tr.heading('Date', text='Date')

tr.column('#0'  , width=width-60-70-160-12)
tr.column('Type', width= 60,minwidth=60 ,stretch=0)
tr.column('Size', width= 70,minwidth=70 ,stretch=0)
tr.column('Date', width=160,minwidth=160,stretch=0)

scr1['command']=tr.yview

tr.grid(row=0,rowspan=g_lines+1,column=0,columnspan=g_tr_w,sticky='nsew')

scr1.grid(row=0,rowspan=g_lines+1,column=g_tr_w,sticky='nsew')

#global img1
#global img2
#global img3
#global img4

#img1=PhotoImage(file='./i1.png')
#img2=PhotoImage(file='./i2.png')
#img3=PhotoImage(file='./i3.png')
#img4=PhotoImage(file='./i4.png')

info = [ '', '', '',]

global rf1,rf2,rf3,rf4,rf5,rf6,rf7,rf8,rf9,rf10,rf11

rf1 =tr.insert('', END, text='</>'  , open=False, values=info )
rf2 =tr.insert('', END, text='<C:/>', open=False, values=info )
rf3 =tr.insert('', END, text='<D:/>', open=False, values=info )
rf4 =tr.insert('', END, text='<E:/>', open=False, values=info )
rf5 =tr.insert('', END, text='<F:/>', open=False, values=info )
rf6 =tr.insert('', END, text='<G:/>', open=False, values=info )
rf7 =tr.insert('', END, text='<H:/>', open=False, values=info )
rf8 =tr.insert('', END, text='<I:/>', open=False, values=info )
rf9 =tr.insert('', END, text='<J:/>', open=False, values=info )
rf10=tr.insert('', END, text='<K:/>', open=False, values=info )
rf11=tr.insert('', END, text='<L:/>', open=False, values=info )

global mu_play,mu_load,mu_pause,mu_pos,item_id0,item_cur,item_notclose,item_close

mu_play=0
mu_load=0
mu_pause=0
mu_pos=0
item_id0=''
item_cur=''
item_notclose=0
item_close=0

probar1 = ttk.Progressbar(mainw, orient=HORIZONTAL, length=width-200-20, mode='indeterminate')
probar1['maximum'] = 10000
probar1['value'] = 0
probar1.grid(row=g_lines+2,column=0,columnspan=g_tr_w-g_probar2_w-1,sticky='nsew')

probar2 = ttk.Progressbar(mainw, orient=HORIZONTAL, length=200, mode='indeterminate')
probar2['maximum'] = 100
probar2['value'] = 100
probar2.grid(row=g_lines+2,column=g_tr_w-g_probar2_w,columnspan=g_probar2_w,sticky='nsew')

global bt3

def bt1Click():
    global mu_pos

    if pygame.mixer.music.get_busy() :
        ps=pygame.mixer.music.get_pos()
        #print(int(ps/1000))
        ps1=mu_pos+ps/1000-30
        if ps1<0:
            ps1=0
        #print(ps1)
        #pygame.mixer.music.rewind()
        #pygame.mixer.music.set_pos(ps1)
        pygame.mixer.music.play(0,ps1)
        mu_pos=ps1
    return

def bt2Click():
    global mu_pos

    if pygame.mixer.music.get_busy() :
        ps=pygame.mixer.music.get_pos()
        #print(int(ps/1000))
        ps1=mu_pos+ps/1000+30
        #print(ps1)
        #pygame.mixer.music.rewind()
        #pygame.mixer.music.set_pos(ps1)
        pygame.mixer.music.play(0,ps1)
        mu_pos=ps1
    return

def bt3Click():

    global mu_play,mu_load,mu_pause

    if mu_load==1:
        if mu_play==1:
            mu_pause=1
            pygame.mixer.music.pause()
            mu_play=0
            bt3['text']='Play'
        else:
            pygame.mixer.music.unpause()
            mu_play=1
            mu_pause=0
            bt3['text']='Pause'

def bt4Click():

    vl=probar2['value']
    if vl<2 :
      vl=2
    vl2=vl*0.85
    if vl2<0  :
        vl2=0
    if vl2>100:
        vl2=100
    probar2['value'] = vl2
    pygame.mixer.music.set_volume(vl2/100)
    mainw.update()

    return

def bt5Click():

    vl=probar2['value']
    if vl<2 :
      vl=2
    vl2=vl*1.18
    if vl2<0  :
        vl2=0
    if vl2>100:
        vl2=100
    probar2['value'] = vl2
    pygame.mixer.music.set_volume(vl2/100)
    mainw.update()

    return

bt1=Button(mainw,height=1,width=1,text='-',command=bt1Click)
bt1.grid(row=g_lines+3,column=0)

lb1 = Label(mainw, height=1, width=18, text="00:00:00/00:00:00")
lb1.grid(row=g_lines+3,column=1)

bt2=Button(mainw,height=1,width=1,text='+',command=bt2Click)

bt3=Button(mainw,height=1,width=14,text='Play',command=bt3Click)
#bt3.grid(row=g_lines+3,column=37)

bt4=Button(mainw,height=1,width=1,text='-',command=bt4Click)

lb2 =Label(mainw, height=1, width=6, text="Volume")
#lb2.grid(row=g_lines+3,column=g_tr_w-1)

bt5=Button(mainw,height=1,width=1,text='+',command=bt5Click)

def file_size_format(size_n1):

  i=0
  f1=0.0

  if size_n1<0 or size_n1>=100000:
      size_str2="****"
  elif size_n1>=10000 and size_n1<100000:
      i=int(size_n1/100);
      size_str2=str(i)
  elif size_n1>=1000 and size_n1<10000:
      i=int(size_n1/10);
      f1=i/10;
      size_str2=str(f1)
  elif size_n1<1000:
      f1=size_n1/100;
      size_str2=str(f1)

  #print('1-',size_str2)

  if len(size_str2)>4:
    size_str2=size_str2[0:3]
  #elif len(size_str2)<4:
  #  size_str2="    "

  #print('2-',size_str2)

  return size_str2

def trClick(event):

    global mu_play,mu_load,mu_pause,item_id0,item_cur,item_notclose,item_close,mainw,tr

    if item_close==1: #click [-]
      item_close=0

      if len(item_cur)>0:
          err=0

          try:
            text =tr.item(item_cur,'text')
          except:
            item_cur=''
            err=1

          if err==0:
            ol=[item_cur,]
            tr.selection_set(ol)

      print('close return')
      return

    if item_notclose==1: #click [+]
      #item_notclose=0

      print('open proccess')

    #print('focus'    ,tr.focus())
    #print('selection',tr.selection())

    item_dir  =''
    item_id0  =tr.selection()
    item_id1  =item_id0
    item_text =tr.item(item_id1,'text')

    if len(item_text)==0:
        return

    if item_text[0]=='<':
      item_text2=item_text.split('<',1)
      item_text3=item_text2[1]
      item_text4=item_text3.split('>',1)
      item_text5=item_text4[0]
    elif item_text[0]=='|':
      return
    else:
      item_text5=item_text

    item_dir=item_text5

    while 1:
      item_id2  =tr.parent(item_id1)

      if len(item_id2)==0:
        #item_text5=item_dir
        break

      item_text=tr.item(item_id2,'text')

      item_text2=item_text.split('<',1)
      item_text3=item_text2[1]
      item_text4=item_text3.split('>',1)
      item_text5=item_text4[0].upper()

      if item_text4[0]=='/':
        item_dir=item_text4[0]+item_dir
        break
      elif len(item_text5)>=2:
        if item_text5[0]>='C' and item_text5[0]<='Z' and item_text5[1]==':':
          item_dir=item_text5+item_dir
          break
        else:
          item_dir=item_text4[0]+'/'+item_dir
          item_id1=item_id2
      else:
        item_dir=item_text4[0]+'/'+item_dir
        item_id1=item_id2

    driver=0
    if len(item_dir)==3:
        if item_dir[0]>='C' and item_dir[0]<='Z' and item_dir[1]==':' :
            driver=1

    if os.path.isdir(item_dir) or driver==1 :
        print(item_dir,driver)

        item_empt=1
        chld=tr.get_children(item_id0)
        item_open=tr.item(item_id0,'open')

        #print('item_open=',item_open)

        if item_open==False or item_notclose==1 :

          for o in chld:
              tr.delete(o)

          dirs=[]
          try:
              dirs = os.listdir(item_dir)
              dirs.sort()
              dir_ok=1
          except:
              dir_ok=0

          if dir_ok==1:
            for files in dirs:

              info2= ['', '', '',]
              if os.path.isdir(item_dir+'/'+files):
                  item_empt=0
                  tr.insert(item_id0, END, text='<'+files+'>', open=False)

          dirs=[]
          try:
              dirs = os.listdir(item_dir)
              dirs.sort()
              dir_ok=1
          except:
              dir_ok=0

          if dir_ok==1:
            for files in dirs:

              if os.path.isfile(item_dir+'/'+files):
                item_empt=0
                ext=files.split('.',-1)

                if len(ext[-1])>5:
                    ext[-1]=''

                file_info=os.lstat(item_dir+'/'+files)
                if file_info.st_size>=1000000000000000:
                  size_str1=''
                  size_str2='****'
                elif file_info.st_size>=1000000000000 and file_info.st_size<1000000000000000:
                  size_str1='TB'
                  size_n1  =int(file_info.st_size/10000000000)
                  size_str2=file_size_format(size_n1)
                elif file_info.st_size>=1000000000 and file_info.st_size<1000000000000:
                  size_str1='GB'
                  size_n1  =int(file_info.st_size/10000000)
                  size_str2=file_size_format(size_n1)
                elif file_info.st_size>=1000000 and file_info.st_size<1000000000:
                  size_str1='MB'
                  size_n1  =int(file_info.st_size/10000)
                  size_str2=file_size_format(size_n1)
                elif file_info.st_size>=1000 and file_info.st_size<1000000:
                  size_str1='KB'
                  size_n1  =int(file_info.st_size/10)
                  size_str2=file_size_format(size_n1)
                elif file_info.st_size<1000:
                  size_str1='B '
                  size_str2=str(file_info.st_size)

                mtime = file_info.st_mtime
                file_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(mtime))

                info2= [ext[-1], size_str2+size_str1, file_time,]

                tr.insert(item_id0, END, text=files, open=True, values=info2 )

          if item_empt==1:
              tr.insert(item_id0, END, text='|'+'Empty Fold'+'|', open=True)

          item_notclose=0;

          tr.item(item_id0,open=True)

        else:

          tr.item(item_id0,open=False)

        if len(item_cur)>0:
          err=0

          try:
            text =tr.item(item_cur,'text')
          except:
            item_cur=''
            err=1

          if err==0:
            ol=[item_cur,]
            tr.selection_set(ol)

    else:
        event = pygame.event.Event(pygame.USEREVENT+2)
        pygame.event.post(event)

def trItemOpen(p):
  global item_notclose
  print('open')
  item_notclose=1

def trItemClose(p):
  global item_close
  print('close')
  item_close=1

def mpNext():

  global mu_load,mu_play,mu_pause,mu_pos,item_id0,item_cur,mainw,tr,bt3

  chld=[]
  id0=[]
  stop=0
  end=0
  next=0

  while 1:
    event = pygame.event.wait()

    print('event.type',event.type,'pg.User1',pygame.USEREVENT+1)

    if event.type == pygame.QUIT:
        return

    if event.type == pygame.USEREVENT+2 : #start to play

      id0=item_id0
      stop=0

      if pygame.mixer.music.get_busy() or mu_pause==1 :
        pygame.mixer.music.stop()

        bt3['text']='Play'     #dead lock
        mu_load=0
        mu_play=0
        stop=1

      item_id1  =tr.parent(id0)

      chld=tr.get_children(item_id1)
      step=0
      nextsong=''
      end=1

      for o in chld:

        next=0

        if step==0:
            for o2 in id0:
                if o==o2:
                    step=1
                    end =0

        if step==1:
            mydir   =''
            item_cur=o
            o3      =o

            try:
                item_text =tr.item(o3,'text')
            except:
                break

            if len(item_text)==0:
                break

            if item_text[0]=='<':
              item_text2=item_text.split('<',1)
              item_text3=item_text2[1]
              item_text4=item_text3.split('>',1)
              mydir=item_text4[0]
              break
            elif item_text[0]=='|':
              mydir=item_text
              break
            else:
              mydir=item_text

            while 1:
              item_id2  =tr.parent(o3)

              if len(item_id2)==0:
                  item_text5=mydir
                  break

              item_text=tr.item(item_id2,'text')

              item_text2=item_text.split('<',1)
              item_text3=item_text2[1]
              item_text4=item_text3.split('>',1)
              item_text5=item_text4[0].upper()

              if item_text4[0]=='/':
                  mydir=item_text4[0]+mydir
                  break
              elif len(item_text5)>=2:
                  if item_text5[0]>='C' and item_text5[0]<='Z' and item_text5[1]==':':
                    mydir=item_text5+mydir
                    break
                  else:
                    mydir=item_text4[0]+'/'+mydir
                    o3=item_id2
              else:
                  mydir=item_text4[0]+'/'+mydir
                  o3=item_id2

            print('mydir',mydir)

            item_dir2=mydir.split('.',-1)
            item_dir2[-1]=item_dir2[-1].lower()
            if item_dir2[-1]=='mp3':

                try:
                    pygame.mixer.init()
                    pygame.mixer.music.load(mydir)
                    pygame.mixer.music.play()
                except:
                    end=1
                    print('break1')
                    break;

                bt3['text']='Pause'
                mu_load=1
                mu_play=1
                mu_pos =0
                end=0

                ol=[o,]
                tr.selection_set(ol)

                mainw.title(mydir)

                pygame.mixer.music.set_endevent(pygame.USEREVENT + 1)

                #vl=pygame.mixer.music.get_volume()
                #vl2=vl*100
                #probar2['value'] = vl2
                #mainw.update()

                step=2
                print('continue2')
                continue
            else:
                end=1
                print('break3')
                break

        if step==2:
            nextsong=o #calculate next song
            next=1
            print('break4')
            break

    if event.type == pygame.USEREVENT+1: #auto next

      if stop==1:
        stop=0
        continue

      if pygame.mixer.music.get_busy() or mu_pause==1 :
        pygame.mixer.music.stop()

        bt3['text']='Play'     #dead lock
        mu_load=0
        mu_play=0
        stop=1

      step=0
      id0=[nextsong,]
      nextsong=''
      end=1

      for o in chld:

        next=0

        if step==0:
            for o2 in id0:
                if o==o2:
                    step=1
                    end =0

        if step==1:
            mydir   =''
            item_cur=o
            o3      =o

            try:
                item_text =tr.item(o3,'text')
            except:
                break

            if len(item_text)==0:
                break

            if item_text[0]=='<':
              item_text2=item_text.split('<',1)
              item_text3=item_text2[1]
              item_text4=item_text3.split('>',1)
              mydir=item_text4[0]
            elif item_text[0]=='|':
              mydir=item_text
              break
            else:
              mydir=item_text

            while 1:
              item_id2  =tr.parent(o3)

              if len(item_id2)==0:
                  item_text5=mydir
                  break

              item_text=tr.item(item_id2,'text')

              item_text2=item_text.split('<',1)
              item_text3=item_text2[1]
              item_text4=item_text3.split('>',1)
              item_text5=item_text4[0].upper()

              if item_text4[0]=='/':
                  mydir=item_text4[0]+mydir
                  break
              elif len(item_text5)>=2:
                  if item_text5[0]>='C' and item_text5[0]<='Z' and item_text5[1]==':':
                    mydir=item_text5+mydir
                    break
                  else:
                    mydir=item_text4[0]+'/'+mydir
                    o3=item_id2
              else:
                  mydir=item_text4[0]+'/'+mydir
                  o3=item_id2

            item_dir2=mydir.split('.',-1)
            item_dir2[-1]=item_dir2[-1].lower()
            if item_dir2[-1]=='mp3':

                try:
                    pygame.mixer.init()
                    pygame.mixer.music.load(mydir)
                    pygame.mixer.music.play()
                except:
                    end=1
                    print('break1')
                    break;

                bt3['text']='Pause'
                mu_load=1
                mu_play=1
                mu_pos =0
                end=0

                ol=[o,]
                tr.selection_set(ol)

                mainw.title(mydir)

                pygame.mixer.music.set_endevent(pygame.USEREVENT + 1)

                #vl=pygame.mixer.music.get_volume()
                #vl2=vl*100
                #probar2['value'] = vl2
                #mainw.update()

                step=2
                print('continue2')
                continue
            else:
                end=1
                print('break3')
                break

        if step==2:
            nextsong=o  #calculate next song
            next=1
            print('break4')
            break

    if event.type == pygame.USEREVENT+3 : #display position

      if pygame.mixer.music.get_busy() :
        ps=mu_pos*1000+pygame.mixer.music.get_pos()
        ps1=int(ps/1000)
        ps2=int(ps1/3600)
        ps3=int((ps1-ps2*3600)/60)
        ps4=int(ps1-ps2*3600-ps3*60)

        s1=str(int(ps2))
        if len(s1)==1:
          s1='0'+s1
        s2=str(int(ps3))
        if len(s2)==1:
          s2='0'+s2
        s3=str(int(ps4))
        if len(s3)==1:
          s3='0'+s3

        ps5=s1+':'+s2+':'+s3+'/00:00:00'
        print('pos=',ps5)
        lb1.config(text=ps5)

        #position seek bar
        if ps1<16*60 : # <16minues
            po1=(((ps1/(16*60))*g_pbar1)/(g_pbar1+g_pbar2+g_pbar3+g_pbar4))*10000
        elif ps1<32*60 : # <32minutes
            po1=((g_pbar1+((ps1-16*60)/(16*60))*g_pbar2)/(g_pbar1+g_pbar2+g_pbar3+g_pbar4))*10000
        elif ps1<64*60 : # <64minutes
            po1=((g_pbar1+g_pbar2+((ps1-32*60)/(32*60))*g_pbar3)/(g_pbar1+g_pbar2+g_pbar3+g_pbar4))*10000
        elif ps1<128*60 : # <128minutes
            po1=((g_pbar1+g_pbar2+g_pbar3+((ps1-64*60)/(64*60))*g_pbar4)/(g_pbar1+g_pbar2+g_pbar3+g_pbar4))*10000
        else :
            po1=10000

        if po1<0 :
            po1=0
        if po1>10000 :
            po1=10000

        probar1['value'] = po1
        mainw.update()

    if end==1 :
        bt3['text']='Play'     #dead lock
        mu_load=0
        mu_play=0
        end=0

def mainwClose():

    global mainw

    event = pygame.event.Event(pygame.QUIT)
    pygame.event.post(event)

    mainw.destroy()

def winResize(e):

    global mainw,bt3,g_bt_init,g_bt_step,g_bt_y1,g_bt_y2,g_bt_y3,g_bt_adj

    #print(e)

    width =e.width
    height=e.height

    #print("size",width,height)

    if e.x==0 and e.y==0 :

        if g_bt_init==0 :
            if g_bt_step==1 :
                g_bt_y2=height
            elif g_bt_step==2 :
                g_bt_y3=height

            g_bt_step=g_bt_step+1

            if g_bt_step>=3 :
                g_bt_init=1

                n1=g_bt_y2-g_bt_y3
                if n1>50 :      #its Windows
                    g_bt_adj=3
                else :          #its Ubuntu
                    g_bt_adj=0

        #print('y1=',g_bt_y1,'y2=',g_bt_y2,'y3=',g_bt_y3)

        if width>=112 and height>=18 :
            #btx=18*8
            #bty=height+19+g_bt_adj
            #bt1.place(x=btx,y=bty)

            btx=23*8
            bty=height+19+g_bt_adj
            bt2.place(x=btx,y=bty)

            btx=int(width/2)-7*8
            bty=height+19+g_bt_adj
            bt3.place(x=btx,y=bty)

            btx=width-25*8
            bty=height+19+g_bt_adj
            bt4.place(x=btx,y=bty)

            btx=width-4*8-3
            bty=height+19+g_bt_adj
            bt5.place(x=btx,y=bty)

            #btx=2*8
            #bty=height+19+g_bt_adj
            #lb1.place(x=btx,y=bty)

            btx=width-15*8
            bty=height+19+g_bt_adj+5
            lb2.place(x=btx,y=bty)

mainw.protocol("WM_DELETE_WINDOW", mainwClose)
mainw.bind('<Configure>', winResize)

tr.bind('<ButtonRelease-1>',trClick)
tr.bind('<<TreeviewOpen>>', trItemOpen)
tr.bind('<<TreeviewClose>>',trItemClose)

pygame.init()
pygame.mixer.music.set_volume(1.0)
pygame.time.set_timer(pygame.USEREVENT+3,500)

thr=Thread(target=mpNext)
thr.start()

mainw.mainloop()