import fnmatch
import glob
import os
import shutil
import zipfile

from no_drama.context import temp_directory
from no_drama.pip_automation import save_wheels

def inject_configuration(cli_args):
    with temp_directory() as staging_dir:
        build_zip_path = os.path.join(staging_dir, 'build.zip')

        shutil.copyfile(cli_args.build_zip, build_zip_path)

        build_zip = zipfile.ZipFile(build_zip_path, mode="a")

        # figuring out where things are in this zip file...
        all_the_wheels = fnmatch.filter(build_zip.namelist(), '*/wheels/*.whl')
        zip_wheel_dir = os.path.dirname(all_the_wheels[0])
        zip_root = os.path.normpath(os.path.join(zip_wheel_dir, '../'))

        # move just the wheels we want into the bundle dir
        wheel_destination = os.path.join(staging_dir, 'wheels')
        if cli_args.requirements_file:
            save_wheels(
                requirements_paths=[cli_args.requirements_file],
                destination=wheel_destination
            )
            wheel_pattern = os.path.join(staging_dir, 'wheels/*.whl')

            saved_wheels = glob.glob(wheel_pattern)

            for wheel_path in saved_wheels:
                name = os.path.join(
                    zip_wheel_dir, os.path.basename(wheel_path))
                build_zip.write(wheel_path, arcname=name)

        build_zip.write(
            cli_args.vars, os.path.join(
                zip_root, 'environment.json'))

        if cli_args.paths:
            build_zip.write(
                cli_args.paths, os.path.join(
                    zip_root, 'paths.d/1_custom.json'))

        if cli_args.prepend_wsgi:
            build_zip.write(cli_args.prepend_wsgi,
                            os.path.join(zip_root, 'pre-wsgi.py-fragment'))

        if cli_args.append_wsgi:
            build_zip.write(cli_args.append_wsgi,
                            os.path.join(zip_root, 'post-wsgi.py-fragment'))

        build_zip.close()
        build_filename = os.path.basename(cli_args.build_zip)
        name, ext = os.path.splitext(build_filename)
        release_filename = "%s_%s%s" % (name, cli_args.slug, ext)
        shutil.copyfile(build_zip_path, release_filename)


from pathlib import Path

# Paths
BASE_DIR = Path(__file__).parent.parent.parent.absolute()
DATA_DIR = Path(BASE_DIR, 'data')
FEATURES_DIR = Path(BASE_DIR, 'features')
STORES_DIR = Path(BASE_DIR, 'stores')
CODE_DIR = Path(BASE_DIR, 'src')

# Final Features
VARIABLES = [
    'rank_t1', 'rank_t2', 'home_win_ratio_t1',
    'home_win_ratio_t2', 'away_win_ratio_t1', 'away_win_ratio_t2',
    'home_draw_ratio_t1', 'home_draw_ratio_t2', 'away_draw_ratio_t1',
    'away_draw_ratio_t2', 'home_loss_ratio_t1', 'home_loss_ratio_t2',
    'away_loss_ratio_t1', 'away_loss_ratio_t2', 'general_goals_scored_t1',
    'general_goals_scored_t2', 'home_goals_scored_t1', 'home_goals_scored_t2',
    'away_goals_scored_t1', 'away_goals_scored_t2', 'general_goals_conceded_t1',
    'general_goals_conceded_t2', 'home_goals_conceded_t1',
    'home_goals_conceded_t2', 'away_goals_conceded_t1',
    'away_goals_conceded_t2', 'outcome']

DVC_FILES = [
    'prep_pipeline.pkl.dvc',
    'model.pkl.dvc',
    'test_data.parquet.dvc',
    'training_data.parquet.dvc',
]

SCRAPER_CONFIG_FILE = Path(CODE_DIR, 'scraper/scraper_config.yml')


from cProfile import label
from http import client
import numpy as np
from Server import *
from Client import *
from utils import *
import argparse

def main(args):
    np.random.seed(args.seed)
    client_num = 20
    mode = args.mode
    if mode == 'pg':
        epochs = 20000
        c = 0
        lr = 0.00001
        p = args.p
    elif mode == 'admm':
        epochs = 200
        c = 0.1
        lr = 1/c
        p = args.p
    elif mode == 'sg':
        epochs = 20000
        c = 0
        lr = 0.001
        p = args.p
    # 最优解
    x_opt = np.random.normal(loc=0, scale=1, size=[300])
    # 非零元素位置
    position = np.random.permutation(300)[:5]
    mask = np.zeros([300])
    mask[position] = 1
    # 得到稀疏度为5的向量
    x_opt = x_opt*mask

    # 初始解
    x = np.zeros(shape=[300])
    x_best = x
    lamb_list = np.zeros(shape=[client_num, 300])
    z = np.zeros(shape=[300])

    server = Server(lr, p, c)
    clients = [Client(x_opt, lr) for i in range(client_num)]

    ckpt = []
    print(
        f"Epoch: 0 Distance to opt: {np.linalg.norm(x_best-x_opt)}", flush=True)
    for epoch in range(1, epochs+1):
        if mode == 'pg':
            # 各个节点求梯度取平均
            grad_list = [clients[i].PG_train(x) for i in range(client_num)]
            # 邻近点投影
            x = server.PG_train(x, grad_list)
            ckpt.append(x)
            x_best = x
            if epoch % 1000 == 0:
                print(
                    f"Epoch: {epoch} Distance to opt: {np.linalg.norm(x_best-x_opt)}", flush=True)
        elif mode == 'admm':
            x_list = np.array(admmWork(clients, z, lamb_list, client_num))
            z, lamb_list = server.ADMM_train(x_list, lamb_list)
            ckpt.append(z)
            x_best = z
            if epoch % 10 == 0:
                print(
                    f"Epoch: {epoch} Distance to opt: {np.linalg.norm(x_best-x_opt)}", flush=True)
        elif mode == 'sg':
            # 递减步长
            cur_lr = lr/np.sqrt(epoch)
            # 各个节点求梯度取平均
            grad_list = [clients[i].PG_train(x) for i in range(client_num)]
            # 求解次梯度
            x = server.SG_train(x, grad_list, cur_lr)
            ckpt.append(x)
            x_best = x
            if epoch % 1000 == 0:
                print(
                    f"Epoch: {epoch} Distance to opt: {np.linalg.norm(x_best-x_opt)}", flush=True)

    plot_distance(ckpt, x_best, x_opt, mode, p)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--mode", type=str, default='pg',
                        help='pg for proximal gradient, admm for ADMM, sg for stochastic gradient')
    parser.add_argument("--seed", type=int, default=2333)
    parser.add_argument("--p", type=float, default=1)
    args = parser.parse_args()
    main(args)


class Solution:
    def applyOperations(self, nums: [int]) -> [int]:
        n = len(nums)
        j = 0

        for i in range(n - 1):
            if nums[i] == nums[i + 1]:
                nums[i] *= 2
                nums[i + 1] = 0

            if nums[i] != 0:
                nums[j], nums[i] = nums[i], nums[j]
                j += 1

        if nums[n - 1] != 0:
            nums[j], nums[n - 1] = nums[n - 1], nums[j]
            j += 1

        for i in range(j, n):
            nums[i] = 0

        return nums

if __name__ == "__main__":
    s = Solution()
    print(s.applyOperations([1,2,2,1,1,0])) # [1,4,2,0,0,0]
    print(s.applyOperations([0,1])) # [1,0]


# -*- coding: utf-8 -*-

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""
Tests for `mozilla-schema-generator` scripts.
"""

import json
import pathlib
import shutil
import subprocess

import pytest

class TestSchemaAliasing(object):

    base_dir = "./test-schemas"
    test_aliases_path = "test-aliases.json"
    source_namespace = "namespace"
    source_doctype = "doctype"

    @pytest.fixture(autouse=True)
    def setup_teardown_dir(self):
        dir_path = pathlib.Path(self.base_dir)
        path = dir_path / self.source_namespace / self.source_doctype
        json_file = path / f"{self.source_doctype}.1.schema.json"
        bq_file = path / f"{self.source_doctype}.1.bq"

        json_file.parent.mkdir(parents=True)
        json_file.touch()
        bq_file.touch()

        yield

        shutil.rmtree(dir_path)
        pathlib.Path(self.test_aliases_path).unlink()

    def write_aliases(self, aliases):
        path = pathlib.Path(self.test_aliases_path)
        with open(path, "w") as f:
            json.dump(aliases, f)

        return path

    def test_aliasing_same_namespace(self):
        test_doctype = "test-doctype"
        aliases_path = self.write_aliases(
            {
                self.source_namespace: {
                    test_doctype: {
                        "source-namespace": self.source_namespace,
                        "source-doctype": self.source_doctype,
                    }
                }
            }
        )

        res = subprocess.run(("./bin/alias_schemas", str(aliases_path), self.base_dir))

        assert res.returncode == 0

        test_path = pathlib.Path(self.base_dir) / self.source_namespace / test_doctype
        assert (test_path / f"{test_doctype}.1.bq").exists()

    def test_aliasing_new_namespace(self):
        test_namespace = "test-namespace"
        test_doctype = "test-doctype"
        aliases_path = self.write_aliases(
            {
                test_namespace: {
                    test_doctype: {
                        "source-namespace": self.source_namespace,
                        "source-doctype": self.source_doctype,
                    }
                }
            }
        )

        res = subprocess.run(("./bin/alias_schemas", str(aliases_path), self.base_dir))

        assert res.returncode == 0

        test_path = pathlib.Path(self.base_dir) / test_namespace / test_doctype
        assert (test_path / f"{test_doctype}.1.bq").exists()

    def test_no_aliasing(self):
        aliases_path = self.write_aliases({})
        res = subprocess.run(("./bin/alias_schemas", str(aliases_path), self.base_dir))

        assert res.returncode == 0

        # should only have bq and json schema for source
        test_path = pathlib.Path(self.base_dir)
        assert len(list(test_path.iterdir())) == 1
        assert len(list((test_path / self.source_namespace).iterdir())) == 1
        assert (
            len(
                list(
                    (test_path / self.source_namespace / self.source_doctype).iterdir()
                )
            )
            == 2
        )

    def test_missing_source_errors(self):
        test_namespace = "test-namespace"
        test_doctype = "test-doctype"
        aliases_path = self.write_aliases(
            {
                test_namespace: {
                    test_doctype: {
                        "source-namespace": "missing-namespace",
                        "source-doctype": self.source_doctype,
                    }
                }
            }
        )

        res = subprocess.run(("./bin/alias_schemas", str(aliases_path), self.base_dir))

        assert res.returncode != 0

    def test_improper_name_errors(self):
        test_namespace = "@test-namespace"
        test_doctype = "test-doctype"
        aliases_path = self.write_aliases(
            {
                test_namespace: {
                    test_doctype: {
                        "source-namespace": "missing-namespace",
                        "source-doctype": self.source_doctype,
                    }
                }
            }
        )

        res = subprocess.run(("./bin/alias_schemas", str(aliases_path), self.base_dir))
        assert res.returncode != 0


from __future__ import annotations

from operator import getitem

from loguru import logger

from astream import Stream
from astream.experimental.partializer import F
from astream.experimental.simple_surrogate import it
from astream.stream_grouper import apredicate_multi_map

async def group_f() -> None:
    logger.info("group_f")

    data = [
        {"vehicle": "car", "max_speed": 200, "n_wheels": 4, "n_doors": 4},
        {"vehicle": "bike", "max_speed": 60, "n_wheels": 2, "n_doors": 0},
        {"vehicle": "truck", "max_speed": 120, "n_wheels": 8, "n_doors": 2},
        {"vehicle": "bus", "max_speed": 100, "n_wheels": 6, "n_doors": 2},
        {"vehicle": "motorcycle", "max_speed": 180, "n_wheels": 2, "n_doors": 0},
        {"vehicle": "boat", "max_speed": 50, "n_wheels": 0, "n_doors": 0},
        {"vehicle": "plane", "max_speed": 800, "n_wheels": 3, "n_doors": 1},
        {"vehicle": "train", "max_speed": 200, "n_wheels": 0, "n_doors": 0},
    ]

    def double_spd(x):
        x["max_speed"] *= 2
        return x

    s = Stream(data) / apredicate_multi_map(
        {
            F(it["n_wheels"] == 0): F(it["max_speed"]),
            F(it["n_wheels"] == 2): lambda x: {**x, "type": "bicycle"},
            F(it["n_wheels"] == 4): double_spd,
            it["n_wheels"] > 4: F(it["vehicle"]),
        }
    )

    async for v in s:
        logger.info(v)

if __name__ == "__main__":
    import asyncio

    asyncio.run(group_f())


import math
from . import nsg_iff
from . import vector3D
from . import vertex_buffer_format

class SWGVertex(object):
    __slots = ('pos', 'normal', 'color', 'texs')
    def __init__(self):
        self.texs = []
        self.pos = None
        self.normal = None
        self.color = None

    def __str__(self):
        return f'P: {self.pos} N: {self.normal} UV0: {self.texs[0]}'

    def __repr__(self):
        return self.__str__()

class Triangle(object):
    __slots__ = ('p1', 'p2', 'p3')
    def __init__(self, p1 = None, p2 = None, p3 = None):
        self.p1 = p1
        self.p2 = p2
        self.p3 = p3

    def __str__(self):
        return f"[{self.p1}, {self.p2}, {self.p3}]"
    def __repr__(self):
        return self.__str__()

class SPS(object):
    __slots__ = ('no', 'shader', 'flags', 'verts', 'tris')
    def __init__(self):
        self.no = 0
        self.shader = ""
        self.flags = 0
        self.verts = []
        self.tris = []
    def __init__(self, no , shader, flags, verts, tris):
        self.no = no
        self.shader = shader
        self.flags = flags
        self.verts = verts
        self.tris = tris

    def __str__(self):
        return f"SPS_No: {self.no} Shader: {self.shader} Flags: {self.flags} Verts: {len(self.verts)} Tris: {len(self.tris)}"

    def __repr__(self):
        return self.__str__()

class SWGMesh(object):
    __slots__ = ('filename', 'spss', 'extents', 'collision', 'hardpoints', 'floor')
    def __init__(self, filename):
        self.filename = filename
        self.spss = []
        self.extents = []
        self.collision = None
        self.hardpoints = []
        self.floor = ""

    def __str__(self):
        s = f"Filename: {self.filename}\nExtents: {str(self.extents)}\nCollision: {str(self.collision_summary_str())}\nSPS: {len(self.spss)}\n"
        for sps in self.spss:
            s += str(sps)+'\n'
        return s

    def __repr__(self):
        return self.__str__()

    def collision_summary_str(self):
        if self.collision:
            first = self.collision[8:12].decode('ASCII')
            return f'Type: {first} Len: {len(self.collision)}'
        else:
            return "(No Collision)"

    def debug_flags(self, flags, sps_no):

        num_uv_sets = vertex_buffer_format.getNumberOfTextureCoordinateSets(flags)
        if(num_uv_sets > 0) and (vertex_buffer_format.getTextureCoordinateSetDimension(flags, num_uv_sets - 1) == 4):
            print(f'Mesh: {self.filename} SPS: {sps_no} Flags: {flags}: Has deprecated DOT3 UVs. Will skip!')

        if vertex_buffer_format.hasPointSize(flags):
            print(f'Mesh: {self.filename} SPS: {sps_no} Flags: {flags}: Has PointSize. Never seen that before! Not doing anything with it FYI')

        if vertex_buffer_format.hasColor1(flags):
            print(f'Mesh: {self.filename} SPS: {sps_no} Flags: {flags}: Has Color1. Never seen that before! Not doing anything with it FYI')

    def read_vertex(self, flags, iff):
        v = SWGVertex()

        num_uv_sets = vertex_buffer_format.getNumberOfTextureCoordinateSets(flags)
        skip_dot3 = False
        if(num_uv_sets > 0) and (vertex_buffer_format.getTextureCoordinateSetDimension(flags, num_uv_sets - 1) == 4):
            skip_dot3 = True
            num_uv_sets -= 1

        v.texs = []

        if vertex_buffer_format.hasPosition(flags):
            v.pos =  vector3D.Vector3D(iff.read_float(), iff.read_float(), iff.read_float())

        if vertex_buffer_format.hasNormal(flags):
            v.normal =  vector3D.Vector3D(iff.read_float(), iff.read_float(), iff.read_float())

        if vertex_buffer_format.hasPointSize(flags):
            point_size = iff.read_float() # unused

        if vertex_buffer_format.hasColor0(flags):
            v.color = iff.read_uint32()

        if vertex_buffer_format.hasColor1(flags):
            color1 = iff.read_uint32() # unused

        for i in range(0, num_uv_sets):
            dim = vertex_buffer_format.getTextureCoordinateSetDimension(flags, i)
            v.texs.append([])
            for j in range(0, dim):
                v.texs[i].append(iff.read_float())

        if skip_dot3:
            iff.read_float()
            iff.read_float()
            iff.read_float()
            iff.read_float()

        return v

    def load(self):
        iff = nsg_iff.IFF(filename=self.filename)
        #print(f"Name: {iff.getCurrentName()} Length: {iff.getCurrentLength()}")
        iff.enterAnyForm()
        version = iff.getCurrentName()

        if version not in ["0005", "0004"]:
            print(f'Unsupported MESH version: {version}')
            return False

        iff.enterForm(version)
        #print(iff.getCurrentName())
        iff.enterForm("APPR")

        appr_version = iff.getCurrentName()

        if appr_version == "0003":
            iff.enterAnyForm()
            iff.enterForm("EXBX")
            iff.enterForm("0001")
            iff.enterForm("EXSP")
            iff.enterForm("0001")
            iff.enterChunk("SPHR")
            x = iff.read_float()
            y = iff.read_float()
            z = iff.read_float()
            rad = iff.read_float()
            #print(f"X: {x} Y: {y} Z: {z} Radius: {rad}")
            iff.exitChunk("SPHR")
            iff.exitForm("0001")
            iff.exitForm("EXSP")

            iff.enterChunk("BOX ")
            maxx = iff.read_float()
            maxy = iff.read_float()
            maxz = iff.read_float()
            minx = iff.read_float()
            miny = iff.read_float()
            minz = iff.read_float()
            #print(f"MaxX: {maxx} MaxY: {maxy} MaxZ: {maxz} MinX: {minx} MinY: {miny} MinZ: {minz}")
            self.extents.append([maxx, maxy, maxz])
            self.extents.append([minx, miny, minz])
            iff.exitChunk("BOX ")

            iff.exitForm("0001")
            iff.exitForm("EXBX")

            # Collision stuff
            # if iff.enterForm("NULL", True):
            #     print("No collision data - bailing")
            #     self.collision = bytearray(0)
            #     iff.exitForm("NULL")
            # else:
            col_data_length = iff.getCurrentLength() + 8
            col_form_name = iff.getCurrentName()
            self.collision = iff.read_misc(col_data_length)
            print(f"Collision form: {col_form_name} Len: {col_data_length}")

            #hardpoints
            iff.enterForm("HPTS", True, False)
            while iff.enterChunk("HPNT", True):
                rotXx = iff.read_float()
                rotXy = iff.read_float()
                rotXz = iff.read_float()
                posX = iff.read_float()
                rotYx = iff.read_float()
                rotYy = iff.read_float()
                rotYz = iff.read_float()
                posY = iff.read_float()
                rotZx = iff.read_float()
                rotZy = iff.read_float()
                rotZz = iff.read_float()
                posZ = iff.read_float()
                hpntName = iff.read_string()
                self.hardpoints.append([rotXx, rotXy, rotXz, posX, rotYx, rotYy, rotYz, posY, rotZx, rotZy, rotZz, posZ, hpntName])
                iff.exitChunk("HPNT")
            iff.exitForm("HPTS")

            if iff.enterForm("FLOR", True):
                if iff.enterChunk("DATA", True):
                    self.floor = iff.read_string()
                    iff.exitChunk("DATA")
                iff.exitForm("FLOR")

            iff.exitForm()
        else:
            print(f"Warning: Unknown APPR version: {appr_version}")

        iff.exitForm("APPR")

        iff.enterForm("SPS ")
        iff.enterForm("0001")
        iff.enterChunk("CNT ")
        cnt = iff.read_uint32()
        iff.exitChunk("CNT ")

        while(not iff.atEndOfForm()):
            sps_no = iff.getCurrentName()
            iff.enterAnyForm()

            iff.enterChunk("NAME")
            sht=iff.read_string()
            iff.exitChunk("NAME")
            #print(f"SPS {sps_no} Shader: {sht}")

            #print(f"Next: {iff.getCurrentName()}")
            iff.enterChunk("INFO")
            cnt=iff.read_uint32()
            iff.exitChunk("INFO")

            version=iff.getCurrentName()
            if version == "0001" or version == "0000":
                iff.enterForm(version)
                iff.enterChunk("INFO")
                iff.exitChunk("INFO")

                iff.enterForm("VTXA")
                iff.enterForm("0003")

                iff.enterChunk("INFO")
                bit_flag = iff.read_int32()
                self.debug_flags(bit_flag, sps_no)
                num_verts = iff.read_uint32()
                verts = [None] * num_verts
                iff.exitChunk("INFO")

                iff.enterChunk("DATA")
                for i in range(0, num_verts):
                    verts[i] = self.read_vertex(bit_flag, iff)

                iff.exitChunk("DATA")
                iff.exitForm("0003")

                iff.exitForm("VTXA")

                size = iff.getCurrentLength()
                iff.enterChunk("INDX")
                indexes = []
                index_count = iff.read_uint32()
                bpi = (size - 4) // index_count
                #print(f'Size: {size} Size - 4: {size - 4}, index_count: {index_count} bpi: {bpi}')
                for i in range(index_count//3):
                    tri = Triangle()
                    if(bpi == 2):
                        tri.p1 = iff.read_int16()
                        tri.p2 = iff.read_int16()
                        tri.p3 = iff.read_int16()
                    elif(bpi == 4):
                        tri.p1 = iff.read_int32()
                        tri.p2 = iff.read_int32()
                        tri.p3 = iff.read_int32()
                    indexes.append(tri)
                #print(f'Read Index Count: {index_count}')

                iff.exitChunk("INDX")
                iff.exitForm(version)
                print(f"SPS {sps_no} Shader: {sht} Version: {version}")

                sps = SPS(sps_no, sht, bit_flag, verts, indexes)

                self.spss.append(sps)

            else:
                print(f"Warning: Unknown SPS {sps_no} Unhandled version: {version}")

            iff.exitForm()

        return True

    def write(self, filename):
        iff = nsg_iff.IFF(initial_size=10000)
        # - BEGIN MESH
        iff.insertForm("MESH")
        iff.insertForm("0005")

        # -- BEGIN APPR
        iff.insertForm("APPR")
        iff.insertForm("0003")

        # --- BEGIN EXTENTS
        iff.insertForm("EXBX")
        iff.insertForm("0001")
        iff.insertForm("EXSP")
        iff.insertForm("0001")

        iff.insertChunk("SPHR")

        diff_x = math.fabs(self.extents[0][0]) + math.fabs(self.extents[1][0])
        diff_y = math.fabs(self.extents[0][1]) + math.fabs(self.extents[1][1])
        diff_z = math.fabs(self.extents[0][2]) + math.fabs(self.extents[1][2])

        center_x = self.extents[1][0] + (diff_x/2)
        center_y = self.extents[1][1] + (diff_y/2)
        center_z = self.extents[1][2] + (diff_z/2)
        rad = (max(diff_x, diff_y, diff_z)/2)

        iff.insertFloatVector3((center_x, center_y, center_z))
        iff.insertFloat(rad)
        iff.exitChunk("SPHR")
        iff.exitForm(("0001"))
        iff.exitForm("EXSP")

        iff.insertChunk("BOX ")
        iff.insertFloatVector3(self.extents[0])
        iff.insertFloatVector3(self.extents[1])
        iff.exitChunk("BOX ")

        iff.exitForm("0001")
        iff.exitForm("EXBX")
        # --- END EXTENTS

        # --- BEGIN COLLISION
        if self.collision == None:
            iff.insertForm("NULL")
        else :
            iff.insertForm(self.collision[8:12].decode('ASCII'))
            iff.insertIffData(self.collision[12:])
        iff.exitForm()
        # --- END COLLISION

        # --- BEGIN HARDPOINTS
        iff.insertForm("HPTS")
        iff.exitForm()
        # --- END HARDPOINTS

        # --- BEGIN FLOOR
        iff.insertForm("FLOR")
        iff.insertChunk("DATA")
        iff.insert_bool(False)
        iff.exitChunk("DATA")
        iff.exitForm("FLOR")
        # --- END EXTENTS

        # -- END APPR
        iff.exitForm("0003")
        iff.exitForm("APPR")

        # -- BEGIN APPR
        iff.insertForm("SPS ")
        iff.insertForm("0001")

        # --- BEGIN CNT
        iff.insertChunk("CNT ")
        iff.insert_uint32(len(self.spss))
        iff.exitChunk("CNT ")

        for i in range(0, len(self.spss)):
            sps = self.spss[i]
            #print(f'Adding SPS {str(i+1).zfill(4)}')
            iff.insertNumberedForm(i+1)
            iff.insertChunk("NAME")
            iff.insertChunkString(sps.shader)
            iff.exitChunk("NAME")
            iff.insertChunk("INFO")
            iff.insert_uint32(1) #"Shader primitive count" - Never seen anything other than 1
            iff.exitChunk("INFO")

            iff.insertForm("0001")
            iff.insertChunk("INFO")
            iff.insert_uint32(9)
            iff.insert_bool(True)
            iff.insert_bool(False)
            iff.exitChunk("INFO")
            iff.insertForm("VTXA")
            iff.insertForm("0003")
            iff.insertChunk("INFO")
            iff.insert_uint32(4357)
            iff.insert_uint32(len(sps.verts))
            iff.exitChunk("INFO")
            iff.insertChunk("DATA")
            for v in sps.verts:
                iff.insertFloatVector3((v.pos.x, v.pos.y, v.pos.z))
                iff.insertFloatVector3((v.normal.x, v.normal.y, v.normal.z))
                if len(v.texs) > 0 and (len(v.texs[0]) > 0):
                    iff.insertFloatVector2((v.texs[0][0], v.texs[0][1]))
                else:
                    iff.insertFloatVector2((0,0))
            iff.exitChunk("DATA")
            iff.exitForm("0003")
            iff.exitForm("VTXA")

            iff.insertChunk("INDX")
            iff.insert_uint32(len(sps.tris)*3)
            for t in sps.tris:
                iff.insert_uint16(t.p1)
                iff.insert_uint16(t.p2)
                iff.insert_uint16(t.p3)
            iff.exitChunk("INDX")

            iff.exitForm("0001")
            iff.exitForm()

        # -- END APPR
        iff.exitForm("0001")
        iff.exitForm("SPS ")

        iff.write(filename)

class SWGBLendShape(object):
    def __init__(self):
        self.name = ""
        self.positions = []
        self.normals = []
        self.dot3 = None

    def __str__(self):
        return f"""Name: {self.name} Positions: {str(len(self.positions))} Norms: {str(len(self.normals))} DOT3: {(str(len(self.dot3)) if self.dot3 else "N/A")}"""

    def __repr__(self):
        return self.__str__()

class SWGPerShaderData(object):
    def __init__(self):
            self.name = ""
            self.pidx = []
            self.nidx = []
            self.dot3 = None
            self.colors = None
            self.txci = []
            self.tcsd = []
            self.num_uvs = 0
            self.uv_dimensions = []
            self.uvs = []
            self.num_prims = 0
            self.prims = []

    def __str__(self):
        s = f"""Name: {self.name} pidx: {str(len(self.pidx))} nidx: {str(len(self.nidx))} DOT3: {(str(len(self.dot3)) if self.dot3 else "N/A")}"""
        s += "\n"
        s += f"""UVS: {self.num_uvs} -- {', '.join( ("UVs: " + str(len(x)) + " Dim: " + str(len(x[0]))) for x in self.uvs)}"""
        s += "\n"
        s += f"""Prims: {self.num_prims} -- {', '.join( ("Tris: " + str(len(x))) for x in self.prims)}"""
        return s

    def __repr__(self):
        return self.__str__()

    def stripped_shader_name(self):
        if self.name == "":
            return "defaultappearance"
        else:
            return self.name.split('/')[1].split('.')[0]

class SWGMgn(object):
    def __init__(self, filename):
        self.filename = filename

        self.max_transforms_vertex = 0
        self.max_transforms_shader = 0

        self.num_skeletons = 0
        self.num_vertex_groups = 0
        self.num_positions = 0
        self.num_transform_weight_data = 0
        self.num_normals = 0
        self.num_shaders = 0
        self.num_blends = 0

        self.num_occ_zones = 0
        self.num_occ_combo_zones = 0
        self.num_this_occludes = 0
        self.occlusion_layer = 2

        self.occlusions = []
        self.skeletons = []
        self.bone_names = []

        self.positions = []
        self.normals = []
        self.dot3 = None

        self.twhd = []
        self.twdt = []

        self.vertex_weights = []

        self.blends = []

        self.psdts = []

    def __str__(self):
        s = f"""Filename: {self.filename}
                max_transforms_vertex: {self.max_transforms_vertex},
                max_transforms_shader: {self.max_transforms_shader},
                self.num_skeletons {self.num_skeletons},
                self.num_vertex_groups: {self.num_vertex_groups},
                self.num_positions: {self.num_positions},
                self.num_transform_weight_data: {self.num_transform_weight_data},
                self.num_normals: {self.num_normals},
                self.num_shaders: {self.num_shaders},
                self.num_blends: {self.num_blends},
                self.num_occ_zones: {self.num_occ_zones},
                self.num_occ_combo_zones: {self.num_occ_combo_zones},
                self.num_this_occludes: {len(self.occlusions)},
                self.occlusion_layer: {self.occlusion_layer}
                self.skeletons: {",".join(self.skeletons)}
                self.bone_names: {",".join(self.bone_names)}
                self.positions: {len(self.positions)}
                self.twhd: {len(self.twhd)}
                self.twdt: {len(self.twdt)}
                self.dot3: {(str(len(self.dot3)) if self.dot3 else "NA")}
                self.occlusions: {', '.join(str(x) for x in self.occlusions)}
                """
        #s += "\n".join(str(x) for x in self.positions)
        s += 'Blends: \n' + "\n".join(str(x) for x in self.blends)

        s += 'Per Shader Data: \n' + "\n".join(str(x) for x in self.psdts)
        return s

    def __repr__(self):
        return self.__str__()

    def normalize_vertex_weights(self, weights):
        for i , posn in enumerate(weights):
            total = 0
            for weight in posn:
                total += weight[1]

            for weight in posn:
                before = weight[1]
                weight[1] = weight[1]/total
                if weight[1] != before:
                    print(f"Vert {i} changed weight for bone {weight[0]} from {before} to {weight[1]}")

    def load(self):
        iff = nsg_iff.IFF(filename=self.filename)
        print(f"Name: {iff.getCurrentName()} Length: {iff.getCurrentLength()}")
        iff.enterAnyForm()
        version = iff.getCurrentName()

        if version not in ["0004",]:
            print(f'Unsupported MGN version: {version}')
            return False

        print(f'Doing Mgn version: {version}')

        iff.enterForm(version)
        #print(iff.getCurrentName())
        iff.enterChunk("INFO")

        self.max_transforms_vertex = iff.read_uint32()
        self.max_transforms_shader = iff.read_uint32()

        self.num_skeletons = iff.read_uint32()
        self.num_vertex_groups = iff.read_uint32()
        self.num_positions = iff.read_uint32()
        self.num_transform_weight_data = iff.read_uint32()
        self.num_normals = iff.read_uint32()
        self.num_shaders = iff.read_uint32()
        self.num_blends = iff.read_uint32()

        self.num_occ_zones = iff.read_uint16()
        self.num_occ_combo_zones = iff.read_uint16()
        self.num_this_occludes = iff.read_uint16()
        self.occlusion_layer = iff.read_uint16()

        iff.exitChunk("INFO")

        iff.enterChunk("SKTM")
        while not iff.atEndOfForm():
            self.skeletons.append(iff.read_string())
        iff.exitChunk("SKTM")

        iff.enterChunk("XFNM")
        while not iff.atEndOfForm():
            self.bone_names.append(iff.read_string())
        iff.exitChunk("XFNM")

        iff.enterChunk("POSN")
        self.positions = [0] * self.num_positions
        i=0
        while not iff.atEndOfForm():
            self.positions[i] = (iff.read_float(), iff.read_float(), -iff.read_float())
            i += 1
        iff.exitChunk("POSN")

        self.twhd = [0] * self.num_positions
        i = 0
        iff.enterChunk("TWHD")
        while not iff.atEndOfForm():
            self.twhd[i] = iff.read_uint32()
            i += 1
        iff.exitChunk("TWHD")

        iff.enterChunk("TWDT")
        self.twdt = [[0,0.0]] * self.num_transform_weight_data
        i = 0
        while not iff.atEndOfForm():
            self.twdt[i] = [iff.read_uint32(), iff.read_float()]
            #print(f'Twdt: {i} ({str(self.twdt[i])})')
            i += 1
        iff.exitChunk("TWDT")

        i = 0
        p = 0
        self.vertex_weights = [None] * self.num_positions
        for p, h in enumerate(self.twhd):
            these_weights = []
            sum=0
            for x in range(0,h):
                twdt = self.twdt[i]
                sum += twdt[1]
                these_weights.append(twdt)
                i += 1

            # if sum != 1.0:
            #     print(f' *** WARN ***: Vertex Weight sum for vert: {p} != 1.0 : {sum}')
            self.vertex_weights[p] = these_weights

        self.normalize_vertex_weights(self.vertex_weights)

        #self.positions = list(zip(self.positions, self.vertex_weights))

        iff.enterChunk("NORM")
        self.normals = [None] * self.num_normals
        i = 0
        while not iff.atEndOfForm():
            self.normals[i] = (iff.read_float(), iff.read_float(), iff.read_float())
            i += 1
        iff.exitChunk("NORM")

        if iff.getCurrentName() == "DOT3":
            iff.enterChunk("DOT3")
            num_dot3 = iff.read_uint32()
            self.dot3 = [None] * num_dot3
            i = 0
            while not iff.atEndOfForm():
                self.dot3[i] = [iff.read_float(), iff.read_float(), iff.read_float(), iff.read_float()]
                i += 1
            iff.exitChunk("DOT3")

        if iff.getCurrentName() == "HPTS":
            iff.enterForm("HPTS")
            iff.exitForm("HPTS")

        if iff.getCurrentName() == "BLTS":
            iff.enterForm("BLTS")
            while not iff.atEndOfForm():
                iff.enterForm("BLT ")
                blt = SWGBLendShape()
                iff.enterChunk("INFO")
                num_positions = iff.read_uint32()
                num_norms = iff.read_uint32()
                blt.name = iff.read_string()
                iff.exitChunk("INFO")
                self.blends.append(blt)

                iff.enterChunk("POSN")
                while not iff.atEndOfForm():
                    blt.positions.append( (iff.read_uint32(), (iff.read_float(), iff.read_float(), iff.read_float())))
                iff.exitChunk("POSN")

                iff.enterChunk("NORM")
                while not iff.atEndOfForm():
                    blt.normals.append( (iff.read_uint32(), (iff.read_float(), iff.read_float(), iff.read_float())))
                iff.exitChunk("NORM")

                if iff.getCurrentName() == "DOT3":
                    iff.enterChunk("DOT3")
                    num_dot3 = iff.read_int32()
                    blt.dot3 = []
                    #for i in range(0, num_dot3):
                    while not iff.atEndOfForm():
                        blt.dot3.append([(iff.read_int32(), (iff.read_float(), iff.read_float(), iff.read_float()))])
                    iff.exitChunk("DOT3")

                iff.exitForm("BLT ")
            iff.exitForm("BLTS")

        if iff.getCurrentName() == "OZN ":
            iff.enterChunk("OZN ")
            i = 0
            while not iff.atEndOfForm():
                self.occlusions.append([iff.read_string(), i, 1])
                i += 1
            iff.exitChunk("OZN ")

        if iff.getCurrentName() == "FOZC":
            iff.enterChunk("FOZC")
            iff.exitChunk("FOZC")

        if iff.getCurrentName() == "OZC ":
            iff.enterChunk("OZC ")
            iff.exitChunk("OZC ")

        if iff.getCurrentName() == "ZTO ":
            iff.enterChunk("ZTO ")
            for occ in self.occlusions:
                occ[2] = 0
            while not iff.atEndOfForm():
                index = iff.read_int16()
                print(f"Found ZTO: {index}")
                for occ in self.occlusions:
                    if occ[1] == index:
                        occ[2] = 1
                        print(f"Occ: {str(occ)} is ZTO: {index} Setting occluded to: {occ[2]}")
            iff.exitChunk("ZTO ")

        while not iff.atEndOfForm():
            if iff.getCurrentName() == "PSDT":
                psdt = SWGPerShaderData()
                iff.enterForm("PSDT")

                iff.enterChunk("NAME")
                psdt.name = iff.read_string()
                iff.exitChunk("NAME")

                iff.enterChunk("PIDX")
                num = iff.read_uint32()
                while not iff.atEndOfForm():
                    i = iff.read_uint32()
                    psdt.pidx.append(i)

                iff.exitChunk("PIDX")

                iff.enterChunk("NIDX")
                while not iff.atEndOfForm():
                    psdt.nidx.append(iff.read_uint32())
                iff.exitChunk("NIDX")

                if iff.getCurrentName() == "DOT3":
                    psdt.dot3 = []
                    iff.enterChunk("DOT3")
                    while not iff.atEndOfForm():
                        psdt.dot3.append(iff.read_uint32())
                    iff.exitChunk("DOT3")

                if iff.getCurrentName() == "VDCL":
                    psdt.colors = []
                    iff.enterChunk("VDCL")
                    while not iff.atEndOfForm():
                        psdt.colors.append([iff.read_byte(), iff.read_byte(), iff.read_byte(), iff.read_byte()])
                    iff.exitChunk("VDCL")

                if iff.getCurrentName() == "TXCI":
                    iff.enterChunk("TXCI")
                    psdt.num_uvs = iff.read_uint32()
                    while not iff.atEndOfForm():
                        psdt.uv_dimensions.append(iff.read_uint32())
                    iff.exitChunk("TXCI")

                    iff.enterForm("TCSF")
                    i = 0
                    while not iff.atEndOfForm():
                        dim = psdt.uv_dimensions[i]
                        num = iff.getCurrentLength() // 4 // dim
                        psdt.uvs.append([None] * num)
                        iff.enterChunk("TCSD")
                        for n in range(0, num):
                            uv = []
                            for m in range(0, dim):
                                uv.append(iff.read_float())
                            psdt.uvs[i][n] = uv
                        iff.exitChunk("TCSD")
                        i += 1
                    iff.exitForm("TCSF")

                iff.enterForm("PRIM")
                iff.enterChunk("INFO")
                psdt.num_prims = iff.read_uint32()
                iff.exitChunk("INFO")
                while not iff.atEndOfForm():
                    prim_type = iff.getCurrentName()
                    iff.enterChunk(prim_type)

                    triangle_list = []
                    if prim_type == "OITL":
                        num_tris = iff.read_uint32()
                        #for n in range(0, num_tris):
                        while not iff.atEndOfForm():
                            occ = iff.read_int16()
                            p1 = iff.read_int32()
                            p2 = iff.read_int32()
                            p3 = iff.read_int32()
                            tri = Triangle(p1, p2, p3)
                            triangle_list.append(tri)
                        psdt.prims.append(triangle_list)
                    elif prim_type == "ITL ":
                        num_tris = iff.read_uint32()
                        for n in range(0, num_tris):
                            p1 = iff.read_int32()
                            p2 = iff.read_int32()
                            p3 = iff.read_int32()
                            tri = Triangle(p1, p2, p3)
                            triangle_list.append(tri)
                        psdt.prims.append(triangle_list)
                    else:
                        print(f'Unhandled PRIM type: {prim_type}')
                    iff.exitChunk(prim_type)

                iff.exitForm("PRIM")
                self.psdts.append(psdt)
                iff.exitForm("PSDT")
            else:
                print(f'Unexpected form: {iff.getCurrentName()}')
                iff.exitForm()
        print(self)

    def get_zones_this_occludes(self):
        i = 0
        for zone in self.occlusions:
            if zone[2] == 1:
                i += 1
        return i

    def write(self):
        iff = nsg_iff.IFF(initial_size=10000)
        print(f"Name: {iff.getCurrentName()} Length: {iff.getCurrentLength()}")
        iff.insertForm("SKMG")
        iff.insertForm("0004")

        iff.insertChunk("INFO")
        iff.insert_uint32(self.max_transforms_vertex)
        iff.insert_uint32(self.max_transforms_shader)
        iff.insert_uint32(len(self.skeletons))
        iff.insert_uint32(len(self.bone_names))
        iff.insert_uint32(len(self.positions))
        iff.insert_uint32(len([vv for v in self.twdt for vv in v ]))
        iff.insert_uint32(len(self.normals))
        iff.insert_uint32(len(self.psdts))
        iff.insert_uint32(len(self.blends))

        iff.insert_uint16(len(self.occlusions))
        iff.insert_uint16(self.num_occ_combo_zones)
        iff.insert_uint16(self.get_zones_this_occludes())
        iff.insert_uint16(self.occlusion_layer)
        iff.exitChunk("INFO")

        iff.insertChunk("SKTM")
        for skel in self.skeletons:
            iff.insertChunkString(skel)
        iff.exitChunk("SKTM")

        iff.insertChunk("XFNM")
        for bone in self.bone_names:
            iff.insertChunkString(bone)
        iff.exitChunk("XFNM")

        iff.insertChunk("POSN")
        for pos in self.positions:
            #pos[0] = -pos[0]
            iff.insertFloatVector3(pos)
        iff.exitChunk("POSN")

        iff.insertChunk("TWHD")
        for twdt in self.twdt:
            iff.insert_uint32(len(twdt))
        iff.exitChunk("TWHD")

        iff.insertChunk("TWDT")
        for twdt in self.twdt:
            for weight in twdt:
                iff.insert_uint32(weight[0])
                iff.insertFloat(weight[1])
        iff.exitChunk("TWDT")

        iff.insertChunk("NORM")
        for norm in self.normals:
            iff.insertFloatVector3(norm)
        iff.exitChunk("NORM")

        if self.dot3:
            iff.insertChunk("DOT3")
            iff.insert_uint32(len(self.dot3))
            for dot3 in self.dot3:
                iff.insertFloatVector4(dot3)
            iff.exitChunk("DOT3")

        # if iff.getCurrentName() == "HPTS":
        #     iff.enterForm("HPTS")
        #     iff.exitForm("HPTS")

        if(len(self.blends) > 0):
            iff.insertForm("BLTS")
            for blend in self.blends:
                iff.insertForm("BLT ")

                iff.insertChunk("INFO")
                iff.insert_uint32(len(blend.positions))
                iff.insert_uint32(len(blend.normals))
                iff.insertChunkString(blend.name)
                iff.exitChunk("INFO")

                iff.insertChunk("POSN")
                for p in blend.positions:
                    iff.insert_uint32(p[0])
                    iff.insertFloatVector3(p[1])
                iff.exitChunk("POSN")

                iff.insertChunk("NORM")
                for n in blend.normals:
                    iff.insert_uint32(n[0])
                    iff.insertFloatVector3(n[1])
                iff.exitChunk("NORM")

                if blend.dot3:
                    iff.insertChunk("DOT3")
                    iff.insert_uint32(len(blend.dot3))
                    for n in blend.dot3:
                        iff.insert_uint32(n[0])
                        iff.insertFloatVector3(n[1])
                    iff.exitChunk("DOT3")

                iff.exitForm("BLT ")
            iff.exitForm("BLTS")

        if len(self.occlusions) > 0:
            iff.insertChunk("OZN ")
            for occ in self.occlusions:
                iff.insertChunkString(occ[0])
            iff.exitChunk("OZN ")

        # if iff.getCurrentName() == "FOZC":
        #     iff.enterChunk("FOZC")
        #     iff.exitChunk("FOZC")

        # if iff.getCurrentName() == "OZC ":
        #     iff.enterChunk("OZC ")
        #     iff.exitChunk("OZC ")

        if len(self.occlusions) > 0:
            iff.insertChunk("ZTO ")
            for occ in self.occlusions:
                if occ[2] == 1:
                    iff.insert_int16(occ[1])
            iff.exitChunk("ZTO ")

        for psdt in self.psdts:
            iff.insertForm("PSDT")
            iff.insertChunk("NAME")
            iff.insertChunkString(f'shader/{psdt.name}.sht')
            iff.exitChunk("NAME")

            iff.insertChunk("PIDX")
            iff.insert_uint32(len(psdt.pidx))
            for pidx in psdt.pidx:
                iff.insert_uint32(pidx)
            iff.exitChunk("PIDX")

            iff.insertChunk("NIDX")
            for nidx in psdt.nidx:
                iff.insert_uint32(nidx)
            iff.exitChunk("NIDX")

            if psdt.dot3:
                iff.insertChunk("DOT3")
                for dot3 in psdt.dot3:
                    iff.insert_uint32(dot3)
                iff.exitChunk("DOT3")

            if len(psdt.uvs) > 0:
                iff.insertChunk("TXCI")
                iff.insert_int32(len(psdt.uvs))
                for uv_set in psdt.uvs:
                    iff.insert_int32(len(uv_set[0]))
                iff.exitChunk("TXCI")

                iff.insertForm("TCSF")
                for uv_set in psdt.uvs:
                    iff.insertChunk("TCSD")
                    for uv in uv_set:
                        iff.insertFloat(uv[0])
                        iff.insertFloat(1 - uv[1])
                    iff.exitChunk("TCSD")
                iff.exitForm("TCSF")

            iff.insertForm("PRIM")

            iff.insertChunk("INFO")
            iff.insert_uint32(len(psdt.prims))
            iff.exitChunk("INFO")

            for prim in psdt.prims:
                iff.insertChunk("ITL ")
                iff.insert_uint32(len(prim) // 3)
                for value in prim:
                    iff.insert_uint32(value)
                iff.exitChunk("ITL ")
            iff.exitForm("PRIM")

            iff.exitForm("PSDT")

        iff.write(self.filename)


# Задача с ожиданием нужной цены

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
import time
import math

link = "http://suninjuly.github.io/explicit_wait2.html"

try:
    browser = webdriver.Chrome()
    browser.get(link)
    button = browser.find_element_by_css_selector("button.btn")
    WebDriverWait(browser, 12).until(EC.text_to_be_present_in_element((By.ID, "price"), "100"))
    button.click()

    x = int(browser.find_element(by=By.ID, value='input_value').text)
    result = str(math.log(abs(12 * math.sin(x))))
    browser.find_element(by=By.ID, value='answer').send_keys(result)
    browser.find_element_by_id("solve").click()

except Exception as error:
    print(f'Произошла ошибка, вот ее трейсбэкЖ {error}')

finally:
    time.sleep(500)
    browser.quit()


from cemc.mcmc import FixedNucleusMC
from cemc.mcmc import Snapshot
from free_energy_barrier import init_bc
from cemc.mcmc import CovarianceCrdInitializer, CovarianceRangeConstraint
from cemc.mcmc import CovarianceBiasPotential
from cemc.mcmc import ReactionPathSampler, AdaptiveBiasReactionPathSampler
from cemc.mcmc import FixEdgeLayers
import numpy as np
from mpi4py import MPI
import sys
from ase.units import kB
import matplotlib as mpl
mpl.rcParams["svg.fonttype"] = "none"
mpl.rcParams["font.size"] = 18
mpl.rcParams["axes.unicode_minus"] = False

comm = MPI.COMM_WORLD
rank = comm.Get_rank()

inertia_bias_file = "inertia_bias_potential.pkl"
inertia_bias_file_new = "inertia_bias_potential.pkl"
h5file = "data/inertia_barrier.h5"
iteration = 0

T = 293

workdir = "data/adaptive_windows{}K".format(T)

def get_nanoparticle():
    from ase.cluster.cubic import FaceCenteredCubic
    from ase.geometry import get_layers
    surfaces = [(1, 0, 0), (1, 1, 0), (1, 1, 1)]
    layers = [10, 13, 9]
    lc = 4.05
    atoms = FaceCenteredCubic('Si', surfaces, layers, latticeconstant=lc)
    tags, array = get_layers(atoms, (1, 0, 0))
    for t, atom in zip(tags, atoms):
        if t % 2 == 0:
            atom.symbol = "Mg"
    print(atoms.get_chemical_formula())
    atoms.rotate(90, 'z', rotate_cell=True)
    return atoms

def update_bias(iter):
    import h5py as h5
    beta = 1.0/(kB*T)
    with h5.File(h5file, 'r') as hfile:
        betaG = np.array(hfile["free_energy"])
        x = np.array(hfile["x"])
        G = betaG/beta

    bias = InertiaBiasPotential(reac_crd=x, free_eng=-G)
    try:
        old_pot = InertiaBiasPotential.load(fname=inertia_bias_file)
        bias += old_pot
    except Exception:
        pass
    bias.fit_smoothed_curve(smooth_length=21, show=False)
    fig = bias.show()
    fig.savefig("{}/bias_potential{}.svg".format(workdir, iter))
    fig.savefig("{}/bias_potential{}.png".format(workdir, iter))
    bias.save(fname=inertia_bias_file_new)

def insert_nano_particle(atoms, nanoparticle):
    """Insert the nano particle into center of atoms."""
    from scipy.spatial import cKDTree as KDTree
    np_pos = nanoparticle.get_positions()
    com = np.sum(np_pos, axis=0)/len(np_pos)
    np_pos -= com
    nanoparticle.set_positions(np_pos)

    cell = atoms.get_cell()
    diag = 0.5 * (cell[:, 0] + cell[:, 1] + cell[:, 2])
    at_pos = atoms.get_positions() - diag
    tree = KDTree(at_pos)

    used_indices = []
    for atom in nanoparticle:
        dists, closest_indx = tree.query(atom.position)
        if closest_indx in used_indices:
            raise RuntimeError("Two indices map to the same!")
        atoms[closest_indx].symbol = atom.symbol
        used_indices.append(closest_indx)

    symbols = [atom.symbol for atom in atoms]
    return symbols

def run(N, use_bias):
    #network_name=["c2_4p050_3", "c2_2p864_2"]
    bc = init_bc(N)
    mc = FixedNucleusMC(
        bc.atoms, T, network_name=["c2_2p864_2"],
        network_element=["Mg", "Si"], mpicomm=comm,
        max_constraint_attempts=1E6)
    #mc.max_allowed_constraint_pass_attempts = 1
    nanop = get_nanoparticle()
    symbs = insert_nano_particle(bc.atoms.copy(), nanop)
    mc.set_symbols(symbs)
    mc.init_cluster_info()

    formula = "(I1+I2)/(2*I3)" # Needle
    #formula = "2*I1/(I2+I3)" # Plate
    inert_init = InertiaCrdInitializer(
        fixed_nucl_mc=mc, matrix_element="Al", cluster_elements=["Mg", "Si"],
        formula=formula)

    inert_rng_constraint = InertiaRangeConstraint(
        fixed_nuc_mc=mc, inertia_init=inert_init, verbose=True)

    if use_bias:
        bias = InertiaBiasPotential.load(fname=inertia_bias_file)
        bias.inertia_range = inert_rng_constraint
        mc.add_bias(bias)

    nsteps = 100000

    if rank == 0:
        snap = Snapshot(atoms=bc.atoms, trajfile="{}/inertia.traj".format(workdir))
        mc.attach(snap, interval=100000)
    # reac_path = ReactionPathSampler(
    #     mc_obj=mc, react_crd=[0.05, 0.9], react_crd_init=inert_init,
    #     react_crd_range_constraint=inert_rng_constraint, n_windows=30,
    #     n_bins=10, data_file=h5file)
    # reac_path.run(nsteps=nsteps)
    # reac_path.save()

    inert_rng_constraint.range = [0.0, 0.9]
    fix_layer = FixEdgeLayers(thickness=5.0, atoms=mc.atoms)
    mc.add_constraint(inert_rng_constraint)
    mc.add_constraint(fix_layer)

    reac_path = AdaptiveBiasReactionPathSampler(
        mc_obj=mc, react_crd=[0.0, 0.9], react_crd_init=inert_init,
        n_bins=100, data_file="{}/adaptive_bias.h5".format(workdir),
        mod_factor=1E-5, delete_db_if_exists=True, mpicomm=None,
        db_struct="{}/adaptive_bias_struct.db".format(workdir))
    reac_path.run()
    reac_path.save()

def plot():
    import h5py as h5
    from matplotlib import pyplot as plt
    beta = 1.0 / (kB * T)
    with h5.File(h5file, 'r') as hfile:
        G = np.array(hfile["free_energy"]) / beta
        x = np.array(hfile["x"])
        print("Datasets in file: {}".format(list(hfile.keys())))
        bias = np.array(hfile["InertiaBiasPotential"])

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot(x, G-bias)
    ax.set_ylabel("Free energy (eV)")
    ax.set_xlabel("\$\eta = 1 - \\frac{I_1 + I_2}{2I_3}\$")

    fig2 = plt.figure()
    ax2 = fig2.add_subplot(1, 1, 1)
    ax2.plot(x, G)
    fig2.savefig(workdir+"/raw_result{}.svg".format(iteration))
    fig.savefig(workdir+"/free_energy{}.svg".format(iteration))
    plt.show()

def plot_iterations(start, end):
    import h5py as h5
    from matplotlib import pyplot as plt
    beta = 1.0 / (kB * T)
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    fig2 = plt.figure()
    ax2 = fig2.add_subplot(1, 1, 1)
    fig3 = plt.figure()
    ax3 = fig3.add_subplot(1, 1, 1)
    l2_norms = []
    figl2 = plt.figure()
    axl2 = figl2.add_subplot(1, 1, 1)
    for iteration in range(start, end+1):
        fname = workdir + "/inertia_barrier{}.h5".format(iteration)
        with h5.File(fname, 'r') as hfile:
            G = np.array(hfile["free_energy"]) / beta
            x = np.array(hfile["x"])
            l2_norms.append(np.sqrt(np.sum(G**2)))
            print("Datasets in file: {}".format(list(hfile.keys())))
            bias = np.array(hfile["InertiaBiasPotential"])

        ax.plot(x, G-bias, label=str(iteration))
        ax2.plot(x, G, label=str(iteration))
        ax3.plot(x, bias, label=str(iteration))
    ax.set_ylabel("Free energy (eV)")
    ax.set_xlabel("\$\eta = 1 - \\frac{I_1 + I_2}{2I_3}\$")
    ax.legend(loc="best", frameon=False)
    ax2.legend(loc="best", frameon=False)
    axl2.plot(l2_norms, marker="x")
    plt.show()
    # fig2.savefig(workdir+"/raw_result{}.svg".format(iteration))
    # fig.savefig(workdir+"/free_energy{}.svg".format(iteration))

if __name__ == "__main__":
    option = sys.argv[1]
    iter = int(sys.argv[2])
    iteration = iter
    inertia_bias_file = "{}/inertia_bias_potential{}.pkl".format(workdir, iter)
    inertia_bias_file_new = "{}/inertia_bias_potential{}.pkl".format(workdir, iter+1)
    h5file = "{}/inertia_barrier{}.h5".format(workdir, iter)
    use_bias = iter > 0
    if option == "run":
        run(50, use_bias)
    elif option == "plot":
        plot()
    elif option == "update_bias":
        update_bias(iter)
    elif option == "plot_iter":
        start = int(sys.argv[2])
        end = int(sys.argv[3])
        plot_iterations(start, end)


from os import environ
from flask import abort
from requests import get
from locale import currency

def stations():
    # Get NS app key from environment variables
    ns_app_key = environ.get('NS_APP_KEY')

    # Validate that NS app key is set
    if not ns_app_key:
        abort(401)

    # Get list of train stations from NS API
    url = 'https://gateway.apiportal.ns.nl/reisinformatie-api/api/v2/stations?countryCodes=nl'
    headers = {'Ocp-Apim-Subscription-Key': ns_app_key}
    response = get(url, headers=headers)

    # Validate that response is successful
    if response.status_code != 200:
        abort(response.status_code)

    # Select station names
    data = response.json()
    stations = []
    for station in data['payload']:
        stations.append(station['namen']['lang'])

    return sorted(stations)

def prices(fromStation, toStation):
    # Get public price information key from environment variables
        public_price_information_key = environ.get('PUBLIC_PRICE_INFORMATION_KEY')

        # Validate that public price information key is set
        if not public_price_information_key:
            abort(401)

        # Get prices from fromStation to toStation from NS API
        url = "https://gateway.apiportal.ns.nl/public-prijsinformatie/prices?fromStation={}&toStation={}".format(fromStation, toStation)
        headers = {'Ocp-Apim-Subscription-Key': public_price_information_key}
        response = get(url, headers=headers)

        # Validate that response is successful
        if response.status_code != 200:
            abort(response.status_code)

        # Select only the prices for a single fare in second class
        data = response.json()
        prices = []
        for price_option in data['priceOptions']:
            if price_option['type'] == 'ROUTE_WITHOUT_OPTIONS':
                for total_price in price_option['totalPrices']:
                    if total_price['classType'] == 'SECOND' and total_price['productType'] == 'SINGLE_FARE':
                        prices.append(total_price)

        # Sort by price, lowest first
        prices = sorted(prices, key=lambda k: k['price'])

        # Format price in euros and discount as text
        for price in prices:
            price['price'] = currency(price['price'] / 100, grouping=True).replace('Eu', '€')
            price['discount'] = price['discountType'].replace('_', ' ').capitalize()

        return prices


from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta

matrix = db.movies.find_one({'title':'매트릭스'})
matrix_star = matrix['star']
print(matrix_star)

same_star = list(db.movies.find({'star':matrix_star},{'_id':False}))
for same_star_list in same_star:
    print(same_star_list['title'])

db.movies.update_one({'title':'매트릭스'},{'$set':{'star':'0'}})
# 문자열 통일을 위해 0 이 아닌 '0' 으로 값 입력


"""empty message

Revision ID: c8b147681f8b
Revises: e1f9f06bcc9f
Create Date: 2021-09-22 08:58:46.033017

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'c8b147681f8b'
down_revision = 'e1f9f06bcc9f'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('FOIRawRequests', sa.Column('createdby', sa.String(length=120), nullable=True))
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('FOIRawRequests', 'createdby')
    # ### end Alembic commands ###


import sys
input = sys.stdin.readline

N, D = map(int, input().split())

shortcut = []
for i in range(N):
    shortcut.append(tuple(map(int, input().split())))
shortcut.sort(key=lambda x: x[0])

dist = [i for i in range(D+1)]  # dp배열
for i in range(0, D+1):
    if i > 0:
        dist[i] = min(dist[i], dist[i-1] + 1)
    while shortcut:
        if shortcut[0][0] == i:
            pop = shortcut.pop(0)
            if pop[1] <= D:
                dist[pop[1]] = min(dist[pop[1]], dist[i] + pop[2])
        else:
            break

print(dist[D])


"""
Author: N. Abrate.

File: setup.py

Description: Class for handling nuclear reactor geometries.
"""
from setuptools import find_packages
from distutils.core import setup

requirements = "requirements.txt"

setup(
   name='COREutils',
   version='0.0.1',
   author='N. Abrate',
   author_email='nicolo.abrate@polito.it',
   url='https://github.com/nicoloabrate/COREutils',
   package_name = ['coreutils'],
   packages=find_packages(),
   license='LICENSE.md',
   description='Handle core geometry and data for reactor physics applications',
#    long_description=open('README.md').read(),
   test_suite="tests",
   setup_requires=['pytest-runner'],
   tests_require=['pytest'],
   include_package_data=True,
   classifiers=[
        "Programming Language :: Python :: 3",
        "License :: MIT License",
        "Operating System :: OS independent",
    ],
    install_requires=open(requirements).read().splitlines(),
    python_requires='>=3.6',
)


import cv2
import numpy as np
from PIL import Image
import colorsys
import time
from itertools import product
# 30976+ 29584+32400=101
fitz = [
    (249, 229, 217),  # 62001+52441+47089= 133
    (242, 213, 195),  # 58564+45369+38025= 125
    (239, 194, 167),  # 57121+37636+27889= 116
    (193, 155, 136),  # 37249+24025+18496= 94
    (153, 113, 95),  # 23409+12769+9025= 70
    (104, 77, 66)  # 10816+5929+4356= 48
]

# def transparent_back(img):
#     L, H = img.size
#     color_0 = img.getpixel((0, 0)) + (104, 80, 70)
#     i = 0
#     for h, l in product(range(H), range(L)):
#         dot = (l, h)
#         color_1 = img.getpixel(dot)
#         if color_1 > color_0:
#             color_1 = color_1[:-1] + (255,)
#             img.putpixel(dot, color_1)
#             i += 1
#     return img, i

def diffColor(a, b):
    c = []
    for a1 in a:
        c.append(np.sqrt(a1[0] ** 2 + a1[1] ** 2 + a1[2] ** 2) / 3)
    d = np.sqrt(b[0] ** 2 + b[1] ** 2 + b[2] ** 2) / 3
    return c, d

def minIndex(c, d):
    x = np.abs(c-d).tolist()
    x = x.index(min(x))
    return x

def get_dominant_color(image):
    # 生成缩略图，减少计算量，减小cpu压力
    image = image.convert("RGBA")

    max_score = 0  # 原来的代码此处为None
    dominant_color = 0  # 原来的代码此处为None，但运行出错，改为0以后运行成功，原因在于在下面的score > max_score的比较中，max_score的初始格式不定

    for count, (r, g, b, a) in image.getcolors(image.size[0] * image.size[1]):
        # 跳过纯黑色
        # if r < 110 or g < 90 or b < 90:
        # if r < 104 or g < 80 or b < 70:
        #     continue
        if (r, g, b) < (104, 80, 70):
            continue
        y = min(abs(r * 2104 + g * 4130 + b * 802 + 4096 + 131072) >> 13, 235)

        y = (y - 16.0) / (235.0 - 16.0)

        # 忽略高亮色
        if y > 0.9:
            continue
        saturation = colorsys.rgb_to_hsv(r, g, b)[2]
        # Calculate the score, preferring highly saturated colors.
        # Add 0.1 to the saturation so we don't completely ignore grayscale
        # colors by multiplying the count by zero, but still give them a low
        # weight.
        score = (saturation + 0.1) * count

        if score > max_score:
            max_score = score
            dominant_color = (r, g, b)
    return dominant_color

def SkinColor(i):
    img = cv2.imread(i)
    img = cv2.resize(img, None, fx=0.2, fy=0.2, interpolation=cv2.INTER_CUBIC)
    # converting from gbr to hsv color space
    img_HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # rgb转hsv格式
    # skin color range for hsv color space
    HSV_mask = cv2.inRange(img_HSV, (10, 15, 10), (17, 170, 255))  # 设置阈值，去除背景部分
    # HSV_mask = cv2.inRange(img_HSV, (20, 20, 10), (20,190,255))
    HSV_mask = cv2.morphologyEx(HSV_mask, cv2.MORPH_OPEN, np.ones((5, 5), np.uint8))  # 被用来填充前景物体中的小洞，或者前景物体上的小黑点。
    HSV_mask = 255 - HSV_mask

    # converting from gbr to YCbCr color space
    img_YCrCb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)  # rgb转YCrCb格式
    # skin color range for hsv color space
    YCrCb_mask = cv2.inRange(img_YCrCb, (10, 135, 85), (255, 180, 135))  # 设置阈值，去掉背景部分
    # YCrCb_mask = cv2.inRange(img_YCrCb, (50, 135, 85), (255, 180, 135))
    YCrCb_mask = cv2.morphologyEx(YCrCb_mask, cv2.MORPH_OPEN, np.ones((5, 5), np.uint8))  # 被用来填充前景物体中的小洞，或者前景物体上的小黑点。
    YCrCb_mask = 255 - YCrCb_mask

    # merge skin detection (YCbCr and hsv)
    global_mask = cv2.bitwise_and(YCrCb_mask, HSV_mask)  # 掩膜与在图像上的区域融合
    global_mask = cv2.medianBlur(global_mask, 3)  # 中值滤波
    global_mask = cv2.morphologyEx(global_mask, cv2.MORPH_OPEN, np.ones((4, 4), np.uint8))
    global_mask = 255 - global_mask
    global_result_ = cv2.bitwise_not(global_mask)

    # global_index = global_result > 0.85
    # global_noindex = global_result < 0.85
    global_result = cv2.cvtColor(global_result_, cv2.COLOR_RGB2BGRA)
    # indexs = np.array(np.where(global_index == True))
    # indexs = np.stack(indexs, axis=1)
    img[0][:, [0, 2]] = img[0][:, [2, 0]]
    img = img[:, :, [2, 1, 0]]
    global_result[global_result_ >= 0.85] = [0, 0, 0, 255]
    global_result[global_result_ < 0.85] = [255, 255, 255, 0]
    mask = Image.fromarray(np.uint8(global_result))
    img = Image.fromarray(np.uint8(img))
    b, g, r, a = mask.split()
    img.paste(mask, mask=a)

    color = get_dominant_color(img)
    print("color", color)
    c, d = diffColor(fitz, color)
    index = minIndex(c, d)
    print("{}号肤色".format(index+1))
    if index < 3:
        print("冷色调")
    else:
        print("暖色调")
    # cv2.imshow("3_global_result.jpg", img)
    # cv2.waitKey()
    # cv2.destroyAllWindows()
    img.show()

if __name__ == '__main__':
    path = r"A:\testdata\15.jpg"
    stime = time.time()
    SkinColor(path)
    etime = time.time()
    print(etime-stime)


import socket
from CONSTANTS import PORTA, MSG_INCIO, PERGUNTAS

pontos = 0

def envia_pergunta(udp, chave, valor, cliente):
    nl = '\n'
    pergunta = f"{chave}) {valor['pergunta']}{nl}{nl.join(valor['opcoes'])}"
    udp.sendto(pergunta.encode('utf-8'), cliente)

def recebe_reposta():
    (resposta, cliente) = udp.recvfrom(1024)
    return int(resposta.decode('utf-8'))

def calcula_pontuacao(valor, resposta, pontos):
    if resposta == valor['resposta']:
            pontos +=1
    return pontos

udp = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
host = socket.gethostbyname("")
udp.bind((host, PORTA))
print('Esperando receber na porta', PORTA, '...')
(msg, cliente) = udp.recvfrom(1024)
msg = msg.decode('utf-8')
if msg == MSG_INCIO:
    for chave, valor in PERGUNTAS.items():
        envia_pergunta(udp, chave, valor, cliente)
        resposta = recebe_reposta()
        print(chave, resposta)
        pontos = calcula_pontuacao(valor, resposta, pontos)

udp.sendto(f"{pontos} PONTOS ".encode('utf-8'), cliente)
udp.close()


import os
import random
import ftplib
from fastapi import FastAPI, Request
import json
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from conf import get_conf

app = FastAPI()

templates = Jinja2Templates(directory="templates")

@app.get("/clear")
def clear_queue():
    with open('queue.json') as f:
        data = json.load(f)
    with open('queue.json', 'w') as f:
        if len(data['queue']) > 0:
            data['queue'] = [data['queue'][0]]
        json.dump(data, f)
    return {"error": False}

@app.post("/remove/{song}")
def remove_from_queue(song: str):
    with open('queue.json') as f:
        data = json.load(f)
    data['queue'].remove(song)
    with open('queue.json', 'w') as f:
        json.dump(data, f)
    return {"error": False}

@app.get("/queue")
def get_queue():
    with open('queue.json') as f:
        data = json.load(f)
    return data['queue']

@app.get("/current")
def get_current():
    with open('queue.json') as f:
        data = json.load(f)
    return data['current']

def set_current(song):
    with open('queue.json') as f:
        data = json.load(f)
    data['current'] = song
    with open('queue.json', 'w') as f:
        json.dump(data, f)

def get_songs(conf):
    if conf['ftp']['enabled']:
        ftp = ftplib.FTP(conf['ftp']['host'])
        ftp.login(conf['ftp']['user'], conf['ftp']['pass'])
        ftp.cwd(conf["music_dir"])
        return ftp.nlst()
    try:
        return os.listdir(conf['music_dir'])
    except FileNotFoundError:
        raise FileNotFoundError("Music directory could not be found")

@app.get("/")
async def root(request: Request):
    conf = get_conf()
    return templates.TemplateResponse("index.html", {"request": request, "conf": conf, "queue": get_queue(),
                                                     "songs": get_songs(conf), "current": get_current(),
                                                     "remove_ext": os.path.splitext})

@app.post("/add/{song}")
async def add_to_queue(song: str):
    with open('queue.json') as f:
        data = json.load(f)
    data['queue'].append(song)
    with open('queue.json', 'w') as f:
        json.dump(data, f)
    return {"error": False}

@app.post("/current/{song}")
async def set_current_song(song: str):
    set_current(song)
    with open("queue.json") as f:
        data = json.load(f)
    with open('queue.json', 'w') as f:
        data['queue'].pop(0)
        json.dump(data, f)
    return {"error": False}

@app.get("/next")
async def next_up():
    queue = get_queue()
    if len(queue) > 0:
        song = queue.pop(0)
    else:
        song = random.choice(get_songs(get_conf()))
        with open("queue.json") as f:
            data = json.load(f)
        with open('queue.json', 'w') as f:
            data['queue'].insert(0, song)
            json.dump(data, f)
    return {"song": song}


import news.News
from news.News import News, get_date_in_ms, get_dictionary
from constants.NEWS import DICTIONARY_HEADLINE, DICTIONARY_DATE_STRING, DICTIONARY_DATE_MS, URL_NEWS_TATA_POWER

class NewsTataPower(News):
    def __init__(self):
        self.url = URL_NEWS_TATA_POWER
        super().__init__(self.url)

    def get_news(self):
        self.set_html()
        self.set_soup()
        list_news = self.soup.find(class_="cont-search-results").find('ul').find_all('li')
        arr_news = []
        for news_item in list_news:
            headline = news_item.find('p').text
            date_string = news_item.find('b').text
            split_string = date_string.split(',')
            concat_string = split_string[1].strip() + ' ' + split_string[2].strip()
            date_ms = get_date_in_ms(concat_string, "%d %B %Y")

            dict_news = get_dictionary(headline, date_string, date_ms)

            arr_news.append(dict_news)
        # print(arr_news)
        return arr_news


from django.contrib import admin
from stats.models import Record
from django.utils.translation import ngettext
from django.contrib import messages
from stats.tasks import manual_release_date_task, manual_views_task

@admin.action(description='Обновить')
def update(self, request, queryset):
    try:
        for obj in queryset:
            manual_release_date_task.delay(obj.id)
        updated = queryset.count()
        self.message_user(request, ngettext(
            '%d запись обновлена.',
            '%d записи обновлены.',
            updated,
        ) % updated, messages.SUCCESS)
    except Exception as e:
        updated = queryset.count()
        self.message_user(request, ngettext(
            f'%d запись необновлены. Запись: {obj.name} Ошибка: {e}',
            f'%d записи необновлены. Запись: {obj.name} Ошибка: {e}',
            updated,
        ) % updated, messages.ERROR)

@admin.action(description='Снять статистику в ручную')
def stats(self, request, queryset):
    try:
        for obj in queryset:
            manual_views_task.delay(obj.id)
        updated = queryset.count()
        self.message_user(request, ngettext(
            '%d запись обновлена.',
            '%d записи обновлены.',
            updated,
        ) % updated, messages.SUCCESS)
    except Exception as e:
        updated = queryset.count()
        self.message_user(request, ngettext(
            f'%d запись необновлены. Запись: {obj.name} Ошибка: {e}',
            f'%d записи необновлены. Запись: {obj.name} Ошибка: {e}',
            updated,
        ) % updated, messages.ERROR)

@admin.register(Record)
class RecordAdmin(admin.ModelAdmin):
    list_display = ('name', 'link', 'views', 'release_date',
                    'stats_date', 'is_active', 'is_deleted')
    fields = ['name', 'link', 'is_active', ]
    ordering = ('-date_created',)
    search_fields = ('is_active', 'is_deleted',)
    actions = [update, stats,]
    list_filter = ('is_active', 'is_deleted')


import numpy as np
import torch, torch.nn as nn, torch.nn.functional as F
from tqdm import tqdm
import random
from scipy import linalg

"""======================================================"""
REQUIRES_STORAGE = True

###
class Sampler(torch.utils.data.sampler.Sampler):
    """
    Plugs into PyTorch Batchsampler Package.
    """
    def __init__(self, opt, image_dict, image_list):
        self.image_dict = image_dict
        self.image_list = image_list

        self.batch_size         = opt.bs
        self.samples_per_class  = opt.samples_per_class
        self.sampler_length     = len(image_list)//opt.bs
        assert self.batch_size%self.samples_per_class==0, '#Samples per class must divide batchsize!'

        self.name             = 'greedy_coreset_sampler'
        self.requires_storage = True

        self.bigbs           = opt.data_batchmatch_bigbs
        self.update_storage  = not opt.data_storage_no_update
        self.num_batch_comps = opt.data_batchmatch_ncomps
        self.dist_lim        = opt.data_gc_coreset_lim

        self.low_proj_dim    = opt.data_sampler_lowproj_dim

        self.softened = opt.data_gc_softened

        self.n_jobs = 16

    def __iter__(self):
        for i in range(self.sampler_length):
            yield self.epoch_indices[i]

    def precompute_indices(self):
        from joblib import Parallel, delayed
        import time

        ### Random Subset from Random classes
        bigb_idxs = np.random.choice(len(self.storage), self.bigbs, replace=True)
        bigbatch  = self.storage[bigb_idxs]

        print('Precomputing Indices... ', end='')
        start = time.time()
        def batchfinder(n_calls, pos):
            idx_sets         = self.greedy_coreset(n_calls, pos)
            structured_batches = [list(bigb_idxs[idx_set]) for idx_set in idx_sets]
            # structured_batch = list(bigb_idxs[self.fid_match(bigbatch, batch_size=self.batch_size//self.samples_per_class)])
            #Add random per-class fillers to ensure that the batch is build up correctly.
            for i in range(len(structured_batches)):
                class_idxs = [self.image_list[idx][-1] for idx in structured_batches[i]]
                for class_idx in class_idxs:
                    structured_batches[i].extend([random.choice(self.image_dict[class_idx])[-1] for _ in range(self.samples_per_class-1)])

            return structured_batches

        n_calls            = int(np.ceil(self.sampler_length/self.n_jobs))
        # self.epoch_indices = batchfinder(n_calls, 0)
        self.epoch_indices = Parallel(n_jobs = self.n_jobs)(delayed(batchfinder)(n_calls, i) for i in range(self.n_jobs))
        self.epoch_indices = [x for y in self.epoch_indices for x in y]
        # self.epoch_indices = Parallel(n_jobs = self.n_jobs)(delayed(batchfinder)(self.storage[np.random.choice(len(self.storage), self.bigbs, replace=True)]) for _ in tqdm(range(self.sampler_length), desc='Precomputing Indices...'))

        print('Done in {0:3.4f}s.'.format(time.time()-start))

    def replace_storage_entries(self, embeddings, indices):
        self.storage[indices] = embeddings

    def create_storage(self, dataloader, model, device):
        with torch.no_grad():
            _ = model.eval()
            _ = model.to(device)

            embed_collect = []
            for i,input_tuple in enumerate(tqdm(dataloader, 'Creating data storage...')):
                embed = model(input_tuple[1].type(torch.FloatTensor).to(device))
                if isinstance(embed, tuple): embed = embed[0]
                embed = embed.cpu()
                embed_collect.append(embed)
            embed_collect = torch.cat(embed_collect, dim=0)
            self.storage = embed_collect

    def full_storage_update(self, dataloader, model, device):
        with torch.no_grad():
            _ = model.eval()
            _ = model.to(device)

            embed_collect = []
            for i,input_tuple in enumerate(tqdm(dataloader, 'Creating data storage...')):
                embed = model(input_tuple[1].type(torch.FloatTensor).to(device))
                if isinstance(embed, tuple): embed = embed[0]
                embed = embed.cpu()
                embed_collect.append(embed)
            embed_collect = torch.cat(embed_collect, dim=0)
            if self.mb_mom>0:
                self.delta_storage = self.mb_mom*self.delta_storage + (1-self.mb_mom)*(embed_collect-self.storage)
                self.storage       = embed_collect + self.mb_lr*self.delta_storage
            else:
                self.storage = embed_collect

    def greedy_coreset(self, calls, pos):
        """
        """
        coll = []

        for _ in range(calls):
            bigbatch   = self.storage[np.random.choice(len(self.storage), self.bigbs, replace=False)]
            batch_size = self.batch_size//self.samples_per_class

            if self.low_proj_dim>0:
                low_dim_proj = nn.Linear(bigbatch.shape[-1],self.low_proj_dim,bias=False)
                with torch.no_grad(): bigbatch = low_dim_proj(bigbatch)

            bigbatch = bigbatch.numpy()

            prod        = np.matmul(bigbatch, bigbatch.T)
            sq          = prod.diagonal().reshape(bigbatch.shape[0], 1)
            dist_matrix = np.clip(-2*prod + sq + sq.T, 0, None)
            coreset_anchor_dists = np.linalg.norm(dist_matrix, axis=1)

            k, sampled_indices = 0, []

            while k<batch_size:
                if k==0:
                    no    = np.random.randint(len(coreset_anchor_dists))
                else:
                    if self.softened:
                        no = np.random.choice(np.where(coreset_anchor_dists>=np.percentile(coreset_anchor_dists,97))[0])
                    else:
                        no    = np.argmax(coreset_anchor_dists)

                sampled_indices.append(no)
                add_d  = dist_matrix[:, no:no+1]
                #If its closer to the remaining points than the new addition/additions, sample it.
                new_dj = np.concatenate([np.expand_dims(coreset_anchor_dists,-1), add_d], axis=1)
                coreset_anchor_dists = np.min(new_dj, axis=1)
                k += 1

            coll.append(sampled_indices)

        return coll

    def __len__(self):
        return self.sampler_length


# Importa as bibliotecas necessárias
import socket
import threading
import datetime
from message import Message
import time

# Função para registrar eventos no log.txt

def log_event(event):
    with open("log.txt", "a") as log_file:
        log_file.write(event + "\n")

# Classe Server

class Server:
    def __init__(self):
        self.mutex = threading.Lock()
        self.queue = []
        self.fila_processos = []
        self.processos_atendidos = []
        self.vezes_atendidos = {}
        self.processo_em_atendimento = None

        self.processes = {}
        self.running = True
        self.process_count = 0
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.socket.bind(('localhost', 8888))
        self.isGranted = False

    # Inicia o servidor
    def start(self):
        # Registra no log que o servidor está iniciando
        log_event(
            f"[STARTING] SERVIDOR SENDO INICIADO  {datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S')}")
        # Cria a thread para receber mensagens
        self.thread_receive = threading.Thread(target=self.receive)
        self.thread_receive.start()

        # Cria a thread para a interface do usuário
        self.thread_interface = threading.Thread(target=self.interface)
        self.thread_interface.start()

    # Função que recebe mensagens dos processos
    def receive(self):
        while True:
            # if(not len(self.fila_processos) > 0):
            #     print("Acabaram os Processos!")
            #     break
            try:
                # Recebe os dados e o endereço do processo
                data, addr = self.socket.recvfrom(1024)

                # Extrai informações da mensagem
                message_type, process_id, _ = data.decode().split(Message.SEPARATOR)
                process_id = int(process_id)

                self.fila_processos.append(process_id)

                print("mensagem recebida: ", message_type, process_id)
                if message_type == Message.REQUEST:

                    print("Request recebido")
                    if (self.processo_em_atendimento == None):
                        print("Processo colocado em atendimento")
                        self.processo_em_atendimento = self.fila_processos.pop(0)
                        print("Processo atendimento", self.processo_em_atendimento)
                        grant_response = (
                            f"[GRANT] Mensagem enviada pelo coordenador dando acesso região critica. Acesso concedido ao processo:{process_id}.  {datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S')}")
                        print("grant", grant_response)
                        self.socket.sendto(
                            Message.GRANT.encode(),addr)
                    else:
                        wait_response = (
                            f"Outro Processo está ocupando a zona critica, aguarde....")
                        self.socket.sendto(
                            wait_response.encode(), addr)

                if message_type == Message.RELEASE:
                    print("Release recebido")
                    self.processo_em_atendimento = None
                    print("Processo em atendimento", self.processo_em_atendimento)
                    if (len(self.fila_processos) > 0):
                        print("Processo colocado em atendimento")
                        self.processo_em_atendimento = self.fila_processos.pop(0)
                        print("Processo atendimento", self.processo_em_atendimento)
                        grant_response = (
                            f"[GRANT] Mensagem enviada pelo coordenador dando acesso região critica. Acesso concedido ao processo:{process_id}.  {datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S')}")
                        print("grant", grant_response)
                        self.socket.sendto(
                            Message.GRANT.encode(),addr)
                    else:
                        print("Acabaram os Processos!")
                        break

                # # Verifica se o processo já está registrado e adiciona caso não esteja
                # if process_id not in self.processes:
                #     self.add_process(process_id, addr)
                # # Se a mensagem for do tipo REQUEST
                # if message_type == Message.REQUEST:
                #     # Adiciona o processo na fila
                #     self.queue.append(process_id)
                #     # Registra no log que o processo solicitou acesso à região crítica
                #     log_event(
                #         f"[REQUEST] Mensagem enviada pelo processo {process_id} para solicitar acesso região critica.  {datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S')}")
                #     # Se o acesso não foi concedido a nenhum processo
                #     if self.isGranted == False:
                #         # Atualiza o contador de vezes que o processo foi atendido
                #         if process_id in self.vezes_atendidos:
                #             self.vezes_atendidos[process_id] += 1
                #         else:
                #             self.vezes_atendidos[process_id] = 1

                #         # Concede o acesso à região crítica para o processo
                #         self.send_message(Message.GRANT, process_id)
                #         # Registra no log que o acesso foi concedido
                #         log_event(
                #             f"[GRANT] Mensagem enviada pelo coordenador dando acesso região critica. Acesso concedido ao processo:{process_id}.  {datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S')}")
                #         time.sleep(1)
                #         # Envia mensagem de RELEASE
                #         message = Message.create_message(
                #             Message.RELEASE, process_id)
                #         log_event(
                #             f"[RELEASE] Mensagem enviada pelo processo {process_id} ao sair da região critica.  {datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S')}")
                #         log_event(f"Formato REQUEST - {message}")
                #         time.sleep(1)

                #         self.isGranted = False
                #     else:
                #         print("Aguardando processo sair da região critica...")
            except:
                print("NENHUM PROCESSO CONECTADO...")

    # Função para enviar mensagens aos processos
    def send_message(self, message_type, process_id):
        message = Message.create_message(message_type, process_id)
        self.socket.sendto(message.encode(), self.processes[process_id])

    # Função para adicionar um processo e seu endereço
    def add_process(self, process_id, addr):
        self.processes[process_id] = addr
        return process_id

    # Função para a interface do usuário
    def interface(self):
        while True:
            print("Bem vindo ao servidor!")
            print("1 - Ver fila")
            print("2 - Ver quantas vezes cada processo foi atendido")
            print("3 - Desconectar")
            command = input("Digite um comando: ")

            if command == "1":
                self.mutex.acquire()
                print(self.queue)
                self.mutex.release()
            elif command == "2":
                self.mutex.acquire()
                for process_id in self.vezes_atendidos:
                    print(
                        f"Processo {process_id} foi atendido {self.vezes_atendidos[process_id]} vezes.")
                self.mutex.release()
            elif command == "3":
                self.running = False
                self.mutex.acquire()
                log_event(
                    f"[DESCONECTANDO] DESCONECTANDO DO SERVIDOR ....  {datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S')}")
                self.socket.close()
                self.mutex.release()
                break

# Inicializa e inicia o servidor
if __name__ == "__main__":
    server = Server()
    server.start()


# -*- coding: UTF-8 -*-

from urllib.parse import urlparse, parse_qs,unquote

str=''
method = '/si  mila r'.replace(' ', '').replace("/", '')
print(method)

if "similar" is method:
    print('ok')
else:
    print('no ')

urldata='word=%E6%A0%BC%E6%A0%BC%E4%B8%8D%E5%85%A5'

urldata = unquote(urldata, encoding='gbk', errors='replace')
res=urlparse(urldata)
print(res)

import urllib.parse
s1='sentences=%E5%8D%A1%E5%A4%AB%E5%8D%A1&id=101'
print(urllib.parse.unquote("%E6%B5%8B%E8%AF%95abc"))
print('s1',urllib.parse.unquote(s1))

ary1='[-1.6975654 - 0.09812085  2.1600244   2.58708     1.3168149 - 2.6738997]'


import glob
import json
import logging
import math
import multiprocessing
import os

import click
import librosa
import soundfile as sf
from pqdm.processes import pqdm
from functools import partial
from denoiser import get_denoiser, run_denoiser
import torch
from tqdm import tqdm

@click.group()
def cli():
    logging.basicConfig(
        format="%(asctime)12s - %(levelname)s - %(message)s", level=logging.INFO
    )

def resampling(file, target_sr=16000, res_type="kaiser_best"):
    speech_array, sampling_rate = sf.read(file)
    if len(speech_array.shape) == 2:
        speech_array = speech_array[..., 0]
    if sampling_rate != target_sr:
        speech_array = librosa.resample(
            speech_array, orig_sr=sampling_rate, target_sr=target_sr, res_type=res_type
        )

    sf.write(
        file.replace("songs_denoise", f"songs_denoise_{int(target_sr/1000)}k"),
        speech_array,
        samplerate=target_sr,
    )

def run_denoise(train_files):
    os.makedirs("./data/train/songs_denoise", exist_ok=True)
    device = "cuda" if torch.cuda.is_available() else "cpu"
    separator = get_denoiser(device=device)
    for song_path in tqdm(train_files):
        audio, sr = run_denoiser(separator, song_path)
        sf.write(song_path.replace("songs", "songs_denoise"), data=audio, samplerate=sr)

@cli.command("resampling-data")
@click.option("--wavs_path", default="./data/train/songs/", show_default=True)
@click.option("--target_sr", default=16000, show_default=True)
@click.option("--res_type", default="kaiser_best", show_default=True)
def resampling_data(wavs_path, target_sr, res_type):
    train_file = glob.glob(os.path.join(wavs_path, "*.wav"))
    run_denoise(train_file)
    train_file = glob.glob(
        os.path.join(wavs_path.replace("songs", "songs_denoise"), "*.wav")
    )
    os.makedirs("./data/train/songs_denoise_16k", exist_ok=True)
    pqdm(
        train_file,
        partial(resampling, target_sr=target_sr, res_type=res_type),
        n_jobs=multiprocessing.cpu_count() - 1,
    )

if __name__ == "__main__":
    cli()


import importlib
import sys
from typing import Optional, Type

from PyQt5.QtWidgets import QApplication

from sunrise import hook
from sunrise.config import env
from sunrise.engines import Engine
from sunrise.filter import MetaFilter
from sunrise.mainwindow import MainWindow
from sunrise.manager import PluginManager
from sunrise.util import clear_cache

_main: Optional[MainWindow] = None
_engine: Optional[Engine] = None
_filter: Optional[MetaFilter] = None
pid: Optional[int] = None
plugin_manager: Optional[PluginManager] = None

def get_filter():
    if _filter is None:
        raise ValueError

    return _filter

def get_engine():
    if _engine is None:
        raise ValueError

    return _engine

def set_engine(engine_module) -> Type[Engine]:
    if _main is None:
        raise ValueError

    module = importlib.import_module(engine_module)
    engine = getattr(module, "Engine")

    if _engine is None:
        return engine(_main)
    # else:
    # _engine.close()

@hook.main_window_instantiate
def init_server():
    clear_cache.start()

@hook.main_window_close
def shutdown_server():
    _filter.shutdown()

def init():
    global _main, _engine, _filter, app, pid
    app = QApplication(sys.argv)
    _main = MainWindow("sunrise公开赛专属登录器正式版")
    _engine = set_engine(env.ENGINE_MODULE)
    pid = _main.pid
    _filter = getattr(importlib.import_module(env.FILTER_MODULE), "Filter")()
    plugin_manager = PluginManager()
    plugin_manager.load_all_plugin("plugins")

def run():
    _main.show()
    _filter.startup()
    sys.exit(app.exec_())


#Nombre:Juan Espinoza

#esConjunto: list -> bool
#True si es conjunto (sin elementos repetidos), False si no lo es
#ej: esConjunto([1,2,3,4,5]) -> True
#ej: esConjunto([67,1,1432]) -> True
#ej: esConjunto(['A','A','X']) -> False
def esConjunto(L):
    A=[]
    assert type(L)==list
    indices=range(len(L))
    for i in indices:
        if L.count(L[i])==1:
            A=A+[1]
        else: A=A+[0]
    if A.count(0)==0:
        return True
    else: return False
assert esConjunto([1,2,3,4,5])
assert esConjunto([67,1,1432])
assert not esConjunto(['A','A','X'])

#iguales: list list -> bool
#True, si ambos conjuntos son iguales sin importar el orden, False si son distintos
#ej: iguales([11,33],[33,11]) -> True
#ej: iguales(['tarea','tres'],['tarea','tres']) -> True
#ej: iguales([3,1,4,5],[3,1,4]) -> False
def iguales(L,R):
    assert esConjunto(L)
    assert esConjunto(R)
    L.sort()
    R.sort()
    return L==R
assert iguales([11,33],[33,11])
assert iguales(['tarea','tres'],['tarea','tres'])
assert not iguales([3,1,4,5],[3,1,4])

#union: list list -> list
#Une dos conjuntos y retorna el conjunto union sin elementos repetidos
#ej: union([1,2],[1,5]) -> [1, 2, 5]
#ej: union([],[1]) -> [1]
#ej: union(['a','x','y'],['z']) -> ['a','x','y','z']
def union(L,R):
    assert esConjunto(L)
    assert esConjunto(R)
    indices=range(len(L))
    for i in indices:
        if (L[i] in R)==True:
            R
        elif (L[i] in R)==False: R=R+[L[i]]
    assert esConjunto(R)
    R.sort()
    return R
assert union([1,2],[1,5])==[1, 2, 5]
assert union([],[1])==[1]
assert union(['a','x','y'],['z'])==['a','x','y','z']

#inter: list list -> list
#retorna los elementos en comun de dos conjuntos
#ej: inter([4, 7, 8],[4]) -> [4]
#ej: inter(['q','w','e'],[]) -> []
#ej: inter([2001,2002,2003],[2001,2002,2003,2004]) -> [2001,2002,2003]
def inter(L,R):
    A=[]
    assert esConjunto(L)
    assert esConjunto(R)
    indices=range(len(L))
    for i in indices:
        if (L[i] in R)==True:
            A=A+[L[i]]
        elif (L[i] in R)==False: A
    assert esConjunto(A)
    return A
assert inter([4, 7, 8],[4])==[4]
assert inter(['q','w','e'],[])==[]
assert inter([2001,2002,2003],[2001,2002,2003,2004])==[2001,2002,2003]

#resta: list list -> list
#resta los elementos de R que posee L
#ej: resta([4, 7, 8],[4]) -> [7,8]
#ej: resta(['z','x','c','v'],['u']) -> ['z','x','c','v']
#ej: resta([2001,2002,2003],[2001,2002,2003,2004]) -> []
def resta(L,R):
    A=[]
    assert esConjunto(L)
    assert esConjunto(R)
    indices=range(len(L))
    for i in indices:
        if (L[i] in inter(L,R))==True:
            A
        elif (L[i] in inter(L,R))==False:
            A=A+[L[i]]
    assert esConjunto(A)
    return A
assert resta([4, 7, 8],[4])==[7,8]
assert resta(['z','x','c','v'],['u'])==['z','x','c','v']
assert resta([2001,2002,2003],[2001,2002,2003,2004])==[]

#pertenece: any list -> bool
#True si x se encuentra dentro de A
#ej: pertence([2],[[2],3]) -> True
#ej: pertenece([22,44,66],[11,22,44,66,99]) -> True
#ej: pertenece('hola',['ciao','hello','hola'])  -> True
#ej: pertenece(98,[33,66,99]) -> False
def pertenece(x,A):
    if type(x)==list:
        return x==inter(x,A)
    else: return x in A
assert pertenece(2,[2,3])
assert pertenece([22,44,66],[11,22,44,66,99])
assert pertenece('hola',['ciao','hello','hola'])
assert not pertenece(98,[33,66,99])

#sea primos.txt un archivo de texto con los primeros 3 primos (uno por linea)

#leerConjunto: str -> list
#conjunto con líneas de archivo de nombre x
#ej: leerConjunto('primos') -> [2,3,5]
def leerConjunto(x):
    V=[]
    A=open(x+'.txt','r')
    for linea in A:
        if linea[len(linea)-1]=='\n':  #se agrega esta condicion ya que la ultima letra de la ultima linea se cortaba
            V=V+[linea[0:-1]]          #ej: 'juan' quedaba en la lista como 'jua' al estar al final.
        else: V=V+[linea]
    A.close()
    return V
#grabarConjunto: list str ->
#archivo de nombre x con valores de conjunto en L (uno por linea)
#ej: grabarConjunto([2,3,5,7],'primos_') -> #crea primos_.txt con 2, 3, 5 y 7 en lineas distintas
def grabarConjunto(L,x):
    A=open(x+'.txt','w')
    indices=range(len(L))
    for i in indices:
        A.write(str(L[i])+'\n')