import math
import os.path
from os.path import join

import torch
from torch.utils.data import DataLoader, Dataset
from typing import Dict, AnyStr, Any
from .image_folder import is_image_file, make_dataset
from PIL import Image
import numpy as np

from .transforms import to_tensor

def linear_transform(x, alpha: float = (math.e - 1), beta: float = 1):
    """
    Mapping x to alpha * x + beta, which transforms [l,r] to [alpha * l + beta, alpha * r + beta]
    """
    return alpha * x + beta

class IntrinsicDataset(Dataset):
    def __init__(self):
        super(IntrinsicDataset, self).__init__()

    @staticmethod
    def __get_transform__(data: dict):
        for key in data.keys():
            data[key] = linear_transform(data[key])
        return data

class MITIntrinsicDataset(IntrinsicDataset):
    """
        Dataset origin: https://www.cs.toronto.edu/~rgrosse/intrinsic/

        Following the train-test split strategy and dataset pre-processing script in
        "Direct intrinsics: Learning albedo-shading decomposition by convolutional regression." CVPR 2015.
        The dataset pre-processing script can be found in
        https://github.com/tnarihi/direct-intrinsics/tree/master/data/mit.

    """
    objects = {
        "train": ['apple', 'box', 'cup1', 'dinosaur', 'frog1', 'panther', 'paper1', 'phone', 'squirrel', 'teabag2'],
        "test": ['cup2', 'deer', 'frog2', 'paper2', 'pear', 'potato', 'raccoon', 'sun', 'teabag1', 'turtle']}

    @staticmethod
    def no_transform(item):
        return item

    def __init__(
            self,
            root: str,
            size: int = None,
            transforms: str = None,
            train: bool = True
    ) -> None:
        super(MITIntrinsicDataset, self).__init__()
        self.size = size
        self.root = root.rstrip('/').rstrip('\\')
        self.train = "train" if train else "test"
        self.transforms = transforms
        self.objs = self.objects[self.train]
        self.dirs = {k: dict() for k in self.objs}
        for key in self.dirs.keys():
            self.dirs[key]["mask"] = self.root + '/' + key + '/' + 'mask.png'
            self.dirs[key]["albedo"] = self.root + '/' + key + '/' + 'reflectance.png'
            self.dirs[key]["shading"] = [self.root + '/' + key + '/' + ('gray_shading%02d.png' % idx) for idx in
                                         range(1, 11)]
            self.dirs[key]["shading"].append(self.root + '/' + key + '/' + 'gray_shading.png')

            self.dirs[key]["input"] = [self.root + '/' + key + '/' + ('light%02d.png' % idx) for idx in range(1, 11)]
            self.dirs[key]["input"].append(self.root + '/' + key + '/' + "diffuse.png")
        # check whether images exists or not
        if self.size is None:
            self.size = 110
        for k, v in self.dirs.items():
            for ptp, pth in v.items():
                if type(pth) == list:
                    for inner_pth in pth:
                        if not os.path.isfile(inner_pth):
                            raise FileNotFoundError(inner_pth)
                else:
                    if not os.path.isfile(pth):
                        raise FileNotFoundError(pth)

    def __getpath__(self,
                    index: int
                    ) -> Dict[AnyStr, Any]:

        if index > self.size:
            raise IndexError("out of the range")

        selected_obj = self.objs[index // 11]

        return {"mask": self.dirs[selected_obj]["mask"],
                "albedo": self.dirs[selected_obj]["albedo"],
                "shading": self.dirs[selected_obj]["shading"][index % 11],
                "input": self.dirs[selected_obj]["input"][index % 11]}

    def __getitem__(
            self,
            index: int
    ) -> Dict[AnyStr, Any]:
        paths = self.__getpath__(index)
        ret = dict()
        img_mask = Image.open(paths["mask"]).convert('L')
        img_albedo = Image.open(paths["albedo"]).convert("RGB")
        img_shading = Image.open(paths["shading"]).convert("RGB")
        img_original_shading = Image.open(paths["shading"]).convert("L")
        img_input = Image.open(paths["input"]).convert("RGB")

        ret["mask"] = to_tensor(img_mask)
        ret["mask"][ret["mask"] < 0.5] = 0
        ret["mask"][ret["mask"] > 0.5] = 1
        ret["albedo"] = to_tensor(img_albedo) * ret["mask"]
        ret["shading"] = to_tensor(img_shading) * ret["mask"]

        ret["input"] = linear_transform(to_tensor(img_input) * ret["mask"])
        ret["org_input"] = to_tensor(img_input) * ret["mask"]
        ret["org_shading"] = to_tensor(img_original_shading) * ret["mask"]
        ret["fn"] = "".join((paths["input"]).strip("/").split("/")[-2:])
        # print(ret["fn"])
        return ret
        # return self.__get_transform__(ret)

    def __len__(self):
        return self.size

class BatchInferenceDataset(IntrinsicDataset):
    """
    This inference-only dataset class loads images from the given path.
    """

    def __init__(
            self,
            root: str,
            size: int = None,
            transforms: str = None,
    ) -> None:

        super(BatchInferenceDataset, self).__init__()
        self.size = size
        self.root = root.rstrip('/').rstrip('\\')
        self.transforms = transforms
        self.images = make_dataset(root)
        print(self.images)
        # check whether images exists or not
        if self.size is None:
            self.size = len(self.images)

    def __getitem__(
            self,
            index: int
    ) -> Dict[AnyStr, Any]:
        if index > self.size:
            raise IndexError("out of the range")
        ret = dict()
        ret["fn"] = "%d" % index
        path = self.images[index]
        img = Image.open(path)
        ret["org_input"] = to_tensor(img)
        ret["mask"] = torch.ones(ret["org_input"].shape).type(torch.FloatTensor)
        ret["input"] = linear_transform(ret["org_input"])
        print(ret)
        return ret

    def __len__(self):
        return self.size


import codecs

from utils.snippets import lowercase_and_normalize
from utils.tokenizers import Tokenizer

dict_path = './albert_base_google_zh/vocab.txt'
token_dict = {}
with codecs.open(dict_path, 'r', 'utf8') as reader:
    for line in reader:
        token = line.strip()
        token_dict[token] = len(token_dict)

class OurTokenizer(Tokenizer):
    def _tokenize(self, text):
        if self._do_lower_case:
            text = lowercase_and_normalize(text)

        spaced = ''
        for ch in text:
            if self._is_punctuation(ch) or self._is_cjk_character(ch):
                spaced += '\t' + ch + '\t'
            elif self._is_space(ch):
                spaced += '\t' + '[unused1]\t'
            elif ord(ch) == 0 or ord(ch) == 0xfffd or self._is_control(ch):
                continue
            else:
                spaced += ch

        tokens = []
        for word in spaced.strip().split('\t'):
            tokens.extend(self._word_piece_tokenize(word))

        return tokens

tokenizer1 = OurTokenizer(token_dict)
txt = "我的iphone6s丢   了"
tokenizer2 = Tokenizer(dict_path, do_lower_case = True)
print(tokenizer1.tokenize(txt))
token_ids, segment_ids = tokenizer1.encode(txt, maxlen = 30)
print(token_ids)
print(segment_ids)

# print(tokenizer.tokenize(u'今天天气不错 '))

# ['[CLS]', '今', '天', '天', '气', '不', '错', '[unused1]', '[SEP]']

# def get_keys(d, value):
#     return [k for k, v in d.items() if v == value]
#
#
# ids = [101, 2225, 1046, 185, 4649, 858, 2861, 2805, 8020, 10560, 11057, 8169, 9409, 12653, 11403, 8021, 5401, 1744,
#        4510, 2512, 4028, 1447, 8024, 8974, 2399, 1139, 4495, 754, 5401, 1744, 6662, 3211, 3172, 2128, 6929, 2336, 3173,
#        1952, 2209, 5679, 8024, 3684, 689, 754, 7350, 5507, 5682, 1920, 2110, 1469, 6662, 3211, 3172, 2128, 6929, 2336,
#        4989, 1920, 2110, 102]
#
# for i, item in enumerate(ids):
#     print((i, get_keys(token_dict, item)[0]),end = "")


from typing import List
from uuid import UUID, uuid4
from fastapi import FastAPI, HTTPException
from models import Gender, Role, User, UserUpdateRequest

app = FastAPI()

db: List[User] = [
    User(
        id=uuid4(),
        first_name="Jenna",
        last_name="Jackson",
        gender=Gender.female,
        roles=[Role.student]
        ),
    User(
        id=uuid4(),
        first_name="John",
        last_name="Jackson",
        gender=Gender.male,
        roles=[Role.admin, Role.user]
        )
]

@app.get("/")
async def root():
    return {"Hello" : "World"}

@app.get("/api/v1/users")
async def list_users():
    return db

@app.post("/api/v1/users")
async def register_user(user: User):
    db.append(user)
    return {"id": user.id}

@app.delete("/api/v1/users/{user_id}")
async def delete_user(user_id: UUID):
    for user in db:
        if user.id == user_id:
            db.remove(user)
            return
    raise HTTPException(
        status_code=404,
        detail=f"user with id: {user_id} doesn't exists"
    )

@app.put("/api/v1/users/{user_id}")
async def update_user(user_id: UUID, user_update: UserUpdateRequest):
    for user in db:
        if user.id == user_id:
            if user_update.first_name is not None:
                user.first_name = user_update.first_name
            if user_update.last_name is not None:
                user.last_name = user_update.last_name
            if user_update.middle_name is not None:
                user.middle_name = user_update.middle_name
            if user_update.roles is not None:
                user.roles = user_update.roles
            return
    raise HTTPException(
        status_code=404,
        detail=f"user with id: {user_id} doesn't exists"
    )


from mta_api import MtaApi
from print_dash import PrintDash
import json
from tabulate import tabulate
import time
import sys
import itertools
from datetime import date
from datetime import datetime

from colorama import Fore, Back, Style

from weather import Weather

# print(Fore.RED + 'some red text')
# print(Back.GREEN + 'and with a green background')
# print(Style.DIM + 'and in dim text')
# print(Style.RESET_ALL)
# print('back to normal now')

use_local = False

train_getter = MtaApi()
print_dash = PrintDash()
weather = Weather()
colors = Fore.BLACK + Back.WHITE

spinner = itertools.cycle(["-", "/", "|", "\\"])
busy = True

def sleep_spinner():
    i = 0
    while i < 60:
        sys.stdout.write(next(spinner))  # write the next character
        sys.stdout.flush()  # flush stdout buffer (actual character display)
        sys.stdout.write("\b")  # erase the last written char
        time.sleep(1)
        i += 1

while True:
    sys.stdout.flush()
    t = time.localtime()
    today = date.today()
    current_time = datetime.now().time()
    hours = current_time.hour
    minutes = current_time.minute
    current_time_in_minutes = hours * 60 + minutes

    if current_time_in_minutes > int(weather.get_sunrise()) and current_time_in_minutes < int(weather.get_sunset()):
        colors = Fore.BLACK + Back.WHITE
    else:
        colors = Fore.WHITE + Back.BLACK
    train_board = train_getter.get_trains(use_local)

    x = 0
    while x < 10:
        print(colors + "\n")
        x += 1
    current_time = time.strftime("%I:%M %p")
    current_date = today.strftime("%m / %d / %Y")
    print(colors + current_time + "  |  " + current_date)
    print(colors + weather.get_weather_printout())
    print(
        colors
        + "\n"
        + tabulate(print_dash.format_trains_to_table(train_board), tablefmt="plain")
    )
    # time.sleep(60)
    sleep_spinner()


"""URL patterns."""

from django.conf.urls import url
from django.contrib.auth import views as auth_views
from . import views

urlpatterns = [
    url(r'^login/$', auth_views.login, name='login', kwargs={'template_name': 'flasharray/login.html'}),
    url(r'^logout/$', auth_views.logout, name='logout', kwargs={'next_page': '/'}),
    url(r'home.html', views.index, name='home'),
    url(r'logs.html', views.logs, name='logs'),
    url(r'^create_array', views.FlashArrayCreate.as_view(), name='create_array'),
    url(r'^delete_array/(?P<pk>[\w-]+)$', views.FlashArrayDelete.as_view(), name='delete_array'),
    url(r'^update_array/(?P<pk>[\w-]+)$', views.FlashArrayUpdate.as_view(), name='update_array'),
]


import sys
from collections import deque
from copy import deepcopy
input = sys.stdin.readline

N = int(input())
candy = [list(input().rstrip()) for _ in range(N)]
u = [[1] * N for _ in range(N)]
dy = [-1, 0, 1, 0]
dx = [0, 1, 0, -1]

qu = deque()
for y in range(N):
    for x in range(N):
        if u [y][x]:
            for i in range(4):
                r, c = y + dy[i], x + dx[i]
                if r < 0 or r >= N or c < 0 or c >= N: continue
                if candy[y][x] == candy[r][c]: continue
                qu.append((y, x, r, c))
                u[y][x] = u[r][c] = 0

ans = 0
while qu:
    if ans == N: break
    n_candy = deepcopy(candy)
    y, x, r, c = qu.popleft()
    n_candy[y][x], n_candy[r][c] = n_candy[r][c], n_candy[y][x]

    ret1 = ret2 = 0
    for i in range(N):
        cnt1 = [1, 1]
        cnt2 = [1, 1]
        for j in range(1, N):
            if n_candy[i][j-1] == n_candy[i][j]:
                cnt1[0] += 1
            if n_candy[i][j-1] != n_candy[i][j] or j == N - 1:
                cnt1[1] = max(cnt1[0], cnt1[1])
                cnt1[0] = 1

            if n_candy[j-1][i] == n_candy[j][i]:
                cnt2[0] += 1
            if n_candy[j-1][i] != n_candy[j][i] or j == N - 1:
                cnt2[1] = max(cnt2[0], cnt2[1])
                cnt2[0] = 1

        ret1 = max(ret1, cnt1[1])
        ret2 = max(ret2, cnt2[1])

    ans = max(ret1, ret2, ans)

print(ans)


from itertools import groupby
import sys

class Entry(object):
    __slots__ = ("when", "who", "what")

    def __init__(self, when, who, what):
        self.when = when
        self.who = who
        self.what = what

    def __repr__(self):
        return "when={self.when}, who={self.who}, what={self.what})".format(self=self)

class Item(object):
    __slots__ = ("duration", "who")

    def __init__(self, duration, who):
        self.duration = duration
        self.who = who

    def __repr__(self):
        return "when={self.duration}, who={self.who})".format(self=self)

def load():
    def make(line):
        parts = line.split(',')
        return Entry(int(parts[0].strip()), parts[1].strip(), parts[2].strip())

    with open(input_file, "r") as f:
        return [make(line) for line in f]

def save(items):
    with open(output_file, "w") as f:
        f.write("duration, who")
        for item in items:
            f.write("\n{0}, {1}".format(item.duration, item.who))

def work():
    entries = load()

    keys = []
    groups = []
    entries = sorted(entries, key=lambda x: x.who)
    for k, g in groupby(entries, key=lambda x: x.who):
        groups.append(list(g))
        keys.append(k)

    items = []

    for i in range(0, len(keys)):
        g = groups[i]
        ordered = list(sorted(g, key=lambda x: x.when))

        start = 0
        duration = 0

        for entry in ordered:
            if entry.what == "login":
                start = entry.when
            elif entry.what == "logout":
                duration += entry.when - start

        items.append(Item(duration, keys[i]))

    items = sorted(items, key=lambda x: x.duration, reverse=True)

    save(items)

input_file = sys.argv[1]
output_file = "out.txt"

if len(sys.argv) > 2:
    output_file = sys.argv[2]

work()


# -*- coding: utf-8 -*-
import scrapy
from ..items import MovieprojectItem

## 先使用scrapy，再使用scrapy_redis

class MovieSpider(scrapy.Spider):
    name = 'movie'  ## redis保存的文件夹名字叫movie
    allowed_domains = ['www.dy2018.com']
    start_urls = ['https://www.dy2018.com/0/']

    def parse(self, response):

        tables = response.xpath('//table[@class="tbspan"]') ## 直接找tabl
        for t in tables:
            item = MovieprojectItem()

            ##获取电影名
            ## 电影介绍
            title =  t.xpath('.//tr[2]//a[2]/text()').extract()[0]
            info = ''.join(t.xpath('.//tr[4]//p/text()').extract()).replace('\u3000','') ## 列表直接平成字符串
            # info =  info.replace('\u3000','') ##info.replace('\u3000','')##  \u3000代表中文空格
            item['title'] = title
            item['info'] = info
            yield item


import torch
from torch.autograd import Variable
import numpy as np
import pdb, os, argparse
from skimage import io
from tqdm import tqdm
from model.VSOD_model import RGBDVSODModel
from data import get_loader

def LOG(logfile, output):
    with open(logfile, 'a') as f:
        f.write(output)

def eval_data(opt, test_loader, ckpt_name, is_ResNet=True, ckpt_path=None):
    model = RGBDVSODModel(opt, isTrain=False, is_ResNet=is_ResNet)
    if is_ResNet:
        model.load_state_dict(torch.load(ckpt_path + 'model.pth.' + str(ckpt_name)))
    else:
        model.load_state_dict(torch.load(ckpt_path + 'model.pth.' + str(ckpt_name)))

    cuda = torch.cuda.is_available()
    if cuda:
        model.cuda()
    model.eval()

    if is_ResNet:
        save_path = os.path.join('./results/Resnet/')
    else:
        save_path = os.path.join('./results/VGG/')
    if not os.path.exists(save_path):
        os.makedirs(save_path)

    logfile = os.path.join('./', 'result.txt')

    print('Evaluating dataset:')
    avg_mae, img_num = 0.0, 0.0
    for i, pack in enumerate(tqdm(test_loader), start=1):
        images, gts, depths, name = pack
        images = Variable(images)
        gts = Variable(gts)
        depths = Variable(depths)
        if cuda:
            images = images.cuda()
            gts = gts.cuda()
            depths = depths.cuda()

        _, _, res = model(images, depths)

        res = res.sigmoid().data.cpu().numpy().squeeze()
        res = (res - res.min()) / (res.max() - res.min() + 1e-8)

        os.makedirs(save_path+name[1][0],exist_ok=True)
        io.imsave(os.path.join(save_path+name[1][0], name[0][0]), np.uint8(res * 255))

        '''Evaluate MAE'''
        gt = gts.data.cpu().numpy().squeeze()
        mea = np.abs(res - gt).mean()
        if mea == mea:  # for Nan
            avg_mae += mea
            img_num += 1.0
    avg_mae /= img_num
    print('[MAE] The current evaluation metric is: {:.4f} mae.'.format(avg_mae))
    LOG(logfile, 'model.pth.{} CKPT with {:.4f} mae.\n'.format(str(ckpt_name), avg_mae))

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--testsize', type=int, default=320, help='testing size')
    parser.add_argument('--baseline_mode', type=bool, default=False, help='whether apply baseline mode or not')
    parser.add_argument('--sample_rate', type=int, default=3, help='sample rate')
    parser.add_argument('--stm_queue_size', type=int, default=3, help='stm queue size')
    parser.add_argument('--is_ResNet', type=bool, default=True, help='VGG or ResNet backbone')
    parser.add_argument('--win_size', type=int, default=-1, help='if not given, mem size + 1')
    cfg = parser.parse_args()

    if cfg.win_size == -1:
        cfg.win_size = cfg.stm_queue_size + 1
    interval = [cfg.win_size - 1, 0]
    assert (len(interval) == 2 and interval[0] >= 0 and interval[1] >= 0)

    videos_ROOT = "Your_DViSal_dataset_path/"
    ckpt_path = 'Your_ckpt_save_path/'

    ckpt_name = 'best'       # specify ckpt name, 'best'+.pth
    test_name = 'test_all'   # specify testset, e.g., test_DET, test_track3D

    test_loader = get_loader(videos_ROOT, batchsize=1, trainsize=cfg.testsize, shuffle=False, pin_memory=False,
                             subset=test_name, augmentation=False, interval=interval, sample_rate=cfg.sample_rate)
    eval_data(cfg, test_loader, ckpt_name, is_ResNet=cfg.is_ResNet, ckpt_path= ckpt_path)


from Collum_generation import CG
from matplotlib import pyplot as plt
import time

class Results():
    def __init__(self,show=False,save=True,max_time=3600):
        self.show = show
        self.save = save

        start_time = time.time()
        self.model = CG()
        self.run_time = time.time()-start_time
        print(f"\nruntime: {round(self.run_time,3)} seconds")

        self.print_stats()
        self.plot_graph()

    def timestep2day(self,timestep):
        '''converts the time step into a string with hour and day number for plotting'''
        tmp = []
        for t in timestep:
            time = t * 4
            h = int(time % 24)
            d = int((time - h) / 24 + 1)
            if h != 0:
                tmp.append(f"{h}h")
            else:
                tmp.append(f"{h}h\nDay {d}")
        return tmp

    def plot_graph(self):
        '''plots and saves the graph that represents the model'''
        c_code = {"AC_1": (1, 0, 0),
                  "AC_2": (0, 0, 1)}
        results = self.model.decision_variable_dict

        plt.figure(figsize=[11,4])
        plt.xticks(range(25),self.timestep2day(range(25)))
        idx2ref = [""] * 6
        for airport_ref, airport in self.model.TSN.data.airport_dict.items():
            idx2ref[airport["index"] - 1] = airport_ref
        plt.yticks(range(7)[1:], idx2ref)

        request_plot_dict = {}
        # for every z_p_r
        for p, zp in results["z"].items():
            for r, zpr in zp.items():
                if type(zpr) != int:
                    path = self.model.path_dict["request paths"][r][p]
                    for arc in path.arcs:
                        a = arc.ref
                        if arc.type != "NS":
                            if self.model.TSN.data.request_dict[r]["airport_D"] != arc.origin_airport:
                                weight = self.model.TSN.data.request_dict[r]["weight"] * zpr.X
                            else:
                                weight = 0
                            try:
                                request_plot_dict[a] += weight
                            except:
                                request_plot_dict[a] = weight
                            t = [arc.origin_timestep,arc.destination_timestep]
                            n = [self.model.TSN.data.airport_dict[arc.origin_airport]["index"] , self.model.TSN.data.airport_dict[arc.destination_airport]["index"]]
                            plt.plot(t, n, linewidth=request_plot_dict[a] / 10, color=(0.3, 0.3, 0.3),zorder = 2)
                        else:
                            if zpr.X:
                                # plt.plot(arc.origin_timestep, self.model.TSN.data.airport_dict[arc.origin_airport]["index"], 'ro')
                                plt.plot([arc.origin_timestep, arc.destination_timestep],
                                         [self.model.TSN.data.airport_dict[arc.origin_airport]["index"],
                                         self.model.TSN.data.airport_dict[arc.destination_airport]["index"]],
                                         color=(0, 0.8, 0), marker='o',markersize=2, linestyle='dashed', linewidth=1, zorder=1)

        for r in self.model.master.getVars():
            if r.X != 0:
                if r.varName[0] in ["x", "y"]:
                    # print(r.varName,r.X)
                    arc_name = r.varName[16:].split("->")
                    t = [0, 0]
                    n = [0, 0]
                    plane = arc_name[1].split("-")[-1]
                    for i in range(2):
                        t[i] = int(arc_name[i].split("-")[0])
                        n[i] = int(self.model.TSN.data.airport_dict[arc_name[i].split("-")[1]]["index"])
                    plt.plot(t, n, color=c_code[plane], linestyle=":",zorder=3)

        if self.save:
            file_name = "Results_model_4"
            plt.savefig(f"{file_name}.png")
            print(f"saved figure to '{file_name}.png'")
        if self.show:
            plt.show()

    def print_stats(self):
        '''prints the stats of the model'''
        # =========================================================== Generate data
        # -> Arc used (non-NS)
        total_arc_used = 0
        f_arc_used = 0
        g_arc_used = 0

        # -> NS arcs used
        NS_arc_used = 0
        # -> Packages handled
        packages_handled = []
        packages_not_handled = []
        packages_not_handled_penalty = 0

        results = self.model.decision_variable_dict

        for p, zp in results["z"].items():
            for r, zpr in zp.items():
                if type(zpr) != int:
                    path = self.model.path_dict["request paths"][r][p]

                    for arc in path.arcs:
                        if arc.type == "NS":
                            NS_arc_used += 1 * zpr.X

                        # elif arc.type == "Ground":
                        #     g_arc_used += 1
                        #
                        # elif arc.type == "Flight":
                        #     f_arc_used += 1

        # ... per request
        for r, request in self.model.TSN.data.request_dict.items():
            # ... find Pns
            for p, path in self.model.path_dict["request paths"][r].items():
                if path.type == "NS":

                    PCr = request["penalty"]  # MU/ton
                    Wr = request["weight"] # ton
                    if type(self.model.decision_variable_dict["z"][p][r]) != int:
                        packages_not_handled_penalty += PCr * Wr * self.model.decision_variable_dict["z"][p][r].x

        total_arc_used += f_arc_used + g_arc_used

        # print(f"- Nb. arcs used: {total_arc_used}")
        # print(f"   > Flight arcs: {f_arc_used}")
        # print(f"   > Ground arcs: {g_arc_used}")

        print(f"- Nb. NS arcs used: {NS_arc_used}")
        print(f"- Nb. packages handled: {115-NS_arc_used}")
        print(f"- Nb. packages not handled: {NS_arc_used}")
        print(f"- Total packages not handled penalty: {packages_not_handled_penalty}")

if __name__ == '__main__':
    Results(show=False,save=True,max_time=3600)


from functools import reduce
from itertools import product
from operator import mul
from typing import Tuple

import numpy as np

from utils import read_file

def parse_input(input_path: str):
    steps = []
    for line in read_file(input_path):
        sign = int(line.startswith("on"))
        ranges = []
        range_strs = line.split(" ")[1].split(",")

        for range_str in range_strs:
            range = list(map(int, range_str.split("=")[1].split("..")))

            # Account for range boundaries to prevent one-off errors
            range[1] += 1
            ranges.append(tuple(range))
        steps.append((sign, tuple(ranges)))
    return steps

def solve_1(steps):
    states = np.zeros((101, 101, 101))
    for step in steps:
        sign, [range_x, range_y, range_z] = step
        states[
            range_x[0] + 50 : range_x[1] + 50,
            range_y[0] + 50 : range_y[1] + 50,
            range_z[0] + 50 : range_z[1] + 50,
        ] = sign

    return np.sum(states)

class Cuboid:
    axes = range(3)

    def __init__(self, boundaries: Tuple[Tuple[int]]):
        self.boundaries = boundaries

    def size(self):
        return reduce(mul, (boundary[1] - boundary[0] for boundary in self.boundaries))

    def overlap(self, other: "Cuboid"):
        return all(
            self.boundaries[idx][0] <= other.boundaries[idx][1] - 1
            and self.boundaries[idx][1] - 1 >= other.boundaries[idx][0]
            for idx in self.axes
        )

def get_non_overlapping(cuboid1: Cuboid, cuboid2: Cuboid):
    """Subtract cuboid2 from cuboid1"""

    boundaries = []
    for axis_id in range(3):
        c1_bounds, c2_bounds = cuboid1.boundaries[axis_id], cuboid2.boundaries[axis_id]
        points = list(c1_bounds)

        if c2_bounds[0] >= c1_bounds[0]:
            points.append(c2_bounds[0])
        if c2_bounds[1] <= c1_bounds[1]:
            points.append(c2_bounds[1])

        points = [
            tuple(sorted(points)[idx : idx + 2]) for idx in range(len(points) - 1)
        ]
        boundaries.append(points)

    subcuboids = product(*boundaries)

    # Take out overlapping ones
    non_overlapping_subcuboids = []
    for c in subcuboids:
        subcuboid = Cuboid(c)
        if not cuboid2.overlap(subcuboid):
            non_overlapping_subcuboids.append(subcuboid)

    return non_overlapping_subcuboids

def solve_2(steps):
    cuboids = []

    for step in steps:
        sign, boundaries = step
        new_cuboids, new_cub = [], Cuboid(boundaries)

        for old_cub in cuboids:
            # Detect and remove overlapping area
            if old_cub.overlap(new_cub):
                # Only keep non-overlapping areas of old cuboid
                non_overlapping_subcubs = get_non_overlapping(old_cub, new_cub)
                new_cuboids.extend(non_overlapping_subcubs)
            else:
                new_cuboids.append(old_cub)
        if sign == 1:
            new_cuboids.append(new_cub)
        cuboids = new_cuboids

    return sum(cuboid.size() for cuboid in cuboids)

if __name__ == "__main__":
    sample1_input = parse_input("data/day_22/sample1.txt")
    sample2_input = parse_input("data/day_22/sample2.txt")
    sample3_input = parse_input("data/day_22/sample3.txt")
    real_input = parse_input("data/day_22/input.txt")

    # Part 1
    assert solve_1(sample1_input) == 39
    assert solve_1(sample2_input) == 590784
    assert solve_1(real_input) == 551693

    # Part 2
    assert solve_2(sample3_input) == 2758514936282235
    assert solve_2(real_input) == 1165737675582132


from flask import Flask, render_template, request, redirect
import sqlite3

app = Flask(__name__)

# Aluno ----------------------------------------------------------------------------------------------------------------
@app.route('/')
def index():
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Consultando os alunos do banco de dados
    cursor.execute("SELECT * FROM aluno")
    alunos = cursor.fetchall()

    # Fechando a conexão com o banco de dados
    conn.close()

    return render_template('index.html', alunos=alunos)

@app.route('/inserir', methods=['POST'])
def inserir():
    # Recuperando os dados do formulário
    nome = request.form['nome']
    email = request.form['email']
    curso = request.form['curso']
    data_nascimento = request.form['data_nascimento']
    endereco = request.form['endereco']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Inserindo um novo aluno na tabela
    cursor.execute("INSERT INTO aluno (nome, email, curso, data_nascimento, endereco) VALUES (?, ?, ?, ?, ?)",
                   (nome, email, curso, data_nascimento, endereco))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/')

@app.route('/remover/<int:aluno_id>')
def remover(aluno_id):
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Removendo o aluno da tabela
    cursor.execute("DELETE FROM aluno WHERE id=?", (aluno_id,))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/')

@app.route('/atualizar/<int:aluno_id>', methods=['POST'])
def atualizar(aluno_id):
    # Recuperando os dados do formulário
    nome = request.form['nome']
    email = request.form['email']
    curso = request.form['curso']
    data_nascimento = request.form['data_nascimento']
    endereco = request.form['endereco']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Atualizando os dados do aluno na tabela
    cursor.execute("UPDATE aluno SET nome=?, email=?, curso=?, data_nascimento=?, endereco=? WHERE id=?",
                   (nome, email, curso, data_nascimento, endereco, aluno_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/')
# ----------------------------------------------------------------------------------------------------------------------

# Professor ------------------------------------------------------------------------------------------------------------
@app.route('/professores')
def listar_professores():
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Consultando os professores do banco de dados
    cursor.execute("SELECT * FROM professor")
    professores = cursor.fetchall()

    # Fechando a conexão com o banco de dados
    conn.close()

    return render_template('professores.html', professores=professores)
@app.route('/inserir_professor', methods=['POST'])
def inserir_professor():
    # Recuperando os dados do formulário
    nome = request.form['nome']
    email = request.form['email']
    curso = request.form['curso']
    data_nascimento = request.form['data_nascimento']
    endereco = request.form['endereco']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Inserindo um novo professor na tabela
    cursor.execute("INSERT INTO professor (nome, email, curso, data_nascimento, endereco) VALUES (?, ?, ?, ?, ?)",
                   (nome, email, curso, data_nascimento, endereco))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página de professores
    return redirect('/professores')

@app.route('/remover_professor/<int:professor_id>')
def remover_professor(professor_id):
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Removendo o professor da tabela
    cursor.execute("DELETE FROM professor WHERE id=?", (professor_id,))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página de professores
    return redirect('/professores')

@app.route('/atualizar_professor/<int:professor_id>', methods=['POST'])
def atualizar_professor(professor_id):
    # Recuperando os dados do formulário
    nome = request.form['nome']
    email = request.form['email']
    curso = request.form['curso']
    data_nascimento = request.form['data_nascimento']
    endereco = request.form['endereco']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Atualizando os dados do professor na tabela
    cursor.execute("UPDATE professor SET nome=?, email=?, curso=?, data_nascimento=?, endereco=? WHERE id=?",
                   (nome, email, curso, data_nascimento, endereco, professor_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página de professores
    return redirect('/professores')
# ----------------------------------------------------------------------------------------------------------------------

# Disciplina------------------------------------------------------------------------------------------------------------
@app.route('/disciplinas')
def disciplinas():
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Obtendo todas as disciplinas da tabela
    cursor.execute("SELECT * FROM disciplina")
    disciplinas = cursor.fetchall()

    # Fechando a conexão com o banco de dados
    conn.close()

    # Renderizando o template disciplina.html e passando as disciplinas como argumento
    return render_template('disciplina.html', disciplinas=disciplinas)

@app.route('/inserir_disciplina', methods=['POST'])
def inserir_disciplina():
    # Recuperando os dados do formulário
    nome = request.form['nome']
    carga_horaria = request.form['carga_horaria']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Inserindo uma nova disciplina na tabela
    cursor.execute("INSERT INTO disciplina (nome, carga_horaria) VALUES (?, ?)",
                   (nome, carga_horaria))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/disciplinas')

@app.route('/remover_disciplina/<int:disciplina_id>')
def remover_disciplina(disciplina_id):
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Removendo a disciplina da tabela
    cursor.execute("DELETE FROM disciplina WHERE id=?", (disciplina_id,))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/disciplinas')

@app.route('/atualizar_disciplina/<int:disciplina_id>', methods=['POST'])
def atualizar_disciplina(disciplina_id):
    # Recuperando os dados do formulário
    nome = request.form['nome']
    carga_horaria = request.form['carga_horaria']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Atualizando os dados da disciplina na tabela
    cursor.execute("UPDATE disciplina SET nome=?, carga_horaria=? WHERE id=?",
                   (nome, carga_horaria, disciplina_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/disciplinas')

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

# Turmas ---------------------------------------------------------------------------------------------------------------
@app.route('/turmas')
def turmas():
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Obtendo todas as turmas da tabela
    cursor.execute("SELECT * FROM turma")
    turmas = cursor.fetchall()

    # Fechando a conexão com o banco de dados
    conn.close()

    # Renderizando o template turma.html e passando as turmas como argumento
    return render_template('turma.html', turmas=turmas)

@app.route('/inserir_turma', methods=['POST'])
def inserir_turma():
    # Recuperando os dados do formulário
    sala = request.form['sala']
    horario = request.form['horario']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Inserindo uma nova turma na tabela
    cursor.execute("INSERT INTO turma (sala, horario) VALUES (?, ?)",
                   (sala, horario))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/turmas')

@app.route('/remover_turma/<int:turma_id>')
def remover_turma(turma_id):
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Removendo a turma da tabela
    cursor.execute("DELETE FROM turma WHERE id=?", (turma_id,))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/turmas')

@app.route('/atualizar_turma/<int:turma_id>', methods=['POST'])
def atualizar_turma(turma_id):
    # Recuperando os dados do formulário
    sala = request.form['sala']
    horario = request.form['horario']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Atualizando os dados da turma na tabela
    cursor.execute("UPDATE turma SET sala=?, horario=? WHERE id=?",
                   (sala, horario, turma_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/turmas')

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

# Matrícula ------------------------------------------------------------------------------------------------------------
@app.route('/matriculas')
def matriculas():
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Obtendo todas as matrículas da tabela
    cursor.execute("SELECT * FROM matricula")
    matriculas = cursor.fetchall()

    # Fechando a conexão com o banco de dados
    conn.close()

    # Renderizando o template matricula.html e passando as matrículas como argumento
    return render_template('matricula.html', matriculas=matriculas)

@app.route('/inserir_matricula', methods=['POST'])
def inserir_matricula():
    # Recuperando os dados do formulário
    aluno_id = request.form['aluno_id']
    disciplina_id = request.form['disciplina_id']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Inserindo uma nova matrícula na tabela
    cursor.execute("INSERT INTO matricula (aluno_id, disciplina_id) VALUES (?, ?)",
                   (aluno_id, disciplina_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/matriculas')

@app.route('/remover_matricula/<int:aluno_id>/<int:disciplina_id>')
def remover_matricula(aluno_id, disciplina_id):
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Removendo a matrícula da tabela
    cursor.execute("DELETE FROM matricula WHERE aluno_id=? AND disciplina_id=?",
                   (aluno_id, disciplina_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/matriculas')

@app.route('/atualizar_matricula/<int:aluno_id>/<int:disciplina_id>', methods=['POST'])
def atualizar_matricula(aluno_id, disciplina_id):
    # Recuperando os dados do formulário
    novo_aluno_id = request.form['aluno_id']
    nova_disciplina_id = request.form['disciplina_id']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Atualizando os dados da matrícula na tabela
    cursor.execute("UPDATE matricula SET aluno_id=?, disciplina_id=? WHERE aluno_id=? AND disciplina_id=?",
                   (novo_aluno_id, nova_disciplina_id, aluno_id, disciplina_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/matriculas')

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

# Leciona --------------------------------------------------------------------------------------------------------------
@app.route('/leciona')
def lecionas():
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Obtendo todas as relações "leciona" da tabela
    cursor.execute("SELECT * FROM leciona")
    lecionas = cursor.fetchall()

    # Fechando a conexão com o banco de dados
    conn.close()

    # Renderizando o template leciona.html e passando as relações "leciona" como argumento
    return render_template('leciona.html', lecionas=lecionas)

@app.route('/inserir_leciona', methods=['POST'])
def inserir_leciona():
    # Recuperando os dados do formulário
    professor_id = request.form['professor_id']
    disciplina_id = request.form['disciplina_id']
    turma_id = request.form['turma_id']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Inserindo uma nova relação "leciona" na tabela
    cursor.execute("INSERT INTO leciona (professor_id, disciplina_id, turma_id) VALUES (?, ?, ?)",
                   (professor_id, disciplina_id, turma_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/leciona')

@app.route('/remover_leciona/<int:professor_id>/<int:disciplina_id>/<int:turma_id>')
def remover_leciona(professor_id, disciplina_id, turma_id):
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Removendo a relação "leciona" da tabela
    cursor.execute("DELETE FROM leciona WHERE professor_id=? AND disciplina_id=? AND turma_id=?",
                   (professor_id, disciplina_id, turma_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/leciona')

@app.route('/atualizar_leciona/<int:professor_id>/<int:disciplina_id>/<int:turma_id>', methods=['POST'])
def atualizar_leciona(professor_id, disciplina_id, turma_id):
    # Recuperando os dados do formulário
    novo_professor_id = request.form['professor_id']
    nova_disciplina_id = request.form['disciplina_id']
    nova_turma_id = request.form['turma_id']

    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Atualizando os dados da relação "leciona" na tabela
    cursor.execute("UPDATE leciona SET professor_id=?, disciplina_id=?, turma_id=? WHERE professor_id=? AND disciplina_id=? AND turma_id=?",
                   (novo_professor_id, nova_disciplina_id, nova_turma_id, professor_id, disciplina_id, turma_id))

    # Salvando as alterações e fechando a conexão com o banco de dados
    conn.commit()
    conn.close()

    # Redirecionando de volta para a página inicial
    return redirect('/leciona')
# ----------------------------------------------------------------------------------------------------------------------

# Junção Interna--------------------------------------------------------------------------------------------------------
@app.route('/juncao_interna')
def juncao():
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Executando a consulta de junção interna
    cursor.execute("SELECT aluno.nome, aluno.email, disciplina.nome FROM aluno "
                   "INNER JOIN matricula ON aluno.id = matricula.aluno_id "
                   "INNER JOIN disciplina ON matricula.disciplina_id = disciplina.id")

    # Obtendo os resultados da consulta
    resultados = cursor.fetchall()

    # Fechando a conexão com o banco de dados
    conn.close()

    # Renderizando o template juncao.html e passando os resultados da junção como argumento
    return render_template('juncao_interna.html', resultados=resultados)

# Junção Externa--------------------------------------------------------------------------------------------------------
@app.route('/juncao_externa')
def juncao_externa():
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Executando a consulta de junção externa
    cursor.execute("SELECT professor.nome, disciplina.nome, leciona.turma_id FROM professor "
                   "LEFT JOIN leciona ON professor.id = leciona.professor_id "
                   "LEFT JOIN disciplina ON leciona.disciplina_id = disciplina.id")

    # Obtendo os resultados da consulta
    resultados = cursor.fetchall()

    # Fechando a conexão com o banco de dados
    conn.close()

    # Renderizando o template juncao_externa.html e passando os resultados da junção como argumento
    return render_template('juncao_externa.html', resultados=resultados)

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

# Sentença de grupo envolvendo as junções dos anteriores ---------------------------------------------------------------
# Página mostrando quantas disciplinas cada aluno faz
@app.route('/disciplinas_por_aluno')
def disciplinas_por_aluno():
    # Conectando ao banco de dados
    conn = sqlite3.connect('sistema_de_matriculas.db')
    cursor = conn.cursor()

    # Executando a consulta para contar as disciplinas por aluno
    cursor.execute("SELECT aluno.nome, COUNT(matricula.disciplina_id) FROM aluno "
                   "LEFT JOIN matricula ON aluno.id = matricula.aluno_id GROUP BY aluno.nome")

    # Obtendo os resultados da consulta
    resultados = cursor.fetchall()

    # Fechando a conexão com o banco de dados
    conn.close()

    # Renderizando o template disciplinas_por_aluno.html e passando os resultados como argumento
    return render_template('disciplinas_por_aluno.html', resultados=resultados)

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

# Sentença com a cláusula HAVING ---------------------------------------------------------------------------------------
@app.route('/filtrar_disciplinas', methods=['GET', 'POST'])
def filtrar_disciplinas():
    if request.method == 'POST':
        # Obter o valor mínimo fornecido pelo usuário no formulário
        valor_minimo = int(request.form['valor_minimo'])

        # Conectar ao banco de dados
        conn = sqlite3.connect('sistema_de_matriculas.db')
        cursor = conn.cursor()

        # Executar a consulta filtrando as disciplinas pelo número mínimo de alunos matriculados
        cursor.execute("SELECT disciplina.nome, COUNT(matricula.aluno_id) FROM disciplina "
                       "LEFT JOIN matricula ON disciplina.id = matricula.disciplina_id "
                       "GROUP BY disciplina.nome "
                       "HAVING COUNT(matricula.aluno_id) >= ?", (valor_minimo,))

        # Obter os resultados da consulta
        resultados = cursor.fetchall()

        # Fechar a conexão com o banco de dados
        conn.close()

        # Renderizar o template disciplinas_filtradas.html e passar os resultados e o valor mínimo como argumentos
        return render_template('disciplinas_filtradas.html', resultados=resultados, valor_minimo=valor_minimo)

    # Renderizar o template de formulário de filtragem
    return render_template('filtrar_disciplinas.html')
# ----------------------------------------------------------------------------------------------------------------------

# Consulta com subconsulta ---------------------------------------------------------------------------------------------
@app.route('/alunos_por_professor', methods=['GET', 'POST'])
def alunos_por_professor():
    if request.method == 'POST':
        # Obter o ID do professor fornecido pelo usuário no formulário
        professor_id = int(request.form['professor_id'])

        # Conectar ao banco de dados
        conn = sqlite3.connect('sistema_de_matriculas.db')
        cursor = conn.cursor()

        # Executar a consulta usando uma subconsulta para obter os nomes dos alunos
        cursor.execute("SELECT aluno.nome FROM aluno WHERE aluno.id IN "
                       "(SELECT matricula.aluno_id FROM matricula "
                       "LEFT JOIN leciona ON matricula.disciplina_id = leciona.disciplina_id "
                       "WHERE leciona.professor_id = ?)", (professor_id,))

        # Obter os resultados da consulta
        resultados = cursor.fetchall()

        # Fechar a conexão com o banco de dados
        conn.close()

        # Renderizar o template alunos_por_professor.html e passar os resultados e o ID do professor como argumentos
        return render_template('alunos_por_professor.html', resultados=resultados, professor_id=professor_id)

    # Renderizar o template de formulário para inserir o ID do professor
    return render_template('informar_professor.html')

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

if __name__ == '__main__':
    app.run()


from flask import Flask, jsonify, request, Response
import requests
import re
import json

app = Flask(__name__)
proxyList = list()
proxyNow = 0
api = "https://service.narvii.com/api/v1"

@app.route('/')
def index():
    return '''  <title>403 Forbidden</title>

403 Forbidden

			'''

@app.route('/<path:path>', methods=["GET", "POST", "DELETE"])
def catch_all(path):
    global proxyNow
    if request.method == 'POST':
        result = requests.post(f"{api}/{path}", headers=request.headers, data=request.data, proxies=proxyList[proxyNow])
        if proxyNow < len(proxyList): proxyNow+=1
        else: proxyNow = 0
    elif request.method == 'GET':
        result = requests.get(f"{api}/{path}", headers=request.headers, proxies=proxyList[proxyNow])
        if proxyNow < len(proxyList): proxyNow+=1
        else: proxyNow = 0
    elif request.method == 'DELETE':
        result = requests.delete(f"{api}/{path}", headers=request.headers, proxies=proxyList[proxyNow])
        if proxyNow < len(proxyList): proxyNow+=1
        else: proxyNow = 0
    return Response(result.text, result.status_code, mimetype='application/json')

if __name__ == '__main__':
    with open("proxies.txt", "r") as file:
        for line in file:
            proxyList.append({"https": line.strip()})
    print(f" * Loaded {len(proxyList)} proxies!")
    app.run(host='0.0.0.0', port=55535, debug=True)


# -*- coding: utf-8 -*-
import os
from setuptools import setup, find_packages, Extension

install_reqs = [
    'hexrd',
    'fabio>=0.11',
    'matplotlib',
    'Pillow',
    'pyside6',
    'pyyaml',
    'silx',
]

setup(
    name='hexrdgui',
    use_scm_version=True,
    setup_requires=['setuptools-scm'],
    description='',
    long_description='',
    author='Kitware, Inc.',
    author_email='kitware@kitware.com',
    url='https://github.com/hexrd/hexrdgui',
    license='BSD',
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Environment :: Web Environment',
        'License :: OSI Approved :: BSD License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.10',
        'Programming Language :: Python :: 3.11',
    ],
    packages=find_packages(),
    package_data={'hexrdgui': ['resources/**/*']},
    python_requires='>=3.10',
    install_requires=install_reqs,
    entry_points={
        'gui_scripts': [
            'hexrdgui = hexrdgui.main:main'
        ]
    }
)


from lib.binance import getCandles
from lib.order import buyWithQt, sellWithQt, borrowAndBuy, borrowAndSell
from lib.manager import get_asset
import time

class CryptoGenerator:
    def __init__(self, symbol, action_func, side="SHORT", leverage=5, slr=0.01, tpr=0.01, init_quote=10):
        if side == "LONG":
            self.side = side
        else:
            self.side = "SHORT"
        self.candles_1m = getCandles(symbol, "15m")
        self.symbol = symbol
        self.position_on = False
        self.stop_loss = 0
        self.take_profit = 0
        self.leverage = leverage
        self.initial_quote = init_quote  * self.leverage
        self.action_func = action_func
        self.posQt = 0
        self.slr = slr
        self.tpr = tpr

    def updateCandles(self):
        if (time.time() * 1000) >= int(self.candles_1m[-1][0] + (60000*15)):
            candles_1m = getCandles(self.symbol, "15m", int(self.candles_1m[-1][0] + (60000*15)))
            if len(candles_1m) > 0:
                if len(candles_1m) == 500:
                    self.candles_1m = candles_1m
                else:
                    self.candles_1m = self.candles_1m[len(candles_1m):] + candles_1m
            return True
        else:
            return False

    def longPosition(self):
        response = borrowAndBuy(self.symbol, self.leverage)
        print(response)
        if "executedQty" in response:
            self.posQt = response["executedQty"]
            self.stop_loss = self.candles_1m[-1][4] - (self.candles_1m[-1][4] * self.slr)
            self.take_profit = self.candles_1m[-1][4] + (self.candles_1m[-1][4] * self.tpr)
            self.position_on = self.candles_1m[-1][4]
        return response

    def shortPosition(self):
        response = borrowAndSell(self.symbol, self.leverage)
        print(response)
        if "executedQty" in response:
            self.posQt = response["executedQty"]
            self.stop_loss = self.candles_1m[-1][4] + (self.candles_1m[-1][4] * self.slr)
            self.take_profit = self.candles_1m[-1][4] - (self.candles_1m[-1][4] * self.tpr)
            self.position_on = self.candles_1m[-1][4]
        return response

    def stopLoss(self):
        if self.side == "LONG":
            response = sellWithQt(self.symbol, self.posQt)
            if "orderId" in response:
                self.position_on = False
            return response
        else:
            response = buyWithQt(self.symbol, (float(self.posQt) * self.candles_1m[-1][4]))
            if "orderId" in response:
                self.position_on = False
            return response

    def takeProfit(self):
        if self.side == "LONG":
            if (float(self.posQt) * self.candles_1m[-1][4]) > self.initial_quote:
                response = sellWithQt(self.symbol, (self.initial_quote / self.candles_1m[-1][4]))
                if "orderId" in response:
                    self.position_on = False
                return response
            else:
                response = sellWithQt(self.symbol, self.posQt)
                if "orderId" in response:
                    self.position_on = False
                return response
        else:
            if (float(self.posQt) * self.candles_1m[-1][4]) > self.initial_quote:
                response = buyWithQt(self.symbol, (float(self.posQt) * self.position_on))
                if "orderId" in response:
                    self.position_on = False
                return response
            else:
                response = buyWithQt(self.symbol, (float(self.posQt) * self.candles_1m[-1][4]))
                if "orderId" in response:
                    self.position_on = False
                return response
    def run(self):
        print("Running the bot")
        while True:
            if self.updateCandles():
                if self.action_func(self.candles_1m) and not self.position_on:
                    if self.side == "LONG":
                        self.longPosition()
                    else:
                        self.shortPosition()
                elif self.position_on and self.side == "LONG":
                    if self.candles_1m[-1][4] >= self.take_profit:
                        self.takeProfit()
                    elif self.candles_1m[-1][4] <= self.stop_loss:
                        self.stopLoss()
                elif self.position_on and self.side == "SHORT":
                    if self.candles_1m[-1][4] <= self.take_profit:
                        self.takeProfit()
                    elif self.candles_1m[-1][4] >= self.stop_loss:
                        self.stopLoss()
            time.sleep(5)

##### SELL RESPONSE #####
#{
#    'symbol': 'BNBUSDT',
#    'orderId': 4302657985,
#    'clientOrderId': 'default_425adfe35c784685ab0f3605ad6a',
#    'transactTime': 1661965359352,
#    'price': '0',
#    'origQty': '0.044',
#    'executedQty': '0.044',
#    'cummulativeQuoteQty': '12.3728',
#    'status': 'FILLED',
#    'timeInForce': 'GTC',
#    'type': 'MARKET',
#    'side': 'SELL',
#    'fills': [{'price': '281.2', 'qty': '0.044', 'commission': '0.0123728', 'commissionAsset': 'USDT'}],
#    'isIsolated': True
#}

##### BUY RESPONSE #####
#{
#    'symbol': 'BNBUSDT',
#    'orderId': 4302660806,
#    'clientOrderId': 'default_900a8fc98c8e4da8901e7e5bd60a',
#    'transactTime': 1661965480980,
#    'price': '0',
#    'origQty': '0.044',
#    'executedQty': '0.044',
#    'cummulativeQuoteQty': '12.364',
#    'status': 'FILLED',
#    'timeInForce': 'GTC',
#    'type': 'MARKET',
#    'side': 'BUY',
#    'fills': [{'price': '281', 'qty': '0.044', 'commission': '0.000033', 'commissionAsset': 'BNB'}],
#    'isIsolated': True
#}


import PyPDF2
import sys
import os

# run this program from the command line with one argument after the .py file: the name of the combined pdf to be
# created. The program loops through each item in the the present working directory and merges all pdf files into one

new_pdf_name = sys.argv[1]
source_dir = os.getcwd()

# create merger object
merger = PyPDF2.PdfFileMerger()

# loop through all files in directory
for file in os.listdir(source_dir):
    if file.endswith('pdf'):
        merger.append(file)
merger.write(new_pdf_name)


#!/opt/storpool/python3/bin/python3

"""
Changes the default boot kernel for the system.
"""

from datetime import datetime
import os
import pathlib
import re
import shutil
import subprocess
import sys
import tempfile

SAFEENC = "Latin-1"

GRUB_DEFAULT_PATH = pathlib.Path("/etc/default/grub")
_BACKUP_TIMESTAMP = datetime.strftime(datetime.now(), "%Y-%m-%d_%H-%M-%S")
GRUB_DEFAULT_BACKUP = f"{GRUB_DEFAULT_PATH}.{_BACKUP_TIMESTAMP}"

GRUB_EFI_BASE = pathlib.Path("/boot/efi/EFI/")
GRUB_CFG_PATHS = [
    pathlib.Path("/boot/grub/grub.cfg"),
    pathlib.Path("/boot/grub2/grub.cfg"),
] + list(GRUB_EFI_BASE.glob("*/grub.cfg"))
BOOT_LOADER_ENTRIES = pathlib.Path("/boot/loader/entries")

GRUB_MKCONFIG_CMDS = ["grub-mkconfig", "grub2-mkconfig"]

GRUB_LINE_FILTER = re.compile(r"^submenu|^menuentry|^\s+menuentry")

def get_grub_menu_title(menu: str) -> str:
    """Get a (sub)menu title out of a grub.conf menu entry."""
    menu_split = menu.split("'")
    if len(menu_split) < 2:
        return ""
    return menu_split[1]

def get_grubcfg_title(cfg_path: pathlib.Path, kernel: str) -> str:
    """
    Parses a grub.cfg and returns the menu and submenu name
    of the desired kernel version in the GRUB menu.
    """
    menu = ""
    submenu = ""

    if not cfg_path.exists():
        return ""

    with open(cfg_path, "r", encoding=SAFEENC) as cfg_file:
        for line in cfg_file.readlines():
            if not GRUB_LINE_FILTER.match(line):
                continue
            line_lower = line.lower()
            if "(recovery mode)" in line_lower or "rescue" in line_lower:
                continue
            line = line.rstrip()

            if line.startswith("menuentry"):
                if kernel in line:
                    menu = get_grub_menu_title(line)
                    break
            elif line.startswith("submenu"):
                menu = get_grub_menu_title(line)
                submenu = ""
                continue
            else:
                if kernel in line:
                    submenu = get_grub_menu_title(line)
                    break

    if not menu:
        return ""
    if not submenu:
        return menu if kernel in menu else ""
    return menu + ">" + submenu

def get_boot_loader_title(kernel: str) -> str:
    """
    Parses /boot/loader/entries files to get the
    bootloader title for the desired kernel.
    """
    title = ""

    if not BOOT_LOADER_ENTRIES.exists():
        return title

    for entry in BOOT_LOADER_ENTRIES.glob(f"*{kernel}*.conf"):
        with open(entry, "r", encoding=SAFEENC) as entry_file:
            for line in entry_file.readlines():
                if not line.startswith("title "):
                    continue
                line = line.rstrip()
                title = line.lstrip("title ")
                break

    return title

def _copy_meta(src: pathlib.Path, dst: pathlib.Path):
    """
    Ensure the destination file has the same owner,
    group, and permissions as the source.
    """
    try:
        src_meta = os.stat(src)
    except OSError:
        return

    try:
        dst_meta = os.stat(dst)
    except OSError as err:
        sys.exit(f"Could not read metadata for {dst}: {err}")

    if dst_meta.st_mode != src_meta.st_mode:
        os.chmod(dst, src_meta.st_mode)

    new_gid, new_uid = -1, -1
    if dst_meta.st_gid != src_meta.st_gid:
        new_gid = src_meta.st_gid
    if dst_meta.st_uid != src_meta.st_uid:
        new_uid = src_meta.st_uid
    if new_gid > -1 or new_uid > -1:
        os.chown(dst, new_uid, new_gid)

def _safe_write(path: pathlib.Path, content: str):
    with tempfile.NamedTemporaryFile(
        mode="w",
        prefix=os.path.basename(path) + ".",
        dir=os.path.dirname(path),
        encoding=SAFEENC,
        delete=False,
    ) as tmpf:
        moved = False
        try:
            tmpf.write(content)
            _copy_meta(path, pathlib.Path(tmpf.name))
            os.rename(tmpf.name, path)
            moved = True
        finally:
            if not moved:
                os.unlink(tmpf.name)
        return moved

def replace_grub_default(title: str) -> bool:
    """
    Replace the GRUB default boot kernel in /etc/default/grub.
    """
    shutil.copy(GRUB_DEFAULT_PATH, GRUB_DEFAULT_BACKUP)
    grub_cfg = ""
    with open(GRUB_DEFAULT_PATH, "r", encoding=SAFEENC) as grub_file:
        for line in grub_file.readlines():
            if line.startswith("GRUB_DEFAULT="):
                line = f'GRUB_DEFAULT="{title}"\n'
            grub_cfg += line

    if not _safe_write(GRUB_DEFAULT_PATH, grub_cfg):
        return False

    grub_mkcfg = next(cmd for cmd in GRUB_MKCONFIG_CMDS if shutil.which(cmd))
    if not grub_mkcfg:
        print(f"Could not find any of the following GRUB tools: {GRUB_MKCONFIG_CMDS}")
        return False
    grub_cfg_path = next(path for path in GRUB_CFG_PATHS if path.exists())
    if not grub_cfg_path:
        print(f"Could not find any of the following GRUB config files: {GRUB_CFG_PATHS}")
        return False

    return subprocess.call([grub_mkcfg, "-o", grub_cfg_path], timeout=120) == 0

def get_kernel_title(kernel: str) -> str:
    """Look for the title of the desired kernel in various locations."""
    kernel_title = ""

    for cfg_path in GRUB_CFG_PATHS:
        kernel_title = get_grubcfg_title(cfg_path, kernel)
        if kernel_title:
            return kernel_title
    kernel_title = get_boot_loader_title(kernel)

    return kernel_title

def main() -> None:
    """
    Find the GRUB title for the desired kernel and
    replace it in the GRUB default configuration.
    """
    if len(sys.argv) != 2:
        sys.exit(
            f"Usage: {sys.argv[0]} <new_kernel_version>\n"
            "Sets the default kernel version to boot from"
        )
    new_kernel = sys.argv[1]
    print(new_kernel)

    kernel_title = get_kernel_title(new_kernel)
    if not kernel_title:
        sys.exit(f"Could not find GRUB kernel title for {new_kernel}, exiting")
    print(f"Found title '{kernel_title}' for kernel '{new_kernel}'")
    if os.getenv("SP_SET_KERNEL_DUMMY"):
        sys.exit(0)

    if not replace_grub_default(kernel_title):
        sys.exit(
            "Could not set new kernel as default, backup of "
            f"'{GRUB_DEFAULT_PATH}' is available at '{GRUB_DEFAULT_BACKUP}'"
        )
    print("GRUB default boot option replaced successfully")

if __name__ == "__main__":
    main()


import numpy as np

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torch.autograd as autograd

from multiprocessing_env import SubprocVecEnv
from minipacman import MiniPacman

import matplotlib.pyplot as plt

from tqdm import tqdm

#USE_CUDA = torch.cuda.is_available()
#Variable = lambda *args, **kwargs: autograd.Variable(*args, **kwargs).cuda() if USE_CUDA else autograd.Variable(*args, **kwargs)

class OnPolicy(nn.Module):
    def __init__(self):
        super(OnPolicy, self).__init__()

    def forward(self, x):
        raise NotImplementedError

    def act(self, x, deterministic=False):
        logit, value = self.forward(x)
        probs = F.softmax(logit)

        if deterministic:
            action = probs.max(1)[1]
        else:
            action = probs.multinomial(1)

        return action

    def evaluate_actions(self, x, action):
        logit, value = self.forward(x)

        probs     = F.softmax(logit)
        log_probs = F.log_softmax(logit)

        action_log_probs = log_probs.gather(1, action)
        entropy = -(probs * log_probs).sum(1).mean()

        return logit, action_log_probs, value, entropy

class ActorCritic(OnPolicy):
    def __init__(self, in_shape, num_actions):
        super(ActorCritic, self).__init__()

        self.in_shape = in_shape

        self.features = nn.Sequential(
            nn.Conv2d(in_shape[0], 16, kernel_size=3, stride=1),
            nn.ReLU(),
            nn.Conv2d(16, 16, kernel_size=3, stride=2),
            nn.ReLU(),
        )

        self.fc = nn.Sequential(
            nn.Linear(self.feature_size(), 256),
            nn.ReLU(),
        )

        self.critic  = nn.Linear(256, 1)
        self.actor   = nn.Linear(256, num_actions)

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        logit = self.actor(x)
        value = self.critic(x)
        return logit, value

    def feature_size(self):
        return self.features(autograd.Variable(torch.zeros(1, *self.in_shape))).view(1, -1).size(1)

# @ikostrikov style

class RolloutStorage(object):
    def __init__(self, num_steps, num_envs, state_shape):
        self.num_steps = num_steps
        self.num_envs  = num_envs
        self.states  = torch.zeros(num_steps + 1, num_envs, *state_shape)
        self.rewards = torch.zeros(num_steps,     num_envs, 1)
        self.masks   = torch.ones(num_steps  + 1, num_envs, 1)
        self.actions = torch.zeros(num_steps,     num_envs, 1).long()
        #self.use_cuda = False

    def cuda(self):
        #self.use_cuda  = True
        self.states    = self.states.cuda()
        self.rewards   = self.rewards.cuda()
        self.masks     = self.masks.cuda()
        self.actions   = self.actions.cuda()

    def insert(self, step, state, action, reward, mask):
        self.states[step + 1].copy_(state)
        self.actions[step].copy_(action)
        self.rewards[step].copy_(reward)
        self.masks[step + 1].copy_(mask)

    def after_update(self):
        self.states[0].copy_(self.states[-1])
        self.masks[0].copy_(self.masks[-1])

    def compute_returns(self, next_value, gamma):
        returns   = torch.zeros(self.num_steps + 1, self.num_envs, 1)
        #if self.use_cuda:
        #    returns = returns.cuda()
        returns[-1] = next_value
        for step in reversed(range(self.num_steps)):
            returns[step] = returns[step + 1] * gamma * self.masks[step + 1] + self.rewards[step]
        return returns[:-1]

def main():
    mode = "regular"
    num_envs = 16

    def make_env():
        def _thunk():
            env = MiniPacman(mode, 1000)
            return env

        return _thunk

    envs = [make_env() for i in range(num_envs)]
    envs = SubprocVecEnv(envs)

    state_shape = envs.observation_space.shape

    #a2c hyperparams:
    gamma = 0.99
    entropy_coef = 0.01
    value_loss_coef = 0.5
    max_grad_norm = 0.5
    num_steps = 5
    num_frames = int(10e3)

    #rmsprop hyperparams:
    lr    = 7e-4
    eps   = 1e-5
    alpha = 0.99

    #Init a2c and rmsprop
    actor_critic = ActorCritic(envs.observation_space.shape, envs.action_space.n)
    optimizer = optim.RMSprop(actor_critic.parameters(), lr, eps=eps, alpha=alpha)

    #if USE_CUDA:
    #    actor_critic = actor_critic.cuda()

    rollout = RolloutStorage(num_steps, num_envs, envs.observation_space.shape)
    #rollout.cuda()

    all_rewards = []
    all_losses  = []

    state = envs.reset()
    state = torch.FloatTensor(np.float32(state))

    rollout.states[0].copy_(state)

    episode_rewards = torch.zeros(num_envs, 1)
    final_rewards   = torch.zeros(num_envs, 1)

    for i_update in tqdm(range(num_frames)):

        for step in range(num_steps):
            action = actor_critic.act(autograd.Variable(state))

            next_state, reward, done, _ = envs.step(action.squeeze(1).cpu().data.numpy())

            reward = torch.FloatTensor(reward).unsqueeze(1)
            episode_rewards += reward
            masks = torch.FloatTensor(1-np.array(done)).unsqueeze(1)
            final_rewards *= masks
            final_rewards += (1-masks) * episode_rewards
            episode_rewards *= masks

            #if USE_CUDA:
            #    masks = masks.cuda()

            state = torch.FloatTensor(np.float32(next_state))
            rollout.insert(step, state, action.data, reward, masks)

        _, next_value = actor_critic(autograd.Variable(rollout.states[-1], volatile=True))
        next_value = next_value.data

        returns = rollout.compute_returns(next_value, gamma)

        logit, action_log_probs, values, entropy = actor_critic.evaluate_actions(
            autograd.Variable(rollout.states[:-1]).view(-1, *state_shape),
            autograd.Variable(rollout.actions).view(-1, 1)
        )

        values = values.view(num_steps, num_envs, 1)
        action_log_probs = action_log_probs.view(num_steps, num_envs, 1)
        advantages = autograd.Variable(returns) - values

        value_loss = advantages.pow(2).mean()
        action_loss = -(autograd.Variable(advantages.data) * action_log_probs).mean()

        optimizer.zero_grad()
        loss = value_loss * value_loss_coef + action_loss - entropy * entropy_coef
        loss.backward()
        nn.utils.clip_grad_norm(actor_critic.parameters(), max_grad_norm)
        optimizer.step()

        if i_update % num_frames == 0:
            all_rewards.append(final_rewards.mean())
            all_losses.append(loss.item())

            #clear_output(True)
            plt.figure(figsize=(20,5))
            plt.subplot(131)
            plt.title('epoch %s. reward: %s' % (i_update, np.mean(all_rewards[-10:])))
            plt.plot(all_rewards)
            plt.subplot(132)
            plt.title('loss %s' % all_losses[-1])
            plt.plot(all_losses)
            plt.show()

        rollout.after_update()

    torch.save(actor_critic.state_dict(), "actor_critic_" + mode)

    import time

    def displayImage(image, step, reward):
        #clear_output(True)
        s = "step: " + str(step) + " reward: " + str(reward)
        plt.figure(figsize=(10,3))
        plt.title(s)
        plt.imshow(image)
        plt.show()
        time.sleep(0.1)

    env = MiniPacman(mode, 1000)

    done = False
    state = env.reset()
    total_reward = 0
    step   = 1

    while not done:
        current_state = torch.FloatTensor(state).unsqueeze(0)
        #if USE_CUDA:
        #    current_state = current_state.cuda()

        action = actor_critic.act(autograd.Variable(current_state))

        next_state, reward, done, _ = env.step(action.data[0, 0])
        total_reward += reward
        state = next_state

        image = torch.FloatTensor(state).permute(1, 2, 0).cpu().numpy()
        displayImage(image, step, total_reward)
        step += 1

if __name__ == '__main__':
    main()


import datetime, time, logging

LOGGER = logging.getLogger( __name__ )

class StopWatch:
    """ StopWatch class used to monitor the time used to execute a part of code."""
    __watchName = None
    __startTime = None
    __stopTime = None
    __showStartAndStop = False

    def __init__( self, name, showStartStop = False ):
        self.__watchName = name
        self.__showStartAndStop = showStartStop

    def start( self ):
        """ Start the StopWatch to monitor the execution time."""
        self.__startTime = time.time()
        if self.__showStartAndStop:
            LOGGER.debug( "StopWatch [%s] has started at %s" % ( self.__watchName, datetime.datetime.fromtimestamp( self.__startTime ).strftime( "%d.%m.%y at %H:%M:%S" ) ) )

    def stop( self ):
        """ Stop the StopWatch."""
        self.__stopTime = time.time()
        if self.__showStartAndStop:
            LOGGER.debug( "StopWatch [%s] has stopped at %s" % ( self.__watchName, datetime.datetime.fromtimestamp( self.__stopTime ).strftime( "%d.%m.%y at %H:%M:%S" ) ) )

    def printStatus( self ):
        """ Print the status of the StopWatch after execution."""
        if self.__startTime == None:
            LOGGER.error( "StopWatch %s not started" % self.__watchName )
            return

        if self.__stopTime == None:
            self.stop()

        delta = self.__stopTime - self.__startTime
        LOGGER.debug( "StopWatch [%s] has ran during %s s" % ( self.__watchName, str( delta ) ) )


# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import absolute_import

import argparse
import sys
import os

import matplotlib.pyplot as plt
import pylab
import matplotlib.image as mpimg
import numpy as np
import shutil
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

reload(sys)
sys.setdefaultencoding("utf-8")

CN_CHARSET = None
CN_T_CHARSET = None
JP_CHARSET = None
KR_CHARSET = None

input_args = ['--dst_font_dir','/DataA/Harric/ChineseCharacterExp/CASIA_Dataset/Sources/64_FoundContentPrototypeTtfOtfs/Simplified/',
              '--single_img_dir', '/DataA/Harric/ChineseCharacterExp/CASIA_Dataset/PrintedData_64Fonts/'
              ]

parser = argparse.ArgumentParser(description='Convert font to images')

parser.add_argument('--dst_font_dir', dest='dst_font_dir', required=True, help='path of the target font dir')
parser.add_argument('--char_size', dest='char_size', type=int, default=150, help='character size')
parser.add_argument('--canvas_size', dest='canvas_size', type=int, default=256, help='canvas size')
parser.add_argument('--x_offset', dest='x_offset', type=int, default=20, help='x offset')
parser.add_argument('--y_offset', dest='y_offset', type=int, default=20, help='y_offset')
parser.add_argument('--single_img_dir', dest='single_img_dir', required=True,help='directory to save paired imgs')

args = parser.parse_args(input_args)

def draw_example(ch, dst_font, canvas_size, x_offset, y_offset):
    def draw_single_char(ch, font, canvas_size, x_offset, y_offset):
        img = Image.new("RGB", (canvas_size, canvas_size), (255, 255, 255))
        draw = ImageDraw.Draw(img)

        try:
            draw.text((x_offset, y_offset), ch, (0, 0, 0), font=font)
        except IOError:
            img_output = np.zeros(shape=[256, 256, 3])
            img_output = Image.fromarray(np.uint8(img_output))
            return img_output

        img_matrix = np.asarray(img)[:, :, 0]
        zero_indices = np.where(img_matrix == 0)
        exceed = 'NONE'

        if np.min(img_matrix) == np.max(img_matrix) or (0 not in img_matrix):
            img_output = np.zeros(shape=[256,256,3])
            img_output = Image.fromarray(np.uint8(img_output))
        else:
            up_p = np.min(zero_indices[0])
            down_p = np.max(zero_indices[0])
            left_p = np.min(zero_indices[1])
            right_p = np.max(zero_indices[1])

            up_down = down_p - up_p
            right_left = right_p - left_p
            if up_down > right_left:
                character_size = up_down
                if not character_size % 2 == 0:
                    character_size = character_size + 1
                    down_p = down_p + 1
                right_left_avg = (right_p + left_p) / 2
                right_p = right_left_avg + int(character_size / 2)
                left_p = right_left_avg - int(character_size / 2)
                if left_p < 0:
                    exceed = 'LEFT'
                    exceed_pixels = np.abs(left_p)
                    left_p = 0
                if right_p > 255:
                    exceed = 'RIGHT'
                    exceed_pixels = right_p - 255
                    right_p = 255

            else:
                character_size = right_left
                if not character_size % 2 == 0:
                    character_size = character_size + 1
                    right_p = right_p + 1

                up_down_avg = (up_p + down_p) / 2
                down_p = up_down_avg + int(character_size / 2)
                up_p = up_down_avg - int(character_size / 2)
                if up_p < 0:
                    exceed = 'UP'
                    exceed_pixels = np.abs(up_p)
                    up_p = 0
                if down_p > 255:
                    exceed = 'DOWN'
                    exceed_pixels = down_p - 255
                    down_p = 255

            img_matrix_cut = img_matrix[up_p:down_p, left_p:right_p]

            if not exceed=='NONE':
                if exceed=='LEFT':
                    added_pixels = np.ones([img_matrix_cut.shape[0],exceed_pixels]) * 255
                    img_matrix_cut = np.concatenate([added_pixels, img_matrix_cut], axis=1)
                elif exceed=='RIGHT':
                    added_pixels = np.ones([img_matrix_cut.shape[0], exceed_pixels]) * 255
                    img_matrix_cut = np.concatenate([img_matrix_cut,added_pixels], axis=1)
                elif exceed=='UP':
                    added_pixels = np.ones([exceed_pixels, img_matrix_cut.shape[1]]) * 255
                    img_matrix_cut = np.concatenate([added_pixels, img_matrix_cut], axis=0)
                elif exceed=='DOWN':
                    added_pixels = np.ones([exceed_pixels, img_matrix_cut.shape[1]]) * 255
                    img_matrix_cut = np.concatenate([img_matrix_cut, added_pixels], axis=0)

            img_matrix_cut = np.tile(np.reshape(img_matrix_cut,
                                                [img_matrix_cut.shape[0], img_matrix_cut.shape[1], 1]),
                                     [1, 1, 3])
            img_cut = Image.fromarray(np.uint8(img_matrix_cut))
            img_resize = img_cut.resize((150, 150), Image.ANTIALIAS)
            img_output = Image.new("RGB", (256, 256), (255, 255, 255))
            img_output.paste(img_resize, (52, 52))

        return img_output

    dst_img = draw_single_char(ch, dst_font, canvas_size, x_offset, y_offset)

    invalid_img = (np.max(dst_img) == np.min(dst_img))

    return dst_img,invalid_img

def font2img(charset,
             character_label_list,
             dst,
             char_size,
             canvas_size,
             x_offset,
             y_offset,
             single_save_dir,
             font_label='0'):
    dst_font = ImageFont.truetype(dst, size=char_size)

    if not os.path.exists(single_save_dir):
        os.makedirs(single_save_dir)

    count = 0
    valid_counter = 0
    invalid_counter = 0

    for c in charset:

        if count == len(charset):
            break

        single_256, invalid_img = draw_example(c, dst_font, canvas_size, x_offset, y_offset)
        if single_256 and (not invalid_img):
            single_64 = single_256.resize((64, 64), Image.ANTIALIAS)
            single_64.save(os.path.join(single_save_dir, "%09d_%s_%s.png" % (count, character_label_list[count], font_label)))
            valid_counter+=1
        else:
            invalid_counter+=1

        count += 1
    return valid_counter, invalid_counter

def get_chars_set_from_level1_2(path,level):
    """
    Expect a text file that each line is a char
    """
    chars = list()
    character_id_1_counter=0
    character_id_2_counter=0
    character_list=list()
    with open(path) as f:
        for line in f:

            line = u"%s" % line
            char_counter=0
            for char in line:

                current_char = line[char_counter]
                chars.append(current_char)

                if level==1:
                    character_id_1 = str(character_id_1_counter + 16 + 160)
                    character_id_2 = str(character_id_2_counter + 1 + 160)
                    character_id = character_id_1 + character_id_2

                    character_id_2_counter += 1
                    if character_id_2_counter == 94:
                        character_id_2_counter = 0
                        character_id_1_counter += 1
                elif level==2:
                    character_id_1 = str(character_id_1_counter + 56 + 160)
                    character_id_2 = str(character_id_2_counter + 1 + 160)
                    character_id = character_id_1 + character_id_2

                    character_id_2_counter += 1
                    if character_id_2_counter == 94:
                        character_id_2_counter = 0
                        character_id_1_counter += 1

                character_list.append(character_id)
                char_counter+=1
    return chars,character_list

def find_file_list( path,train_mark):
    file_list=list()
    counter=0

    dir_list=os.listdir(path)
    dir_list.sort()

    for dir in dir_list:
        current_full_path=os.path.join(path,dir)
        files = [f for f in os.listdir(current_full_path) if os.path.isfile(os.path.join(current_full_path, f))]
        files.sort()
        for fn in files:
            if fn.find('.jpg') != -1:
                file_list.append(os.path.join(current_full_path,fn))
                counter = counter + 1

    return file_list

if __name__ == "__main__":

    dir_serach_list=args.dst_font_dir.split(",")

    dst_file_list=[]
    for current_dir in dir_serach_list:
        for root, dirs, files in os.walk(current_dir):
            for name in files:

                file_path = (os.path.join(root, name))
                file_extension = os.path.splitext(file_path)[1]

                if file_extension == '.TTF' or file_extension == '.OTF' or file_extension == '.ttf' or file_extension == '.otf':
                    dst_file_list.append(os.path.join(root, name))

    dst_file_list.sort()

    charset_level1_smp, character_label_level1_smp = get_chars_set_from_level1_2(path='../charset/GB2312_Level1_Simplified.txt',level=1)
    charset_level2_smp, character_label_level2_smp = get_chars_set_from_level1_2(path='../charset/GB2312_Level2_Simplified.txt',level=2)
    charset_level1_trd, character_label_level1_trd = get_chars_set_from_level1_2(path='../charset/GB2312_Level1_Traditional.txt', level=1)
    charset_level2_trd, character_label_level2_trd = get_chars_set_from_level1_2(path='../charset/GB2312_Level2_Traditional.txt', level=2)

    if os.path.exists(args.single_img_dir):
        shutil.rmtree(args.single_img_dir)
    os.makedirs(args.single_img_dir)

    font_counter=0
    print("###########################################################################")
    for dst_file in dst_file_list:

        file_name=dst_file.split('/')
        file_name=file_name[len(file_name)-1]
        font_label=file_name.split('_')
        font_label=str(font_label[0])

        current_dir_smp = os.path.join(args.single_img_dir,'Simplified')
        current_dir_trd = os.path.join(args.single_img_dir, 'Traditional')

        current_save_dir_l1_smp = os.path.join(current_dir_smp,'GB2312_L1')
        current_save_dir_l2_smp = os.path.join(current_dir_smp, 'GB2312_L2')
        current_save_dir_l1_smp = os.path.join(current_save_dir_l1_smp, font_label)
        current_save_dir_l2_smp = os.path.join(current_save_dir_l2_smp, font_label)

        current_save_dir_l1_trd = os.path.join(current_dir_trd, 'GB2312_L1')
        current_save_dir_l2_trd = os.path.join(current_dir_trd, 'GB2312_L2')
        current_save_dir_l1_trd = os.path.join(current_save_dir_l1_trd, font_label)
        current_save_dir_l2_trd = os.path.join(current_save_dir_l2_trd, font_label)

        valid_l1_smp, invalid_l1_smp = \
            font2img(charset=charset_level1_smp,
                     character_label_list=character_label_level1_smp, dst=dst_file,
                     char_size=args.char_size,canvas_size=args.canvas_size,
                     x_offset=args.x_offset, y_offset=args.y_offset,
                     single_save_dir=current_save_dir_l1_smp,
                     font_label=font_label)
        valid_l2_smp, invalid_l2_smp = \
            font2img(charset=charset_level2_smp,
                     character_label_list=character_label_level2_smp,
                     dst=dst_file,
                     char_size=args.char_size,canvas_size=args.canvas_size,
                     x_offset=args.x_offset, y_offset=args.y_offset,
                     single_save_dir=current_save_dir_l2_smp,
                     font_label=font_label)

        valid_l1_trd, invalid_l1_trd = \
            font2img(charset=charset_level1_trd,
                     character_label_list=character_label_level1_trd, dst=dst_file,
                     char_size=args.char_size, canvas_size=args.canvas_size,
                     x_offset=args.x_offset, y_offset=args.y_offset,
                     single_save_dir=current_save_dir_l1_trd,
                     font_label=font_label)
        valid_l2_trd, invalid_l2_trd = \
            font2img(charset=charset_level2_trd,
                     character_label_list=character_label_level2_trd,
                     dst=dst_file,
                     char_size=args.char_size, canvas_size=args.canvas_size,
                     x_offset=args.x_offset, y_offset=args.y_offset,
                     single_save_dir=current_save_dir_l2_trd,
                     font_label=font_label)

        font_counter=font_counter+1

        dst_file_name = dst_file.split("/")[-1]
        print("%s, Processing Font-->Pict:%d/%d with FontLabel:%s"
              % (dst_file_name, font_counter, len(dst_file_list), font_label))

        print("ValidL1_Smp:%04d,InvalidL1_Smp:%04d; ValidL2_Smp:%04d,InvalidL2_Smp:%04d;"
              % (valid_l1_smp, invalid_l1_smp, valid_l2_smp, invalid_l2_smp))
        print("ValidL1_Trd:%04d,InvalidL1_Trd:%04d; ValidL2_Trd:%04d,InvalidL2_Trd:%04d;"
              % (valid_l1_trd, invalid_l1_trd, valid_l2_trd, invalid_l2_trd))
        print("###########################################################################")


import os
import shutil
import argparse
from tests import *

tmp_dir = 'scripts/tests/tmp'

def parse_args():
    parser = argparse.ArgumentParser(description='Script to test repository functionality')

    ogroup = parser.add_argument_group('Optional Arguments')

    ogroup.add_argument('--all',
                        help='Runs all tests',
                        required=False,
                        action='store_true')

    ogroup.add_argument('--save',
                        help='If FLAG is included script will keep generated data set',
                        required=False,
                        action='store_true')

    ogroup.add_argument('--data_dir',
                        help='Directory to save data set to',
                        required=False,
                        type=str,
                        default=tmp_dir)

    args = parser.parse_args()

    return args

def main(args):

    if args.all:

        if not args.save:
            dir = args.data_dir
        else:
            dir = os.environ['DCNN_DATASETS_PATH']
        if not os.path.exists(dir):
            os.mkdir(dir)

        test_data_set(dir)

        if not args.save:
            shutil.rmtree(dir)

if __name__ == '__main__':
    args = parse_args()
    main(args)


from PIL import Image, ImageDraw, ImageGrab, ImageFile
import pyautogui
import keyboard
import time
import random
import cv2

captcha_vert_r, captcha_vert_g, captcha_vert_b, captcha_vert_T = 16, 23, 41, 255 # en haut a gauche le premier pixel vert du captcha

liste_compte = []

def screen():
    capture = pyautogui.screenshot()
    capture.save(r"C:\Users\balin\OneDrive\Bureau\bot GouzouGouzou\capture.png")

def captcha_resolver():
    macro = True
    while macro == True:
        cours = True
        if keyboard.is_pressed("ctrl+!"):
            screen()
            while cours == True:
                vert_r, vert_g, vert_b = img.getpixel((827,421))
                if vert_r == captcha_vert_r and vert_g == captcha_vert_g and vert_b == captcha_vert_b:
                    for x in range(827,1086):
                        for y in range(421,504):
                            trouver_gris_r, trouver_gris_g, trouver_gris_b, trouver_gris_T = img.getpixel((x,y))
            coo = pyautogui.locateCenterOnScreen("bouton_vert.png")
            print(coo)
            pyautogui.click(coo)
        elif keyboard.is_pressed("²"):
            macro=False
        else:
            continue

def couleur(a,b):
    img = Image.open("capture.PNG")
    nr,nv,nb,nn = img.getpixel((a,b))
    print(nr,nv,nb,nn)

class running:
    def verif_bloquage():
        oui = 0
    def sus(nombre):
        print("program statut : running \nfollowing")
        macro = True
        bouclee = 0
        sortir = False
        coo_sabonner_temp = 0
        while macro == True:
            cours = True
            if keyboard.is_pressed("!"):
                boucle = 0
                while boucle < nombre:
                    coo_sabonner = pyautogui.locateCenterOnScreen("sabonner.png", confidence = 0.9)
                    bloquage = pyautogui.locateCenterOnScreen("bloquage.png")
                    if bloquage is not None:
                        print("bloquage")
                        ok = pyautogui.locateCenterOnScreen("OK.png")
                        pyautogui.click(ok)
                        time.sleep(2)
                        coo_croix = pyautogui.locateCenterOnScreen("croix.png")
                        pyautogui.click(coo_croix)
                        print("program statut : Stoped")
                        sortir = True
                        break
                    elif coo_sabonner is not None:
                        if coo_sabonner_temp == coo_sabonner:
                            pyautogui.click(coo_sabonner)
                            print("attendre : 2s")
                            time.sleep(2)
                        else:
                            time.sleep(1)
                            coo_sabonner_temp = coo_sabonner
                            pyautogui.click(coo_sabonner)
                            print("sabonner : ",boucle+1)
                            boucle += 1
                    elif boucle == nombre:
                        sortir = True
                        coo_croix = pyautogui.locateCenterOnScreen("croix.PNG")
                        if coo_croix is not None:
                            pyautogui.click(coo_croix)
                            print("croix")
                            break
                        else:
                            break
                    else:
                        print("descendre")
                        pyautogui.scroll(-200)
                        time.sleep(2)
            if sortir == True:
                break
            elif keyboard.is_pressed("p"):
                macro=False
            else:
                continue

    def desus(nombre):
        print("program statut : running \ndesus")
        macro = True
        bouclee = 0
        boucle = 0
        sortir = False
        coo_desabonner_temp = 0
        while macro == True:
            cours = True
            if keyboard.is_pressed("!"):
                while True:
                    bloquage = pyautogui.locateCenterOnScreen("bloquage.png", confidence = 0.9)
                    coo_desabonner = pyautogui.locateCenterOnScreen("desabonner.png", confidence = 0.9)
                    if bloquage is not None:
                        print("bloquage")
                        ok = pyautogui.locateCenterOnScreen("OK.png")
                        pyautogui.click(ok)
                        time.sleep(1)
                        coo_croix = pyautogui.locateCenterOnScreen("croix.png")
                        pyautogui.click(coo_croix)
                        print("program statut : Stoped")
                        sortir = True
                        break
                    elif coo_desabonner is not None:
                        if coo_desabonner_temp == coo_desabonner:
                            print("attendre : 15s")
                            time.sleep(15)
                        else:
                            while boucle < nombre:
                                print("desabonner : ",boucle+1)
                                boucle += 1
                                bouclee = boucle
                                coo_desabonner = pyautogui.locateCenterOnScreen("desabonner.png", confidence = 0.9)
                                if coo_desabonner is not None:
                                    pyautogui.click(coo_desabonner)
                                    coo_sedesabonner = pyautogui.locateCenterOnScreen("sedesabonner.png", confidence = 0.9)
                                    if coo_sedesabonner is not None:
                                        pyautogui.click(coo_sedesabonner)
                                        time.sleep(1)
                                    else:
                                        time.sleep(1)
                                else:
                                    pyautogui.scroll(-100)
                                    time.sleep(2)
                    elif bouclee == nombre:
                        sortir = True
                        print("croix")
                        coo_croix = pyautogui.locateCenterOnScreen("croix.png")
                        if coo_croix is not None:
                            pyautogui.click(coo_croix)
                            sortir = True
                            break
                    else:
                        continue
                if sortir == True:
                    break
            elif keyboard.is_pressed("p"):
                macro=False
            else:
                continue
running.sus(250)