"""A module containing a TextIngestor class."""

from .IngestorInterface import IngestorInterface
from .QuoteModel import QuoteModel

from typing import List

class TextIngestor(IngestorInterface):
    """A class TextIngestor representing a strategy object which realizes IngestorInterface."""

    allowed_extensions = ['txt']

    @classmethod
    def parse(cls, path:str) -> List[QuoteModel]:
        """Parse a .txt file at the passed destination and output the content as a collection of QuoteModel objects."""
        quotes = []

        with open(path, 'r') as infile:
            for line in infile.readlines():
                line = line.strip('\n\r').strip()
                if len(line) > 0:
                    parse = line.split('-')
                    quote = QuoteModel(parse[0], parse[1])
                    quotes.append(quote)

        return quotes


import settings
import requests
import re
import SecondReportTitle

# 管理中心url
url = 'https://service.account.weibo.com/index?type=5&status=0&page=%d'

def first_page():
    for i in range(0, 5):
        # 拼接翻页url
        url1 = url % i
        # 向管理中心发起请求获取响应
        response1 = requests.get(url=url1, headers=settings.headers).content\
            .decode('unicode-escape')

        # 提取管理中心里每个被举报人的拜访数
        visit_counts = re.findall(r'<td>(\d+)<\\/td>', response1)

        # 获取所有被举报人的url
        by_url = re.findall(r'a href="(.+)"\starget="_blank".+\n\s\s<td>\d+',
                            response1)

        # 获取所有被举报时间
        report_time = re.findall(r'<td>(.+)<\\/td>\n\t<\\/tr>', response1)

        # 获取所有举报标题url
        title_url = re.findall(r'class="m_table_tit"\s*><a\s*href="(.+)"+?\s',
                               response1)

        data_dict = {'visit_counts': visit_counts,
                     'by_url': by_url,
                     'report_time': report_time,
                     'title_url': title_url,
                     'page1': i
                     }

        # print(response1)
        #
        # print(len(by_url))
        # print(by_url)
        #
        # print(len(visit_counts))
        # print(visit_counts)
        #
        # print(len(report_time))
        # print(report_time)
        #
        # print(len(title_url))
        # print(title_url)

        # 举报标题界面数据爬取
        SecondReportTitle.second_page(data_dict)

if __name__ == "__main__":
    first_page()


from __future__ import annotations
from time import perf_counter
from typing import Any, Dict
from uuid import uuid4

from traffic_agent.sumo import Simulation

MAX_ALLOWED_STEPS = 5000
PRINT_EVERY = 250
# MAX_ALLOWED_STEPS = 100 # For testing

class TrafficAgent():

    def __init__(
        self,
    ):
        self._id = uuid4()

    def execute(self, simulation: Simulation) -> Dict[str, float]:
        steps = 0
        simulation_times = 0.0
        agent_times = 0.0
        while not simulation.complete():
            steps += 1
            if steps % PRINT_EVERY == 0:
                print(f"Step {steps}")
                print(f"Average of {simulation_times/PRINT_EVERY}s per simulation step and {agent_times/PRINT_EVERY}s per agent step")
                simulation_times = 0.0
                agent_times = 0.0
            if steps >= MAX_ALLOWED_STEPS:
                print(f"Exceeded max steps allowed - {MAX_ALLOWED_STEPS}")
                break
            start_simulation = perf_counter()
            simulation.step()
            end_simulation = perf_counter()
            self.step(simulation)
            end_agent = perf_counter()

            simulation_times += end_simulation - start_simulation
            agent_times += end_agent - end_simulation

        simulation.stop()
        stats = simulation.get_stats()
        print("STATS", stats)
        simulation.shutdown()

        return stats

    def step(self, simulation: Simulation):
        raise NotImplemented

    def __eq__(self, other: TrafficAgent) -> bool:
        if other is None:
            return False
        return self._id == other._id

    def __le__(self, other: TrafficAgent) -> bool:
        if other is None:
            return False
        return self._id < other._id


import sys
import asyncio
import time

from bleak import BleakClient

ADDRESS = "A1379F49-AA6C-D07E-5B6B-C7971F54AC85"
GENERAL_CHAR = "0000ee02-0000-1000-8000-00805f9b34fb"
STEP = 16
DELAY = 42

def toRGB(c, a):
    return bytearray([0x69, 0x96, 0x5, 0x2, c[0], c[1], c[2], a])

def calcTime(s):
    time_obj = time.gmtime(s)
    return time.strftime("%H:%M:%S", time_obj)

async def main(address):
    print("ok wait")
    async with BleakClient(address) as client:
        total = STEP * DELAY
        print("seconds: " + str(total))
        for i in range(STEP, -1, -1):
            color = [i, 0, round(i/2)]
            alpha = 0
            converted = toRGB(color, alpha)
            print(color)
            await client.write_gatt_char(GENERAL_CHAR, converted)
            print("SET ok: " + str(i))
            for j in range(DELAY, 0, -1):
                total = total - 1
                print("\r" + str(j) + "s until next jump ( " + calcTime(total) + " til finish)               ", end="")
                time.sleep(1)

if __name__ == "__main__":
    asyncio.run(main(sys.argv[1] if len(sys.argv) == 2 else ADDRESS))


#%%
from pathlib import Path
import os
import pandas as pd

dir_root = Path(
    "/mnt/win/UMoncton/OneDrive - Université de Moncton/Data/Reference/Arctic/Complete"
)
dest_dir = Path("/mnt/win/UMoncton/Doctorat/dev/dlbd/applications/stage hugo/results")
global_path = dest_dir / "global_labels.csv"
grouped_path = dest_dir / "grouped_labels.csv"
ref_classes_path = Path(
    "/mnt/win/UMoncton/Doctorat/dev/dlbd/examples/resources/reference_classes.csv"
)
corrected_path = dest_dir / "corrected_labels.csv"

#%%
# Alire: https://peps.python.org/pep-0008/

# Ajout d'argument a la fonction pour eviter d'utiliser une valeur definie en dehors et eviter
# les effets de bord
def assemblage(src_dir, final_dest_path, gb_dest_path, ext=".csv"):
    res = []
    # Tu utilises pathlib pour generer ton chemin, autant ne pas melanger les styles
    if not final_dest_path.exists():
        file_list = list(src_dir.rglob("*" + ext))
        for file_path in file_list:
            path_plot = file_path.parts[-2]
            path_year = file_path.parts[-3]
            try:
                print("Loading file " + str(file_path))
                df = pd.read_csv(file_path)
                df["year"] = path_year
                df["plot"] = path_plot
                res.append(df)
            except Exception:
                print("Error, impossible to read file {}".format(file_path))

        ############################## Zone de sauvegarde + concaténation ##############################
        df_final = pd.concat(res).drop_duplicates().reset_index(drop=True)
        df_final.to_csv(final_dest_path, index=False)
    else:
        df_final = pd.read_csv(final_dest_path)
    df_gb = df_final.groupby(["Label", "Related"]).agg(
        "count"
    )  # Enregistrement d'un csv brute de Label et de Related

    df_gb.reset_index().to_csv(gb_dest_path, index=False)

    return df_final, df_gb

final, grouped = assemblage(dir_root, global_path, grouped_path)

#%%

###########################################################
##########################             ##########################
#############################   Feature   #############################
##########################             ##########################
###########################################################

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

def replace_related(df, df_ref):
    # Fonction de d'harmonisation des Relateds en fonction des Labels
    for (Label, Related) in df_ref.itertuples(index=False):
        df.loc[
            df.Label == Label, "Related"
        ] = Related  # Modification du Related en fonction du Label de reference
    df.loc[df.Related.isnull(), "Related"] = ""
    return df

ref_classes = pd.read_csv(ref_classes_path)
corrected = replace_related(final, ref_classes)
corrected.to_csv(corrected_path, index=False)

corrected.groupby(["Label", "Related"]).count()

#%%

##################################################################
#########################   Feature Dispatch   #########################
##################################################################

def Dispatch_Plot_Year():
    df = pd.read_csv(name4)
    try:
        del df["Unnamed: 0"]
    except:
        pass
    for (Plot, Year), group in df.groupby(["Plot", "Year"]):
        Year = str(Year)
        try:
            os.makedirs(name5 / Essai0 / Year)
        except FileExistsError:
            pass
        group.to_csv(f"{name5/Essai0/Year/Plot}.csv", index=False)

def Dispatch_Label():
    df = pd.read_csv(name4)
    for (Label), group in df.groupby(["Label"]):
        try:
            os.makedirs(name5 / Essai)
        except FileExistsError:
            pass
        group1 = group.groupby(["Label"]).sum()
        del group1["id"]
        del group1["Year"]
        del group1["noise"]
        group1.to_csv(f"{name5/Essai/Label}.csv", index=False)

def Unpack():
    Dispatch_Plot_Year()
    Dispatch_Label()
    fenetre = Tk()
    label = Label(fenetre, text="Dispatch done")
    label.pack()
    b1 = Button(fenetre, text="Ok", command=fenetre.destroy)
    b1.pack()
    fenetre.mainloop()

###############################################################
#########################   Feature Stats   #########################
###############################################################

def Stat_Mean():
    df_Stat_Mean = pd.read_csv(name4)  # Ouverture du fichier rangé
    try:
        del df_Stat_Mean["Unnamed: 0"]
    except:
        pass
    df_Stat = (
        df_Stat_Mean.loc[
            :, ["MaxAmp", "MinAmp", "MeanAmp", "MinimumFreq_Hz", "MaximumFreq_Hz"]
        ]
        .groupby(df_Stat_Mean["Label"])
        .mean()
    )
    df_Stat.columns = [
        "MaxAmp_Mean",
        "MinAmp_Mean",
        "MeanAmp_Mean",
        "MinimumFreq_Hz_Mean",
        "MaximumFreq_Hz_Mean",
    ]
    df_Stat.to_csv(f"{name5/Essai1}.csv", index=True)  # Enregistrement du fichier
    return df_Stat

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

def Stat_Max():
    df_Stat_Max = pd.read_csv(name4)  # Ouverture du fichier rangé
    try:
        del df_Stat_Max["Unnamed: 0"]
    except:
        pass
    df_Stat = (
        df_Stat_Max.loc[
            :, ["MaxAmp", "MinAmp", "MeanAmp", "MinimumFreq_Hz", "MaximumFreq_Hz"]
        ]
        .groupby(df_Stat_Max["Label"])
        .max()
    )
    df_Stat.columns = [
        "MaxAmp_Max",
        "MinAmp_Max",
        "MeanAmp_Max",
        "MinimumFreq_Hz_Max",
        "MaximumFreq_Hz_Max",
    ]
    df_Stat.to_csv(f"{name5/Essai2}.csv", index=False)  # Enregistrement du fichier
    return df_Stat

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

def Stat_Min():
    df_Stat_Min = pd.read_csv(name4)  # Ouverture du fichier rangé
    try:
        del df_Stat_Min["Unnamed: 0"]
    except:
        pass
    df_Stat = (
        df_Stat_Min.loc[
            :, ["MaxAmp", "MinAmp", "MeanAmp", "MinimumFreq_Hz", "MaximumFreq_Hz"]
        ]
        .groupby(df_Stat_Min["Label"])
        .min()
    )
    df_Stat.columns = [
        "MaxAmp_Min",
        "MinAmp_Min",
        "MeanAmp_Min",
        "MinimumFreq_Hz_Min",
        "MaximumFreq_Hz_Min",
    ]
    df_Stat.to_csv(f"{name5/Essai3}.csv", index=True)  # Enregistrement du fichier
    return df_Stat

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

def Stat_Std():
    df_Stat_Std = pd.read_csv(name4)  # Ouverture du fichier rangé
    try:
        del df_Stat_Std["Unnamed: 0"]
    except:
        pass
    df_Stat_Std["Sing_Time_Seconds"] = (
        df_Stat_Std["LabelEndTime_Seconds"] - df_Stat_Std["LabelStartTime_Seconds"]
    )  # Creation d'une colonne qui recup le temps de chaque chant
    df_Stat = (
        df_Stat_Std.loc[:, ["Sing_Time_Seconds"]].groupby(df_Stat_Std["Label"]).std()
    )
    df_Stat.columns = ["Std"]
    df_Stat.to_csv(f"{name5/Essai5}.csv", index=True)  # Enregistrement du fichier
    return df_Stat

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

def Stat_Global():
    df_Stat_Global = pd.read_csv(name4)  # Ouverture du fichier rangé
    try:
        del df_Stat_Global["Unnamed: 0"]
    except:
        pass
    df_Label = pd.read_csv(name3, delimiter=";")
    try:
        del df_Label["Unnamed: 0"]
    except:
        pass
    df_Stat = (
        df_Stat_Global.loc[:, ["LabelStartTime_Seconds", "LabelEndTime_Seconds"]]
        .groupby(df_Stat_Global["Label"])
        .sum()
    )
    df2 = df_Stat_Global["Label"].value_counts()
    frames = [df_Stat, df2]  # Assemblage
    A, B, C, D = Stat_Min(), Stat_Max(), Stat_Mean(), Stat_Std()
    result = (
        pd.concat(frames, axis=1).drop_duplicates().reset_index(drop=True)
    )  # Assemblage concaténation
    result["Total_Sing"] = (
        result["LabelEndTime_Seconds"] - result["LabelStartTime_Seconds"]
    )  # Durée total de chant
    result["Mean_Sing"] = result["Total_Sing"] / result["Label"]  # Temps moyen de chant
    frames1 = [A, B, C, D]
    result1 = pd.concat(frames1, axis=1).drop_duplicates().reset_index(drop=True)
    frames2 = [result1, result]
    result3 = pd.concat(frames2, axis=1).drop_duplicates().reset_index(drop=True)
    result3["Labels"] = df_Label["Label"]
    result3.set_index("Labels", inplace=True)
    result3.to_csv(
        f"{name5/Essai4}.csv", index=True
    )  # Enregistrement du fichier    #Enregistrement du fichier

    fenetre = Tk()
    label = Label(fenetre, text="Done")
    label.pack()
    b1 = Button(fenetre, text="Ok", command=fenetre.destroy)
    b1.pack()
    b2 = Button(fenetre, text="Graph", command=Graph_Global)
    b2.pack()
    fenetre.mainloop()

    return result3

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

###############################################################
#########################   Feature Manip   #########################
###############################################################

def Stat_Label():
    try:
        global subset
        df = pd.read_csv(name4)
        try:
            del df["Unnamed: 0"]
        except:
            pass
        df2 = df["Label"].value_counts()
        df3 = (
            df.loc[:, ["LabelStartTime_Seconds", "LabelEndTime_Seconds"]]
            .groupby(df["Label"])
            .sum()
        )
        df3["Total_Sing"] = df3["LabelEndTime_Seconds"] - df3["LabelStartTime_Seconds"]
        del df3["LabelEndTime_Seconds"], df3["LabelStartTime_Seconds"]
        df3["Total_Tag"] = df2
        df3["Mean_Sing_Seconds"] = df3["Total_Sing"] / df3["Total_Tag"]
        df4 = df.loc[:, ["background"]].groupby(df["Label"]).sum()
        df3["Background"] = df4
        df3["%_Background"] = df3["Background"] * 100 / df3["Total_Tag"]
        Noice1 = df[df["noise"] == 1].groupby(df["Label"]).sum()
        Noice1["%Noice"] = Noice1["noise"] * 100 / df3["Total_Tag"]
        Noice2 = (df[df["noise"] == 2].groupby(df["Label"]).sum()) / 2
        Noice2["%Noice"] = Noice2["noise"] * 100 / df3["Total_Tag"]
        Noice3 = (df[df["noise"] == 3].groupby(df["Label"]).sum()) / 3
        Noice3["%Noice"] = Noice3["noise"] * 100 / df3["Total_Tag"]
        (A, B, C) = (
            round(Noice1["%Noice"], 2),
            round(Noice2["%Noice"], 2),
            round(Noice3["%Noice"], 2),
        )
        (
            df3["Rain"],
            df3["Rain%"],
            df3["Wind"],
            df3["Wind%"],
            df3["Both"],
            df3["Both3%"],
        ) = (Noice1["noise"], A, Noice2["noise"], B, Noice3["noise"], C)
        df3["Index"] = df3.index.drop_duplicates()
        df3.to_csv(f'{name5/"Monki"}.csv', index=True)
        df3_dic = df3.loc[subset].to_dict()
        print("Bonjour")
        fenetre = Tk()
        label = Label(fenetre, text=df3.loc[subset])
        label.pack()
        b1 = Button(fenetre, text="Ok", command=fenetre.destroy)
        b1.pack()
        b2 = Button(fenetre, text="Graph", command=Graph_Label)
        b2.pack()
        fenetre.mainloop()
        return (df3.loc[subset], df3_dic)
    except:
        fenetre = Tk()
        label = Label(
            fenetre,
            text="Unknown keyword, check the writing and be careful with the case",
        )
        label.pack()
        label1 = Label(fenetre, text="Back to main menu")
        label1.pack()
        b1 = Button(fenetre, text="Ok", command=fenetre.destroy)
        b1.pack()
        fenetre.mainloop()

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

def Input():
    def Jsp():
        root = Tk()
        root.geometry("300x200")

        def action(event):
            # Obtenir l'élément sélectionné
            global subset
            subset = listeCombo.get()
            print("Vous avez sélectionné : '", subset, "'")

        labelChoix = Label(root, text="Veuillez faire un choix !")
        labelChoix.pack()

        # 2) - créer la liste Python contenant les éléments de la liste Combobox
        df1 = pd.read_csv(name3, delimiter=";")
        test = df1["Label"].tolist()
        listeLabel = test

        # 3) - Création de la Combobox via la méthode ttk.Combobox()
        listeCombo = ttk.Combobox(root, values=listeLabel)
        listeCombo.current(0)

        listeCombo.pack()
        listeCombo.bind("<<ComboboxSelected>>", action)
        b3 = Button(root, text="Next", font=("times", 18), command=Stat_Label)
        b3.pack()
        b4 = Button(root, text="Leave", font=("times", 18), command=root.destroy)
        b4.pack()

        root.mainloop()

    fen = Tk()
    b1 = Button(fen, text="Per Label", font=("times", 18), command=Jsp)
    b2 = Button(fen, text="Global", font=("times", 18), command=Stat_Global)
    b3 = Button(fen, text="Leave", font=("times", 18), command=fen.destroy)
    b1.pack(side="top")
    b2.pack()
    b3.pack(side=("bottom"))
    fen.mainloop()

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

def Graph_Label():
    print("test")

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

def Graph_Global():
    print("test")

###############################################################
#########################    Main Window    #########################
###############################################################

lafen = Tk()

b1 = Button(lafen, text="Assemblage", font=("times", 18), command=Assemblage)
b2 = Button(lafen, text="Input", font=("times", 18), command=Input)
b3 = Button(lafen, text="Sort", command=Sort)
b4 = Button(lafen, text="Dispatch", command=Unpack)
b5 = Button(lafen, text="Leave", command=lafen.destroy)

b1.pack()
b2.pack()
b3.pack()
b4.pack()
b5.pack()

lafen.mainloop()


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

from captcha.models import CaptchaStore
from django.db.models import Q
from django.http import JsonResponse
from django.utils import timezone

from Account.models import User, PhoneCaptcha, EmailCaptcha
from Dic.models import CoinType
from .exceptions import *
from .models import BalanceWithDraw, CoinTypeProperty

def fail(code=10001, message='请求参数格式错误'):
    return JsonResponse({'result': False, 'code': code, 'msg': message})

def success(data=None, **kwargs):
    if data is None:
        return JsonResponse({'result': True, 'data': {'status': 1}})
    else:
        response = dict({'result': True, 'data': data}, **kwargs)
        return JsonResponse(response)

def check_coin_type(coin_type):
    try:
        ct = CoinType.objects.get(id=coin_type)
        return ct.code
    except:
        raise CoinTypeNotFoundException(code=10033, message='找不到此币种，请确认币种信息')

def check_captcha(key, value):
    if value:
        CaptchaStore.remove_expired()
        try:
            CaptchaStore.objects.get(response=value, hashkey=key,
                                     expiration__gt=timezone.now()).delete()
        except CaptchaStore.DoesNotExist as e:
            raise CaptchaFailException(code=10007, message='验证码校验失败')
    else:
        raise CaptchaFailException(code=10008, message='验证码不能为空')

def check_phone_captcha(phone_number, captcha):
    if not User.objects.filter(phone_number=phone_number, is_phone_verified=True).exists():
        raise PhoneCaptchaFailException(code=10019, message='手机号码未注册或未通过认证')

    if captcha:
        PhoneCaptcha.remove_expired()
        try:
            PhoneCaptcha.objects.get(response=captcha,
                                     phone_number=phone_number,
                                     expiration__gt=timezone.now()).delete()
        except PhoneCaptcha.DoesNotExist:
            raise PhoneCaptchaFailException(code=10007, message='验证码校验失败')
    else:
        raise PhoneCaptchaFailException(code=10008, message='验证码不能为空')

def check_email_captcha(email, captcha):
    if not User.objects.filter(email=email, is_email_verified=True).exists():
        raise EmailCaptchaFailException(code=10019, message='电子邮件未注册或未通过认证')

    if captcha:
        EmailCaptcha.remove_expired()
        try:
            EmailCaptcha.objects.get(response=captcha,
                                     email=email,
                                     expiration__gt=timezone.now()).delete()
        except EmailCaptcha.DoesNotExist:
            raise EmailCaptchaFailException(code=10007, message='验证码校验失败')
    else:
        raise EmailCaptchaFailException(code=10008, message='验证码不能为空')

def check_withdraw_upper_limit(user, coin_type, amount):
    time_range = (timezone.now().date(), timezone.now())
    status_not = 14
    AMOUNTCOINTYPELIMIT = dict([(p.coin_type, p.day_limit) for p in CoinTypeProperty.objects.all()])
    bwds = BalanceWithDraw.objects.filter(
        address__user__id=user.id,
        address__coin_type=coin_type,
        create_time__range=time_range
    ).filter(~Q(status=status_not))
    if not len(bwds):
        return
    amount_sum = 0
    for bwd in bwds:
        amount_sum += bwd.amount
    if amount_sum + amount > AMOUNTCOINTYPELIMIT[coin_type]:
        raise AmountExceededLimitException(code=10073, message='今日提币金额已达上限')


import pygame, os, random
from math import sqrt

width, height = 800, 800
screen = pygame.display.set_mode((width, height))
running = True
screen.fill((255, 255, 255))
def load_image(name, colorkey=None):
    fullname = os.path.join('data', name)
    image = pygame.image.load(fullname)
    if colorkey is not None:
        if colorkey == -1:
            colorkey = image.get_at((0, 0))
        image.set_colorkey(colorkey)
    return image

class Bomb(pygame.sprite.Sprite):
    image = load_image("g11.jpg", 1)
    w, h = 100, 100
    image = pygame.transform.scale(image, (w, h))

    def __init__(self, group):
        w, h = 100, 100
        # НЕОБХОДИМО вызвать конструктор родительского класса Sprite. Это очень важно!!!
        super().__init__(group)
        self.image = Bomb.image
        self.rect = self.image.get_rect()
        self.rect.x = 200
        self.rect.y = 200

class bullet(pygame.sprite.Sprite):
    image = load_image("g11.jpg", 1)

    image = pygame.transform.scale(image, (10, 10))

    def __init__(self, group, xy):
        # НЕОБХОДИМО вызвать конструктор родительского класса Sprite. Это очень важно!!!
        super().__init__(group)
        self.image = bullet.image
        self.rect = self.image.get_rect()
        self.rect.x = 200
        self.rect.y = 200
        self.speed = 1.0
        nx, ny = xy
        self.rast = sqrt((200 - nx) ** 2 + (200 - ny) ** 2)
        sin = (-200 + nx) / sqrt((200 - nx)**2 + (200 - ny)**2)
        cos = (-200 + ny) / sqrt((200 - nx) ** 2 + (200 - ny) ** 2)
        self.nx, self.ny = round(sin * 50.0), round(cos * 50.0)
        self.pr = 0
        print(1)

    def update(self):
        self.rect.x = self.rect.x + self.nx
        self.rect.y = self.rect.y + self.ny
        self.pr += self.speed
        if self.rast < self.pr:
            return False

clock = pygame.time.Clock()

bomb_image = load_image("car2.png")
bomb_image = pygame.transform.scale(bomb_image, (100, 100))
all_sprites = pygame.sprite.Group()
bul = pygame.sprite.Group()
for _ in range(1):
    Bomb(all_sprites)
gh = False
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            gh = True
            bullet(bul, event.pos)
        if event.type == pygame.MOUSEBUTTONUP:
            gh = False
        if event.type == pygame.MOUSEMOTION:
            x, y = event.pos

    for i in bul:
        if i.update() == False:
            bul.remove(i)
    print(len(bul))
    if not gh:
        ji = 0
    if gh:
        ji += 1
        if ji % 10 == 0:
            bullet(bul, [x, y])

    screen.fill((255, 255, 255))
    all_sprites.draw(screen)
    bul.draw(screen)
    pygame.display.flip()
    clock.tick(60)
pygame.quit()


# Wack.py
# Whack-a-mole game using pygame

import pygame, random, sys, time
from pygame.locals import *
from pygame.font import *

pygame.init()

# some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
DARKGRAY = (47, 79, 79)

RED = (255, 0, 0)
GREEN = (0, 255, 0)
DARKGREEN = (0, 155, 0)
BLUE = (0, 0, 255)

WINDOWWIDTH = 1547
WINDOWHEIGHT = 1000
WALDOWIDTH = 30
WALDOHEIGHT = 50
CURSORHEIGHT = 32
CURSORWIDTH = 32
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
points = 0
BASICFONTSIZE = 40
ENDFONTSIZE = 160
BASICFONT = pygame.font.Font('freesansbold.ttf', BASICFONTSIZE)
ENDFONT = pygame.font.Font('freesansbold.ttf', ENDFONTSIZE)
ENDSURF = ENDFONT.render('GAME OVER', True, RED)
soundEffect = pygame.mixer.Sound('ha-got-eeem.wav')
FPS = 60

background = pygame.transform.scale(pygame.image.load("background.jpg"), (WINDOWWIDTH, WINDOWHEIGHT))

def main():
    global startTime, searchTime, wack, cursor, FPSCLOCK
    FPSCLOCK = pygame.time.Clock()
    startTime = time.time()
    searchTime = 60
    wack = Waldo()
    cursor = MagnifyingGlass()
    pygame.display.set_caption('Wack')
    isPlaying = True
    pygame.mouse.set_visible(False)

    while True:

        for event in pygame.event.get():
            if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
                pygame.quit()
                sys.exit()
            if isPlaying:
                if event.type == MOUSEMOTION:
                    cursor.moveGlass(event.pos)
                if event.type == MOUSEBUTTONUP:
                    if wack.waldoRect.colliderect(cursor.cursorRect):
                        wack.reincarnate()

        if( time.time() - startTime>= searchTime):
            isPlaying = False
            DISPLAYSURF.blit(ENDSURF, (325, 400))

        if(isPlaying):
            updateScreen()
            updatePoints()
            updateTime()
        FPSCLOCK.tick(FPS)
        pygame.display.update()

class Waldo():

    def __init__(self):
        self.waldoImage = pygame.transform.scale(pygame.image.load("waldo.png"), (WALDOWIDTH, WALDOHEIGHT))
        self.waldoRect = self.waldoImage.get_rect()
        self.xpos = random.randrange(WINDOWWIDTH - WALDOWIDTH)
        self.ypos = random.randrange(100, WINDOWHEIGHT - WALDOHEIGHT)
        self.waldoRect.topleft = (self.xpos, self.ypos)

    def reincarnate(self):
        resetSearch()
        self.xpos = random.randrange(WINDOWWIDTH - WALDOWIDTH)
        self.ypos = random.randrange(WINDOWHEIGHT - WALDOHEIGHT)
        self.waldoRect.topleft = (self.xpos, self.ypos)
        soundEffect.play()

class MagnifyingGlass():

    def __init__(self):
        self.glassImg = pygame.transform.scale(pygame.image.load("glass.png"), (CURSORWIDTH, CURSORHEIGHT))
        self.cursorRect = self.glassImg.get_rect()

    def moveGlass(self, center):
        self.cursorRect.center = center

def resetSearch():
    global points, startTime, searchTime
    points += 1
    startTime = time.time()
    if (points > 20):
        searchTime = 15
    elif (points > 15):
        searchTime = 20
    elif (points > 10):
        searchTime = 30
    elif (points > 5):
        searchTime = 45
    else:
        searchTime = 60

def updateScreen():

    DISPLAYSURF.blit(background, (0, 0))
    DISPLAYSURF.blit(wack.waldoImage, wack.waldoRect)
    DISPLAYSURF.blit(cursor.glassImg, cursor.cursorRect)

def updatePoints():
    POINTS_SURF = BASICFONT.render("Points: " + str(points) , True, BLACK)
    DISPLAYSURF.blit(POINTS_SURF, (500, 30))

def updateTime():
    POINTS_SURF = BASICFONT.render("Time Remaining: " + str(int(searchTime - (time.time() - startTime))), True, BLACK)
    DISPLAYSURF.blit(POINTS_SURF, (750, 30))

main()


# -*- coding: utf-8 -*-
from datetime import datetime, timedelta
from decimal import Decimal
import scrapy
import json
import re
import logging
import os
from music import items

RECORDS_NEWER_THAN=os.environ.get(
    'RECORDS_NEWER_THAN',
    (datetime.utcnow().date() - timedelta(days=2)).isoformat()
)

def _music_uri(path):
    return 'tag:eric.moritz@gmail.com,2016:music/{}'.format(path)

def _pitchfork_uri(path):
    return _music_uri('pitchfork.com/{}'.format(path))

class PitchforkSpider(scrapy.Spider):
    name = "pitchfork"
    allowed_domains = ["pitchfork.com"]
    start_urls = (
        'http://pitchfork.com/api/v1/albumreviews/?format=json',
    )

    def parse(self, response):
        data = json.loads(response.body)
        nextPage = data.get('next')
        if nextPage:
            yield scrapy.Request(
                response.urljoin(nextPage),
                callback=self.parse
            )

        publisher = items.Organization(
            uri = "http://pitchfork.com/",
            name = 'Pitchfork'
        )

        for result in data['results']:
            date_published = _date(result['timestamp'])
            if date_published < RECORDS_NEWER_THAN:
                raise scrapy.exceptions.CloseSpider(
                    "{} < {}".format(
                        date_published,
                        RECORDS_NEWER_THAN
                    )
                )

            authors = [
                items.Person(
                    uri = _pitchfork_uri(x['url'].lstrip('/')),
                    url = 'http://pitchfork.com' + x['url'],
                    name = x['name']
                )
                for x in result['authors']
            ]
            for x in authors:
                yield x

            for i, album_json in enumerate(result['tombstone']['albums']):

                review_uri =  _pitchfork_uri(
                    'review/{}/{}'.format(result['id'],i)
                )

                artists = [
                    items.MusicGroup(
                        uri = _pitchfork_uri('artists/{}'.format(x['id'])),
                        name = x['display_name']
                    )
                    for x in album_json['album']['artists']
                ]
                for x in artists: yield x

                album = items.MusicAlbum(
                    uri = _pitchfork_uri('album/{}'.format(_album_id(album_json))),
                    name = album_json['album']['display_name'],
                    byArtist = [_link(x['uri']) for x in artists]
                )
                yield album

                rating = items.Rating(
                    uri = review_uri + "#reviewRating",
                    bestRating = 1000,
                    worstRating = 0,
                    ratingValue = int(Decimal(album_json['rating']['rating']) * 100)
                )
                yield rating

                labels = [
                    items.Organization(
                        uri=_pitchfork_uri('label/{}'.format(l['id'])),
                        name=l['name']
                    )
                    for x in album_json['labels_and_years']
                    for l in x['labels']
                ]

                for x in labels:
                    yield x

                year = min(
                    unicode(x['year']).split('/')[0]
                    for x in album_json['labels_and_years']
                )

                release = items.MusicRelease(
                    uri = review_uri + '#itemReviewed/{}'.format(i),
                    releaseOf = _link(album['uri']),
                    datePublished = year,
                    recordLabel = [_link(l['uri']) for l in labels]
                )

                yield release
                yield items.Review(
                    uri = review_uri,
                    url = "http://pitchfork.com" + result['url'],
                    datePublished = date_published,
                    itemReviewed = _link(release['uri']),
                    reviewRating = _link(rating['uri']),
                    publisher = _link(publisher['uri']),
                    author = [_link(x['uri']) for x in authors]
                )

def _date(x):
    return datetime.utcfromtimestamp(x / 1000).isoformat() + 'Z'

def _link(x):
    return {'@id': x}

def t(val):
    logging.info(repr(val))
    return val

ALBUM_ID_PAT = re.compile('.+/albums/(\d+)')
def _album_id(album_json):
    match = ALBUM_ID_PAT.match(album_json['album']['artwork']['default'])
    if match:
        return match.group(1)
    else:
        raise ValueError("Could not detect album id")


from __future__ import annotations
from flask_sqlalchemy import SQLAlchemy
from typing import Optional, List

db = SQLAlchemy()

class Question(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    question_id = db.Column(db.Integer, nullable=False)
    question_text = db.Column(db.Text, nullable=False)
    answer_text = db.Column(db.Text, nullable=False)
    created_at = db.Column(db.DateTime, nullable=False)

    def __repr__(self):
        return f'Question({self.id})'

    @classmethod
    def get_latest(cls) -> Optional[Question]:
        max_id = db.session.query(db.func.max(cls.id)).scalar()
        return cls.query.filter_by(id=max_id).first()

    @classmethod
    def get_duplicates(cls, questions_ids: List[int]) -> List[int]:
        existing_questions = cls.query.filter(cls.question_id.in_(questions_ids)).all()
        return [q.question_id for q in existing_questions]


"""
This is a simple example of how to use Scrapy

Note that this is an "in code" running of scrapy which *does not*
use the scrapy(1) command line tool. This is an integrated way
of running scrapy from within your code. There is another way
of running scrapy when all you are doing is scraping with a full
project structure and all. This is not that way.
"""

import scrapy.crawler

class SearchSpider(scrapy.Spider):
    name = __name__
    allowed_domains = [
        "jet.com"
    ]
    start_urls = (
        "https://jet.com/search/",
    )

    def __init__(self, *args, **kwargs):
        """ constructor """
        # important, call the parent
        super().__init__(*args, **kwargs)
        self.logger.info("in __init__")

    def parse(self, _response, **_kwargs):
        """
        This method is called whenever you get a response
        """
        self.logger.info("in parse")

    def closed(self, _reason):
        """
        This method is called automatically when the crawler finishes
        """
        self.logger.info("in closed")

if __name__ == "__main__":
    process = scrapy.crawler.CrawlerProcess()
    process.crawl(SearchSpider)
    process.start()


import logging
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.views.generic.base import TemplateView

from web_admin.exceptions import PermissionDeniedException
from web_admin.mixins import GetChoicesMixin
from web_admin.restful_methods import RESTfulMethods
from web_admin.api_settings import GET_REPORT_AGENT_BALANCE
from web_admin.api_settings import COMPANY_BALANCE_HISTORY
from web_admin.api_settings import COMPANY_BALANCE_ADD
from web_admin.api_settings import GET_AGENT_BALANCE
from web_admin import api_settings, setup_logger
from authentications.utils import get_correlation_id_from_username, check_permissions_by_user
from braces.views import GroupRequiredMixin

logger = logging.getLogger(__name__)

class CompanyBalanceView(GroupRequiredMixin, TemplateView, GetChoicesMixin, RESTfulMethods):
    group_required = "SYS_VIEW_COMPANY_BALANCE"
    login_url = 'web:permission_denied'
    raise_exception = False

    template_name = "company_balance.html"
    company_agent_id = 1
    company_agent_user_type = 2
    logger = logger

    def check_membership(self, permission):
        self.logger.info(
            "Checking permission for [{}] username with [{}] permission".format(self.request.user, permission))
        return check_permissions_by_user(self.request.user, permission[0])

    def dispatch(self, request, *args, **kwargs):
        correlation_id = get_correlation_id_from_username(self.request.user)
        self.logger = setup_logger(self.request, logger, correlation_id)
        return super(CompanyBalanceView, self).dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return render(request, self.template_name,
                      self._build_context(request)
                      )

    def post(self, request, *args, **kwargs):
        if not check_permissions_by_user(request.user, 'SYS_ADD_COMPANY_BALANCE'):
            raise PermissionDeniedException()

        new_company_balance = request.POST.get('new_company_balance')
        amount = request.POST.get('adding_balance')
        string_amount = amount

        if isinstance(amount, str):
            amount = amount.replace(',', '')
        currency = request.POST.get('currency')

        data = {'amount': amount}

        response, success = self._add_company_balance(currency, data)

        if success:
            messages.add_message(
                request,
                messages.SUCCESS,
                'Added balance successfully'
            )
            return redirect(request.META['HTTP_REFERER'])
        else:
            messages.add_message(
                request,
                messages.ERROR,
                response
            )
            context = self._build_context(request)
            context['new_company_balance'] = new_company_balance
            context['string_amount'] = string_amount
            context['selected_currency'] = currency
            return render(request, self.template_name, context)

    def _get_company_balance(self, currency):
        url = GET_REPORT_AGENT_BALANCE
        body = {
            'user_id': self.company_agent_id,
            'currency': currency,
            'user_type': 2,
            "paging": False,
            "page_index": -1
        }
        func_description = "Getting balance by username: {} \
        ,agent id: {} and currency: {}".format(self.request.user.username,
                                               self.company_agent_id,
                                               currency, )
        return self._post_method(api_path=url,
                                 func_description=func_description,
                                 logger=logger,
                                 params=body)

    def _get_new_company_balance(self, data):
        def calculate_balance_after_change(x):
            x['balance_after_change'] = x['balance_before_change'] + x['changed_amount']
            return x

        return map(calculate_balance_after_change, data)

    def _get_company_balance_history(self, currency):
        url = COMPANY_BALANCE_HISTORY + currency
        return self._get_method(api_path=url,
                                func_description="company balance list by user",
                                logger=logger,
                                is_getting_list=True)

    def _add_company_balance(self, currency, body):
        url = COMPANY_BALANCE_ADD + currency
        return self._put_method(api_path=url,
                                func_description="add company balance",
                                logger=logger,
                                params=body)

    def _get_currency_choices_by_agent(self, agent_id, company_agent_user_type):
        url = GET_AGENT_BALANCE
        body = {'user_id': agent_id, 'user_type': company_agent_user_type, 'paging':False}
        data, success = self._post_method(api_path=url,
                                          func_description="currency list by agent",
                                          logger=logger,
                                          params=body)
        if success:
            currency_list = [i['currency'] for i in data['cash_sofs']]
            return currency_list, True
        else:
            return data, True

    def _get_currency_choices_list(self):
        url = api_settings.GET_ALL_CURRENCY_URL
        self.logger.info('Get currency choice list from backend')
        data, success = self._get_method(api_path=url,
                                         func_description="currency choice list",
                                         logger=logger,
                                         is_getting_list=False)
        if success:
            value = data.get('value', '')
            if isinstance(value, str):
                currency_list = map(lambda x: x.split('|'), value.split(','))
            else:
                currency_list = []
            result = currency_list, True
        else:
            result = data, False
        return result

    def sum_balance(self, balance_lst):
        return sum([balance['changed_amount'] for balance in balance_lst])

    def _build_context(self, request):
        default_decimal = 1
        currency_choices, success_currency = self._get_currency_choices_by_agent(self.company_agent_id,
                                                                                self.company_agent_user_type)
        if not success_currency:
            messages.add_message(
                request,
                messages.ERROR,
                message=currency_choices
            )
            currency_choices = []

        currency_list, success_currency = self._get_currency_choices_list()
        if not success_currency:
            messages.add_message(
                request,
                messages.ERROR,
                message=currency_list
            )
            currency_list = []

        currency_list = list(filter(lambda x: x[0] in currency_choices, currency_list))
        if currency_list:
            currency = request.GET.get('currency', currency_list[0][0])
            decimal = list(filter(lambda x: x[0] == currency, currency_list))[0][1]
        else:
            return {'objects': [],
                    'currency_list': [],
                    'decimal': None,
                    'company_balance': None,
                    'total_balance': None}

        totalData, success_total_balance = self._get_company_balance(currency)

        if not success_total_balance:
            messages.add_message(
                request,
                messages.ERROR,
                message=totalData
            )
            totalData = {}
        else:
            totalData = totalData['cash_sofs'][0]

        data, success_balance = self._get_company_balance_history(currency)
        if success_balance:
            data = self._get_new_company_balance(data)
        else:
            messages.add_message(
                request,
                messages.ERROR,
                message=data
            )
            data = []
        objs = list(data)
        return {
            'objects': objs,
            'currency_list': currency_list,
            'decimal': decimal,
            'company_balance': totalData,
            'total_balance': self.sum_balance(objs)
        }

company_balance = login_required(CompanyBalanceView.as_view(), login_url='authentications:login')


from sklearn.model_selection import GridSearchCV

from chronus.domain.interfaces.optimizer_interface import OptimizerInterface
from chronus.domain.Run import Run

class RandomTreeOptimizer(OptimizerInterface):
    @staticmethod
    def name() -> str:
        return "random-tree"

    def make_model(self, runs: list[Run]):
        import numpy as np
        from sklearn.model_selection import train_test_split

        X = []
        y = []

        for run in runs:
            X.append([run.cores, run.threads_per_core, run.frequency])
            y.append(run.gflops_per_watt)

        X = np.array(X)
        y = np.array(y)

        param_grid = {
            "n_estimators": [10, 50, 100, 200],
            "max_depth": [None, 10, 20, 30],
            "min_samples_split": [2, 5, 10],
            "min_samples_leaf": [1, 2, 4],
            "max_features": ["auto", "sqrt"],
            "bootstrap": [True, False],
        }
        from sklearn.ensemble import RandomForestRegressor

        rf = RandomForestRegressor(random_state=42)
        grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, n_jobs=-1, verbose=2)

        grid_search.fit(X, y)
        best_params = grid_search.best_params_

        print("Best hyperparameters:")
        print(best_params)

        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

        # random forrest regressor with these paremters {'bootstrap': False, 'max_depth': None, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 10}
        model = RandomForestRegressor(**best_params, random_state=42)
        model.fit(X, y)

        from sklearn.metrics import mean_squared_error, r2_score

        # Define the range of cores, threads_per_core, and frequencies you want to test
        cores_range = range(1, 33)
        threads_per_core_range = range(1, 3)
        frequencies_range = [1500000.0, 2200000.0, 2500000.0]

        # Generate all possible combinations of configurations
        configurations = [
            {"cores": cores, "threads_per_core": tpc, "frequency": freq}
            for cores in cores_range
            for tpc in threads_per_core_range
            for freq in frequencies_range
        ]

        configurations_np = np.array([list(config.values()) for config in configurations])
        predicted_efficiencies = model.predict(configurations_np)
        best_config_index = np.argmax(predicted_efficiencies)

        best_config = configurations[best_config_index]
        best_efficiency_pred = predicted_efficiencies[best_config_index]

        print("Best predicted configuration:")
        print(f"Cores: {best_config['cores']}")
        print(f"Threads per core: {best_config['threads_per_core']}")
        print(f"Frequency: {best_config['frequency']} Hz")
        print(f"Predicted energy efficiency: {best_efficiency_pred} GFLOPS/Watt")


import discord
from discord.ext import commands
from discord_ui import UI , Button, Interaction
from keystone import keystone_const as ksconst

from asyncio import sleep as asleep
from convertor import b64_convert
from help import getHelp
from helper import get_Author, findURL, translateURL

# permissions integer: 534723951680
bot = commands.Bot(command_prefix='.')
ui = UI(bot)

@bot.event
async def on_message(message):
    ctx = await bot.get_context(message)
    author = get_Author(ctx)
    msg, hasURL = findURL(message)

    # Dont reply to self, bots
    if ctx.author.bot:
        return

    # Nothing in DMs
    if ctx.guild == None:
        await bot.process_commands(message)
        return

    # Dont respond to normal messages
    if not hasURL:
        await bot.process_commands(message)
        return

    embed = discord.Embed(title=f"", description=msg, colour=discord.Colour.green())
    embed.set_author(name = ctx.author, icon_url=author[1])
    embed.set_footer(text = "Links are encoded.")

    if message.reference is not None:
        # Fetching the message
        channel = bot.get_channel(message.reference.channel_id)
        referenced_message = await channel.fetch_message(message.reference.message_id)

        await ui.components.send(channel=message.channel,embed=embed,
                                reference=message.reference,
                                mention_author= referenced_message.author.mentioned_in(message),
                                components=[Button("Decode Links", "translate", "green")])

    else:
        await(ui.components.send(channel=message.channel, embed = embed,
                                components=[Button("Decode Links", "translate", "green")]))

        await message.delete()

    await bot.process_commands(message)

@bot.listen("on_interaction_received")
async def on_interact(interaction: Interaction):
    # See if translate button is clicked
    if interaction.data["custom_id"] == 'translate':
        msg = interaction.message
        embed = msg.embeds[0]
        links = translateURL(embed.description)
        await interaction.respond(content="**Links:**\n```\n" + links + "```", hidden=True)

@bot.command()
async def sh(ctx, task, string=None):
    username = get_Author(ctx)[0]

    if task == 'encode':
        embed = discord.Embed(title=f"Encoded string for {username}:", description=b64_convert(string, False), colour=discord.Colour.green())
        await ctx.send(embed=embed)

    elif task == 'decode':
        embed = discord.Embed(title=f"Decoded string for {username}:", description=b64_convert(string, True), colour=discord.Colour.green())
        await ctx.send(embed=embed)

    elif task == 'help':
        embed = discord.Embed(title="List of commands:", description=getHelp(), colour=discord.Colour.green())
        await ctx.send(embed=embed)

    else:
        embed = discord.Embed(title="List of commands:", description=getHelp(), colour=discord.Colour.green())
        await ctx.send(embed=embed)

@bot.event
async def on_ready():
    await bot.change_presence(activity = discord.Activity(name="Trying to Dream", type=discord.ActivityType.custom))
    print("Bot is ready!")

bot.load_extension("cogs.asm")
bot.run("MY BOT TOKEN")


import pandas as pd
from imblearn.over_sampling import SMOTE
from typing import List, Union
from utils import *
from sklearn.model_selection import train_test_split

class CfModel:
    """
    A Classification model
    """

    def __init__(self, l90d: pd.DataFrame, n180d: pd.DataFrame, growth_data: pd.DataFrame, stable_data: pd.DataFrame,
                 features: List[str], subset_type: str):
        """Create a base classifier model object

        Args:
            l90d (pd.DataFrame): df for last 90 days training data.
            n180d (pd.DataFrame): df for next 180 days test data.
            growth_data (pd.DataFrame): df for growth data with growth labels
            stable_data (pd.DataFrame): df for growth data with growth labels
            features (List[str]): either growth/stable features
            subset_type (str): string specifying 'growth' or 'stable'
        """
        self.l90d = l90d
        self.n180d = n180d
        self.df270 = pd.concat([self.l90d, self.n180d], ignore_index=True) \
            .drop_duplicates() \
            .sort_values(by=['user_id', 'pt_date'])
        self.subset_type = subset_type
        self.growth_data = growth_data
        self.stable_data = stable_data
        self.data = self.growth_data if subset_type == 'growth' else self.stable_data
        self.features = features

        # model training variables
        self.X_train = None
        self.y_train = None
        self.X_test = None
        self.y_test = None
        self.train_users = None
        self.test_users = None
        self.y_pred = None
        self.model = None
        self.get_x_train_y_train()

    def get_x_train_y_train(self) -> None:
        """
        Prepares data for modeling by conducting train-test split and applying SMOTE.
        """
        data = self.data
        X = data.drop(columns=['label'])
        y = data['label']

        # Train-test split on user level
        X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.2, random_state=0)

        train_users = X_train['user_id'].tolist()
        test_users = X_test['user_id'].tolist()
        X_train = X_train.drop(columns=['user_id'])
        X_test = X_test.drop(columns=['user_id'])

        # oversample with SMOTE to overcome class imbalance
        smote = SMOTE(sampling_strategy='minority', random_state=42)
        X_train, y_train = smote.fit_resample(X_train, y_train)

        self.X_train, self.y_train, self.X_test, self.y_test, self.train_users, self.test_users = (
            X_train[self.features], y_train, X_test[self.features], y_test, train_users, test_users)

    def train(self):
        pass

    def predict(self):
        pass

    def evaluate(self):
        pass

    def show_metrics(self):
        metrics_df = get_metrics_df(self.y_test, self.y_pred)
        print(metrics_df)
        return metrics_df

    def get_results_df(self, user_features: pd.DataFrame) -> pd.DataFrame:
        """
        Adds user features to the test set of users

        Args:
            user_features (pd.DataFrame): Df containing user features

        Returns:
            pd.DataFrame: df with user labels, features and weight
        """
        results_df = pd.DataFrame({
            'user_id': self.test_users,
            'true_label': self.y_test,
            'predicted_label': self.y_pred
        })

        results_df = results_df.merge(user_features, on='user_id', how='left')

        # Weight of each user relative to the 10k validation set users (not entire portfolio of 50k users)
        results_df['weight'] = results_df['avg_balance'] / np.sum(results_df['avg_balance'])
        return results_df

    def get_subset_pred_true(self) -> (pd.DataFrame, pd.DataFrame):
        """
        Returns two separate predicted and true subsets
        """
        results_df = self.get_results_df(self.data)
        # Predicted subset
        subset_pred = results_df[results_df['predicted_label'] == 1].copy()
        subset_pred = self._get_subset_pred_true(subset_pred)

        # Actual subset
        subset_true = results_df[results_df['true_label'] == 1].copy()
        subset_true = self._get_subset_pred_true(subset_true)

        return subset_pred, subset_true

    @staticmethod
    def _get_subset_pred_true(df: pd.DataFrame) -> pd.DataFrame:
        """
        Calculate weight relative to subset & obtain weighted stability
        """
        df['subset_weight'] = df['avg_balance'] / df['avg_balance'].sum()
        df['weighted_stability'] = df['subset_weight'] * df['stability_index']

        return df


from keras.models import Model
from keras.layers import Layer
from keras.layers import Dense, Conv2D, BatchNormalization, Flatten, Dense, MaxPooling2D, AveragePooling2D, Activation, Add

class IdentityBlock(Layer):

    def __init__(self, filters):
        super(IdentityBlock, self).__init__()

        self.conv1 = Conv2D(filters=filters[0], kernel_size=(1, 1), strides = 1, padding='valid')
        self.batch_norm1 = BatchNormalization()
        self.activation1 = Activation('relu')

        self.conv2 = Conv2D(filters=filters[1], kernel_size=(3, 3), strides = 1, padding='same')
        self.batch_norm2 = BatchNormalization()
        self.activation2 = Activation('relu')

        self.conv3 = Conv2D(filters=filters[2], kernel_size=(1, 1), strides = 1, padding='valid')
        self.batch_norm3 = BatchNormalization()

        self.add = Add()
        self.activation3 = Activation('relu')

    def call(self, inputs):
        # First block in Identity block
        x = self.conv1(inputs)
        x = self.batch_norm1(x)
        x = self.activation1(x)

        # Second Block in identity block
        x = self.conv2(x)
        x = self.batch_norm2(x)
        x = self.activation2(x)

        # Third Block in identity block
        x = self.conv3(x)
        x = self.batch_norm3(x)

        # Add input_x to the main path
        x = self.add(inputs=[x, inputs])
        x = self.activation3(x)

        return x

class ConvBlock(Layer):

    def __init__(self, filters, stride=2):
        super(ConvBlock, self).__init__()

        self.conv1 = Conv2D(filters=filters[0], kernel_size=(1, 1), strides = stride, padding='valid')
        self.batch_norm1 = BatchNormalization()
        self.activation1 = Activation('relu')

        self.conv2 = Conv2D(filters=filters[1], kernel_size=(3, 3), strides = 1, padding='same')
        self.batch_norm2 = BatchNormalization()
        self.activation2 = Activation('relu')

        self.conv3 = Conv2D(filters=filters[2], kernel_size=(1, 1), strides = 1, padding='same')
        self.batch_norm3 = BatchNormalization()

        self.input_conv = Conv2D(filters=filters[2], kernel_size=(1, 1), strides = stride, padding='valid')
        self.batch_norm4 = BatchNormalization()

        self.add = Add()
        self.activation5 = Activation('relu')

    def call(self, inputs):
        # First block in Identity block
        x = self.conv1(inputs)
        x = self.batch_norm1(x)
        x = self.activation1(x)

        # Second Block in identity block
        x = self.conv2(x)
        x = self.batch_norm2(x)
        x = self.activation2(x)

        # Third Block in identity block
        x = self.conv3(x)
        x = self.batch_norm3(x)

        # shortcut path
        short_cut = self.input_conv(inputs)
        short_cut = self.batch_norm4(short_cut)

        # Add short_cut to the main path
        x = self.add(inputs=[x, short_cut])
        x = self.activation5(x)

        return x

class ResNet50(Model):

    def __init__(self):
        super(ResNet50, self).__init__(name='ResNet50')

        self.conv       = Conv2D(filters=64, kernel_size=(7, 7), strides= 2)
        self.batch_norm = BatchNormalization()
        self.activation = Activation('relu')
        self.max_pool   = MaxPooling2D(pool_size=(3, 3), strides=2)

        self.conv_block2      = ConvBlock    (filters=[64, 64, 256], stride=1)
        self.identity_block2a = IdentityBlock(filters=[64, 64, 256])
        self.identity_block2b = IdentityBlock(filters=[64, 64, 256])

        self.conv_block3      = ConvBlock    (filters=[128, 128, 512])
        self.identity_block3a = IdentityBlock(filters=[128, 128, 512])
        self.identity_block3b = IdentityBlock(filters=[128, 128, 512])

        self.conv_block4      = ConvBlock    (filters=[256, 256, 1024])
        self.identity_block4a = IdentityBlock(filters=[256, 256, 1024])
        self.identity_block4b = IdentityBlock(filters=[256, 256, 1024])

        self.conv_block5      = ConvBlock    (filters=[512, 512, 2048])
        self.identity_block5a = IdentityBlock(filters=[512, 512, 2048])
        self.identity_block5b = IdentityBlock(filters=[512, 512, 2048])

        self.average_pool = AveragePooling2D(pool_size=(2, 2), strides= 1)
        self.flatten      = Flatten()
        self.dense        = Dense(6, activation='softmax')

    def call(self, inputs):
        # Block-1
        x = self.conv(inputs)
        x = self.batch_norm(x)
        x = self.activation(x)
        x = self.max_pool(x)

        # Block-2
        x = self.conv_block2(x)
        x = self.identity_block2a(x)
        x = self.identity_block2b(x)

        # Block-3
        x = self.conv_block3(x)
        x = self.identity_block3a(x)
        x = self.identity_block3b(x)

        # Block-4
        x = self.conv_block4(x)
        x = self.identity_block4a(x)
        x = self.identity_block4b(x)

        # Block-5
        x = self.conv_block5    (x)
        x = self.identity_block5a(x)
        x = self.identity_block5b(x)

        # Pooling
        x = self.average_pool(x)

        # classifier
        x = self.flatten(x)
        x = self.dense(x)

        return x

resnet50 = ResNet50()
resnet50.build(input_shape=(None, 64, 64, 3))
resnet50.summary()

"""
Model: "ResNet50"
_______________________________________________________________________________
 Layer (type)                               Output Shape             Param #
===============================================================================
 conv2d (Conv2D)                            multiple                 9472

 batch_normalization (BatchNormalization)   multiple                 256

 activation (Activation)                    multiple                 0

 max_pooling2d (MaxPooling2D)               multiple                 0

 conv_block (ConvBlock)                     multiple                 76928

 identity_block (IdentityBlock)             multiple                 71552

 identity_block_1 (IdentityBlock)           multiple                 71552

 conv_block_1 (ConvBlock)                   multiple                 383232

 identity_block_2 (IdentityBlock)           multiple                 282368

 identity_block_3 (IdentityBlock)           multiple                 282368

 conv_block_2 (ConvBlock)                   multiple                 1520128

 identity_block_4 (IdentityBlock)           multiple                 1121792

 identity_block_5 (IdentityBlock)           multiple                 1121792

 conv_block_3 (ConvBlock)                   multiple                 6054912

 identity_block_6 (IdentityBlock)           multiple                 4471808

 identity_block_7 (IdentityBlock)           multiple                 4471808

 average_pooling2d (AveragePooling2D)       multiple                 0

 flatten (Flatten)                          multiple                 0

 dense (Dense)                              multiple                 12294

=================================================================================
Total params: 19,952,262
Trainable params: 19,909,894
Non-trainable params: 42,368
_________________________________________________________________________________
"""


import pygame
import os
from .piece import Piece, colors
import game

class Pawn(Piece):
    def __init__(self, color):
        super().__init__(color)

        self.making_promotion = False
        self.img = pygame.transform.scale(pygame.image.load(os.path.join("assets/pieces/" + self.color, self.color + "_pawn.png")), (50, 50))

    def check_valid_move(self, whites, blacks, row, col):

        for p in (whites + blacks):
            if p is not self:
                if self.current_col == col and p.current_col == self.current_col and row == p.current_row:
                    return False

                if p.color == self.enemy_color and p.current_row == row and p.current_col == col and (p.current_col == self.current_col + 1 or p.current_col == self.current_col - 1):
                    if self.color == colors[0]:
                        # color is white
                        if p.current_row == self.current_row - 1:
                            self.piece_to_kill = p
                            self.pieces_to_kill = blacks
                            return True
                    else:
                        # color is black
                        if p.current_row == self.current_row + 1:
                            self.piece_to_kill = p
                            self.pieces_to_kill = whites
                            return True

        for p in (whites + blacks):
            if col == self.current_col:
                if self.color == colors[0]:
                    if self.current_row == 6:
                        if self.current_row - row == 2:
                            if p.current_row == self.current_row - 1 and p.current_col == col:
                                return False
                            return True
                    if self.current_row - row == 1:
                        return True
                    else:
                        return False

                else:
                    if self.current_row == 1:
                        if row - self.current_row == 2:
                            if p.current_row == self.current_row + 1 and p.current_col == col:
                                return False
                            return True
                    if row - self.current_row == 1:
                        return True
                    else:
                        return False
            else:
                return False

        return True

    def draw(self, win):
        super().draw(win)

    def click_promotion(self, x, y, whites, blacks):

        if self.making_promotion:
            for rect_num, rect in enumerate(self.rects):
                if x <= rect.right and x >= rect.left and y >= rect.top and y <= rect.bottom:
                    self.possible_selections[rect_num].set_position(self.current_row, self.current_col, self.current_square)
                    self.making_promotion = False
                    game.rules_check = True

                    if self.color == colors[0]:
                        # color is white
                        whites.append(self.possible_selections[rect_num])
                        whites.remove(self)
                    else:
                        # color is black
                        blacks.append(self.possible_selections[rect_num])
                        blacks.remove(self)

                    return

    def create_promotion_screen(self):
        from .queen import Queen
        from .rook import Rook
        from .bishop import Bishop
        from .knight import Knight

        self.wide_rect = pygame.Rect(75, 225, 270, 160)

        self.current_color_index = colors.index(self.color)

        rook = Rook(self.current_color_index)
        rook.has_moved = True

        self.possible_selections = [Queen(self.current_color_index), rook, Bishop(self.current_color_index), Knight(self.current_color_index)]
        self.rects = []

        for rect_num in range(len(self.possible_selections)):
            self.rects.append(pygame.Rect(self.wide_rect.left + (50*rect_num) + 10*(rect_num+1) + 10, self.wide_rect.top + self.wide_rect.height*0.5, 50, 50))

        self.font = pygame.font.SysFont('Comic Sans MS', 25, bold = True)

    def draw_promotion(self, win):
        if self.making_promotion:
            pygame.draw.rect(win, (255, 0, 0), self.wide_rect)

            for r_num, r in enumerate(self.rects):
                pygame.draw.rect(win, (255, 255, 255), r)
                win.blit(self.possible_selections[r_num].img, (r.left, r.top))

            win.blit(self.font.render("Choose a promotion", True, (255, 255, 255)), (self.wide_rect.left + 20, self.wide_rect.top + 15))


import os, sys
import numpy as np
import pandas as pd
import ROOT as r
from ROOT import TTree, TObjArray, TCanvas, TPad, TFile, TPaveText
import json
from collections import OrderedDict
from multiprocessing import Pool
from memory_profiler import profile
from root_pandas import read_root
import rootpy
from rootpy.io import root_open
from tqdm import tqdm, trange
from collections import defaultdict

selection = sys.argv[1]

XS_table ={ 'ww'              :  12178,
            'wz_2l2q'         :  5595,
            'wz_3lnu'         :  4430,
            'zz_2l2nu'        :  564,
            'zz_2l2q'         :  3220,
            'zz_4l'           :  1210,

           'zjets_m-10to50'   : 18610000,
           'z1jets_m-10to50'  : 1.18*730300,
           'z2jets_m-10to50'  : 1.18*387400,
           'z3jets_m-10to50'  : 1.18*95020,
           'z4jets_m-10to50'  : 1.18*36710,

           'zjets_m-50'       :  5765400,
           'z1jets_m-50'      :  1.18*1012000,
           'z2jets_m-50'      :  1.18*334700,
           'z3jets_m-50'      :  1.18*102300,
           'z4jets_m-50'      :  1.18*54520,

           'w1jets'           :  9493000,
           'w2jets'           :  3120000,
           'w3jets'           :  942300,
           'w4jets'           :  524100,

           't_tw'             :  35850,
           'tbar_tw'          :  35850,
           'ttbar_inclusive'  :  832000,

           'TTZToLLNuNu'      : 252.9,
           'TTZToQQ'          : 529.7,
           'TTWJetsToLNu'     : 204.3,
           'TTWJetsToQQ'      : 406.2,
           'ttHJetTobb'       : 295.0,

           'qcd_ht100to200'   :27990000000,
           'qcd_ht200to300'   :1712000000,
           'qcd_ht300to500'   :347700000,
           'qcd_ht500to700'   :32100000,
           'qcd_ht700to1000'  :6831000,
           'qcd_ht1000to1500' :1207000,
           'qcd_ht1500to2000' :119900,
           'qcd_ht2000'       :25240,
          }

def make_directory(filePath, clear=True):
    if not os.path.exists(filePath):
        os.system('mkdir -p '+filePath)

    if clear and len(os.listdir(filePath)) != 0:
        os.system('rm '+filePath+'/*')

def fill_lepton_vars(tree, name, SF):

    out_dict = {}
    out_dict['nMuons']       =  tree.nMuons
    out_dict['nElectrons']   =  tree.nElectrons
    out_dict['nJets']        =  tree.nJets
    out_dict['nBJets']       =  tree.nBJets
    out_dict['nPV']          =  tree.nPV
    out_dict['nPU']          =  tree.nPU

    correction = tree.eventWeightPu
    correction *= tree.eventWeightTrigger
    correction *= tree.eventWeightId
    correction *= tree.eventWeightIso

    weight = SF * correction
    if name in ['zjets_m-50','zjets_m-10to50']:
        out_dict['nPartons']  =  tree.nPartons
    #     if 0 < tree.nPartons < 5:
    #         weight  = 0.0
    out_dict['eventWeight']  =  weight
    out_dict['met']          =  tree.met
    out_dict['metPhi']       =  tree.metPhi

    # 1. Filling leptons
    lep1 = tree.leptonOneP4
    lep2 = tree.leptonTwoP4
    dilepton = lep1+lep2

    out_dict['lepton1_pt']  = lep1.Pt()
    out_dict['lepton1_eta'] = lep1.Eta()
    out_dict['lepton1_phi'] = lep1.Phi()

    out_dict['lepton2_pt']  = lep2.Pt()
    out_dict['lepton2_eta'] = lep2.Eta()
    out_dict['lepton2_phi'] = lep2.Phi()

    out_dict['dilepton_mass'] = dilepton.M()

    lep3 = tree.leptonThreeP4
    out_dict['lepton3_iso']     = tree.leptonThreeISO

    out_dict['lepton3_deltaPhi']= lep3.DeltaPhi(dilepton) #tree.leptonThreeDeltaPhi
    out_dict['lepton3_pt']      = lep3.Pt()
    out_dict['lepton3_eta']     = lep3.Eta()
    out_dict['lepton3_phi']     = lep3.Phi()

    return out_dict

def fill_ntuple(tree, name, SF):
    n = int(tree.GetEntriesFast())

    for i in trange(n,
                    desc       = selection+' selection *** '+name,
                    leave      = True,
                    unit_scale = True,
                    ncols      = 100,
                    total      = n
                    ):
        tree.GetEntry(i)
        entry = {}
        entry.update(fill_lepton_vars(tree, name, SF))
        n -= 1
        yield entry

def pickle_ntuple(ntuple_data):
    # unpack input data
    name        = ntuple_data[0]
    SF          = ntuple_data[1]
    input_file  = ntuple_data[2]
    output_path = ntuple_data[3]
    if name in datalist:
        output_path +="data2016/"
    elif name in mcttbosonlist:
        output_path +="mcttboson/"
    elif name in mcqcdlist:
        output_path +="mcqcd/"
    elif name in mcdibosonlist:
        output_path +="mcdiboson/"
    elif name in mcdylist:
        output_path +="mcdy/"
    elif name in mctlist:
        output_path +="mct/"
    elif name in mcttlist:
        output_path +="mctt/"
    make_directory(output_path, clear=False)

    # get the tree, convert to dataframe, and save df to pickle
    #froot  = TFile(input_file)
    #tree   = froot.Get('tree_{}'.format(name))
    tree   = input_file.Get('tree_{}'.format(name))

    if tree.GetEntriesFast() >0:

        ntuple = fill_ntuple(tree, name, SF)
        df     = pd.DataFrame(ntuple)
        df.to_pickle('{0}/ntuple_{1}.pkl'.format(output_path, name))

###########################################
###########################################
#               Main
###########################################
###########################################

input_root_file_name  = "/home/zchen/Documents/Analysis/workplace/data/root/{}.root".format(selection)
input_root_file = TFile(input_root_file_name)
output_directory = "/home/zchen/Documents/Analysis/workplace/data/fake/{}/".format(selection)

## 1. define datalist
datalist      = ['muon_2016B', 'muon_2016C', 'muon_2016D','muon_2016E',
                 'muon_2016F','muon_2016G','muon_2016H']
## 2. define mclist
mcttbosonlist = ['TTZToLLNuNu','TTZToQQ','TTWJetsToLNu','TTWJetsToQQ','ttHJetTobb']

mcqcdlist     = ['qcd_ht100to200','qcd_ht200to300','qcd_ht300to500',
                 'qcd_ht500to700','qcd_ht700to1000','qcd_ht1000to1500',
                 'qcd_ht1000to1500','qcd_ht1500to2000','qcd_ht2000']
mcdibosonlist = ['ww','wz_2l2q','wz_3lnu','zz_2l2nu','zz_2l2q','zz_4l' ]
mcdylist      = ['zjets_m-10to50','zjets_m-50',
                 #'z1jets_m-10to50','z2jets_m-10to50','z3jets_m-10to50','z4jets_m-10to50',
                 #'z1jets_m-50','z2jets_m-50','z3jets_m-50','z4jets_m-50',
                 'w1jets','w2jets','w3jets','w4jets']
mctlist       = ['t_tw','tbar_tw']
mcttlist      = ['ttbar_inclusive']
mclist =  mcttbosonlist + mcdibosonlist + mcdylist + mctlist + mcttlist

## 3. Calculate SF for each element in datalist and mclist
SF_table = {}
SF_table = defaultdict(lambda: 1.0, SF_table)
for mc in mclist:
    h = input_root_file.Get("TotalEvents_"+mc)
    nGenTotal = h.GetBinContent(1)
    crossection = XS_table[mc]
    SF_table[mc] = crossection * 35.864 / nGenTotal
for data in datalist:
    SF_table[data] = 1.0

## 4. pickle ntuples
dataset_list = datalist + mclist
for dataset in dataset_list:
    SF = SF_table[dataset]
    root2df_config = [dataset,SF,input_root_file,output_directory]
    pickle_ntuple(root2df_config)


import os, argparse, sys
from multiprocessing import Process, Pool, Queue, cpu_count
from itertools import product
import multiprocessing as mp
import rasterio as rio
from rasterio import windows
from rasterio.merge import merge
from rasterio.plot import show
from rasterio.mask import mask
from rasterio.warp import calculate_default_transform, reproject, Resampling

# declare global variables
dst_crs = 'EPSG:4326'
# out_path = r'D:/Raster/HRO/parsed_ortho_files/'
list_of_tifs = []

# fetch argparse params
parser = argparse.ArgumentParser()
parser.add_argument('--inpath', help='full directory path to location of tif files')
parser.add_argument('--outpath', help='full directory path to location to store clipped tiles')
parser.add_argument('--width', help='specify the width for spliced image')
parser.add_argument('--height', help='specify the height for spliced image')
args = parser.parse_args()

# argparse variables
arg_inpath = args.inpath
arg_outpath = args.outpath
arg_width = args.width
arg_height = args.height

# check if input folder exists
if not os.path.exists(arg_inpath):
    print('Source folder does not exist, exiting program...')
    sys.exit(0)

# check if output folder exists
if not os.path.exists(arg_outpath):
    print(f'Destination folder does not exist, creating it...')
    os.mkdir(arg_outpath)

# function to fetch the path of every .TIF file within subfolder of inpath
def get_tif_path(start):
    curr_dir = os.listdir(start)
    for root, folders, files in os.walk(start):
        for file in files:
            if file.__contains__('.tif'):
                list_of_tifs.append(os.path.join(root, file))

# method to create and return a dimensional window based on argparse width and height
def generate_tiles(input_tif, width=500, height=500):
    n_cols, n_rows = input_tif.meta['width'], input_tif.meta['height']
    offsets = product(range(0, n_cols, width), range(0, n_rows, height))
    full_window = windows.Window(col_off=0, row_off=0, width=n_cols, height=n_rows)
    for col_off, row_off in offsets:
        window=windows.Window(col_off=col_off, row_off=row_off, width=width, height=height).intersection(full_window)
        transform = windows.transform(window, input_tif.transform)
        yield window, transform

# method to clip a single 5000x5000 tif file into NxM tiles based on argparse width and height
def clip_full_raster(in_file, in_path, out_file, out_path, dst_crs):
    with rio.open(in_path, num_threads=8) as in_tiff: #, num_threads=8
        tile_width, tile_height = int(arg_width), int(arg_height)
        meta = in_tiff.meta.copy()
        number_of_bands = meta['count']

        # iterate over each window returned to read only active window dimensions
        for window, transform in generate_tiles(in_tiff, tile_width, tile_height):
            meta['transform'] = transform
            meta['width'], meta['height'] = window.width, window.height
            meta['photometric'] = 'RGB'
            print(meta)
            full_dest_path = os.path.join(out_path, out_file.format(int(window.col_off), int(window.row_off)))
            raster_window = in_tiff.read(window=window)

            # write clipped window of original tif to file without reprojection
            with rio.open(full_dest_path, 'w', num_threads=8, **meta) as out_tiff: #, num_threads=8
                out_tiff.write(raster_window, indexes=list(range(1, number_of_bands+1)))

# helper method to parse file path into in and out paths and file names
def parse_file_path(folder):
    in_path = folder
    in_file = folder.split('\\')[-1]
    prefix = in_file.replace('.tif','')
    out_file = prefix + '_{}-{}.tif'
    clip_full_raster(in_file, in_path, out_file, arg_outpath, dst_crs)

# method to handle multiprocessing pool
def pool_handler(pool_me):
    num_processors = 8 #int(mp.cpu_count() / 2)
    p = Pool(processes=num_processors)
    p.map(parse_file_path, pool_me)

if __name__ == "__main__":
    image_folders = [folder for folder in os.listdir(arg_inpath) if not folder.__contains__('.ipynb')]
    for folder in image_folders:
        get_tif_path(os.path.join(arg_inpath, folder))

    # print(list_of_tifs)
    pool_handler(list_of_tifs)

###----------------------------------------------------------------###

### SCRIPT FOR REPROJECTING TO DESTINATION CRS ###
#       # attempting to reproject to EPSG 4326 while applying windows
#         with rasterio.open(outpath, 'w', **meta) as out_tiff:
#             for i in range(1, in_tiff.count+1):
#                 reproject(
#                     source=rio.band(in_tiff, i),
#                     destination=rio.band(out_tiff, i),
#                     src_transform=in_tiff.transform,
#                     src_crs=in_tiff.crs,
#                     dst_transform=transform,
#                     dst_crs=dst_crs,
#                     resampling=Resampling.nearest)


import psycopg2
import pandas as pd

def load_data():
    connection = psycopg2.connect(host="localhost", port="5432", database="Diet", user="postgres")
    cursor = connection.cursor()
    # cursor.execute('create table if not exists ' + "diet_dataset" + ' as select c1,c4,c5,c6,c7,c24,c170 from new_diet')
    # cursor.execute('ALTER TABLE "diet_dataset" ADD PRIMARY KEY (c1);')
    # connection.commit()

    dataset = pd.read_sql_query('select * from diet_dataset where weight IS NULL', con=connection)

    df = pd.DataFrame(dataset)
    print(df)
    # print(len(df.index))
    # df = df.dropna(how='any', axis=0)
    # print(len(df.index))
    # # nation and region => nation_region
    # #
    # # cursor.execute('drop table nation_region_customer_supplier')
    # # connection.commit()

if __name__ == "__main__":
    load_data()


from logging import getLogger
from os import urandom
from urllib.parse import urlparse, urljoin, urlencode

import flask
from flask_login import current_user, login_user, \
            logout_user, login_required, LoginManager
from babel.dates import format_datetime

from .user import User
from ._version import __version__
from .forms import LoginForm, NewAuditForm
from .backend import Backend
from .constants import AuditState, AuditFrequency

app = flask.Flask(__name__)
app.secret_key = urandom(16)
app.config.update(
    #  SESSION_COOKIE_SECURE=True,
    SESSION_COOKIE_HTTPONLY=True,
    SESSION_COOKIE_SAMESITE='Lax',
)

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
login_manager.remember_cookie_http_only = True
login_manager.remember_cookie_samesite = True

backend = Backend()
log = getLogger(__name__)

class Pagination(object):
    def __init__(self, total_entries, page_size=5, p_name='page'):
        try:
            current_page = int(flask.request.args.get(p_name))
        except Exception:
            current_page = 1

        first_page = 1
        last_page = total_entries//page_size + 1

        if not (first_page <= current_page and current_page <= last_page):
            raise IndexError("Page index out of range")
        if first_page == last_page:
            self.needed = False
            return
        self.needed = True

        args = flask.request.args.to_dict()

        self.page = current_page
        self.first = first_page
        self.last = last_page

        self.previous = ""
        self.next = ""
        if self.page != self.first:
            args[p_name] = current_page - 1
            self.previous = "?" + urlencode(args)
        if self.page != self.last:
            args[p_name] = current_page + 1
            self.next = "?" + urlencode(args)

        self.links = []
        for i in range(first_page, last_page+1):
            args.update({p_name: i})
            url = '?' + urlencode(args)
            self.links.append({p_name: i, 'href': url})

        if len(self.links) > 7:
            if current_page - first_page < 4:
                right = max(5, current_page - first_page + 2)
                self.links = self.links[:right] + [None] + [self.links[-1]]
            elif last_page - current_page < 4:
                left = min(last_page - first_page - 4, last_page -
                           first_page - (last_page - current_page))
                self.links = [self.links[0]] + [None] + self.links[left:]
            else:
                left = current_page - first_page - 1
                right = current_page - first_page + 2
                self.links = [self.links[0]] + [None] + \
                    self.links[left:right] + \
                    [None] + [self.links[-1]]

def get_context():
    return dict(
        version=__version__,
        user=current_user.get_id(),
        config_errors=sum(backend.config.get_errors().values()),
    )

def is_safe_url(target):
    # Check if the URL belongs to our application
    ref_url = urlparse(flask.request.host_url)
    test_url = urlparse(urljoin(flask.request.host_url, target))
    return (test_url.scheme in ('http', 'https')
            and ref_url.netloc == test_url.netloc)

@login_manager.user_loader
def load_user(user_id):
    return User.logged_in_users[user_id]

@app.route('/login', methods=['POST', 'GET'])
def login():
    if current_user.is_authenticated:
        return flask.redirect(flask.url_for('home'))

    next_url = flask.request.args.get('next', "")

    form = LoginForm(next_url=next_url)
    if form.validate_on_submit():
        next_url = form.next_url.data
        # Prevent open redirection
        if not is_safe_url(next_url):
            return flask.abort(400)
        auth_config = backend.config['authentication']
        user = None
        try:
            user = User.authenticate(
                form.user.data,
                form.password.data,
                auth_config,
            )
        except Exception as e:
            log.warning(str(e))
        if not user:
            flask.flash("Invalid username or password.", 'danger')
            return flask.render_template('login.html', form=form)
        login_user(user, remember=form.remember_me.data)
        return flask.redirect(next_url or flask.url_for('home'))
    return flask.render_template('login.html', form=form)

@app.route('/')
@login_required
def home():
    try:
        status = backend.get_status()
    except Exception as e:
        log.exception(e)
        status = []
    return flask.render_template(
        'home.html',
        sections=status,
        **get_context(),
    )

@app.route('/audit')
@login_required
def audit():
    try:
        audit_uuid = flask.request.args.get('id')
        _, audit_record = backend.get_report_and_audit(audit_uuid)

        audit = {}
        dummy_form = NewAuditForm()
        display_str = {
            'uuid': "ID",
            'end': "End at",
            'state': "State",
            'report': "Report",
        }
        for k, v in audit_record.items():
            if k in ['metadata', 'id']:
                continue
            if k == 'frequency':
                audit[k] = AuditFrequency(v).name
            elif k == 'state':
                audit[k] = AuditState(v).name
            else:
                audit[k] = v
            try:
                display_str[k] = getattr(dummy_form, k).label
            except AttributeError:
                pass
    except Exception as e:
        log.error("Error while retrieving audit: %s" % str(e))
        log.exception(e)
        return str(e), 500
    return flask.render_template(
        'audit.html',
        display_str=display_str,
        audit=audit,
        **get_context(),
    )

@app.route('/audits')
@login_required
def audits():
    try:
        page = int(flask.request.args.get('page'))
    except Exception:
        page = 1
    page_size = 5

    past_audits = backend.get_past_audits()
    pagination = Pagination(len(past_audits))
    past_audits = past_audits[(page - 1)*page_size:page*page_size]

    scheduled_audits = backend.get_scheduled_audits()
    for audit in scheduled_audits:
        audit['start'] = format_datetime(audit['start'], format='short')
        if audit['end']:
            audit['end'] = format_datetime(audit['end'], format='short')

    return flask.render_template(
        'audits.html',
        running_audit=None,
        past_audits=past_audits,
        scheduled_audits=scheduled_audits,
        pagination=pagination,
        **get_context(),
    )

@app.route('/audits/delete', methods=['POST'])
@login_required
def delete_audit():
    audit_uuid = flask.request.args.get('id')
    backend.delete_audit(audit_uuid)
    return flask.redirect(flask.url_for('audits'))

@app.route('/audits/new', methods=['POST', 'GET'])
@login_required
def new_audit():
    AUDIT_MESSAGE = """\
Dear user,

your password has been identified as too weak during a fully automated
password audit. Please change your password to a more secure one soon.

This is an automated message. No human has seen your current password.
Please contact your IT department if you have further questions.
"""
    audit_uuid = flask.request.args.get('id')
    if audit_uuid:
        _, audit = backend.get_report_and_audit(audit_uuid)
        audit['password'] = ''
        audit['start'] = ''
        form = NewAuditForm(**dict(audit))
    else:
        form = NewAuditForm(message=AUDIT_MESSAGE)
    if form.validate_on_submit():
        values = flask.request.form.copy()
        if 'csrf_token' in values:
            del values['csrf_token']
        try:
            id = backend.add_audit(values)
            log.info("User '%s' created a new audit with ID %s" %
                     (current_user.get_id(), id))
            return flask.redirect(flask.url_for('home'))
        except Exception as e:
            log.error(
                "User '%s' attempted to create a new audit, but it failed: %s"  # noqa
                % (current_user.get_id(), str(e))
            )
            log.exception(e)
            flask.flash(str(e), 'danger')
    return flask.render_template(
        'new-audit.html',
        form=form,
        **get_context(),
    )

@app.route('/events')
@login_required
def events():
    if 'flat' in flask.request.args:
        response = flask.make_response(backend.get_log(), 200)
        response.mimetype = "text/plain"
        return response
    try:
        page = int(flask.request.args.get('page'))
    except Exception:
        page = 1
    page_size = 5
    pagination = Pagination(backend.get_event_count())
    event_entries = backend.get_events((page - 1)*page_size, page*page_size)
    return flask.render_template(
        'events.html',
        events=event_entries,
        pagination=pagination,
        **get_context(),
    )

@app.route('/config', methods=['POST', 'GET'])
@login_required
def config():
    sections = backend.config.get_sections()
    section = flask.request.args.get('section') or \
        flask.request.form.get('section') or \
        sections[0][0]

    errors = backend.config.get_errors()

    form = backend.config.get_form(section)
    form.validate()
    if form.validate_on_submit():
        try:
            values = form.data
            if 'csrf_token' in values:
                del values['csrf_token']
            backend.update_config(section, values)
            section = flask.request.form.get('section')
            flask.flash("Settings updated.", 'success')
            return flask.redirect(flask.url_for('config', section=section))
        except Exception as e:
            log.error("Error while updating the config: %s" % str(e))
            log.exception(e)
            flask.flash(str(e), 'danger')
    return flask.render_template(
        'config.html',
        config=config,
        section=section,
        sections=sections,
        form=form,
        errors=errors,
        **get_context(),
    )

@app.route('/logout', methods=['POST'])
@login_required
def logout():
    logout_user()
    return flask.redirect(flask.url_for('login'))

@app.route('/report')
@login_required
def report():
    try:
        audit_id = flask.request.args.get('id', '')
        report, audit = backend.get_report_and_audit(audit_id)
        from .reports import create_text_report, create_figures
        figures = create_figures(report)
        text_report = create_text_report(report)
    except Exception as e:
        log.error("Error while retrieving report: %s" % str(e))
        log.exception(e)
        return "Unable to retrieve report", 500
    return flask.render_template(
        'report.html',
        audit_id=audit_id,
        thisaudit=audit,
        report=text_report,
        figures=figures,
        **get_context(),
    )


import cv2
import io
import os
import numpy as np
import time
from PIL import Image
from ultralytics import YOLO
from datetime import datetime, timedelta

def save_photo(frame):
    img_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    img = Image.fromarray(img_rgb)

    bio = io.BytesIO()
    bio.name = 'image.jpeg'
    img.save(bio, 'JPEG')
    bio.seek(0)

model_path1 = os.path.join('.', 'runs', 'detect', 'train', 'weights', 'drone.pt')
model = YOLO(model_path1)
model1 = YOLO("yolov8n.pt")
classes1 = [
    'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck',
    'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench',
    'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra',
    'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis',
    'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard',
    'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon',
    'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog',
    'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'dining table',
    'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave',
    'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
    'teddy bear', 'hair drier', 'toothbrush'
]

classes=['drone']
COLORS = np.random.uniform(0, 255, size=(len(classes), 3))
cap = cv2.VideoCapture(0)
fps_camera = cap.get(cv2.CAP_PROP_FPS)
target_fps = 10
n = int(fps_camera / target_fps)
frame_counter, not_detected = 0, 0

while True:
    ret, frame = cap.read()
    if not ret:
        break

    if frame_counter % n == 0:
        outs = model(frame, task='detect', iou=0.2, conf=0.3, show=True, save_conf=True, classes=[0], boxes=True)

        pred_classes = [classes[int(i.item())] for i in outs[0].boxes.cls]
        pred_bbox = [i.tolist() for i in outs[0].boxes.xywh]

        length = len(pred_classes)
        drone_boxes= []
        drone_flag=0
        for i in range(length):
            if pred_classes[i] in ['drone']:

                outs1 = model1(frame, task='detect', iou=0.2, conf=0.3, classes=[0, 14])
                pred_classes1 = [classes1[int(i.item())] for i in outs1[0].boxes.cls]
                if pred_classes1[i] in ['person','bird']:
                    print("NOT A DRONE")
                else:
                    drone_boxes.append((round(pred_bbox[i][0]), round(pred_bbox[i][1]), round(pred_bbox[i][0] + pred_bbox[i][2]), round(pred_bbox[i][1] + pred_bbox[i][3])))
                    drone_flag = 1
                    print("Drone detected")
                    save_photo(frame)

    drone_flag = 0
    drone_boxes = [(0, 0, 0, 0)]
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()


from sqlalchemy import func

from ..db import get_db
from ..models import ClazzModel, DatasetModel, ExperimentalItemModel, UserModel, UserInfoModel

class Dataset:
    def __init__(self):
        self._db = get_db()

    def create(self, dataset_name, experimental_item_id, file_key, deleted=0, description=None, user_only=0, user_id=None):
        dataset = DatasetModel(name=dataset_name, experimental_item_id=experimental_item_id, file_key=file_key, deleted=deleted, description=description, user_id=user_id, user_only=user_only)
        try:
            self._db.add(dataset)
            self._db.commit()
            d_id = dataset.id
        except:
            self._db.rollback()
            d_id = -1
        finally:
            self._db.close()
        return d_id

    def query(self, dataset_id=None, dataset_name=None, experimental_item_id=None, file_key=None, user_only=None, user_id=None, school_id=None, deleted=0, description=None, limit=None, offset=None):
        try:
            query = self._db.query(DatasetModel, ExperimentalItemModel, ClazzModel, UserModel, UserInfoModel).filter(DatasetModel.experimental_item_id == ExperimentalItemModel.id, ExperimentalItemModel.clazz_id == ClazzModel.id, ClazzModel.teacher_id == UserModel.id, ExperimentalItemModel.deleted == 0, UserModel.id == UserInfoModel.user_id)
            if dataset_id is not None:
                query = query.filter(DatasetModel.id == dataset_id)
            if dataset_name is not None:
                query = query.filter(DatasetModel.name == dataset_name)
            if experimental_item_id is not None:
                query = query.filter(DatasetModel.experimental_item_id == experimental_item_id)
            if file_key is not None:
                query = query.filter(DatasetModel.file_key == file_key)
            if description is not None:
                query = query.filter(DatasetModel.description == description)
            if user_only is not None:
                query = query.filter(DatasetModel.user_only == user_only)
            if user_id is not None:
                query = query.filter(DatasetModel.user_id == user_id)
            if school_id is not None:
                query = query.filter(UserModel.school_id == school_id)
            query = query.filter(DatasetModel.deleted == deleted)
            query = query.order_by(DatasetModel.create_time.desc())
            if limit is not None:
                query = query.limit(limit)
                if offset is not None:
                    query = query.offset(offset)
            rets = query.all()
            datasets = list(map(lambda d: {
                'dataset_id': d.DatasetModel.id,
                'dataset_name': d.DatasetModel.name,
                'experimental_item_id': d.DatasetModel.experimental_item_id,
                'teacher_id': d.ClazzModel.teacher_id,
                'teacher_name': d.UserInfoModel.name,
                'file_key': d.DatasetModel.file_key,
                'user_id': d.DatasetModel.user_id,
                'user_only': d.DatasetModel.user_only,
                'deleted': d.DatasetModel.deleted,
                'description': d.DatasetModel.description,
                'create_time': d.DatasetModel.create_time.strftime("%Y-%m-%d  %H:%M:%S")
            }, rets))
        finally:
            self._db.close()
        return datasets

    def update(self, dataset_id, dataset_name=None, description=None):
        flag = -1
        mp = {}
        if dataset_name is not None:
            mp['name'] = dataset_name
        if description is not None:
            mp['description'] = description
        try:
            self._db.query(DatasetModel).filter(DatasetModel.id == dataset_id).update(mp)
            self._db.commit()
            flag = 1
        except:
            self._db.rollback()
        finally:
            self._db.close()
        return flag

    def delete(self, dataset_id):
        flag = -1
        try:
            self._db.query(DatasetModel).filter(DatasetModel.id == dataset_id).update({'deleted': 1})
            self._db.commit()
            flag = 1
        except:
            self._db.rollback()
        finally:
            self._db.close()
        return flag

    def get_count(self, experimental_item_id):
        try:
            count = self._db.query(func.count(DatasetModel.id)).filter(DatasetModel.experimental_item_id == experimental_item_id, DatasetModel.deleted == 0).first()[0]
        finally:
            self._db.close()
        return count