import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import uic
from Kiwoom import *
import time
#ui에 연결
form_class = uic.loadUiType("pytrader.ui")[0]

class MyWindow(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.trade_stocks_done = False
        #키움에 연결
        self.kiwoom = Kiwoom()
        self.kiwoom.comm_connect()
        # 현시간 확인
        self.timer = QTimer(self)
        self.timer.start(1000)
        self.timer.timeout.connect(self.timeout)
        #타이머 2 10초후 연결
        self.timer2 = QTimer(self)
        self.timer2.start(1000 *10)
        self.timer2.timeout.connect(self.timeout2)
        #계좌정보 얻기 (지금은 모의계좌)
        accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT"))
        accounts = self.kiwoom.get_login_info("ACCNO")
        #계좌번호는 ;로 분리되어있어서 ; 기준으로 분류해서 저장
        accounts_list = accounts.split(';')[0:accouns_num]
        self.w_account.addItems(accounts_list)
        #연결 사실 잘 모르겠음 아마 접속하는 버튼 누르는거임
        self.w_event_code.textChanged.connect(self.code_changed)
        self.w_orderbutton.clicked.connect(self.send_order)
        self.w_lookup.clicked.connect(self.check_balance)

        self.load_buy_sell_list()
    # 파일 buy리스트와 sell리스트를 들고와서 변수에 값 저장
    def trade_stocks(self):
        hoga_lookup = {'지정가': "00", '시장가': "03"}

        f = open("buy_list.txt", 'rt')
        buy_list = f.readlines()
        f.close()

        f = open("sell_list.txt", 'rt')
        sell_list = f.readlines()
        f.close()

        # account
        account = self.w_account.currentText()

        # buy list 에서 살 주식 주문
        for row_data in buy_list:
            split_row_data = row_data.split(';')
            hoga = split_row_data[2]
            code = split_row_data[1]
            num = split_row_data[3]
            price = split_row_data[4]

            if split_row_data[-1].rstrip() == '매수전':
                self.kiwoom.send_order("send_order_req", "0101", account, 1, code, num, price, hoga_lookup[hoga], "")

        # sell list 팔 주식 주문
        for row_data in sell_list:
            split_row_data = row_data.split(';')
            hoga = split_row_data[2]
            code = split_row_data[1]
            num = split_row_data[3]
            price = split_row_data[4]

            if split_row_data[-1].rstrip() == '매도전':
                self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, price, hoga_lookup[hoga], "")

        # buy list 삿을경우 매수전을 주문완료로
        for i, row_data in enumerate(buy_list):
            buy_list[i] = buy_list[i].replace("매수전", "주문완료")

        # file update 사야할 목록 업데이트
        f = open("buy_list.txt", 'wt')
        for row_data in buy_list:
            f.write(row_data)
        f.close()

        # sell list 팔았을 경우 주문완료로
        for i, row_data in enumerate(sell_list):
            sell_list[i] = sell_list[i].replace("매도전", "주문완료")

        # file update 팔아야할 목록 업데이트 이는 pymon에서 들고올거
        f = open("sell_list.txt", 'wt')
        for row_data in sell_list:
            f.write(row_data)
        f.close()

    # 산 주식의 리스트를 가져온다
    def load_buy_sell_list(self):
        f = open("buy_list.txt", 'rt')
        buy_list = f.readlines()
        f.close()

        f = open("sell_list.txt", 'rt')
        sell_list = f.readlines()
        f.close()

        row_count = len(buy_list) + len(sell_list)
        self.tableWidget_4.setRowCount(row_count)

        # buy list
        for j in range(len(buy_list)):
            row_data = buy_list[j]
            split_row_data = row_data.split(';')
            split_row_data[1] = self.kiwoom.get_master_code_name(split_row_data[1].rsplit())

            for i in range(len(split_row_data)):
                item = QTableWidgetItem(split_row_data[i].rstrip())
                item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter)
                self.tableWidget_4.setItem(j, i, item)

        # sell list
        for j in range(len(sell_list)):
            row_data = sell_list[j]
            split_row_data = row_data.split(';')
            split_row_data[1] = self.kiwoom.get_master_code_name(split_row_data[1].rstrip())

            for i in range(len(split_row_data)):
                item = QTableWidgetItem(split_row_data[i].rstrip())
                item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter)
                self.tableWidget_4.setItem(len(buy_list) + j, i, item)

        self.tableWidget_4.resizeRowsToContents()
    #이건 주식 코드를 치면 코드의 이름을 받아온다.
    def code_changed(self):
        code = self.w_event_code.text()
        name = self.kiwoom.get_master_code_name(code)
        self.w_event_name.setText(name)
    #주문하는창
    def send_order(self):
        order_type_lookup = {'신규매수': 1, '신규매도': 2, '매수취소': 3, '매도취소': 4}
        hoga_lookup = {'지정가': "00", '시장가': "03"}

        account = self.w_account.currentText()
        order_type = self.w_order.currentText()
        code = self.w_event_code.text()
        hoga = self.w_kinds.currentText()
        num = self.w_quantity.value()
        price = self.w_price.value()

        self.kiwoom.send_order("send_order_req", "0101", account, order_type_lookup[order_type], code, num, price, hoga_lookup[hoga], "")
    #시간이 9시가 되면 자동으로 사게하는 함수
    def timeout(self):
        market_start_time = QTime(9, 0, 0)
        current_time = QTime.currentTime()
        #현재시간이 마켓이 시작했고, trade_stocks_done이라는 변수는 맨처음에 false로 저장해놓는데 첫번째로 시작했으면 trade_stocks를 실행하는 코드
        if current_time > market_start_time and self.trade_stocks_done is False:
            self.trade_stocks()
            self.trade_stocks_done = True

        text_time = current_time.toString("hh:mm:ss")
        time_msg = "현재시간: " + text_time
        #연결상태
        state = self.kiwoom.get_connect_state()
        if state == 1:
            state_msg = "서버 연결 중"
        else:
            state_msg = "서버 미 연결 중"

        self.statusbar.showMessage(state_msg + " | " + time_msg)

    def timeout2(self):
        if self.checkBox.isChecked():
            self.check_balance()
    #이름은 잔고확인인데 계좌에서 데이터 뽑아온다 (이는 opw00018이다.)
    def check_balance(self):
        self.kiwoom.reset_opw00018_output()
        account_number = self.kiwoom.get_login_info("ACCNO")
        account_number = account_number.split(';')[0]

        self.kiwoom.set_input_value("계좌번호", account_number)
        self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000")

        while self.kiwoom.remained_data:
            time.sleep(0.2)
            self.kiwoom.set_input_value("계좌번호", account_number)
            self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000")

        # opw00001
        self.kiwoom.set_input_value("계좌번호", account_number)
        self.kiwoom.comm_rq_data("opw00001_req", "opw00001", 0, "2000")

        # balance
        item = QTableWidgetItem(self.kiwoom.d2_deposit)
        item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
        self.tableWidget.setItem(0, 0, item)

        for i in range(1, 6):
            item = QTableWidgetItem(self.kiwoom.opw00018_output['single'][i - 1])
            item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
            self.tableWidget.setItem(0, i, item)

        self.tableWidget.resizeRowsToContents()

        # Item list
        item_count = len(self.kiwoom.opw00018_output['multi'])
        self.tableWidget_2.setRowCount(item_count)

        for j in range(item_count):
            row = self.kiwoom.opw00018_output['multi'][j]
            for i in range(len(row)):
                item = QTableWidgetItem(row[i])
                item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
                self.tableWidget_2.setItem(j, i, item)

        self.tableWidget_2.resizeRowsToContents()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWindow = MyWindow()
    myWindow.show()
    app.exec_()


import falcon

from sqlalchemy.orm import Session
from sqlalchemy import exists, and_
from database import engine, Base
from tables import UsersTable, SignaturesTable
from time import ctime

from utilities import getSignatureQuery, getJson, to_bool
from auth import authenticate

def recordUser(session, valueDict):
        userRow = None
        requiredValues = ["Signature", "Name", "Email", "UserID"]

        for value in requiredValues:
            if value not in valueDict.keys():
                return None
                #resp.body = "Error, missing key {}".format(value)
                #resp.status = falcon.HTTP_400

        # User table values
        signature = valueDict.get("Signature")
        name = valueDict.get("Name")
        email = valueDict.get("Email")
        company = valueDict.get("Company")
        userID = valueDict.get("UserID")

        userExists = True
        userRow = session.query(UsersTable).get((signature, userID))

        if userRow is None:
            userExists = False
            userRow = UsersTable(Signature=signature, Name=name, Email=email, Company=company, UserID=userID, InstallDateTime=ctime())

        return userRow, userExists

def createSignatureRow(session, valueDict):
        signatureRow = None
        signature = valueDict.get("Signature")

        # Signature table values
        installLimit = valueDict.get("InstallLimit")
        unlimitedInstalls = to_bool(valueDict.get("UnlimitedInstalls"))

        if unlimitedInstalls is True:
            signatureRow = SignaturesTable(PrimaryKey=signature, InstallCount=0, InstallLimit=0, UnlimitedInstalls=unlimitedInstalls)
            print("Created Signature: {}, with UnlimitedInstalls".format(signature))
        elif installLimit is not None:
            signatureRow = SignaturesTable(PrimaryKey=signature, InstallCount=0, InstallLimit=installLimit, UnlimitedInstalls=False)
            print("Created Signature: {}, with InstallLimit of: {}".format(signature, installLimit))
        else:
            print("Error creating row with Signature: {}. No valid UnlimitedInstalls or InstallLimit provided".format(signature))

        return signatureRow

class Resource(object):

    def on_get(self, req, resp):
        resp.body = "Accepted!"
        resp.status = falcon.HTTP_200

    def on_post(self, req, resp):
        validRequest = authenticate(req)

        if not validRequest:
            resp.body = "Invalid username/password"
            resp.status = falcon.HTTP_401
            return

        session = Session(engine)
        valueDict = getJson(req)

        signatureQuery = getSignatureQuery(req, session)

        message = "Unable to add Signature"
        resp.status = falcon.HTTP_400

        if "Signature" in valueDict.keys() and signatureQuery is None:
            signatureRow = createSignatureRow(session, valueDict)
            message = "Unable to create signature row"
            if signatureRow is not None:
                session.add(signatureRow)
                message = "Added signature to database: {}".format(signatureRow.PrimaryKey)
                resp.status = falcon.HTTP_200

        elif "Signature" in valueDict.keys():
            message = "Unable to add Signature, already exists in database"

        resp.body = message
        print(message)

        session.commit()
        session.close()


# -*- coding = utf-8 -*-
# @Author: youngfuns
# @Time : 2021/12/11 21:49
# @File : demo1.py
# @Software: PyCharm
import re
import urllib.error  # 制定url， 获取网页数据
import urllib.request
from bs4 import BeautifulSoup
import xlwt  # 进行Excel操作
import sqlite3

def main():
    baseurl = "https://movie.douban.com/top250?start="
    # 爬取网页
    datalist = getData(baseurl)
    # 保存到Excel
    # savepath = '.\\豆瓣电影top250.xls'
    # saveData(datalist, savepath)
    #  保存到SQLit
    sqlitePath = 'movie250.db'
    saveToDb(datalist, sqlitePath)

findLink = re.compile(r'')
findImgSrc = re.compile(r'', re.S)
findTitle = re.compile(r'(.*)')
findRating = re.compile(r'span class="rating_num" property="v:average">(.*)')
findJudge = re.compile(r'(\d*)人评价')
findInq = re.compile(r'span class="inq">(.*)')
findBd = re.compile(r'
(.*?)
', re.S)

# 爬取网页
def getData(baseurl):
    datalist = []
    for i in range(0, 10):
        url = baseurl + str(i * 25)
        html = askUrl(url)
        # print(url)

        # 解析数据
        soup = BeautifulSoup(html, "html.parser")
        # print(soup.findAll("a"))
        for item in soup.findAll("div", class_="item"):
            data = []
            item = str(item)

            # 获取相关信息
            link = re.findall(findLink, item)[0]
            data.append(link)

            imgSrc = re.findall(findImgSrc, item)[0]
            print(re.findall(findImgSrc, item))
            data.append(imgSrc)

            titles = re.findall(findTitle, item)
            if len(titles) == 2:
                ctitle = titles[0]
                data.append(ctitle)
                otitle = titles[1].replace("/", "")
                data.append(otitle)
            else:
                data.append(titles[0])
                data.append(" ")

            rating = re.findall(findRating, item)[0]
            data.append(rating)

            judgeNum = re.findall(findJudge, item)[0]
            data.append(judgeNum)

            inq = re.findall(findInq, item)
            if len(inq) != 0:
                inq = inq[0].replace("。", "")
                data.append(inq)
            else:
                data.append(" ")

            bd = re.findall(findBd, item)[0]
            bd = re.sub('
(\s+)?', ' ', bd)
            bd = re.sub('/', " ", bd)
            data.append(bd.strip())

            datalist.append(data)

    # print(datalist)
    return datalist

def askUrl(url):
    head = {
        "user-agent": "Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 96.0.4664.93Safari / 537.36"
    }
    request = urllib.request.Request(url, headers=head)
    # html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
        return html
        # print(html)
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
            if hasattr(e, "reason"):
                print(e.reason)

# 保存数据
def saveData(datalist, savepath):
    book = xlwt.Workbook(encoding="utf-8", style_compression=0)
    sheet = book.add_sheet("豆瓣电影TOP250", cell_overwrite_ok=True)
    col = ("电影详情链接", "图片链接", "影片中文名", "影片外国名", "评分", "评价数", "概况", "相关信息")
    for i in range(0, 8):
        sheet.write(0, i, col[i])
    for i in range(0, 250):
        print("爬取第%d条" % i)
        for j in range(0, 8):
            sheet.write(i + 1, j, datalist[i][j])
    book.save(savepath)

def saveToDb(datalist, dbpath):
    # 连接数据库 创建数据表
    init_db(dbpath)
    # 插入数据
    conn = sqlite3.connect(dbpath)
    cursor = conn.cursor()
    for data in datalist:
        for i in data:
            if data.index(i) == 4 or data.index(i) == 5:
                continue
                i = '"' + i + '"'
        sql = '''
            insert movie_top (
                info_link,
                banner_link,
                title,
                i_title,
                rating,
                judge,
                inq,
                info
            ) values (%s);
        ''' % ','.join(data)
        # cursor.execute(sql)
        # conn.commit()
        # conn.close()
        print(sql)
    # info = sqlite3.connect(dbpath)
    # cu = info.cursor()
    # c = cu.execute('select * from movie_top')
    # print(c)
    # info.commit()
    # info.close()

def init_db(dbpath):
    sql = '''
        create table movie_top(
        id integer primary key autoincrement,
        info_link text,
        banner_link text,
        title varchar,
        i_title varchar,
        rating numeric,
        judge numeric,
        inq text,
        info text
        )
    '''

    conn = sqlite3.connect(dbpath)
    cursor = conn.cursor()
    cursor.execute(sql)
    conn.commit()
    conn.close()

if __name__ == "__main__":
    main()


import sys

import tiktoken
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import UnstructuredPDFLoader
from langchain.schema import HumanMessage, SystemMessage

INPUT_PRICE_PER_1K_TOKENS = 0.0015
OUTPUT_PRICE_PER_1K_TOKENS = 0.002
YEN_PER_DOLLAR = 140

MODEL_NAME = "gpt-3.5-turbo"

SYSTEM_PROMPT = """Please translate the following English text into Japanese.
Please output in markdown format.

Input is extracted from PDF, so it may contain elements other than the title and text.
Please ignore elements that do not appear to be titles and body text.

日本語でお願いします。
"""

def translate(text: str, callback) -> str:
    chat = ChatOpenAI(
        model_name=MODEL_NAME,
        temperature=0,
        streaming=True,
        callbacks=[callback],
    )

    messages = [
        SystemMessage(content=SYSTEM_PROMPT),
        HumanMessage(content=text),
    ]

    return chat(messages).content

def count_tokens(text):
    encoding = tiktoken.encoding_for_model(MODEL_NAME)
    tokens = encoding.encode(text)
    return len(tokens)

def calculate_price_as_doller(input_token_count, output_token_count):
    return (
        input_token_count * INPUT_PRICE_PER_1K_TOKENS / 1000
        + output_token_count * OUTPUT_PRICE_PER_1K_TOKENS / 1000
    )

def doller_to_yen(doller):
    return doller * YEN_PER_DOLLAR

def load_pdf(file_path: str) -> list[str]:
    loader = UnstructuredPDFLoader(file_path=file_path, mode="elements")
    docs = loader.load()

    last_doc = docs[-1]
    last_doc_page_number = last_doc.metadata["page_number"]

    texts = [""] * last_doc_page_number

    for doc in docs:
        metadata = doc.metadata
        page_number = metadata["page_number"]
        category = metadata["category"]

        if category in ["Title", "NarrativeText"]:
            texts[page_number - 1] += doc.page_content + "\n\n"
        elif category in ["UncategorizedText", "ListItem"]:
            pass
        else:
            raise ValueError(f"Unknown category: {category}")

    return texts

if __name__ == "__main__":
    file_path = sys.argv[1]
    texts = load_pdf(file_path)
    for i, text in enumerate(texts):
        print(f"========== Page {i+1} ==========")
        print(text)


# coding:utf-8

import xgboost as xgb

if __name__ == "__main__":
	trainPath = r'E:\python\PythonSpace\Git\ML\agaricus_train.txt'
	testPath = r'E:\python\PythonSpace\Git\ML\agaricus_test.txt'
	data_train = xgb.DMatrix(trainPath)
	data_test = xgb.DMatrix(testPath)
	# print(type(data_test.get_label()))
	# print(data_test.get_label())

	# 设置参数
	# eta是学习率，
	# silent=1表示不打印运行过程的信息，默认为0，表示打印信息
	# object表示设置当前问题类型
	param = {"max_depth": 3, "eta": 0.2, "silent": 1, "object": "binary:logistic"}
	watchlist = [(data_train, "train"), (data_test, "eval")]
	n_round = 5  # 表示训练7轮
	# obj和feral可以分别用来设置损失函数和最终的模型评估函数
	bst = xgb.train(param, data_train, num_boost_round=n_round, evals=watchlist)

	y_hat = bst.predict(data_test)
	y_test = data_test.get_label()
	# 计算错误率
	error = sum(y_test != (y_hat>0.5))
	error_rate = float(error) / len(y_hat)
	print("样本总数：", len(y_hat))
	print("错误数目：", error)
	print("错误率：%.4f%%" % (100*error_rate))


from sklearn.ensemble import RandomForestRegressor
import xgboost as xgb
import pandas as pd

def recover_missing(df, input_attr, missing_attr, method='RandomForest'):
    """
    :param df: input dataframe
    :param input_attr: type -> list:
    :param missing_attr: str: attrb need to be recover
    :param method: which method choose to recover data -> 'RandomForest', 'Xgboost', 'lightgbm'
    :return: df
    """
    attrb_df = df[[missing_attr] + input_attr]
    train = attrb_df[getattr(attrb_df, missing_attr).notnull()].values
    test = attrb_df[getattr(attrb_df, missing_attr).isnull()].values

    train_label = train[:, 0]
    train_data = train[:, 1:]

    if method == 'RandomForest':
        model = RandomForestRegressor(random_state=1, n_estimators=2000, n_jobs=-1)
        model.fit(train_data, train_label)
        predict_result = model.predict(test[:, 1:])
        df.loc[(hasattr(df, missing_attr).isnull()), missing_attr] = predict_result
    elif method == 'Xgboost':
        best_params = {
            'max_depth': 5,
            'learning_rate': 0.01,
            'n_estimators': 3000,
            'gamma': 0.8,
            'min_child_weight': 2,
            'reg_alpha': 0.001,
            'max_delta_step': 0,
            'subsample': 0.8,
            'colsample_bytree': 0.8,
            'colsample_bylevel': 0.9,
            'base_score': 10,
            'seed': 1,
            'nthread': 30
        }
        model = xgb.XGBRegressor(**best_params)
        model.fit(train_data, train_label)
        predict_result = model.predict(test[:, 1:])
        df.loc[(getattr(df, missing_attr).isnull()), missing_attr] = predict_result
    return df, model

def feature_transform(df, func):
    nrow, ncol = df.shape
    for i in range(nrow):
        func(df, i)
    return df

if __name__ == '__main__':
    data = pd.read_csv('../../data/titanic_disaster/train.csv')
    df = recover_missing(data, ['Fare', 'Parch', 'SibSp', 'Pclass'], 'Age', method='Xgboost')


import pyperclip
# string in the book to copy
'''
Lists of animals
Lists of aquarium life
Lists of biologists by author abbreviation
Lists of cultivars
'''
text = pyperclip.paste()
# print(repr(text)) # using repr() built in function we can convert any string to a raw string, i.e. we can see what has been copied, including the escape sequence characters
# Note : I ended up having the program with a weird behaviour where only the last line was getting printed out. I thaught it to be a bug, as I thaught that my code is not concatinating the string and is just replacing the string and in the end the last string is getting replaces.
# eventually I got to know that my copied string is containg a escape sequence character \r which stands for carriage return. and this overwrites the currect line on the terminal
# the conclusion was, the code was working fine, and the string stored was also correct, the issue was that because of this \r character, on the terminal only the last line was getting showing as all the other lines we getting overwriten using direct print function.
textList = text.split('\r\n')
for i in range(len(textList)):
    textList[i] = ('* '+textList[i])
print('\n'.join(textList))


# To run this, pay attention to this:
# define num_classes when initializing the model
# define f2c when calling train() and test()

'''Train CIFAR100 with PyTorch.'''
from __future__ import print_function

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torch.backends.cudnn as cudnn

import torchvision
import torchvision.transforms as transforms
import dataset

import os
import argparse

from models import *
from utils import progress_bar, adjust_optimizer, setup_logging
from torch.autograd import Variable
from datetime import datetime
import logging
import numpy as np
import pickle

NUM_CLASSES = 2
NUM_CLUSTERS = 5

parser = argparse.ArgumentParser(description='PyTorch CIFAR100 Training')
parser.add_argument('--lr', default=0.1, type=float, help='learning rate')
parser.add_argument('--resume', '-r', action='store_true', help='resume from checkpoint')
parser.add_argument('--results_dir', metavar='RESULTS_DIR', default='./results',
                    help='results dir')
parser.add_argument('--resume_dir', default=None, help='resume dir')
args = parser.parse_args()

args.save = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
save_path = os.path.join(args.results_dir, args.save)
if not os.path.exists(save_path):
    os.makedirs(save_path)
setup_logging(os.path.join(save_path, 'log.txt'))
logging.info("saving to %s", save_path)
logging.info("run arguments: %s", args)

use_cuda = torch.cuda.is_available()
best_acc = 0  # best test accuracy
start_epoch = 0  # start from epoch 0 or last checkpoint epoch

# Data
print('==> Preparing data..')
transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.5071, 0.4867, 0.4408), (0.2675, 0.2565, 0.2761)),
])

transform_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5071, 0.4867, 0.4408), (0.2675, 0.2565, 0.2761)),
])

trainset = dataset.data_cifar100_red.CIFAR100_RED(root='/home/rzding/DATA', train=True, download=True, transform=transform_train)
#trainset = dataset.data_cifar10.CIFAR10(root='/home/rzding/DATA', train=True, download=True, transform=transform_train)
#trainloader = torch.utils.data.DataLoader(trainset, batch_size=256, shuffle=True, num_workers=2)

testset = dataset.data_cifar100_red.CIFAR100_RED(root='/home/rzding/DATA', train=False, download=True, transform=transform_test)
#testset = dataset.data_cifar10.CIFAR10(root='/home/rzding/DATA', train=False, download=True, transform=transform_test)
testloader = torch.utils.data.DataLoader(testset, batch_size=500, shuffle=False, num_workers=2)

# Model
if args.resume:
    # Load checkpoint.
    print('==> Resuming from checkpoint..')
    assert os.path.isdir(args.resume_dir)
    checkpoint = torch.load(os.path.join(args.resume_dir, 'ckpt.t7'))
    net = checkpoint['net']
    best_acc = checkpoint['acc']
    start_epoch = checkpoint['epoch']
else:
    print('==> Building model..')
    # net = VGG('VGG19')
    # net = ResNet18()
    #net = PreActResNet18(num_classes=100)
    net = wide_resnet(num_classes=100)
    # net = GoogLeNet()
    # net = DenseNet121()
    # net = ResNeXt29_2x64d()
    # net = MobileNet()
    # net = MobileNetV2()
    # net = DPN92()
    # net = ShuffleNetG2()
    # net = SENet18()

logging.info("model structure: %s", net)
num_parameters = sum([l.nelement() for l in net.parameters()])
logging.info("number of parameters: %d", num_parameters)

if use_cuda:
    net.cuda()
    net = torch.nn.DataParallel(net, device_ids=[0])
    cudnn.benchmark = True

# Step1: start from a pre-trained model, load it and save the output of last layer
# result format: a matrix where each row is a datapoint, a vector as class of each datapoint
def get_feat(net, trainloader):
    net.eval()
    all_feats = []
    all_idx = []
    all_targets = []
    for batch_idx, (inputs, input_idx, targets) in enumerate(trainloader):
        all_idx.append(input_idx.numpy())
        all_targets.append(targets.numpy())
        if use_cuda:
            inputs, targets = inputs.cuda(), targets.cuda()
        inputs, targets = Variable(inputs, volatile=True), Variable(targets)
        outputs, feats = net(inputs)
        all_feats.append(feats.data.cpu().numpy())
    all_feats = np.vstack(all_feats)
    all_idx = np.hstack(all_idx)
    all_targets = np.hstack(all_targets)
    return all_feats, all_idx, all_targets

trainloader = torch.utils.data.DataLoader(trainset, batch_size=256, shuffle=False, num_workers=2)
train_feats, train_idx, all_targets = get_feat(net, testloader)
pickle.dump(train_feats, open(os.path.join(save_path, 'test_feats.pkl'), 'wb'))
print('all feats size: {}'.format(train_feats.shape))
print('feats sum: {}'.format(train_feats.sum(axis=1)))
print('feats first row: {}'.format(train_feats[0]))
#pickle.dump([train_idx, all_targets], open(os.path.join(save_path, 'debug.pkl'), 'wb'))
pickle.dump([None, all_targets], open(os.path.join(save_path, 'debug.pkl'), 'wb'))

# criterion = nn.CrossEntropyLoss()
# optimizer = optim.SGD(net.parameters(), lr=args.lr, momentum=0.9, weight_decay=5e-4)
# regime = {
#     0: {'optimizer': 'SGD', 'lr': 1e-1,
#         'weight_decay': 5e-4, 'momentum': 0.9, 'nesterov': False},
#     60: {'lr': 2e-2},
#     120: {'lr': 4e-3},
#     160: {'lr': 8e-4}
# }
# logging.info('training regime: %s', regime)

# # Training
# def train(epoch, f2c=False):
#     print('\nEpoch: %d' % epoch)
#     net.train()
#     train_loss = 0
#     correct = 0
#     total = 0
#     global optimizer
#     optimizer = adjust_optimizer(optimizer, epoch, regime)
#     for batch_idx, (inputs, targets) in enumerate(trainloader):
#         if f2c:
#             for idx,target in enumerate(targets):
#                 targets[idx] = classes_f2c[target]
#         if use_cuda:
#             inputs, targets = inputs.cuda(), targets.cuda()
#         optimizer.zero_grad()
#         inputs, targets = Variable(inputs), Variable(targets)
#         outputs = net(inputs)
#         loss = criterion(outputs, targets)
#         loss.backward()
#         optimizer.step()

#         train_loss += loss.data[0]
#         _, predicted = torch.max(outputs.data, 1)
#         total += targets.size(0)
#         correct += predicted.eq(targets.data).cpu().sum()

#         #progress_bar(batch_idx, len(trainloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'
#         #    % (train_loss/(batch_idx+1), 100.*correct/total, correct, total))
#         if batch_idx % 10 == 0:
#             logging.info('\n Epoch: [{0}][{1}/{2}]\t'
#                         'Training Loss {train_loss:.3f} \t'
#                         'Training Prec@1 {train_prec1:.3f} \t'
#                         .format(epoch, batch_idx, len(trainloader),
#                         train_loss=train_loss/(batch_idx+1),
#                         train_prec1=100.*correct/total))

# def test(epoch, f2c=False, train_f=True):
#     global best_acc
#     net.eval()
#     test_loss = 0
#     correct = 0
#     total = 0
#     for batch_idx, (inputs, targets) in enumerate(testloader):
#         if f2c:
#             for idx,target in enumerate(targets):
#                 targets[idx] = classes_f2c[target]
#         if use_cuda:
#             inputs, targets = inputs.cuda(), targets.cuda()
#         inputs, targets = Variable(inputs, volatile=True), Variable(targets)
#         outputs = net(inputs)
#         loss = criterion(outputs, targets)

#         test_loss += loss.data[0]
#         _, predicted = torch.max(outputs.data, 1)
#         total += targets.size(0)
#         if train_f and f2c:
#             predicted_np = predicted.cpu().numpy()
#             #print('predicted: {}'.format(predicted))
#             #print('predicted_np: {}'.format(predicted_np))
#             for idx,a_predicted in enumerate(predicted_np):
#                 predicted_np[idx] = classes_f2c[a_predicted]
#             #correct += (predicted_np == targets.cpu().numpy()).sum()
#             #print('targets: {}'.format(targets))
#             correct += (predicted_np == targets.data.cpu().numpy()).sum()
#         else:
#             correct += predicted.eq(targets.data).cpu().sum()

#         #progress_bar(batch_idx, len(testloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'
#         #    % (test_loss/(batch_idx+1), 100.*correct/total, correct, total))

#     logging.info('\n Epoch: {0}\t'
#                     'Testing Loss {test_loss:.3f} \t'
#                     'Testing Prec@1 {test_prec1:.3f} \t\n'
#                     .format(epoch,
#                     test_loss=test_loss/len(testloader),
#                     test_prec1=100.*correct/total))

#     # Save checkpoint.
#     acc = 100.*correct/total
#     if acc > best_acc and args.resume_dir is None and not (train_f and f2c):
#         print('Saving..')
#         state = {
#             'net': net.module if use_cuda else net,
#             'acc': acc,
#             'epoch': epoch,
#         }
#         torch.save(state, os.path.join(save_path, 'ckpt.t7'))
#         best_acc = acc

# for epoch in range(start_epoch, start_epoch+200):
#     train(epoch, f2c=False)
#     test(epoch, f2c=False)
#     test(epoch, f2c=True, train_f=True)

# # test(0, f2c=True, train_f=True)


import discord
from discord.ext import commands

class Developer:
    def __init__(self, bot):
        self.bot = bot

    def dev_check(self, id):
       if id == 277981712989028353 or id == 231028316843278346:
           return True
       return False

    @commands.command()
    async def changename(self, ctx, *, name=None):
        if not self.dev_check(ctx.author.id):
            return await ctx.send("Sorry, but this command is for devs only. ¯\_(ツ)_/¯")
        await self.bot.user.edit(username=name)
        await ctx.send(f"My name is now changed to: **{name}**")

    @commands.command()
    async def restart(self, ctx):
        if not self.dev_check(ctx.author.id):
            return await ctx.send("Sorry, but this command is for devs only. ¯\_(ツ)_/¯")
        await ctx.send("Turning off...Till next time!")
        await self.bot.logout()

def setup(bot):
    bot.add_cog(Developer(bot))


"""
Options file that can be imported and used for unfolding.  Good to separate
data from behavior.
"""
import os
import ROOT as rt
import ordereddict
from tianlu import directories
from tianlu.analysis.utils import SELECTIONPAIR
from tianlu.analysis.P0DCutUtils import getLayerCutStr
from collections import defaultdict

__author__ = 'Tianlu Yuan'
__email__ = 'tianlu.yuan [at] colorado.edu'

#################### Globals ######################
# Set debug to false when analysis is finalized and data can be used
DEBUG = False
# Use T2K style for DrawingTools
T2KSTYLE = False
# production version to use as inputs
PROD_MCP = 'prod6B'
PROD_RDP = 'prod6E'
# highland analysis specifier. need to change SIGNAL and CUTS if this changes
ANALYSIS = 'RunP0DNumuCCQEAnalysis'
# Set to True to use merged MC files, otherwise will use a single
# output instead of merged. If true, a cache file is saved to speed up
# later processing if xsToolsUnfold.stack_sources is called
FULLSTATS = True
# flag for whether to set the fake-data to data POT
FAKEPOT = True
#################### Inputs ######################
FILE_SPEC = 'merged' if FULLSTATS else '1'

# MCP NEUT
NEUT_TEMPLATE = os.path.join(directories.HIGHLAND2_STORE, ANALYSIS, PROD_MCP,
                             'mcp', 'neut', '{0}',
                             '{0}_{1}_{2}'.format(ANALYSIS,
                                                  PROD_MCP,
                                                  'mcp_neut_{0}_'+FILE_SPEC+'.root'))
MCP_NEUT_RUN1 = NEUT_TEMPLATE.format('RUN1')
MCP_NEUT_RUN2A = NEUT_TEMPLATE.format('RUN2air')
MCP_NEUT_RUN2W = NEUT_TEMPLATE.format('RUN2water')
MCP_NEUT_RUN3C = NEUT_TEMPLATE.format('RUN3')
MCP_NEUT_RUN4W = NEUT_TEMPLATE.format('RUN4water')
MCP_NEUT_RUN4A = NEUT_TEMPLATE.format('RUN4air')

# MCP GENIE
GENIE_TEMPLATE = os.path.join(directories.HIGHLAND2_STORE, ANALYSIS, PROD_MCP,
                              'mcp', 'genie', '{0}',
                              '{0}_{1}_{2}'.format(ANALYSIS,
                                                   PROD_MCP,
                                                   'mcp_genie_{0}_'+FILE_SPEC+'.root'))
MCP_GENIE_RUN1 = GENIE_TEMPLATE.format('RUN1')
MCP_GENIE_RUN2A = GENIE_TEMPLATE.format('RUN2air')
MCP_GENIE_RUN2W = GENIE_TEMPLATE.format('RUN2water')
MCP_GENIE_RUN3C = GENIE_TEMPLATE.format('RUN3')
MCP_GENIE_RUN4W = GENIE_TEMPLATE.format('RUN4water')
MCP_GENIE_RUN4A = GENIE_TEMPLATE.format('RUN4air')

# RDP
BEAM_TEMPLATE = os.path.join(directories.HIGHLAND2_STORE, ANALYSIS, PROD_RDP,
                             'rdp', 'beam', '{0}',
                             '{0}_{1}_{2}'.format(ANALYSIS,
                                                  PROD_RDP,
                                                  'rdp_beam_{0}_'+FILE_SPEC+'.root'))
RDP_RUN1 = BEAM_TEMPLATE.format('RUN1')
RDP_RUN2A = BEAM_TEMPLATE.format('RUN2air')
RDP_RUN2W = BEAM_TEMPLATE.format('RUN2water')
RDP_RUN3C = BEAM_TEMPLATE.format('RUN3c')
RDP_RUN4W = BEAM_TEMPLATE.format('RUN4water')
RDP_RUN4A = BEAM_TEMPLATE.format('RUN4air')

# Weights
# t2krw
WEIGHTS_TEMPLATE = os.path.join(ANALYSIS, PROD_MCP, 'mcp', 'neut',
                                '{0}', FILE_SPEC, 'weights_unified.root')
WEIGHTS_NEUT_RUN1 = WEIGHTS_TEMPLATE.format('RUN1')
WEIGHTS_NEUT_RUN2W = WEIGHTS_TEMPLATE.format('RUN2water')
WEIGHTS_NEUT_RUN2A = WEIGHTS_TEMPLATE.format('RUN2air')
WEIGHTS_NEUT_RUN3C = WEIGHTS_TEMPLATE.format('RUN3')
WEIGHTS_NEUT_RUN4W = WEIGHTS_TEMPLATE.format('RUN4water')
WEIGHTS_NEUT_RUN4A = WEIGHTS_TEMPLATE.format('RUN4air')
# mass
MASS_TEMPLATE = os.path.join(ANALYSIS, PROD_MCP, 'mcp', 'neut',
                             '{0}', FILE_SPEC, 'weights_mass.root')
MASS_NEUT_RUN1 = MASS_TEMPLATE.format('RUN1')
MASS_NEUT_RUN2W = MASS_TEMPLATE.format('RUN2water')
MASS_NEUT_RUN2A = MASS_TEMPLATE.format('RUN2air')
MASS_NEUT_RUN3C = MASS_TEMPLATE.format('RUN3')
MASS_NEUT_RUN4W = MASS_TEMPLATE.format('RUN4water')
MASS_NEUT_RUN4A = MASS_TEMPLATE.format('RUN4air')

# xsTool generated rwfiles, needed to get NRooTrackerVtxs
RWFILE_DEFAULT_TEMPLATE = os.path.join(ANALYSIS, PROD_MCP, 'mcp', 'neut',
                                       '{0}', FILE_SPEC, 'rwfile_default.root')
RWFILE_DEFAULT_NEUT_RUN1 = RWFILE_DEFAULT_TEMPLATE.format('RUN1')
RWFILE_DEFAULT_NEUT_RUN2W = RWFILE_DEFAULT_TEMPLATE.format('RUN2water')
RWFILE_DEFAULT_NEUT_RUN2A = RWFILE_DEFAULT_TEMPLATE.format('RUN2air')
RWFILE_DEFAULT_NEUT_RUN3C = RWFILE_DEFAULT_TEMPLATE.format('RUN3')
RWFILE_DEFAULT_NEUT_RUN4W = RWFILE_DEFAULT_TEMPLATE.format('RUN4water')
RWFILE_DEFAULT_NEUT_RUN4A = RWFILE_DEFAULT_TEMPLATE.format('RUN4air')

RWFILE_TRUTH_TEMPLATE = os.path.join(ANALYSIS, PROD_MCP, 'mcp', 'neut',
                                     '{0}', FILE_SPEC, 'rwfile_truth.root')
RWFILE_TRUTH_NEUT_RUN1 = RWFILE_TRUTH_TEMPLATE.format('RUN1')
RWFILE_TRUTH_NEUT_RUN2W = RWFILE_TRUTH_TEMPLATE.format('RUN2water')
RWFILE_TRUTH_NEUT_RUN2A = RWFILE_TRUTH_TEMPLATE.format('RUN2air')
RWFILE_TRUTH_NEUT_RUN3C = RWFILE_TRUTH_TEMPLATE.format('RUN3')
RWFILE_TRUTH_NEUT_RUN4W = RWFILE_TRUTH_TEMPLATE.format('RUN4water')
RWFILE_TRUTH_NEUT_RUN4A = RWFILE_TRUTH_TEMPLATE.format('RUN4air')
##################### End #######################

##################### Flux ######################
FLUX_RUN1 = '{0}/beam/flux/13a/tuned13av1.1/run1/nd5_tuned13av1.1_13anom_run1_fine.root'.format(directories.NFS_BASE)
FLUX_RUN2 = '{0}/beam/flux/13a/tuned13av1.1/run2/nd5_tuned13av1.1_13anom_run2_fine.root'.format(directories.NFS_BASE)
FLUX_RUN3C = '{0}/beam/flux/13a/tuned13av1.1/run3c/nd5_tuned13av1.1_13anom_run3c_fine.root'.format(directories.NFS_BASE)
FLUX_RUN4 = '{0}/beam/flux/13a/tuned13av1.1/run4/nd5_tuned13av1.1_13anom_run4_fine.root'.format(directories.NFS_BASE)
FLUX_HIST_NUMU = 'enu_nd5_tuned13a_numu'
# for xsReweightSystematics.  This specifies which neutrino is used for the
# flux weights
NEUTRINO = 'numu'

################ fake-data POT ##################
# for fake-data studies
# taken from the actual highland2 merged data outputs and retrieved
# using xsInputdataHighland2::GetPOTdata
if FAKEPOT:
     FAKEPOT_RUN1 = 1.67e19
     FAKEPOT_RUN2W = 4.29e19
     FAKEPOT_RUN2A = 3.55e19
     FAKEPOT_RUN3C = 1.35e20
     FAKEPOT_RUN4W = 1.63e20
     FAKEPOT_RUN4A = 1.76e20
else:
    FAKEPOT_RUN1 = -1
    FAKEPOT_RUN2W = -1
    FAKEPOT_RUN2A = -1
    FAKEPOT_RUN3C = -1
    FAKEPOT_RUN4W = -1
    FAKEPOT_RUN4A = -1
##################### End #######################

################## Selection ####################
# (T.Y. 5/6/14) && particle ==13'
SELECT = SELECTIONPAIR('Sum$(accum_level[0][0]) > 3', 'topology==0')
INCLUSIVE = SELECTIONPAIR('Sum$(accum_level[0][0]) > 2', 'topology<3')
SELECT_2TRACK0MICHEL = SELECTIONPAIR('Sum$(accum_level[0][1]) > 3 && nmichel==0 && np0d==2', 'topology==0')
##################### End #######################

################### Sidebands ####################
# list all sidebands to be added here
SIDEBANDS = [SELECTIONPAIR('Sum$(accum_level[0][1]) > 3 && np0d == 2 && nmichel>0', 'topology == 1'),
             SELECTIONPAIR('Sum$(accum_level[0][1]) > 3 && np0d > 2', 'topology == 2')]
# disable for specific sources
SIDEBAND_DISABLED = ['T2KReWeight_flux', 'Mass_all']
##################### End #######################

################# Backgrounds ###################
# Only the background components.
SELECT_BACKGROUND = SELECTIONPAIR('Sum$(accum_level[0][0]) > 3 && topology!=0',
                                  'topology!=0')
SELECT_CC1PI = SELECTIONPAIR('Sum$(accum_level[0][0]) > 3 && topology==1',
                             'topology==1')
SELECT_CCOTHER = SELECTIONPAIR('Sum$(accum_level[0][0]) > 3 && topology==2',
                               'topology==2')
SIDEBAND1_CC1PI = SELECTIONPAIR('&&'.join(SIDEBANDS[0]),
                                SIDEBANDS[0].true)
SIDEBAND2_CCOTHER = SELECTIONPAIR('&&'.join(SIDEBANDS[1]),
                                  SIDEBANDS[1].true)
##################### End #######################

################ Inefficiency ###################
MISSED = SELECTIONPAIR('Sum$(accum_level[0][0]) <=3 && topology==0', 'topology==0')
##################### End #######################

########### Categories Sideband Fit #############
# for category fitting
CATEGS = ['topology==1', 'topology==2']
##################### End #######################

##################### Errors ####################
COLORS = defaultdict(lambda:rt.kOrange,
                     Mass_all=rt.kOrange+2,
                     statistics_data=rt.kCyan,
                     statistics_mc=rt.kCyan+2,
                     T2KReWeight_fsi=rt.kRed,
                     T2KReWeight_xs=rt.kYellow,
                     T2KReWeight_flux=rt.kGreen)
# List here the groups of error sources that we want to include.
# Sort in order of decreasing number of sources for drawing on top of previous
# Empty list corresponds to all implemented errors.
MASTER = ordereddict.OrderedDict()
MASTER['detector'] = (['statistics_data',
                       'statistics_mc',
                       'T2KReWeight_fsi',
                       'T2KReWeight_xs',
                       'T2KReWeight_flux',
                       'Mass_all',
                       'highland_all_syst'], COLORS['detector'])
MASTER['mass'] = (['statistics_data',
                   'statistics_mc',
                   'T2KReWeight_fsi',
                   'T2KReWeight_xs',
                   'T2KReWeight_flux',
                   'Mass_all'], COLORS['Mass_all'])
MASTER['flux'] = (['statistics_data',
                   'statistics_mc',
                   'T2KReWeight_fsi',
                   'T2KReWeight_xs',
                   'T2KReWeight_flux'], COLORS['T2KReWeight_flux'])
MASTER['cross-section'] = (['statistics_data',
                            'statistics_mc',
                            'T2KReWeight_fsi',
                            'T2KReWeight_xs'], COLORS['T2KReWeight_xs'])
MASTER['fsi'] = (['statistics_data',
                  'statistics_mc',
                  'T2KReWeight_fsi'], COLORS['T2KReWeight_fsi'])
MASTER['statistical (mc)'] = (['statistics_data',
                               'statistics_mc'], COLORS['statistics_mc'])
MASTER['statistical (data)'] = (['statistics_data'], COLORS['statistics_data'])

STATSYST = ordereddict.OrderedDict()
STATSYST['systematics'] = (['statistics_data',
                            'statistics_mc',
                            'T2KReWeight_fsi',
                            'T2KReWeight_xs',
                            'T2KReWeight_flux',
                            'Mass_all',
                            'highland_all_syst'], COLORS['T2KReWeight_fsi'])
STATSYST['statistics'] = (['statistics_data',
                           'statistics_mc'], COLORS['statistics_data'])

STATONLY = ordereddict.OrderedDict()
STATONLY['statistical (mc)'] = (['statistics_data',
                                 'statistics_mc'], COLORS['statistics_mc'])
STATONLY['statistical (data)'] = (['statistics_data'], COLORS['statistics_data'])

STATDATA = ordereddict.OrderedDict()
STATDATA['statistical (data)'] = (['statistics_data'], COLORS['statistics_data'])

STATMC = ordereddict.OrderedDict()
STATMC['statistical (mc)'] = (['statistics_mc'], COLORS['statistics_mc'])

XSFSIMC = ordereddict.OrderedDict()
XSFSIMC['fsi'] = (['statistics_mc',
                   'T2KReWeight_xs',
                   'T2KReWeight_fsi'], COLORS['T2KReWeight_fsi'])
XSFSIMC['cross-section'] = (['statistics_mc',
                             'T2KReWeight_xs'], COLORS['T2KReWeight_xs'])
XSFSIMC['statistical (mc)'] = (['statistics_mc'], COLORS['statistics_mc'])

MODELSTAT = ordereddict.OrderedDict()
MODELSTAT['cross-section'] = (['statistics_data',
                               'statistics_mc',
                               'T2KReWeight_xs'], COLORS['T2KReWeight_xs'])
MODELSTAT['statistical (mc)'] = (['statistics_data',
                                 'statistics_mc'], COLORS['statistics_mc'])
MODELSTAT['statistical (data)'] = (['statistics_data'], COLORS['statistics_data'])

FLUXSTAT = ordereddict.OrderedDict()
FLUXSTAT['flux'] = (['statistics_data',
                     'statistics_mc',
                     'T2KReWeight_flux'], COLORS['T2KReWeight_flux'])
FLUXSTAT['statistical (mc)'] = (['statistics_data',
                                 'statistics_mc'], COLORS['statistics_mc'])
FLUXSTAT['statistical (data)'] = (['statistics_data'], COLORS['statistics_data'])

T2KRW = ordereddict.OrderedDict()
T2KRW['flux'] = (['T2KReWeight_fsi',
                  'T2KReWeight_xs',
                  'T2KReWeight_flux'], COLORS['T2KReWeight_flux'])
T2KRW['cross-section'] = (['T2KReWeight_fsi',
                           'T2KReWeight_xs'], COLORS['T2KReWeight_xs'])
T2KRW['fsi'] = (['T2KReWeight_fsi'], COLORS['T2KReWeight_fsi'])

T2KFLUX = ordereddict.OrderedDict()
T2KFLUX['flux'] = (['T2KReWeight_flux'], COLORS['T2KReWeight_flux'])

T2KFSI = ordereddict.OrderedDict()
T2KFSI['fsi'] = (['T2KReWeight_fsi'], COLORS['T2KReWeight_fsi'])

T2KXS = ordereddict.OrderedDict()
T2KXS['cross-section'] = (['T2KReWeight_xs'], COLORS['T2KReWeight_xs'])

DETECTOR = ordereddict.OrderedDict()
DETECTOR['detector'] = (['highland_all_syst'], COLORS['detector'])

MASS = ordereddict.OrderedDict()
MASS['mass'] = (['Mass_all'], COLORS['Mass_all'])

OOFV = ordereddict.OrderedDict()
OOFV['oofv'] = (['highland_p0dccqeoofv_syst'], COLORS['detector'])

# for merged flux, xs, fsi throws
ALL = ordereddict.OrderedDict()
ALL['detector'] = (['statistics_data',
                    'statistics_mc',
                    'T2KReWeight_all',
                    'Mass_all',
                    'highland_all_syst'], COLORS['detector'])
ALL['mass'] = (['statistics_data',
                'statistics_mc',
                'T2KReWeight_all',
                'Mass_all'], COLORS['Mass_all'])
ALL['theory'] = (['statistics_data',
                  'statistics_mc',
                  'T2KReWeight_all'], COLORS['T2KReWeight_fsi'])
ALL['statistical (mc)'] = (['statistics_data',
                               'statistics_mc'], COLORS['statistics_mc'])
ALL['statistical (data)'] = (['statistics_data'], COLORS['statistics_data'])

# for ungrouped t2krw dials
UNGROUPEDXS = ordereddict.OrderedDict()
UNGROUPEDXS['MaQE'] = (['T2KReWeight_NIWG2014a_pF_O16',
                        'T2KReWeight_NIWG2014a_Eb_O16',
                        'T2KReWeight_NIWGMEC_Norm_O16',
                        'T2KReWeight_NXSec_CA5RES',
                        'T2KReWeight_NXSec_MaNFFRES',
                        'T2KReWeight_NXSec_MaCCQE'], COLORS['T2KReWeight_xs'])
UNGROUPEDXS['MaNFFRES'] = (['T2KReWeight_NIWG2014a_pF_O16',
                        'T2KReWeight_NIWG2014a_Eb_O16',
                        'T2KReWeight_NIWGMEC_Norm_O16',
                        'T2KReWeight_NXSec_CA5RES',
                        'T2KReWeight_NXSec_MaNFFRES'], COLORS['T2KReWeight_fsi'])
UNGROUPEDXS['CA5RES'] = (['T2KReWeight_NIWG2014a_pF_O16',
                        'T2KReWeight_NIWG2014a_Eb_O16',
                        'T2KReWeight_NIWGMEC_Norm_O16',
                        'T2KReWeight_NXSec_CA5RES'], COLORS['T2KReWeight_flux'])
UNGROUPEDXS['MEC_O16'] = (['T2KReWeight_NIWG2014a_pF_O16',
                        'T2KReWeight_NIWG2014a_Eb_O16',
                        'T2KReWeight_NIWGMEC_Norm_O16'], COLORS['detector'])
UNGROUPEDXS['Eb_O16'] = (['T2KReWeight_NIWG2014a_pF_O16',
                        'T2KReWeight_NIWG2014a_Eb_O16'], COLORS['statistics_mc'])
UNGROUPEDXS['pF_O16'] = (['T2KReWeight_NIWG2014a_pF_O16'], COLORS['statistics_data'])

MAQE = ordereddict.OrderedDict()
MAQE['MaQE'] = (['T2KReWeight_NXSec_MaCCQE'], COLORS['T2KReWeight_xs'])
EBO = ordereddict.OrderedDict()
EBO['Eb_O16'] = (['T2KReWeight_NIWG2014a_Eb_O16'], COLORS['statistics_mc'])
PFO = ordereddict.OrderedDict()
PFO['pF_O16'] = (['T2KReWeight_NIWG2014a_pF_O16'], COLORS['statistics_data'])
MECO = ordereddict.OrderedDict()
MECO['MEC_O16'] = (['T2KReWeight_NIWGMEC_Norm_O16'], COLORS['detector'])
##################### End #######################

#################### Volumes ####################
DEFAULT_VOLUME = 'Entire P0D-FV'
XLAYER_VOLUME = 'X-layer Only'
YLAYER_VOLUME = 'Y-layer Only'
BAGXLAYER_VOLUME = 'No Y-layers'
##################### End #######################

################### Reweight ####################
BANFF_FILE = os.path.join(directories.IRODS,
                          'asg/banff/postfit/postfit_banff_2015_data_20150417_allparams.root')
MASS_FILE = os.path.join(os.getenv('P0DNUMUCCANALYSISROOT'), 'data', 'P0DMassWeights.dat')
EMC_FILE = os.path.join(directories.WORK314, 'myAnalyses', 'P0DCC0Pi', 'Systematics', 'emc.root')
##################### End #######################

################### xsCache #####################
XSCACHE_FILE = os.path.join(directories.XSCACHE_STORE, 'xscache.root')
##################### End #######################

############# flux test files ###################
# these files were generated with 5000 throws of the t2kreweight
# parameters using a small highland2 microtree. this allows us to get
# a large number of throws to calculate the flux uncertainties.
JEREMY_TEST = '/usr/users/jplopez/data41/T2K/Work/P0DCC0Pi/FluxTest/'
MCP_TEST = os.path.join(JEREMY_TEST, 'microtree.root')
RDP_TEST = os.path.join(JEREMY_TEST, 'microtree.root')
WEIGHTS_TEST = os.path.join(JEREMY_TEST, 'out2', 'weights_unified.root')
RWFILE_DEFAULT_TEST = os.path.join(JEREMY_TEST, 'out2', 'rwfile_default.root')
RWFILE_TRUTH_TEST = os.path.join(JEREMY_TEST, 'out2', 'rwfile_truth.root')
##################### End #######################

### DEBUG ###
if DEBUG:
    # Some alternative selections
    SELECT_XLAYER = SELECTIONPAIR(SELECT.reco+'&&'+getLayerCutStr('selmu_pos[2]', 'x'),
                                  SELECT.true+'&&'+getLayerCutStr('truemu_pos[2]', 'x'))
    SELECT_YLAYER = SELECTIONPAIR(SELECT.reco+'&&'+getLayerCutStr('selmu_pos[2]', 'y'),
                                  SELECT.true+'&&'+getLayerCutStr('truemu_pos[2]', 'y'))
    SELECT_BAGX = SELECTIONPAIR(SELECT.reco+'&&'+getLayerCutStr('selmu_pos[2]', 'bagx'),
                                SELECT.true+'&&'+getLayerCutStr('truemu_pos[2]', 'bagx'))

    # testing 100% pure sideband
    PURE_SIDEBANDS = [SELECTIONPAIR('Sum$(accum_level[0][1]) > 3 && np0d == 2 && topology==1', 'topology == 1'),
                      SELECTIONPAIR('Sum$(accum_level[0][1]) > 3 && np0d > 2 && topology==2', 'topology == 2')]

    MICHEL1_SIDEBANDS = [SELECTIONPAIR('Sum$(accum_level[0][1]) > 3 && np0d == 2 && nmichel==1', 'topology == 1'),
                         SELECTIONPAIR('Sum$(accum_level[0][1]) > 3 && np0d > 2', 'topology == 2')]

    # testing sideband with additiona dphiT cut
    DPHIT_SIDEBANDS = [SELECTIONPAIR(
        'Sum$(accum_level[0][1]) > 3 && np0d == 2 && sel_dphi*180/TMath::Pi()>60', 'topology == 1')]

    # debugging source error dependece on the order of sources, fixed due to bincache
    # DETECTOR['detector'] = (['T2KReWeight_fsi', 'highland_all_syst'], COLORS['detector'])


import re
import sys
import time

from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
from selenium.common.exceptions import NoSuchElementException

def get_driver():
    opts = {
        'platformName': 'Android',
        'platformVersion': '8.0',
        'appPackage': 'br.gov.sinesp.cidadao.android',
        'appActivity': 'MainActivity',
        'deviceName': 'emulator-5554',
    }
    return webdriver.Remote('http://localhost:4723/wd/hub', opts)

def search_plate(plate):
    wd = get_driver()

    # Touch vehicle search image button
    botoes = wd.find_element_by_id('botoes')
    TouchAction(wd).tap(x=400, y=500).perform()

    # Fill form and search for vehicle by plate
    wd.find_element_by_id('txPlacaLetra').send_keys(plate[:3])
    wd.find_element_by_id('txPlacaNumero').send_keys(plate[3:])
    wd.find_element_by_id('imgBtnConsultar').click()

    try:
        message = wd.find_element_by_id('message')
    except NoSuchElementException:
        message = None

    message = message and message.text
    if message and message.lower() == 'Veículo não encontrado':
            data = {
                'city': None,
                'state': None,
                'brand': None,
                'model': None,
                'year': None,
                'color': None,
                'municipio_uf': None,
                'chassis': None,
                'date': None,
                'return_code': 1,
                'return_message': message,
                'status_code': None,
                'status_message': None,
            }
            return data

    consulta = None
    start_time = int(time.time())
    while not consulta:
        end_time = int(time.time())
        if (end_time - start_time) > 30:
            print('Timeout')
            exit(1)

        try:
            consulta = wd.find_element_by_id('txDataHoraConsulta')
        except NoSuchElementException:
            pass

    try:
        situacao = wd.find_element_by_id('imgBtnSituacaoLegal')
    except NoSuchElementException:
        situacao = None

    marca_modelo = wd.find_element_by_id('txMarcaModelo').text
    munipicio_uf = wd.find_element_by_id('txMunicipioUF').text
    chassi = wd.find_element_by_id('txChassi').text
    data_hora = wd.find_element_by_id('txDataHoraConsulta').text

    city, state = munipicio_uf.split('/')
    brand_model, year, color = [x.strip() for x in marca_modelo.split('-')]
    brand = brand_model.split()[0]
    model = ' '.join(brand_model.split()[1:])
    chassis = '************' + chassi.split()[-1]
    date = data_hora.split()[-3] + ' ' + data_hora.split()[-1]
    status_code = 0 if situacao else 1
    status_message = 'Sem restrição' if situacao else 'Com restrição'

    data = {
        'city': city,
        'state': state,
        'brand': brand,
        'model': model,
        'year': year,
        'color': color,
        'municipio_uf': munipicio_uf,
        'chassis': chassis,
        'date': data_hora,
        'return_code': 0,
        'return_message': 'Sem erros.',
        'status_code': status_code,
        'status_message': status_message,
    }

    return data

if __name__ == '__main__':
    try:
        plate = ''.join(sys.argv[1].upper().split())
    except IndexError:
        print('Usage: sinesp_bot.py <plate as XYZ1234>')
        exit(1)

    results = search_plate(plate)

    import json
    print(json.dumps(results))


import os
import logging
import asyncio
import pickle
import hashlib
import random
from collections import defaultdict

log = logging.getLogger(__name__)

IFS = defaultdict(list)

def implements(ifname):
    def decorator(cls):
        IFS[ifname].append(cls)
        return cls
    return decorator

def uses(ifname, attr):
    def decorator(cls):
        if hasattr(cls, '_uses'):
            cls._uses.append((ifname, attr))
        else:
            cls._uses = [(ifname, attr)]
        return cls
    return decorator

class ABC:
    def __init__(self, name, upper, udp, addr, peers,
                 init=True, initargs=()):
        self._udp = udp
        self.name, self.upper = name, upper
        self.addr, self.peers = addr, peers
        self.members = set(peers) | {addr}
        self.N = len(self.members)
        if init:
            trigger(self, 'Init', *initargs)

        from .ifconf import get_implementation
        for ifname, attr in self._uses:
            concrete = get_implementation(ifname)
            that = concrete('%s.%s' % (name, attr), self, udp, addr, peers)
            setattr(self, attr, that)

def trigger(obj, event, *attrs):
    m = getattr(obj, 'upon_' + event, None)
    if not m:
        log.warn('Unknown event %s to %s', event, obj.__class__.__name__)
        return
    # put event to a queue instead of calling it right now
    # need this hack, since some modules have cycle dependency
    # in their Init event
    import asyncio
    loop = asyncio.get_event_loop()
    loop.call_soon(m, *attrs)

def start_timer(delay, callback, *args):
    loop = asyncio.get_event_loop()
    loop.call_later(delay, callback, *args)

def mhash(m):
    return hashlib.md5(pickle.dumps(m)).hexdigest()

class UDPProtocol:
    DELAY = 2

    def connection_made(self, transport):
        self.transport = transport
        self.handlers = {}

    def connection_lost(self, exc):
        log.warn('connection %s lost: %s', self, exc)

    def datagram_received(self, data, peer):
        try:
            name, msg = pickle.loads(data)
            handler = self.handlers[name]
        except KeyError:
            log.warn('unknown link name: %s', name)
        except:
            log.warn('bad msg from %s: %s', peer, data)
        else:
            loop = asyncio.get_event_loop()
            loop.call_later(
                random.random() * self.DELAY,
                trigger, handler, 'Deliver', peer, msg)

    def register(self, name, handler):
        self.handlers[name] = handler

        def sendto(msg, peer):
            data = pickle.dumps((name, msg))
            loop = asyncio.get_event_loop()

            def _send():
                log.debug('%s --> %s: %s', self.addr, peer, msg)
                self.transport.sendto(data, peer)
            return loop.call_later(random.random() * self.DELAY, _send)
        return sendto

class Store:
    def __init__(self, storeid):
        self.filename = os.path.abspath('__store.%s' % storeid)

    def exists(self):
        return os.path.exists(self.filename)

    def store(self, data):
        with open(self.filename, 'wb') as file:
            pickle.dump(data, file)

    def retrieve(self):
        with open(self.filename, 'rb') as file:
            obj = pickle.load(file)
        return obj


from settings import *
import pygame
import random
import pyperclip
import threading
import os
import time
from math import cos, sin

pygame.init()
os.environ['SDL_VIDEO_CENTERED'] = '1' #center window
clock = pygame.time.Clock()
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)

colors = [pygame.Color("red"), pygame.Color("purple"), pygame.Color("pink"),
		pygame.Color("white"), pygame.Color("yellow"), pygame.Color("lightblue")]

abc = "abcdefghijklmnopqrstuvwxyz"

prvi=["Ku","Ste","Ser","Gri","Di","Ni","Pa","Bo","A","Je","Ta","Gav","Mi","Sla","Sne","Snje","Di","Du","Da","Bor","Bran","Zdrav","Ra","Lje","Vu","Bo","Voj","Ja","Ran","Nov","Su","Sve","Svje",
		  "Zvje","Zve","Sve","Dmi","Slav","Mir","Rat","Rad","Boj","Stra","Ne","Ve","Sun","Ma","Ta","Fej","Ju","Je","I","Vla"]
sred=["go","ri","mi","tri","ko","li","sta","si","li","sa","ve","tja","lo","ri","dja","za","ja","brav","bor","doj","po","sa","go","sla","dran","za","tla","zda","mir","ni","lja","boj","hi",
		  "ci","ri","ja","hu","a","dzu","tu","re","mi","ho","di","mir","sti"]
zadn=["fan","gej","je","na","vle","jo","ja","ta","lo","mir","ca","djan","ven","ka","va","ljub","slav","ko","tar","sa","nja","bor","ja","din","lah","suf","da","sus","dolf","sta","sto"]

def namer():
		middle=''
		for _ in range(random.randrange(0,3)):
				middle=''.join([middle, random.choice(sred)])
		first = random.choice(prvi)
		last = random.choice(zadn)
		return first+middle+last

def planet_namer():
	output = ""
	for _ in range(random.randint(3,15)):
		output += abc[random.randint(0, 25)]

	return output

class StarType:
	def __init__(self, name, color, temperature, life=False, chance=(0,40)):
		self.name = name #Ime vrste // string
		self.color = color #Boja zvijezde // tuple(R,G,B)
		self.temperature = temperature #Temperatura planeta u celsiusu // tuple(od, do)
		self.life = life #Dal planete mogu imati zivot // True False
		self.chance = chance

#ovdje dodavaj vrste zvijezda
star_types = [
	StarType("Gentle", (255,200,255), (10,40), life=True),
	StarType("Temperate", (255,81,12), (150, 450)), #pakao
	StarType("Frozen", (125,192,255), (-300, -100)),
	StarType("Radioactive", (255,234,100), (30,70), life=True),
	StarType("Acid", (160,255,0), (-120, 120), chance=(0,80)),
	StarType("Black Hole", (10,10,10), (-273, -200), chance=(0,250)),
	StarType("White Hole", (255,255,255), (69, 420), chance=(0,1000), life=True)
]

class Planet:
	def __init__(self):
		self.radius = 0
		self.name = ""
		self.t = 0
		self.reversedRotation = False
		self.hasWater = False
		self.life = False
		self.ring = False
		self.temperature = 0 #celsius
		self.gas_giant = False
		self.moons = []

		self.gases = 0.0
		self.water = 0.0
		self.minerals = 0.0
		self.resources = 0.0
		self.population = 0

class Star:
	def __init__(self, x, y, generateSystem=True):
		seed = (x & 0xFFFF) << 16 | (y & 0xFFFF)
		random.seed(seed)
		self.type = random.choice(star_types)
		self.starExists = random.randint(*self.type.chance) == 1
		if not self.starExists:
				return

		self.color = self.type.color
		self.radius = random.randint(5, 22)

		#Ako mi treba samo da prikaze zvijezdu ne mora onda generisati sve planete i detalje o njoj
		#nego samo izgled
		if not generateSystem:
			return

		self.name = namer()
		self.planets = []
		n_planets = random.randint(0, 6)
		for _ in range(n_planets):
			p = Planet()
			p.name = namer()
			p.radius = random.randint(5,12)
			p.reversedRotation = random.randint(0,150)==1
			p.t = random.randint(0,360)
			nMoons = random.randint(-5, 3) #-5 da budu vece sanse da nemaju nista nego da svaka ima satelit
			for _ in range(nMoons):
				t = random.randint(0,360)
				reversedRotation = random.randint(0,20)==1
				p.moons.append([t, reversedRotation])

			p.ring = random.randint(0,10) == 1
			p.temperature = random.randint(*self.type.temperature)

			if p.radius >= 10:
				p.gas_giant = random.randint(0,5) == 1

			if not p.gas_giant:
				if p.temperature > 0 and p.temperature < 100:
					p.hasWater = random.randint(0,50) == 1
					if p.hasWater and self.type.life:
						p.life = random.randint(0,10) == 1

			if p.gas_giant:
				p.gases = 1.0
				p.minerals = 0.0
				p.resources = 0.0
				p.water = 0.0
			else:
				p.gases = random.random()
				p.minerals = random.random()
				p.resources = random.random()
				if p.hasWater: p.water = random.random()
			final = 1.0 / (p.gases + p.minerals + p.resources + p.water)
			p.gases *= final * 100
			p.minerals *= final * 100
			p.resources *= final * 100
			p.water *= final * 100
			#Ovaj dio sluzi da izracuna procenat %
			self.planets.append(p)

class Camera:
	def __init__(self):
		self.x = 0
		self.y = 0
		self.speed = 1

	def move(self):
		pressed = False
		key = pygame.key.get_pressed()
		speed = self.speed
		if key[pygame.K_LSHIFT]:
			speed += 2
			if key[pygame.K_LCTRL]:
				speed += 100

		if key[pygame.K_w]:
				self.y -= speed
				pressed = True

		if key[pygame.K_s]:
				self.y += speed
				pressed = True

		if key[pygame.K_a]:
				self.x -= speed
				pressed = True

		if key[pygame.K_d]:
				self.x += speed
				pressed = True

		if key[pygame.K_v]:
			#ako se pritisne V onda uzme od clipboarda podatke
			try:
				x, y = pyperclip.paste().split(":")
				x, y = int(x), int(y)
				self.teleport(x, y)
			except:
				return

		return pressed

	def teleport(self, x, y):
		self.x = x
		self.y = y

cam = Camera()

font = pygame.font.SysFont("Arial", 30)
font_star = pygame.font.SysFont("Arial", 12, bold=True)
font_info = pygame.font.SysFont("Arial", 25)

def get_mouse_in_segment(galaxy=True):
	mos_pos = pygame.mouse.get_pos()
	mos_pos = (mos_pos[0]//SEGMENTS, mos_pos[1]//SEGMENTS) #pozicija misa na ekranu
	mos_galaxy = (mos_pos[0] + cam.x, mos_pos[1] + cam.y) #pozicija misa u svemiru

	if galaxy:
		return mos_galaxy
	else:
		return mos_pos

def clicked():
	click = pygame.mouse.get_pressed()

	if click[0]:
		return 1
	elif click[2]:
		return 2

def command():
	#Konzola thread
	print("To change coords use this format - x:y or use WASD")
	while True:
		coords = input(">>> ")
		try:
			x, y = coords.split(":")
			x, y = int(x), int(y)
		except:
			continue

		cam.teleport(x, y)

threading.Thread(target=command, daemon=True).start()

width = HALF_WIDTH
height = HEIGHT
border = 1

selected = False
selectedStar = [0,0] #x,y

running = True
while running:
	clock.tick(60)
	win.fill(BLACK)

	cam.move()

	for x in range(SECTORS_X):
		for y in range(SECTORS_Y):
			#pygame.draw.rect(win, WHITE, (x*SEGMENTS,y*SEGMENTS,SEGMENTS,SEGMENTS), 1)
			star = Star(x + cam.x, y + cam.y, False)
			if star.starExists:
				center = (x*SEGMENTS+SEGMENTS//2, y*SEGMENTS+SEGMENTS//2)
				pygame.draw.circle(win, star.color, center, star.radius)
				#renderuje zvijezde bez generisanja detalja (samo izgleda)

	if selected:
		x, y = selectedStar
	else:
		x, y = get_mouse_in_segment()
	star = Star(x, y)
	if star.starExists:
		x, y = x-cam.x, y-cam.y
		center = (x*SEGMENTS+SEGMENTS//2, y*SEGMENTS+SEGMENTS//2)
		if x > -SECTORS_X and x < SEGMENTS:
			if y > -SECTORS_Y and y < SEGMENTS:
				#ako je x,y u ekranu onda radi slijedece:
				pygame.draw.circle(win, WHITE, center, star.radius+5, 1)
				name_text = font_star.render(star.name, True, WHITE)
				name_w = name_text.get_width()
				name_h = name_text.get_height()
				win.blit(name_text, (center[0] - name_w//2,center[1] + star.radius+5))
				try:
					pos_text = font_star.render(f"x:{x+cam.x} y: {y+cam.y}", True, WHITE)
					pos_w = pos_text.get_width()
					win.blit(pos_text, (center[0] - pos_w//2,center[1] +star.radius+20))
				except:
					pass

		rel_x = 0
		rel_y = HEIGHT-height - border

		if x*SEGMENTS <= rel_x + width:
			#if y*SEGMENTS >= rel_y and y*SEGMENTS <= rel_y+height:
			#ako je x na lijevoj strani onda prikaze podatke na desnoj
			rel_x = WIDTH-width-border
			rel_y = 0 - border

		rel_x_center = rel_x+width//2
		rel_y_center = rel_y+height//2
		left_bottom = (rel_x, height)

		pygame.draw.rect(win, BLACK, (rel_x, rel_y, width, height))
		pygame.draw.rect(win, WHITE, (rel_x, rel_y, width, height), 2)

		pygame.draw.circle(win, star.color, (rel_x_center, rel_y_center), star.radius)
		mos_x, mos_y = pygame.mouse.get_pos()

		texts = []
		texts.append(font_info.render(f"Name: {star.name}", True, WHITE))
		texts.append(font_info.render(f"Type: {star.type.name}", True, WHITE))
		texts.append(font_info.render(f"Number of planets: {len(star.planets)}", True, WHITE))

		text_width = texts[2].get_width()
		text_height = texts[0].get_height()
		text_offset = -text_height
		for text in reversed(texts):
			win.blit(text, (rel_x+width-text_width, height+text_offset))
			text_offset -= text_height
			#Render textova

		orbit = star.radius*2 + 25
		for n, planet in enumerate(star.planets):
			n += 1
			planet.t += -time.time()/n if planet.reversedRotation else time.time()/(n**2)

			planet_x = orbit * cos(planet.t) + rel_x_center
			planet_y = orbit * sin(planet.t) + rel_y_center

			pygame.draw.circle(win, WHITE, (rel_x_center, rel_y_center), orbit, 1)

			if planet.moons:
				moon_orbit = planet.radius + 10
				for n, (t, reversedRotation) in enumerate(planet.moons):
					n += 1 #da nebi bilo djeljenja sa 0
					t += -time.time()/n if reversedRotation else time.time()/n
					moon_x = moon_orbit * cos(t) + planet_x
					moon_y = moon_orbit * sin(t) + planet_y
					moon_size = random.randint(3,5)
					pygame.draw.circle(win, WHITE, (int(planet_x), int(planet_y)), moon_orbit, 1)
					pygame.draw.circle(win, WHITE, (int(moon_x), int(moon_y)), moon_size)
					moon_orbit += 10

			if selected:
				if (mos_x - rel_x_center)**2 + (mos_y - rel_y_center)**2 < (orbit+10)**2:
					if (mos_x - rel_x_center)**2 + (mos_y - rel_y_center)**2 > (orbit-10)**2:
						pygame.draw.circle(win, WHITE, (int(planet_x), int(planet_y)), planet.radius+3, 2)
						pygame.draw.circle(win, WHITE, (rel_x_center, rel_y_center), orbit+1, 3)

						texts = []

						texts.append(font_info.render(f"Gases: {round(planet.gases)}%", True, WHITE))
						texts.append(font_info.render(f"Minerals: {round(planet.minerals)}%", True, WHITE))
						texts.append(font_info.render(f"Resources: {round(planet.resources)}%", True, WHITE))
						texts.append(font_info.render(f"Water: {round(planet.water)}%", True, WHITE))
						texts.append(font_info.render(f"Temperature: {planet.temperature}C", True, WHITE))
						texts.append(font_info.render(f"Name: {planet.name}", True, WHITE))

						text_height = texts[0].get_height()
						text_offset = -text_height
						for text in texts:
							win.blit(text, (rel_x+3, height+text_offset))
							text_offset -= text_height

			pygame.draw.circle(win, BLUE if planet.water and not planet.life else GREEN if planet.life else GAS if planet.gas_giant else BROWN,
							(int(planet_x), int(planet_y)), planet.radius)
			orbit += 45

		if clicked() == 1:
			if mos_x >= rel_x and mos_x <= rel_x+width:
				pass
			else:
				selected = False

	if clicked() == 1:
		x, y = get_mouse_in_segment()
		star = Star(x, y, False)
		if star.starExists:
			pyperclip.copy(f"{x - (SECTORS_X//2)}:{y - (SECTORS_Y//2)}")
			if not selected:
				selected = True
				selectedStar = [x,y]

	try:
			cords = font.render(f"X:{str(cam.x)}, Y: {str(cam.y)}", True, WHITE)
	except:
			cords = font.render(f"You are too far from the center. Don't get lost", True, WHITE)
	fps = font.render(f"FPS: {str(int(clock.get_fps()))}", True, WHITE)
	win.blit(fps, FPS_POS)
	win.blit(cords, CORD_POS)

	pygame.display.flip()
	for event in pygame.event.get():
			if event.type == pygame.QUIT:
					running = False

pygame.quit()
quit()


import matplotlib
import matplotlib.pyplot as plt
from matplotlib import ticker
from sklearn import datasets, manifold
import numpy as np
def plot_line(x, y1,y2,labels = [],colors=[],title="",xlabel="",ylabel="",path=""):
    # 创建直线图
    plt.plot(x, y1, label=labels[0], color=colors[0], linestyle='-', marker='o', markersize=5)
    plt.scatter(x, y1, color='black', marker='o', s=10)  # s参数用于设置圆点的大小
    plt.plot(x, y2, label=labels[1], color=colors[1], linestyle='-', marker='o', markersize=5)
    plt.scatter(x, y2, color='black', marker='o', s=10)  # s参数用于设置圆点的大小
    # 添加标题和标签
    plt.title(title)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    # 添加图例
    plt.legend()
    # 显示图形
    plt.show()
    if path is not None:
        plt.savefig(path,dpi=600,format='png')
    plt.close()

def plot_2d(points, points_color, title=" ", cmap=None, path=None):
    """
    这里事先不指定坐标，

    """
    fig, ax = plt.subplots(figsize=(10, 10), facecolor="white", constrained_layout=True)
    fig.suptitle(title, size=16)
    x, y = points.T
    col = ax.scatter(x, y, c=points_color, cmap=cmap, s=5, alpha=1.0)
    ax.set_title(title)
    # ax.xaxis.set_major_formatter(ticker.NullFormatter())
    # ax.yaxis.set_major_formatter(ticker.NullFormatter())
    # ax.set_xlim(-100,100)
    # ax.set_ylim(-10,10)
    # plt.xlim(-1, 1)  # 设置 x 轴范围为 [2, 4]
    # plt.ylim(-1, 1)  # 设置 y 轴范围为 [15, 25]
    fig.colorbar(col, ax=ax, orientation="horizontal", shrink=0.6, aspect=60, pad=0.01)
    plt.show()
    if path is not None:
        plt.savefig(path,dpi=600,format='png')
    # 添加颜色条

def plot_3d(points, points_color,title=" ", cmap=None, path=None):
    x, y, z = points.T
    fig, ax = plt.subplots(
    figsize=(6, 6),
    facecolor="white",
    tight_layout=True,
    subplot_kw={"projection": "3d"},
    )
    fig.suptitle(title, size=16)
    col = ax.scatter(x, y, z, c=points_color, cmap=cmap, s=50, alpha=0.8)
    ax.view_init(azim=-60, elev=9)
    ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
    ax.yaxis.set_major_locator(ticker.MultipleLocator(1))
    ax.zaxis.set_major_locator(ticker.MultipleLocator(1))
    fig.colorbar(col, ax=ax, orientation="horizontal", shrink=0.6, aspect=60, pad=0.01)
    plt.show()
    if path is not None:
        plt.savefig(path,dpi=600,format='png')
if __name__ == "__main__":
    """
    test plot_2d
    """
    n_samples = 1500
    circles, y = datasets.make_circles(n_samples)
    S_color = 0.5
    n_components = 2  # number of coordinates for the manifold
    t_sne = manifold.TSNE(
        n_components=n_components,
        perplexity=30,
        init="pca",
        n_iter=250,
        random_state=0,
    )
    S_t_sne = t_sne.fit_transform(circles)
    plot_2d(S_t_sne, S_color, "T-distributed Stochastic  \n Neighbor Embedding")

    """
    test plot_3d
    """
    n_samples = 1500
    S_points, S_color = datasets.make_s_curve(n_samples, random_state=0)
    n_components = 2  # number of coordinates for the manifold
    t_sne = manifold.TSNE(
        n_components=n_components,
        perplexity=30,
        init="pca",
        n_iter=250,
        random_state=0,
    )
    S_t_sne = t_sne.fit_transform(S_points)
    plot_3d(S_t_sne, S_color, "T-distributed Stochastic  \n Neighbor Embedding")

# Here, a variable parameter x is defined and multiple ndarrray can be passed in to display in the histogram.
def plot_hist(*x, colors = ["blue"], title = "Histogram", xlabel = "", ylabel = ""):
    num_bins = 50
    fig, ax = plt.subplots()
    # the histogram of the data
    if x.dim == 1:
        n, bins, patches = ax.hist(x, num_bins, density=True, color=colors[0])
    elif x.dim == 2:
        for i in range(x.shape[0]):
            n, bins, patches = ax.hist(x[i], num_bins, density=True,color = colors[i])
    n, bins, patches = ax.hist(x, num_bins, density=True)
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    ax.set_title(title )
    plt.legend()
    # Tweak spacing to prevent clipping of ylabel
    fig.tight_layout()
    plt.show()


import os
import sys
import configparser
import time
from lib.python.subby import start_subtitle_extraction
from lib.python.plexScanner import startScan
from lib.python.plexScanner import getPlexSectionID
import subprocess

class bcolors:
        HEADER = '\033[95m'
        OKBLUE = '\033[94m'
        OKCYAN = '\033[96m'
        OKGREEN = '\033[92m'
        WARNING = '\033[93m'
        FAIL = '\033[91m'
        ENDC = '\033[0m'
        BOLD = '\033[1m'
        UNDERLINE = '\033[4m'

class Main:

    def __init__(self):
        self.logo = '''
         ___ _   _ ___ _____   __    __
        / __| | | | _ ) _ ) \ / /  __ \ \
        \__ \ |_| | _ \ _ \\ V /   |___| |
        |___/\___/|___/___/ |_|   |___| |
                                     /_/
        '''
        #check if the config file exists
        self.script_path = os.path.dirname(os.path.realpath(__file__))
        if os.path.isfile(self.script_path + '/config.ini'):
            #load the config file
            config = configparser.ConfigParser()
            config.read(self.script_path + '/config.ini')

            #--- SETUP ---
            print(bcolors.FAIL + "Loading Configs" + bcolors.ENDC)

            #plex variables
            self.plex_host = config['plex']['serverAddress']
            self.plex_token = config['plex']['serverToken']
            self.plex_port = config['plex']['serverPort']
            self.plex_libraries = config['plex']['serverLibaries'].split(',')
            self.only4k = self.str_to_bool(config['subby']['only4K'].capitalize())

            #making sure no unwanted spaces are in the libraries
            for lib in self.plex_libraries:
                index = self.plex_libraries.index(lib)
                if ' ' in lib[0]:
                    lib = self.plex_libraries[index] = lib[1:]
                if ' ' in lib[-1]:
                    self.plex_libraries[index] = lib[:-1]
            self.plex_media_path = config['plex']['plexPath']
            self.plex_local_path = config['plex']['localPath']

            #determine if the plex media path is on linux or windows
            if self.plex_media_path != "":
                #check which os seperator is used
                if '/' in self.plex_media_path:
                    self.plex_sep = 'lnx'
                else:
                    self.plex_sep = 'win'

            self.plex_notify = self.str_to_bool(config['plex']['notifyPlex'].capitalize())
            print(bcolors.OKGREEN + 'Plex config loaded!' + bcolors.ENDC)

            #subby variables
            self.tesseract_path = config['subby']['pathToTesseractEXE']
            self.export_srt = self.str_to_bool(config['subby']['exportEmbeddedSRTs'].capitalize())

            print(bcolors.OKGREEN + 'Subby config loaded!' + bcolors.ENDC)

            #get wanted languages
            self.wanted_languages = config['subby']['wantedLanguages']
            if self.wanted_languages == '':
                self.wanted_languages = 'all'
            elif ',' in self.wanted_languages:
                self.wanted_languages = self.wanted_languages.split(',')
                for lang in self.wanted_languages:
                    index = self.wanted_languages.index(lang)
                    if ' ' in lang[0]:
                        lang = self.wanted_languages[index] = lang[1:]
                    if ' ' in lang[-1]:
                        self.wanted_languages[index] = lang[:-1]

            #set local bin paths
            self.mkvToolsPath = self.script_path + '/lib/bin/mkvtools/'

            #set local java paths
            self.BDSup2SubPath = self.script_path + '/lib/java/BDSup2Sub.jar'

            #-- END SETUP --

            #check the command line arguments
            print(self.logo)
            if len(sys.argv) > 1:
                if sys.argv[1] == '--plex':
                    #print(bcolors.WARNING + 'Scanning Plex for items with subtitles, please wait.' + bcolors.ENDC)
                    for library in self.plex_libraries:
                        if self.plex_notify == True:
                            collectExtracts = []
                        print( bcolors.WARNING +' Scanning library: ' + library + ', Please wait :D' + bcolors.ENDC)
                        self.sectionID = getPlexSectionID(self.plex_host, self.plex_port, self.plex_token, library)
                        print(bcolors.OKGREEN + ' Library ID: ' + self.sectionID + bcolors.ENDC)
                        items = self.plex_scan(library=library)
                        if items != None:
                            print(bcolors.WARNING + '    Plex scan complete for {}, Processing {} items, estimated time for completeion is {} hours'.format(library,len(items), len(items) * 5 / 60 * 0.75) + bcolors.ENDC)
                            if len(items) > 0:
                                for item in items:
                                    print(bcolors.WARNING + '    Processing {}'.format(item) + bcolors.ENDC)
                                    #print(os.path.dirname(item))
                                    extract = start_subtitle_extraction(item,self.tesseract_path, self.export_srt, self.wanted_languages, self.mkvToolsPath, self.BDSup2SubPath)
                                    if extract != None:
                                        if self.plex_notify == True:
                                            file = os.path.dirname(item.replace(self.plex_local_path,self.plex_media_path))
                                            if self.plex_sep == 'win':
                                                file = file.replace('/','\\')
                                            else:
                                                file = file.replace('\\','/')
                                            collectExtracts.append(file)
                                            #self.notify_plex(item.replace(self.plex_local_path,self.plex_media_path))
                        if len(collectExtracts) > 0:
                            #time.sleep(10)
                            collectExtracts = list(set(collectExtracts))
                            for i in collectExtracts:
                                time.sleep(3)
                                self.notify_plex(i)
                        else:
                            print(bcolors.OKGREEN + '    No extractions made' + bcolors.ENDC)
                else:
                    start_subtitle_extraction(sys.argv[1],self.tesseract_path, self.export_srt, self.wanted_languages, self.mkvToolsPath, self.BDSup2SubPath)
            else:
                print(bcolors.WARNING + '    No arguments given, use --plex to toggle plex scan or give a path to a file to process, ex: "D:/blahblah.mkv"' + bcolors.ENDC)

    def notify_plex(self,plexFilePath):

        curlUrl = 'http://{}/library/sections/{}/refresh?path={}&X-Plex-Token={}'.format(self.plex_host+':'+self.plex_port,self.sectionID,plexFilePath,self.plex_token).replace(' ','%20')
        cmd = "curl \"{}""\"".format(curlUrl)
        print(bcolors.WARNING + '    Notifying Plex of changes, curl command is: {}'.format(cmd) + bcolors.ENDC)
        process = subprocess.Popen(
            cmd,
            shell=True,
            stdout=subprocess.PIPE)
        #process.wait()
        data, err = process.communicate()
        if process.returncode == 0:
            return data.decode('utf-8')
        else:
            print("Error:", err)
            return ""

    def plex_scan(self,library):
        scan = startScan(self.plex_host, self.plex_port, self.plex_token, self.plex_media_path, self.plex_local_path,self.only4k, library)
        return scan

    def str_to_bool(self,s):
        if s == 'True':
            return True
        elif s == 'False':
            return False

main = Main()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import stationspinner.libs.fields
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [
        ('evemail', '0001_initial'),
        ('character', '0020_mailmessage_receivers'),
    ]

    operations = [
        migrations.CreateModel(
            name='Mail',
            fields=[
                ('messageID', models.BigIntegerField(serialize=False, primary_key=True)),
                ('title', models.CharField(max_length=255, null=True, blank=True)),
                ('senderName', models.CharField(max_length=255, null=True, blank=True)),
                ('senderID', models.IntegerField()),
                ('sentDate', stationspinner.libs.fields.DateTimeField()),
                ('parsed_message', models.TextField(null=True)),
                ('read', models.BooleanField(default=False)),
                ('owner', models.ForeignKey(to=settings.AUTH_USER_MODEL))
            ],
            options={
                'managed': False,
            },
            bases=(models.Model,),
        ),
    ]


import os
from PIL import Image, ImageOps

# Set the input and output directories
input_dir = "./input"

output_dir = "./output"
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

output_trim_dir = "./output_trim"
if not os.path.exists(output_trim_dir):
    os.makedirs(output_trim_dir)

output_resized_dir = "./output_resized"
if not os.path.exists(output_resized_dir):
    os.makedirs(output_resized_dir)

def trim_png(filename):
    """Trims the empty space from a PNG file.
    Args:
        filename (str): The path to the input PNG file.
    Returns:
        The trimmed PIL image object.
    """
    # Open the image file and convert it to the RGBA mode
    with Image.open(filename).convert("RGBA") as img:
        # Convert the image to grayscale
        img_gray = img.convert("L")
        # Find the bounding box of the non-empty pixels in the image
        bbox = img_gray.getbbox()
        # Crop the image to the bounding box
        img_cropped = img.crop(bbox)
        # Return the trimmed image
        return img_cropped

def resize_image(img):
    """Resizes the input image to have a maximum width or height of 300 pixels while maintaining the aspect ratio.

    Args:
        img (PIL.Image): The input PIL image object.

    Returns:
        The resized PIL image object.
    """
    # Get the current size of the image
    width, height = img.size

    # Check if the image is already within the maximum size
    if width <= 300 and height <= 300:
        return img

    # Calculate the new size of the image while maintaining the aspect ratio
    if width > height:
        new_width = 300
        new_height = int(300 * height / width)
    else:
        new_height = 300
        new_width = int(300 * width / height)

    # Resize the image to the new size using bilinear interpolation
    img_resized = img.resize((new_width, new_height), resample=Image.BILINEAR)

    # Return the resized image
    return img_resized

def square_image(img_resized):
    """Fits the resized input image into a square of 300x300 pixels while maintaining the aspect ratio and filling the empty space with transparency.

    Args:
        img_resized (PIL.Image): The resized PIL image object.

    Returns:
        The squared PIL image object.
    """
    # Create a new RGBA image with transparent background
    img_square = Image.new("RGBA", (300, 300), (0, 0, 0, 0))

    # Calculate the coordinates to center the resized image in the new image
    x_offset = (300 - img_resized.width) // 2
    y_offset = (300 - img_resized.height) // 2

    # Paste the resized image onto the new image at the calculated coordinates
    img_square.paste(img_resized, (x_offset, y_offset))

    # Return the squared image
    return img_square

# Loop through each file in the input directory
for file_name in os.listdir(input_dir):
    if file_name.endswith(".png"):
        # Trim the PNG file and save the result to the output directory
        input_path = os.path.join(input_dir, file_name)
        output_path = os.path.join(output_dir, file_name)
        trim_output_path = os.path.join(output_trim_dir, file_name)
        resi_output_path = os.path.join(output_resized_dir, file_name)
        # Trim image
        trimmed_img = trim_png(input_path)
        trimmed_img.save(trim_output_path, "PNG")
        # Resize image
        resized_image = resize_image(trimmed_img)
        resized_image.save(resi_output_path, "PNG")
        # Square
        out_image = square_image(resized_image)
        out_image.save(output_path, "PNG")


#!/usr/bin/env python

import argparse
import os

__info__ = {
	'title': "Add a watermark to an image",
    'description': "Add a watermark to an image",
    'url': "http://github.com/TonkWorks/watermark_on_an_image/archive/master.zip",
    'input': [
        {
            'label': 'Image / Images to put watermark on',
            'type': 'file',
            'map': 'image',
        },
        {
            'label': 'Watermark',
            'type': 'file',
            'map': 'watermark',
        }
    ]
}

def script():
    from PIL import Image

    parser=argparse.ArgumentParser()
    parser.add_argument('--image')
    parser.add_argument('--watermark')

    args=parser.parse_args()
    image = args.image
    image_file_name = os.path.basename(image)

    watermark = args.watermark

    image = Image.open(image)
    mark = Image.open(watermark)
    image = make_watermark(image, mark, (100, 100), 0.5)

    image.save(image_file_name, "JPEG")

#http://code.activestate.com/recipes/362879/
def reduce_opacity(im, opacity):
    """Returns an image with reduced opacity."""
    from PIL import ImageEnhance

    assert opacity >= 0 and opacity <= 1
    if im.mode != 'RGBA':
        im = im.convert('RGBA')
    else:
        im = im.copy()
    alpha = im.split()[3]
    alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
    im.putalpha(alpha)
    return im

def make_watermark(im, mark, position, opacity=1):
    """Adds a watermark to an image."""
    from PIL import Image

    if opacity < 1:
        mark = reduce_opacity(mark, opacity)
    if im.mode != 'RGBA':
        im = im.convert('RGBA')
    # create a transparent layer the size of the image and draw the
    # watermark in that layer.
    layer = Image.new('RGBA', im.size, (0,0,0,0))
    if position == 'tile':
        for y in range(0, im.size[1], mark.size[1]):
            for x in range(0, im.size[0], mark.size[0]):
                layer.paste(mark, (x, y))
    elif position == 'scale':
        # scale, but preserve the aspect ratio
        ratio = min(
            float(im.size[0]) / mark.size[0], float(im.size[1]) / mark.size[1])
        w = int(mark.size[0] * ratio)
        h = int(mark.size[1] * ratio)
        mark = mark.resize((w, h))
        layer.paste(mark, ((im.size[0] - w) / 2, (im.size[1] - h) / 2))
    else:
        layer.paste(mark, position)
    # composite the watermark with the layer
    return Image.composite(layer, im, layer)

if __name__ == '__main__':
	script()


# -*- coding:utf-8 -*-
# 策略实现
from datetime import datetime
import time
import numpy as np
# import ui_thread
import pandas as pd
import talib
import numpy as np
import math

STATE_WAITING_BUY = 0
STATE_CHECK_BUY = 1
STATE_WAITING_SELL = 2

class MyStrategy:

    def __init__(self, market):
        """ 初始化
        """
        self.klines = None
        self.last_macd_bar_val = -1

        self.status = STATE_WAITING_BUY
        self.start_check_time = -1

        # 1.5秒执行1次
        LoopRunTask.register(self.on_update_data_ticker, 0.1)

    async def on_update_data_ticker(self, *args, **kwargs):
        """ 定时执行任务
        """
        ori_data, _ = await self._rest_api.get_klines(self.symbol, '5min', sfrom=int(time.time() - 3600 * 5), to=int(time.time()))
        if not ori_data:
            logger.info("ori data is None: %r", ori_data)
            return
        data = ori_data['data']
        for info in data:
            info['time'] = datetime.fromtimestamp(int(info['id'])).now()
            del info['id']
        self.klines = data
        df_stockload = pd.DataFrame(self.klines)
        await self.on_ticker()

    async def on_ticker(self, *args, **kwargs):
        return

        if self.status == STATE_WAITING_BUY:
            await self.WaitToBuy()
        elif self.status == STATE_CHECK_BUY:
            self.CheckBuy()
        elif self.status == STATE_WAITING_SELL:
            await self.WaitToSell()

    # 判断是否购买成功
    def CheckBuy(self):
        if not self.trader.position:
            return
        if self.trader.position.long_quantity or self.trader.position.short_quantity or time.time() - self.start_check_time > 15:
            self.status = STATE_WAITING_SELL
            logger.info("[STATE] change to ", self.status)
        else:
            logger.info("[Check][Wait] Wait buy")

    # 等待时机购买
    async def WaitToBuy(self):
        if not self.klines or self.ask1_price == 0:
            return
        if not self.trader.assets or not self.trader.assets.assets.get(self.raw_symbol):
            return
        if self.macd_bar is None:
            return

        if self.macd_bar[-2] * self.macd_bar[-3] < 0 and self.macd_bar[-1] * self.macd_bar[-2] >= 0:
            if self.macd_bar[-2] > 0:
                # 买多
                price = self.ask1_price
                volume = math.floor(float(self.trader.assets.assets.get(self.raw_symbol).get("free")) * self.level * price // self.face_value)
                if volume <= 0:
                    logger.info("[Err][Buy] Can't buy! ")
                    return
                quantity = volume
                direction = 1
                logger.info("[OP][Buy] direction=up, price=%r, quantity=%r" % (price, quantity))
                order_id, err = await self.trader.create_order('BUY', str(price), int(quantity), lever_rate=self.level)
            else:
                price = self.bid1_price
                volume = math.floor(float(self.trader.assets.assets.get(self.raw_symbol).get("free")) * self.level * price // self.face_value)
                if volume <= 0:
                    logger.info("[Err][Buy] Can't buy! ")
                    return
                # 买空
                direction = -1
                quantity = -volume
                logger.info("[OP][Buy] direction=down, price=%r, quantity=%r" % (price, quantity))
                order_id, err = await self.trader.create_order('SELL', str(price), int(quantity), lever_rate=self.level)
            if err is None and order_id:
                self.status = STATE_CHECK_BUY
                self.start_check_time = time.time()
                logger.info("[STATE] change to ", self.status)
            logger.info("[RET][Buy] order_id=%r, err=%r" % (order_id, err))

    async def WaitToSell(self):
        if not self.trader.position:
            return
        if self.macd_bar is None:
            return

        if self.trader.orders:
            del_orders = []
            for order_id in self.trader.orders:
                if self.trader.orders[order_id].trade_type in [3, 4]:
                    del_orders.append(order_id)

            if del_orders:
                logger.info("[OP][Cancel] cancel order=%r" % (del_orders, ))
                _, error = await self.trader.revoke_order(*del_orders)
                if error:
                    return

        position = self.trader.position
        if position.long_quantity == 0 and position.short_quantity == 0:
            del_orders = self.trader.orders.keys()
            if del_orders:
                logger.info("[OP][Cancel] status ready to change, cancel order=%r" % (del_orders, ))
                _, error = await self.trader.revoke_order(*del_orders)
                if error:
                    return

            self.status = STATE_WAITING_BUY
            logger.info("[STATE] change to ", self.status)
            return

        if position.long_quantity:
            buy_price = position.long_avg_price
            win_rate = 100 * self.level * (self.bid1_price - buy_price) / buy_price
            sail_num = 0

            if win_rate < -9:
                sail_num = position.long_quantity
            elif self.macd_bar[-1] < self.macd_bar[-2] and self.macd_bar[-2] < self.macd_bar[-3] and win_rate >= 1:
                sail_num = position.long_quantity

            if sail_num:
                order_id, err = await self.trader.create_order('SELL', self.bid1_price, position.long_quantity, lever_rate=self.level)
                logger.info("[OP][SELL] direction=up, price=%r, quantity=%r, err=%r, order_id=%r" % (self.bid1_price, position.long_quantity, err, order_id))
        if position.short_quantity:
            buy_price = position.short_avg_price
            win_rate = 100 * self.level * (buy_price - self.ask1_price) / buy_price
            sail_num = 0

            if win_rate < -9:
                sail_num = position.short_quantity
            elif self.macd_bar[-1] > self.macd_bar[-2] and self.macd_bar[-2] > self.macd_bar[-3] and win_rate >= 1:
                sail_num = position.short_quantity

            if sail_num:
                order_id, err = await self.trader.create_order('BUY', self.bid1_price, -position.short_quantity, lever_rate=self.level)
                logger.info("[OP][SELL] direction=down, price=%r, quantity=%r, err=%r, order_id=%r" % (self.bid1_price, -position.long_quantity, err, order_id))


import json
from pathlib import Path
import pickle
import networkx as nx
import numpy as np
import pandas as pd
import seaborn as sns
from giskard.graph import MaggotGraph
from giskard.utils import to_pandas_edgelist
from sklearn.utils import Bunch

version_loc = Path(__file__).parent / "version.txt"
with open(version_loc) as f:
    version = f.readline()

DATA_VERSION = version
DATA_PATH = Path(__file__).parent.parent.parent.parent  # don't judge me judge judy
DATA_PATH = DATA_PATH / "data"

def _get_folder(path, version):
    if path is None:
        path = DATA_PATH
    if version is None:
        version = DATA_VERSION
    folder = path / version
    return folder

def load_node_meta(path=None, version=None):
    folder = _get_folder(path, version)
    meta = pd.read_csv(folder / "meta_data.csv", index_col=0)
    meta.sort_index(inplace=True)
    return meta

def load_edgelist(graph_type="G", path=None, version=None):
    folder = _get_folder(path, version)
    edgelist = pd.read_csv(
        folder / f"{graph_type}_edgelist.txt",
        delimiter=" ",
        header=None,
        names=["source", "target", "weight"],
    )
    return edgelist

def load_networkx(graph_type="G", node_meta=None, path=None, version=None):
    edgelist = load_edgelist(graph_type, path=path, version=version)
    g = nx.from_pandas_edgelist(edgelist, edge_attr="weight", create_using=nx.DiGraph())
    if node_meta is not None:
        meta_data_dict = node_meta.to_dict(orient="index")
        nx.set_node_attributes(g, meta_data_dict)
    return g

def load_adjacency(
    graph_type="G", nodelist=None, output="numpy", path=None, version=None
):
    g = load_networkx(graph_type=graph_type, path=path, version=version)
    if output == "numpy":
        adj = nx.to_numpy_array(g, nodelist=nodelist)
    elif output == "pandas":
        adj = nx.to_pandas_adjacency(g, nodelist=nodelist)
    return adj

def load_palette(path=None, version=None):
    folder = _get_folder(path, version)
    with open(folder / "simple_color_map.json", "r") as f:
        palette = json.load(f)
    return palette

def load_maggot_graph(path=None, version=None):
    nodes = load_node_meta()
    g = nx.MultiDiGraph()
    g.add_nodes_from(nodes.index)
    nx.set_node_attributes(g, nodes.to_dict(orient="index"))
    graph_types = ["Gaa", "Gad", "Gda", "Gdd"]
    for graph_type in graph_types:
        g_type = load_networkx(graph_type=graph_type)
        for u, v, data in g_type.edges(data=True):
            g.add_edge(u, v, key=graph_type[1:], edge_type=graph_type[1:], **data)

    g_type = load_networkx(graph_type="G")
    for u, v, data in g_type.edges(data=True):
        g.add_edge(u, v, key="sum", edge_type="sum", **data)

    edges = to_pandas_edgelist(g)

    return MaggotGraph(g, nodes, edges)

def load_network_palette():
    colors = sns.color_palette("Set2")
    palette = dict(zip(["Left", "Right"], [colors[0], colors[1]]))
    return palette, "Side"

def load_node_palette(key="simple_group"):
    if key == "merge_class":
        from src.visualization import CLASS_COLOR_DICT

        return CLASS_COLOR_DICT, "merge_class"
    elif key == "simple_group":
        palette = load_palette()
        return palette, "simple_group"

def load_navis_neurons(ids=None, path=None, version=None):
    folder = _get_folder(path, version)
    with open(folder / "neurons.pickle", "rb") as f:
        neuron_list = pickle.load(f)
    return neuron_list

# def load_networkx(graph_type, base_path=None, version=DATA_VERSION):
#     if base_path is None:
#         base_path = DATA_PATH
#     data_path = Path(base_path)
#     data_path = data_path / version
#     file_path = data_path / (graph_type + ".graphml")
#     graph = nx.read_graphml(file_path, node_type=str, edge_key_type="str")
#     return graph

def load_data(graph_type, base_path=None, version=None):
    # TODO deprecate this and pull out of old scripts
    if base_path is None:
        base_path = DATA_PATH
    if version is None:
        version = DATA_VERSION

    data_path = Path(base_path)
    data_path = data_path / version

    edgelist_path = data_path / (graph_type + ".edgelist")
    meta_path = data_path / "meta_data.csv"

    graph = nx.read_edgelist(
        edgelist_path, create_using=nx.DiGraph, nodetype=int, data=[("weight", int)]
    )
    meta = pd.read_csv(meta_path, index_col=0)
    adj = nx.to_numpy_array(graph, nodelist=meta.index.values, dtype=float)
    missing_nodes = np.setdiff1d(meta.index, list(graph.nodes()))
    for node in missing_nodes:
        graph.add_node(node)

    return Bunch(graph=graph, adj=adj, meta=meta)