import itertools as it

import numpy as np

from ..utilities import normalize_ids

def test_get_atomic_positions(case_data, get_atom_ids):
    """
    Test :meth:`.Molecule.get_atomic_positions`.

    Parameters
    ----------
    case_data : :class:`.CaseData`.
        A test case. Holds the molecule to test and the correct
        atomic positions.

    get_atom_ids : :class:`callable`
        Takes a single parameter, `molecule` and returns a valid
        `atom_ids` parameter for
        :meth:`.Molecule.get_atomic_positions`. This allows the testing
        of different values of this parameter.

    Returns
    -------
    None : :class:`NoneType`

    """

    _test_get_atomic_positions(
        molecule=case_data.molecule,
        position_matrix=case_data.position_matrix,
        get_atom_ids=get_atom_ids,
    )

def _test_get_atomic_positions(
    molecule,
    position_matrix,
    get_atom_ids,
):
    """
    Test :meth:`.Molecule.get_atomic_positions`.

    Parameters
    ----------
    molecule : :class:`.Molecule`
        The molecule to test.

    position_matrix : :class:`numpy.ndarray`
        The correct atomic positions.

    get_atom_ids : :class:`callable`
        Takes a single parameter, `molecule` and returns a valid
        `atom_ids` parameter for
        :meth:`.Molecule.get_atomic_positions`. This allows the testing
        of different values of this parameter.

    Returns
    -------
    None : :class:`NoneType`

    """

    for atom_id, position in it.zip_longest(
        normalize_ids(molecule, get_atom_ids(molecule)),
        molecule.get_atomic_positions(get_atom_ids(molecule)),
    ):
        assert np.allclose(
            a=position,
            b=position_matrix[atom_id],
            atol=1e-6,
        )


from __future__ import annotations

import pickle
from pathlib import Path
from typing import List

import cachetools
import numpy as np
import pandas as pd
import qlib
from qlib.constant import REG_CN
from qlib.contrib.ops.high_freq import BFillNan, Cut, Date, DayCumsum, DayLast, FFillNan, IsInf, IsNull, Select
from qlib.data.dataset import DatasetH

dataset = None

class DataWrapper:
    def __init__(
        self,
        feature_dataset: DatasetH,
        backtest_dataset: DatasetH,
        columns_today: List[str],
        columns_yesterday: List[str],
        _internal: bool = False,
    ):
        assert _internal, "Init function of data wrapper is for internal use only."

        self.feature_dataset = feature_dataset
        self.backtest_dataset = backtest_dataset
        self.columns_today = columns_today
        self.columns_yesterday = columns_yesterday

    @cachetools.cached(  # type: ignore
        cache=cachetools.LRUCache(100),
        key=lambda _, stock_id, date, backtest: (stock_id, date.replace(hour=0, minute=0, second=0), backtest),
    )
    def get(self, stock_id: str, date: pd.Timestamp, backtest: bool = False) -> pd.DataFrame:
        start_time, end_time = date.replace(hour=0, minute=0, second=0), date.replace(hour=23, minute=59, second=59)
        dataset = self.backtest_dataset if backtest else self.feature_dataset
        return dataset.handler.fetch(pd.IndexSlice[stock_id, start_time:end_time], level=None)

def init_qlib(qlib_config: dict, part: str = None) -> None:
    """Initialize necessary resource to launch the workflow, including data direction, feature columns, etc..

    Parameters
    ----------
    qlib_config:
        Qlib configuration.

        Example::

            {
                "provider_uri_day": DATA_ROOT_DIR / "qlib_1d",
                "provider_uri_1min": DATA_ROOT_DIR / "qlib_1min",
                "feature_root_dir": DATA_ROOT_DIR / "qlib_handler_stock",
                "feature_columns_today": [
                    "$open", "$high", "$low", "$close", "$vwap", "$bid", "$ask", "$volume",
                    "$bidV", "$bidV1", "$bidV3", "$bidV5", "$askV", "$askV1", "$askV3", "$askV5",
                ],
                "feature_columns_yesterday": [
                    "$open_1", "$high_1", "$low_1", "$close_1", "$vwap_1", "$bid_1", "$ask_1", "$volume_1",
                    "$bidV_1", "$bidV1_1", "$bidV3_1", "$bidV5_1", "$askV_1", "$askV1_1", "$askV3_1", "$askV5_1",
                ],
            }
    part
        Identifying which part (stock / date) to load.
    """

    global dataset  # pylint: disable=W0603

    def _convert_to_path(path: str | Path) -> Path:
        return path if isinstance(path, Path) else Path(path)

    provider_uri_map = {}
    if "provider_uri_day" in qlib_config:
        provider_uri_map["day"] = _convert_to_path(qlib_config["provider_uri_day"]).as_posix()
    if "provider_uri_1min" in qlib_config:
        provider_uri_map["1min"] = _convert_to_path(qlib_config["provider_uri_1min"]).as_posix()

    qlib.init(
        region=REG_CN,
        auto_mount=False,
        custom_ops=[DayLast, FFillNan, BFillNan, Date, Select, IsNull, IsInf, Cut, DayCumsum],
        expression_cache=None,
        calendar_provider={
            "class": "LocalCalendarProvider",
            "module_path": "qlib.data.data",
            "kwargs": {
                "backend": {
                    "class": "FileCalendarStorage",
                    "module_path": "qlib.data.storage.file_storage",
                    "kwargs": {"provider_uri_map": provider_uri_map},
                },
            },
        },
        feature_provider={
            "class": "LocalFeatureProvider",
            "module_path": "qlib.data.data",
            "kwargs": {
                "backend": {
                    "class": "FileFeatureStorage",
                    "module_path": "qlib.data.storage.file_storage",
                    "kwargs": {"provider_uri_map": provider_uri_map},
                },
            },
        },
        provider_uri=provider_uri_map,
        kernels=1,
        redis_port=-1,
        clear_mem_cache=False,  # init_qlib will be called for multiple times. Keep the cache for improving performance
    )

    if part == "skip":
        return

    # this won't work if it's put outside in case of multiprocessing
    from qlib.data import D  # noqa pylint: disable=C0415,W0611

    if part is None:
        feature_path = Path(qlib_config["feature_root_dir"]) / "feature.pkl"
        backtest_path = Path(qlib_config["feature_root_dir"]) / "backtest.pkl"
    else:
        feature_path = Path(qlib_config["feature_root_dir"]) / "feature" / (part + ".pkl")
        backtest_path = Path(qlib_config["feature_root_dir"]) / "backtest" / (part + ".pkl")

    with feature_path.open("rb") as f:
        feature_dataset = pickle.load(f)
    with backtest_path.open("rb") as f:
        backtest_dataset = pickle.load(f)

    dataset = DataWrapper(
        feature_dataset,
        backtest_dataset,
        qlib_config["feature_columns_today"],
        qlib_config["feature_columns_yesterday"],
        _internal=True,
    )

def fetch_features(stock_id: str, date: pd.Timestamp, yesterday: bool = False, backtest: bool = False) -> pd.DataFrame:
    assert dataset is not None, "You must call init_qlib() before doing this."

    if backtest:
        fields = ["$close", "$volume"]
    else:
        fields = dataset.columns_yesterday if yesterday else dataset.columns_today

    data = dataset.get(stock_id, date, backtest)
    if data is None or len(data) == 0:
        # create a fake index, but RL doesn't care about index
        data = pd.DataFrame(0.0, index=np.arange(240), columns=fields, dtype=np.float32)  # FIXME: hardcode here
    else:
        data = data.rename(columns={c: c.rstrip("0") for c in data.columns})
        data = data[fields]
    return data


## Calculate SPEC B field (and related quantities) purely in python
## attempt to remove pyoculus dependency (easier installation and more transparent calculation)
## TESTED against existing pyoculus-based implementation
## not tested for nonstell-symmetric cases

import numpy as np
from numba import njit

## parameters ---------------------------------------------------------

## numba signficantly speeds up calculations, can be installed with pip install ... numba
run_with_numba = True

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

if(run_with_numba):
    run_decorator = njit(fastmath=True, cache=True, parallel=False)
else:
    run_decorator = lambda x: x

def get_field_mod(self, lvol, sarr, tarr, zarr, Bcontrav=None, g=None):

    if(Bcontrav is None):
        Bcontrav = self.get_field_contrav(lvol, sarr, tarr, zarr)

    if(g is None):
        g = self.get_metric(sarr, tarr, zarr, lvol)

    Bmod = np.sqrt(np.einsum("i...,ij...,j...->...", Bcontrav, g, Bcontrav, optimize=True))

    return Bmod

def get_field_cov(self, lvol, sarr, tarr, zarr):

    Bcontrav = get_field_contrav(self, lvol, sarr, tarr, zarr)
    metric = self.get_metric(sarr, tarr, zarr, lvol)

    Bcov = np.einsum('i...,ij...->j...', Bcontrav, metric, optimize=True)

    return Bcov

def get_field_cart(self, lvol, sarr, tarr, zarr):
    """Generates the cartesian magnetic field in (R, Z, phi) coordinates)"""

    # geometry = self.input.physics.Igeometry
    # rpol = self.input.physics.rpol
    # rtor = self.input.physics.rtor
    # Rac, Rbc = self.output.Rbc[lvol : lvol + 2]
    # Zas, Zbs = self.output.Zbs[lvol : lvol + 2]
    # # Ras, Rbs = self.output.Rbs[lvol : lvol + 2]
    # # Zac, Zbc = self.output.Zbc[lvol : lvol + 2]
    # im = np.array(self.output.im, dtype=int)
    # in_ = np.array(self.output.in_, dtype=int)

    Rarr, Zarr = self.get_coord_transform(lvol, sarr, tarr, zarr)

    Bcontrav = self.get_field_contrav(lvol, sarr, tarr, zarr)

    Bcart = np.empty_like(Bcontrav)

    Bcart[0] = Bcontrav[0] * Rarr[1] + Bcontrav[1] * Rarr[2] + Bcontrav[2] * Rarr[3]
    Bcart[1] = Bcontrav[0] * Zarr[1] + Bcontrav[1] * Zarr[2] + Bcontrav[2] * Zarr[3]
    Bcart[2] = Bcontrav[2] * Rarr[0]

    return Bcart

def get_field_contrav(self, lvol, sarr, tarr, zarr):

    Aze = np.atleast_2d(self.vector_potential.Aze[lvol])
    Ate = np.atleast_2d(self.vector_potential.Ate[lvol])
    # Azo = np.atleast_2d(self.vector_potential.Azo[lvol])
    # Ato = np.atleast_2d(self.vector_potential.Ato[lvol])

    lrad = self.input.physics.Lrad[lvol]
    mpol = self.input.physics.Mpol
    im = self.output.im
    _in = self.output.in_
    coord_sing = self.input.physics.Igeometry > 1 and lvol == 0

    jac = self.get_jacobian(sarr, tarr, zarr, lvol)

    if(coord_sing):
        sbar = np.where(0.5*(sarr+1) > 0.0, 0.5*(sarr+1), 0)
        basis = get_zernike_basis(sbar, lrad, mpol)

        Bcontrav = get_field_sing(sarr, tarr, zarr, lrad, im, _in, basis, Aze, Ate, jac)

    else:
        basis = get_cheby_basis(sarr, lrad)

        Bcontrav = get_field_nonsing(sarr, tarr, zarr, lrad, im, _in, basis, Aze, Ate, jac)

    return Bcontrav

@run_decorator
def get_field_nonsing(sarr, tarr, zarr, lrad, im, _in, basis, Aze, Ate, jac):
    """Generates the contravariant magnetic field (volume without coordinate singularity)
    """

    Bcontrav = np.zeros((3, len(sarr), len(tarr), len(zarr)))

    for t in range(len(tarr)):
        for z in range(len(zarr)):
            for ii in range(len(im)):

                mi = im[ii]
                ni = _in[ii]
                arg = mi * tarr[t] - ni * zarr[z]
                carg = np.cos(arg)
                sarg = np.sin(arg)

                for s in range(len(sarr)):
                    for l in range(lrad+1):
                        Bcontrav[0, s, t, z] += (- mi * Aze[ii, l] - ni * Ate[ii, l]) * basis[l, 0, s] * sarg
                        Bcontrav[1, s, t, z] += (- Aze[ii, l] * basis[l, 1, s]) * carg
                        Bcontrav[2, s, t, z] += (Ate[ii, l] * basis[l, 1, s]) * carg

                    # if(not stell_sym): # needs Ato, Azo
                    #     Bcontrav[0, s, t, z] += (- mi * Azo[ii, l+1] - ni * Ato[ii, l+1]) * basis[l, 0, s] * carg
                    #     Bcontrav[1, s, t, z] += (- Azo[ii, l+1] * basis[l, 1, s]) * sarg
                    #     Bcontrav[2, s, t, z] += (Ato[ii, l+1] * basis[l, 1, s]) * sarg

    Bcontrav /= jac

    return Bcontrav

@run_decorator
def get_field_sing(sarr, tarr, zarr, lrad, im, _in, basis, Aze, Ate, jac):
    """Generates the contravariant magnetic field (volume with coordinate singularity)
    """

    Bcontrav = np.zeros((3, len(sarr), len(tarr), len(zarr)))

    for t in range(len(tarr)):
        for z in range(len(zarr)):
            for ii in range(len(im)):

                mi = im[ii]
                ni = _in[ii]
                arg = mi * tarr[t] - ni * zarr[z]
                carg = np.cos(arg)
                sarg = np.sin(arg)

                for s in range(len(sarr)):
                    for l in range(lrad+1):
                        Bcontrav[0, s, t, z] += (- mi * Aze[ii, l] - ni * Ate[ii, l]) * basis[l, mi, 0, s] * sarg
                        Bcontrav[1, s, t, z] += (- Aze[ii, l] * basis[l, mi, 1, s]) * 0.5 * carg
                        Bcontrav[2, s, t, z] += (Ate[ii, l] * basis[l, mi, 1, s]) * 0.5 * carg

                    # if(not stell_sym): # needs Ato, Azo
                    #     Bcontrav[0, s, t, z] += (- mi * Azo[ii, l+1] - ni * Ato[ii, l+1]) * basis[l, mi, 0, s] * carg
                    #     Bcontrav[1, s, t, z] += (- Azo[ii, l+1] * basis[l, mi, 1, s]) * 0.5 * sarg
                    #     Bcontrav[2, s, t, z] += (Ato[ii, l+1] * basis[l, mi, 1, s]) * 0.5 * sarg

    Bcontrav /= jac

    return Bcontrav

@run_decorator
def get_cheby_basis(sarr, lrad):

    # [radial mode (0->lrad), func/derivative (0/1), radial coord (sarr)]
    basis = np.zeros((lrad+1, 2, sarr.size))

    for s in range(len(sarr)):

        basis[0, 0, s] = 1.0
        basis[1, 0, s] = sarr[s]
        basis[1, 1, s] = 1.0

        for l in range(2, lrad+1):
            basis[l, 0, s] = 2.0 * sarr[s] * basis[l-1, 0, s] - basis[l-2, 0, s]
            basis[l, 1, s] = 2.0 * basis[l-1, 0, s] + 2.0 * sarr[s] * basis[l-1, 1, s] - basis[l-2, 1, s]

        # basis recombination
        basis[:, 0, s] -= (-1)**np.arange(lrad+1)

    # rescale for conditioning
    for l in range(0, lrad+1):
        basis[l] /= (l + 1.0)

    return basis

@run_decorator
def get_zernike_basis(sbararr, lrad, mpol):

    # [radial mode (0->lrad), poloidal mode (0->mpol), func/derivative (0/1), radial coord (sarr)]
    basis = np.zeros((lrad+1, mpol+1, 2, sbararr.size))

    for s in range(len(sbararr)):
        r = sbararr[s]
        rm = 1.0 # sbar^m
        rm1 = 0.0 # sbar^(m-1)
        for m in range(mpol+1):

            if(m <= lrad):
                basis[m, m, 0, s] = rm
                basis[m, m, 1, s] = m * rm1

            if(m+2 <= lrad):
                basis[m+2, m, 0, s] = (m+2) * rm * r**2.0 - (m+1) * rm
                basis[m+2, m, 1, s] = (m+2)**2.0 * rm * r - (m+1) * m * rm1

            for l in range(m+4, lrad+1, 2):
                fac1 = l / (l**2.0 - m**2.0)
                fac2 = 4.0 * (l - 1)
                fac3 = (l - 2 + m) **2.0 / (l - 2) + (l - m)**2.0 / l
                fac4 = ((l - 2)**2.0 - m**2.0) / (l - 2.0)

                basis[l, m, 0, s] = fac1 * ( (fac2 * r**2.0 - fac3) * basis[l-2, m, 0, s] - fac4 * basis[l-4, m, 0, s])
                basis[l, m, 1, s] = fac1 * ( 2.0 * fac2 * r * basis[l-2, m, 0, s]
                                            + (fac2 * r**2.0 - fac3) * basis[l-2, m, 1, s] - fac4 * basis[l-4, m, 1, s])

            rm1 = rm
            rm = rm * r

    # basis recombination
    for l in range(2, lrad+1, 2):
        basis[l, 0, 0] -= (-1)**(l/2.0)

    if(mpol >= 1):
        for s in range(len(sbararr)):
            for l in range(3, lrad+1, 2):
                basis[l, 1, 0, s] -= (-1)**((l-1)*0.5) * (l+1) * 0.5 * sbararr[s]
                basis[l, 1, 1, s] -= (-1)**((l-1)*0.5) * (l+1) * 0.5

    # rescaling
    for m in range(0, mpol+1):
        for l in range(m, lrad+1, 2):
            basis[l, m, :] /= (l + 1.0)

    return basis


import sys
import os
from random import randint
from PySide6.QtWidgets import (
    QMainWindow, QApplication, QWidget,
    QLabel, QCheckBox, QComboBox, QListWidget, QLineEdit, QPushButton,
    QLineEdit, QSpinBox, QDoubleSpinBox, QSlider,
    QLayout, QHBoxLayout
)

from PySide6.QtCore import Qt, QSize, QUrl

from PySide6.QtMultimedia import (QAudio, QAudioOutput, QMediaFormat, QMediaPlayer, QSoundEffect)

from PySide6.QtGui import QPixmap,QIcon

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.cat_number = 0
        self.windows = []

        self.setWindowTitle("My App")

        label = QLabel("select number of cats")

        spin = QSpinBox()
        spin.setMinimum(0)
        spin.valueChanged.connect(self.setcatnumber)

        button = QPushButton(QIcon("cat.png"), "press to generate kittens")
        button.clicked.connect(self.showcats)

        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addWidget(spin)
        layout.addWidget(button)

        dummy = QWidget()
        dummy.setLayout(layout)

        self.setCentralWidget(dummy)

        """ AUDIO """
        self._audio_output = QAudioOutput()
        self._player = QMediaPlayer()
            # NOTE: to play music: self._player.play()
            # NOTE: to pause music: self._player.pause()
            # NOTE: to stop: self._player.stop()
            # NOTE: to setup source:  self._player.setSource(self._playlist[self._playlist_index])
        self._player.setAudioOutput(self._audio_output)

        """using a low latency sound effect
        read: https://doc.qt.io/qtforpython/PySide6/QtMultimedia/QSoundEffect.html
        """
        miew_sound = QSoundEffect()
        miew_sound.setSource(QUrl.fromLocalFile("Kitten_Meow.wav"))
        miew_sound.setLoopCount(QSoundEffect.Infinite)
        miew_sound.setVolume(100)
        miew_sound.playingChanged.connect(print("playing changed!"))
        miew_sound.play()
        print("initialised main window")

    def setcatnumber(self, number):
        self.cat_number = number
        print("current cat number: ",int(number))

    def showcats(self, checked):
        print("generating {} cats".format(self.cat_number))
        for i in range(self.cat_number):
            # create a new window and show ignorantly
            cat = QLabel()
            cat.setPixmap(QPixmap("cat.png"))
            cat.setGeometry(randint(1,10)*100,randint(1,5)*50,800,800)
            cat.show()
            self.windows.append(cat)

"""app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
"""

if __name__ == "__main__":

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


#!/usr/bin/env python3
import glob
import importlib
import json
import os
import selectors
import socket
import threading
from console.logger import logger
from mutex.rwlock import ReadWriteLock
from platform.game import GameBase
from typing import Any, NewType

GameConstructor = NewType("GameConstructor", Any)
logger.level = 3

HOST = os.getenv('HOST', 'localhost')
PORT = int(os.getenv('PORT', '18880'))

def is_alive(sock) -> bool:
    """Check if a socket is alive
    """
    try:
        sock.settimeout(3)
        data = sock.recv(1, socket.MSG_PEEK)
        return True
    except BlockingIOError:
        return False
    except ConnectionResetError:
        return False
    except socket.timeout:
        return False

def recvline(sock) -> bytes:
    """Receive a line of data

    Receive data from a socket until it reads '\n'
    """
    data = b''
    while True:
        c = sock.recv(1)
        if c == b'':
            raise ConnectionRefusedError("Connection closed from client")
        if c == b'\n':
            break
        data += c
    return data

def sendline(sock, raw):
    assert b'\n' not in raw, "Do not include newline"
    sock.sendall(raw + b'\n')

def recv_data(sock):
    """Receive a JSON data
    """
    return json.loads(recvline(sock).decode())

def send_data(sock, data, type):
    """Send data to client
    """
    payload = {'result': 'success', 'type': type, 'data': data}
    sendline(sock, json.dumps(payload).encode())

def send_error(sock, msg):
    """Send error message to client
    """
    data = {'result': 'error', 'reason': msg}
    sock.sendall(json.dumps(data).encode())
    sock.close()
    raise Exception(msg)

known_games: dict[str, GameConstructor] = {}
known_games_lock = ReadWriteLock()

connections = {}
connections_lock = ReadWriteLock()

def start_game(game_class: GameConstructor, players):
    """Game manager

    Start a new game
    """
    num_players = len(players)
    name_by_id = {pid: player[0] for pid, player in enumerate(players)}
    sock_by_id = {pid: player[1] for pid, player in enumerate(players)}

    # Initialize game
    game = game_class(num_players, name_by_id)
    game.initialize()

    # Game loop
    logger.info(f"New game started: {game_class.name()}")
    logger.info(f"Players:")
    for pid in range(num_players):
        logger.info(f"- {name_by_id[pid]}")

    selector = selectors.DefaultSelector()
    for pid in range(num_players):
        selector.register(sock_by_id[pid], selectors.EVENT_READ, pid)

    no_game = False
    while True:
        # Check if game is over
        is_over = game.is_over()
        for pid in range(num_players):
            send_data(sock_by_id[pid], is_over, type='gameover')
        if is_over: break

        # Who to ask?
        pid_list = game.next_players()
        if not isinstance(pid_list, list):
            raise ValueError("Invalid game implementation: "
                             "Player ID list not given by 'next_players'")
        if not all([0 <= pid < num_players for pid in pid_list]):
            raise ValueError("Invalid game implementation: "
                             "Invalid player ID given by 'next_players'")

        # Share current state
        for pid in range(num_players):
            state = game.share_state(pid)
            logger.debug(f"Sharing state with {name_by_id[pid]}: {state}")
            try:
                send_data(sock_by_id[pid], state, type='state')
                send_data(sock_by_id[pid], pid in pid_list, type='turn')
            except Exception as _e:
                # Abort game by connection error
                no_game = True
                break
            # TODO: ここで時間計測開始

        # Abort game if a client died
        if no_game: break

        inputs_by_id = {}
        # Get inputs
        while len(inputs_by_id) < len(pid_list):
            events = selector.select()

            for key, _ in events:
                sock, pid = key.fileobj, key.data

                # Check if it's this player's turn now
                print(pid, pid_list)
                if pid not in pid_list:
                    logger.warning(f"{name_by_id[pid]} sent input on invalid turn")
                    no_game = True
                    break

                # Check if not yet received
                if pid in inputs_by_id:
                    logger.warning(f"{name_by_id[pid]} sent inputs twice")

                try:
                    inputs_by_id[pid] = recv_data(sock)
                except Exception as _e:
                    logger.warning(f"Could not receive input from"
                                   f"{name_by_id[pid]}")
                    no_game = True
                    break

                # TODO: タイムアウト処理

            if no_game: break

        # Abort game if a client died
        if no_game: break

        # Update if everyone sent the next moves
        for pid in pid_list:
            try:
                game.update_state(pid, inputs_by_id[pid])
            except Exception as e:
                # TODO: 失格リストを作る
                logger.warning(f"Invalid input from {name_by_id[pid]}: {e}")
                no_game = True
                break

        if no_game: break

    if no_game:
        # Game interrupted by connection error
        payload = {"result": "abort", "reason": "Game aborted by connection error"}
        score_by_id = {}
        for pid in range(num_players):
            try:
                if not is_alive(sock_by_id[pid]):
                    # FIXME: Not working
                    raise ConnectionRefusedError("Client is not alive")

                sendline(sock_by_id[pid], json.dumps(payload).encode())
                score_by_id[pid] = 0
            except Exception as _e:
                score_by_id[pid] = -9999 # TODO: configuable penalty
    else:
        # Game over
        score_by_id = game.is_over()
        print(score_by_id)
        if not isinstance(score_by_id, dict):
            raise ValueError("Invalid game implementation: "
                             "'is_over' must return score in dictionary")

    # Show result
    logger.info("Game result:")
    rank_by_id = {}
    rank = 1
    for (pid, score) in sorted(score_by_id.items(), key=lambda x:-x[1]):
        logger.info(f"{rank}. {name_by_id[pid]} (score: {score})")
        rank_by_id[pid] = rank
        rank += 1

    # Notify result
    for pid in range(num_players):
        payload = {
            "result": "success",
            "data": {"score": score_by_id[pid], "rank": rank_by_id[pid]}
        }
        try:
            sendline(sock_by_id[pid], json.dumps(payload).encode())
        except Exception as _e:
            logger.warning(f"Could not send game result to {name_by_id[pid]}")

def handle_connection(sock, client_host: str):
    """Handle new connection from client
    """
    try:
        # Receive client data
        data = json.loads(recvline(sock).decode())
        if 'game' not in data:
            send_error(sock, "Game not specified")
        if 'name' not in data:
            send_error(sock, "Your name not given")
        if not isinstance(data['game'], str):
            send_error(sock, "Game name must be string")
        if not isinstance(data['name'], str):
            send_error(sock, "Client name must be string")

        game = data["game"]
        name = data["name"]

        # Lookup game
        known_games_lock.acquire_read()
        is_known_game = game in known_games
        known_games_lock.release_read()
        if not is_known_game:
            send_error(sock, f"Game '{data['game']}' not found")

        # If everything is valid, add to client list
        connections_lock.acquire_write()
        if game not in connections:
            connections[game] = []
        connections[game].append((name, sock))

        # Notify the bot that it's registered
        send_data(sock, "Registered", type='meta')

        # Check if we can start the game
        cnt = known_games[game].min_players()
        if len(connections[game]) >= cnt:
            # Pass to game manager
            threading.Thread(
                target=start_game,
                args=(known_games[game], connections[game][:cnt])
            ).start()
            connections[game] = connections[game][cnt:]
        connections_lock.release_write()

    except Exception as e:
        logger.error(f"Error: {e} (Connection closed: {client_host})")
        sock.close()
        return

def load_game(game_dir: str) -> GameConstructor:
    """Load a single game

    Args:
      game_dir (str): Path to the game folder to import
    """
    if not os.path.isfile(f"{game_dir}/game.py"):
        raise FileNotFoundError(f"'game.py' not found in {game_dir}")

    # Import game
    module_name = f"{game_dir.replace('/', '.')}.game"
    game_class = importlib.import_module(module_name).Game

    return game_class

def load_all(root_dir: str) -> dict[str, GameConstructor]:
    """Load every game from game root directory
    """
    known_games = {}

    # Strip the leading './'
    if root_dir.startswith("./"):
        root_dir = root_dir[2:]

    for game_dir in glob.iglob(f"{root_dir}/*"):
        if not os.path.isdir(game_dir): continue
        try:
            game = load_game(game_dir)
            known_games[game.name()] = game
        except Exception as e:
            logger.error(f"Could not load a game: {e}")

    return known_games

def main():
    global known_games
    known_games = load_all("./game/")

    # Setup socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    s.bind(('0.0.0.0', PORT))
    s.setblocking(False)
    s.listen(128)

    selector = selectors.DefaultSelector()
    selector.register(s, selectors.EVENT_READ)

    while True:
        events = selector.select()
        for key, _ in events:
            sock, addr = key.fileobj.accept()
            logger.debug(f"New connection from {addr[0]}:{addr[1]}")

            threading.Thread(target=handle_connection, args=(sock, addr)).start()

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
"""
Created on Thu Mar  1 14:31:45 2018

@author: vuik/dupuits
"""

from collections import namedtuple
import numpy as np

def overtopping(Hm0, Tm, slope, Rc, **kwargs):
    """
    required input:
        Hm0   : significant wave height (m)
        Tm    : spectral mean wave period Tm-1,0 (s)
        slope : characteristic outer slope angle of dike slope=tan(alpha)
        Rc    : relative freeboard (with respect to MWL) (m)
    optional input:
        yb    : reduction factor for presence of berm
        yf    : reduction factor for roughness
        betaw : angle of oblique incidence (degrees)
        yv    : reduction factor for effect of wave wall
        ctype : probabilic ('prob') or deterministic ('det')
        ed    : edition of EurOtop: 2007 or 2016
        C**   : parameters for overtopping formulas, depending on ctype and ed.
                A default value is used if C**=0 or not set at all.
    output:
        q     : average overtopping discharge (m3/s/m)
    """

    if Hm0.shape != Tm.shape or Hm0.shape != slope.shape or Hm0.shape != Rc.shape:
        raise ValueError('Hm0, Tm, slope and/or Rc do not have the same array shape')

    # Default values
    yb    = kwargs.get("yb",    np.ones(Hm0.shape))
    yf    = kwargs.get("yf",    np.ones(Hm0.shape))
    betaw = kwargs.get("betaw", np.zeros(Hm0.shape))
    yv    = kwargs.get("yv",    np.ones(Hm0.shape))
    ctype = kwargs.get("ctype", "prob")
    ed    = kwargs.get("ed",    2016)
    g     = kwargs.get("g",     9.81)
    debug = kwargs.get("debug", False)

    if ed not in [2007, 2016] or ctype not in ["prob", "det"]:
        raise ValueError("Unrecognized value for 'ed'.")

    # Default values for overtopping constants.
    parnames = ["C1a", "C1b", "C1c", "C2a", "C2b", "C2c", "C3a", "C3b", "C3c"]
    if ed == 2007 and ctype == "prob":
        par = dict(zip(parnames, [0.067, 4.75, 1.0, 0.20,   2.60, 1.0, -0.92, 0.33, 0.022]))
    if ed == 2007 and ctype == "det":
        par = dict(zip(parnames, [0.067, 4.30, 1.0, 0.20,   2.30, 1.0, -0.68, 0.33, 0.022]))
    if ed == 2016 and ctype == "prob":
        par = dict(zip(parnames, [0.023, 2.70, 1.3, 0.09,   1.50, 1.3, -0.79, 0.33, 0.022]))
    if ed == 2016 and ctype == "det":
        par = dict(zip(parnames, [0.026, 2.50, 1.3, 0.1035, 1.35, 1.3,  0.50, 0.33, 0.022]))

    # Check if any of the overtopping constants needs to be overwritten.
    for key, value in kwargs.items():
        if key in parnames and value != 0.0:
            par[key] = value

    # Convert to a namedtuple because:
    #  - Makes it less painful to look at long formulas (use of dot operator).
    #  - Raises an error if code tries to alter a value of the namedtuple.
    OvertoppingConstants = namedtuple("OvertoppingConstants", parnames)
    par = OvertoppingConstants(**par)

    # Create copies of the input
    Hm0 = Hm0.copy()
    Tm = Tm.copy()
    slope = slope.copy()
    Rc = Rc.copy()

    # Create empty arrays to fill later
    q1 = np.empty(Hm0.shape)
    q2 = np.empty(Hm0.shape)
    q3 = np.empty(Hm0.shape)
    zeta = np.empty(Hm0.shape)
    q = np.empty(Hm0.shape)

    # Special case for negative freeboard
    rc_neg = Rc < 0
    rc_pos = Rc >= 0
    if ed == 2007:
        q[rc_neg] = 0.60 * np.sqrt(g * np.abs(Rc[rc_neg])**3)
    elif ed == 2016:
        q[rc_neg] = 0.54 * np.sqrt(g * np.abs(Rc[rc_neg])**3)

    # Negative or NaN results in NaN
    hm0_neg = (Hm0 < 0) | (Tm < 0) | np.isnan(Hm0) | np.isnan(Tm)
    q[rc_pos & hm0_neg] = np.nan

    # Zero wave height or period is zero discharge
    hm0_zer = ((Hm0 == 0) & (Tm >= 0)) | ((Tm == 0) & (Hm0 >= 0))
    q[rc_pos & hm0_zer] = 0.0

    # Valid indices for non-negative freeboards and positive waveheight/periods
    valid_ind = rc_pos & (Hm0 > 0) & (Tm > 0)

    # Fix betaw to be between 0 and 180, and derive gamma beta
    if betaw > 180:
        betaw = 360-betaw

    ybeta = np.ones(Hm0.shape) * 0.736

    if betaw <= 80:
        ybeta = 1.0 - 0.0033 * betaw # still valid in 2016, Eq. 5.29

    # Zero overtopping discharge for waves not attacking the profile
    q[valid_ind & (betaw > 110)] = 0.0
    valid_ind = valid_ind & (betaw <= 110)

    # Reduce wave height and periods for very oblique waves
    if valid_ind & (betaw > 80):
        Hm0 = Hm0 * (110.0 - betaw) / 30.0
        Tm  = Tm * np.sqrt((110.0 - betaw) / 30.0)

    # Reduce variables to the valid indices, makes the calculations for
    # q1, q2 and q3 more readable
    Hm0 = Hm0[valid_ind]
    Tm = Tm[valid_ind]
    Rc = Rc[valid_ind]
    slope = slope[valid_ind]
    ybeta = ybeta
    yb = yb
    yf = yf
    yv = yv
    # Calculate L0, sm and zeta
    L0    = g * Tm**2 / 2.0 / np.pi
    sm    = Hm0 / L0
    zeta[valid_ind]  = slope / np.sqrt(sm)
    q1[valid_ind] = par.C1a / np.sqrt(slope) * np.sqrt(g * Hm0**3) * yb * zeta[valid_ind]
    q1[valid_ind] *= np.exp(-(par.C1b * Rc / (zeta[valid_ind] * Hm0 * yb * yf * ybeta * yv))**par.C1c)

    q2[valid_ind] = par.C2a * np.sqrt(g * Hm0**3)
    q2[valid_ind] *= np.exp(-(par.C2b * Rc / (Hm0 * yf * ybeta))**par.C2c)

    q3[valid_ind] = 10.0**par.C3a * np.sqrt(g * Hm0**3)
    q3[valid_ind] *= np.exp(-Rc / (yf * ybeta * Hm0 * (par.C3b + par.C3c * zeta[valid_ind])))

    # Zeta conditionals
    zeta_smal = valid_ind & (zeta < 5)
    q[zeta_smal] = np.minimum(q1[zeta_smal], q2[zeta_smal])

    zeta_larg = valid_ind & (zeta > 7)
    q[zeta_larg] = q3[zeta_larg]

    zeta_between = valid_ind & (zeta <= 7) & (zeta >= 5)
    lb = np.minimum(q1[zeta_between], q2[zeta_between])
    q[zeta_between] = (zeta[zeta_between] - 5.0) / (7.0 - 5.0) * (q3[zeta_between] - lb) + lb

    return q

if __name__ == '__main__':
    # fill in function which corresponds to results of JORL2
    Hm0 = 4.07 # m
    Tm = 8.11 # s Tm-1,0 (s)
    slope = 0.25 # mTAW
    Rc = 1.09
    betaw = 0.0

    yb = 0.8
    yf = 0.9
    yv = 0.7

    q = overtopping(np.array(Hm0),np.array(Tm),np.array(slope),np.array(Rc),
                    betaw = betaw, yf = yf, yb = yb, yv = yv,
                    ed = 2007, ctype = 'det')

    print(q*1000) # result JORL2 sheet = 561.2 l/s/m


import unittest2

import openerp

class test_domain_normalization(unittest2.TestCase):
    def test_normalize_domain(self):
        expression = openerp.osv.expression
        norm_domain = domain = ['&', (1, '=', 1), ('a', '=', 'b')]
        assert norm_domain == expression.normalize_domain(domain), "Normalized domains should be left untouched"
        domain = [('x', 'in', ['y', 'z']), ('a.v', '=', 'e'), '|', '|', ('a', '=', 'b'), '!', ('c', '>', 'd'), ('e', '!=', 'f'), ('g', '=', 'h')]
        norm_domain = ['&', '&', '&'] + domain
        assert norm_domain == expression.normalize_domain(domain), "Non-normalized domains should be properly normalized"


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

# hash table
class Solution(object):
    def arithmeticTriplets(self, nums, diff):
        """
        :type nums: List[int]
        :type diff: int
        :rtype: int
        """
        lookup = set(nums)
        return sum((x-diff in lookup) and (x-2*diff in lookup) for x in nums)

# Time:  O(n)
# Space: O(n)
import collections

# dp
class Solution2(object):
    def arithmeticTriplets(self, nums, diff):
        """
        :type nums: List[int]
        :type diff: int
        :rtype: int
        """
        result = 0
        cnt1 = collections.Counter()
        cnt2 = collections.Counter()
        for x in nums:
            result += cnt2[x-diff]
            cnt2[x] += cnt1[x-diff]
            cnt1[x] += 1
        return result


from distutils.log import debug
from tarfile import PAX_FIELDS
import pandas as pd
import plotly.express as px
from dash import Dash, html, dcc

app = Dash(__name__)

df = pd.read_csv('materiais.csv')
df = df.sort_values(by='Grupo')

fig = px.bar(df, x='Grupo', y='Classe', color='PDM', barmode='group')

app.layout = html.Div(children=[
    html.H1(children='Olá Dashboard'),

    html.Div(children='''
        Dash: Uma aplicação web framework para seus dados.
    '''),

    dcc.Graph(
        id='exemplo de gráfico',
        figure=fig
    )
])

if __name__ == '__main__':
    app.run_server(debug=True)


import time

import pandas as pd
from sqlalchemy.orm import sessionmaker

from models import *
from settings import PROVIDER

engine = create_engine(PROVIDER['postgres'], echo=False)
Session = sessionmaker(bind=engine)
session = Session()

testcase = 'K'
orm = 'SQLAlchemy'

def main():
    result = pd.DataFrame()
    objs = list(session.query(Customer).all())
    count = len(objs)

    start = time.time()

    for obj in objs:
        session.delete(obj)
    session.commit()

    now = time.time()

    query_res = {'Testcase': testcase, 'Table': 'Item', 'Rows': count, 'Total time': f"{(now - start):10.2f}",
                 'RowsPerSec': f"{count / (now - start): 10.2f}", "ORM": orm}
    result = result.append(query_res, ignore_index=True)
    result.to_csv('sqlalchemy_outputs/test_k.csv')
    print(f"SQLAlchemy Testcase K, Rows deleted: {count}, time taken: {now-start}")
    print(f"SQLAlchemy ORM, K: Rows/sec: {count / (now - start): 10.2f}")

if __name__ == "__main__":
    main()


#!/usr/bin/python

import os
import pathlib
import datetime
import requests
import logging
from dateutil import tz
import configparser
import argparse
import json
import requests

def count_images_between_string_time_infilename(
    source_directory, start_time, end_time, local_tz
):
    """group images together by string time in their file name and copy them to a target directory"""
    count = 0
    for file in os.listdir(source_directory):
        filename = os.fsdecode(file)
        filepath = source_directory + filename
        fname = pathlib.Path(filepath)
        if filepath.endswith(".jpg"):
            filetime = filename[:14]
            filetime = datetime.datetime.strptime(filetime, "%Y%m%d_%H-%M")
            filetime = filetime.replace(tzinfo=local_tz)
            if filetime >= start_time and filetime <= end_time:
                count += 1
            else:
                continue
    return count

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--config",
        required=True,
        help="filename - dhconfig.txt or bhconfig.txt",
    )
    args = parser.parse_args()
    config = configparser.ConfigParser()
    config_file = os.path.join(os.path.dirname(__file__), args.config)
    config.read(config_file)
    image_storage_root_directory = config["directories"]["image_storage_root_directory"]
    image_check_location = config["logging"]["image_check_location"]
    slackhook = config["slack"]["slackhook"]
    slackheaders = config["slack"]["slackheaders"]

    # convert srting config inputs to dicts so they are read correctly
    slackheaders = json.loads(slackheaders)

    logging.basicConfig(
        filename=image_check_location,
        format="%(asctime)s - %(message)s",
        datefmt="%d-%b-%y %H:%M:%S",
        level=logging.INFO,
    )

    local_tz = tz.gettz("America/New_York")
    today = datetime.datetime.today()
    start_time = today.replace(hour=00, minute=00, second=00).astimezone(local_tz)
    end_time = today.replace(hour=23, minute=59, second=59).astimezone(local_tz)

    directions = ["north", "east", "south", "west"]
    stats_dict = {"north": {"#images": 0, "#missing": 0}, "east": {"#images": 0, "#missing": 0}, "south": {"#images": 0, "#missing": 0}, "west": {"#images": 0, "#missing": 0}}

    for i in directions:
        source_directory = image_storage_root_directory + i
        count = count_images_between_string_time_infilename(source_directory, start_time, end_time, local_tz)
        expected_count = (today.hour * 60) + today.minute
        difference = expected_count - count
        stats_dict[i]['#images'] = count
        stats_dict[i]['#missing'] = difference

    logging.info(stats_dict)

    slackjson = {
        "text": args.config + " " + str(stats_dict)
    }
    r = requests.post(slackhook, json=slackjson, headers=slackheaders)

if __name__ == "__main__":
    main()


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import sys,os,time
import subprocess
import scipy.io as sio
import tensorflow as tf
from six.moves import urllib
import numpy as np
import shutil

sys.path.append("utils/")
import cifar10
import cifar10_input
import modules
from candidate import Candidate
import cifar_DetaNet
import evolution_algo
import train

FLAGS = None

def main(_):
  # clear save files
  shutil.rmtree(FLAGS.save_dir)
  os.mkdir(FLAGS.save_dir)
  shutil.rmtree("./tmp/")
  os.mkdir("./tmp/")
  #os.remove("/dataset/svhn/svhn_train.tfrecords")

  seed_network = Candidate()
  seed_network.set_empty_prefix()
  structure1 = task(data_set = 'cifar20', prefix_structure = seed_network)
  structure2 = task(data_set = 'cifar10', prefix_structure = structure1)
  structure3 = task(data_set = 'svhn', prefix_structure = structure2)

def task(data_set, prefix_structure = None):
  # evolution
  best_candidate = evolution_algo.evolution_algo(
    FLAGS = FLAGS,
    data_set = data_set,
    prefix_structure = prefix_structure
  )
  # combine
  if prefix_structure != None:
    best_structure = prefix_structure.extend(best_candidate)
  else:
    best_structure = best_candidate
  # train
  best_structure.display_structure()
  '''
  train structure should be desperate to restore previous fixed weights
  '''
  _, final_avg_acc = train.train(
    FLAGS = FLAGS,
    prefix_structure = prefix_structure,
    candidate = best_candidate,
    data_set = data_set,
    max_steps = FLAGS.max_step
  )

  # display
  print("------------------transfer results------------------")
  print("best structure training_avg_acc "+ str(final_avg_acc))
  best_structure.display_structure()
  compurtation_of_network = best_structure.compurtation_of_network()
  print("compurtation_of_network :  " + str( )+ str(compurtation_of_network))
  print("")

  return best_structure

if __name__ == '__main__':
  parser = argparse.ArgumentParser()

  parser.add_argument('--save_dir', type=str, default='./save/transfer/',
                      help='save trained argues')
  parser.add_argument('--learning_rate', type=float, default=0.01,
                      help='Initial learning rate')
  parser.add_argument('--T', type=int, default=3000,
                      help='The Number of steps per geopath')
  parser.add_argument('--batch_size', type=int, default=256,
                      help='The Number of batches per each geopath')
  parser.add_argument('--candi', type=int, default=6,
                      help='The Number of Candidates of geopath, should greater than 4')
  parser.add_argument('--max_generations', type = int,default = 6,
                      help='The Generation Number of Evolution')
  parser.add_argument('--max_step', type = int,default = 15000,#200000,
                      help='The max training step of final structure')
  parser.add_argument('--dropout', type=float, default=1,
                      help='Keep probability for training dropout.')
  parser.add_argument('--use_fp16', type=bool, default=False,
                      help='Use float16 in netwrok or not.')
  parser.add_argument('--use_moving_avg', type=bool, default=False,#True,
                      help='Use shadow variables to replace origal variables for evaluation or not when restorage variables')
  # cifar
  parser.add_argument('--cifar_data_dir', type=str, default='/dataset/cifar_data/cifar-10-batches-bin/',
                      help='Directory for storing input data')
  parser.add_argument('--cifar100_data_dir', type=str, default='/dataset/cifar100/cifar-100-binary/',
                      help='Directory for storing input data')
  # svhn
  parser.add_argument('--svhn_data_dir', type=str, default='/dataset/svhn/',
                      help='Directory for storing input data')
  # mnist argus
  parser.add_argument('--data_dir', type=str, default='/dataset/mnist/',
                      help='Directory for storing input data')
  parser.add_argument('--a1', type=int, default=1,
                      help='The first class of task1')
  parser.add_argument('--a2', type=int, default=3,
                      help='The second class of task1')
  parser.add_argument('--b1', type=int, default=1,
                      help='The first class of task2')
  parser.add_argument('--b2', type=int, default=2,
                      help='The second class of task2')
  parser.add_argument('--c1', type=int, default=3,
                      help='The first class of task3')
  parser.add_argument('--c2', type=int, default=4,
                      help='The second class of task3')
  parser.add_argument('--d1', type=int, default=4,
                      help='The first class of task4')
  parser.add_argument('--d2', type=int, default=5,
                      help='The second class of task4')

  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)


import pygame
from pygame.locals import *

__all__ = ["SquarePlayer", "Ghost", "Goal", "Portal", "Level"]

class SquarePlayer:
    def __init__(self, display, color, width, height, x, y):
        self.display = display
        self.color = color
        self.x, self.y = x, y
        self.width, self.height = width, height
        self.object = pygame.rect.Rect(x, y, width, height)

    def draw(self):
        pygame.draw.rect(self.display, self.color, self.object, 5)

class Ghost:
    def __init__(self, display, ghost_x, ghost_y):
        self.display = display
        self.color = (0, 255, 0)
        self.width, self.height = 64, 64
        self.x, self.y = ghost_x, ghost_y
        self.object = pygame.rect.Rect(self.x, self.y, self.width, self.height)

    def draw(self):
        pygame.draw.rect(self.display, self.color, self.object, 5)

    def kill(self,):
        #self.x, self.y = player_Coords
        #self.object = pygame.rect.Rect(self.x, self.y, self.width, self.height)
        pygame.draw.rect(self.display, self.color, self.object, 5)

class Goal:
    def __init__(self, display, x, y):
        self.display = display
        self.color = (255, 0, 0)
        self.x, self.y = x, y
        self.coords = (self.x, self.y)
        self.width, self.height = (64, 64)
        self.object = pygame.rect.Rect(self.x, self.y, self.width, self.height)
        self.goal_completed = False

    def draw(self):
        pygame.draw.rect(self.display, self.color, self.object)

class Portal:
    def __init__(self, display, x, y):
        self.display = display
        self.color = (255, 0, 0)
        self.x, self.y = x, y
        self.width, self.height = (64, 64)
        self.object = pygame.rect.Rect(self.x, self.y, self.width, self.height)
        self.goal_completed = False

    def draw(self, color):
        self.color = color
        pygame.draw.rect(self.display, self.color, self.object)

class Level:
    def __init__(self, display, grid, name):
        x = 0
        y = 0
        self.name = name

        self.display = display
        self.grid = grid
        self.surface = pygame.Surface((512, 512))
        self.surface.set_colorkey((0, 0, 0))

        self.wall_points = []

        self.goal = 0

        self.safe_zone = []
        for rows in grid:
            for square_code in rows:
                if x == 512:
                    x = 0
                if square_code == 1:
                    self.square_x = x
                    self.square_y = y
                    self.player_spawn = pygame.rect.Rect(
                        self.square_x, self.square_y, 64, 64
                    )
                    self.safe_zone.append(self.player_spawn)

                if square_code == 2:
                    self.goal = Goal(self.display, x, y)
                    pygame.draw.rect(self.surface, self.goal.color, self.goal.object)

                if square_code == 3:
                    wall_object = pygame.rect.Rect(x, y, 32, 32)
                    self.wall_points.append(wall_object)
                    pygame.draw.rect(self.surface, (128, 128, 128), wall_object)

                if square_code == 4:
                    safe_square = pygame.rect.Rect(x, y, 32, 32)
                    self.safe_zone.append(safe_square)
                    pygame.draw.rect(self.surface, (128, 255, 255), safe_square)

                x += 32
            y += 32

    def blit_level(self):
        self.display.blit(self.surface, (0, 0))

    def level_reset(self):
        self.goal.goal_completed = False


import tkinter as tk
from window_manager import get_tibia_windows, get_window_id
from utils import send_key
from time import sleep
WINDOW_ID = int(get_window_id(), 16)
APP_TITLE = "EyePatch BOT"

class App:
    def __init__(self, master):
        self.master = master
        self.master.title(f"{APP_TITLE}")

        # Create the menu bar
        menubar = tk.Menu(master)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Open", command=self.open_file)
        filemenu.add_command(label="Save", command=self.save_file)
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=master.quit)
        menubar.add_cascade(label="File", menu=filemenu)

        # Create a dropdown list
        self.var = tk.StringVar(master)
        self.var.set("Pick a Client")
        clientmenu = tk.Menu(menubar, tearoff=0)
        for client in get_tibia_windows():
            clientmenu.add_command(label=client, command=lambda c=client: self.select_client(c))
        menubar.add_cascade(label="Pick Client", menu=clientmenu)

        # Add the menu bar to the master window
        master.config(menu=menubar)

        # Create a button
        self.button = tk.Button(master, text="Start EyePatch", command=self.startBot)
        self.button.pack()

        self.buttonKey = tk.Button(master, text="Send Key", command=self.sendKey)
        self.buttonKey.pack()

    def select_client(self, client):
        self.var.set(client)
        self.master.title(f"{client} - {APP_TITLE}")

    def open_file(self):
        print("Opening file...")

    def save_file(self):
        print("Saving file...")

    def startBot(self):
        tibia_window = self.var.get()
        if tibia_window != "Pick a Client":
            print(f"Proceeding with Tibia window '{tibia_window}'")

    def sendKey(self):
        key = "F7"
        window_id = self.var.get()
        send_key(key, window_id)

if __name__ == '__main__':
    root = tk.Tk()
    app = App(root)
    root.minsize(200, 50)
    print(f"{WINDOW_ID}")
    root.mainloop()


from django.http.response import HttpResponse
from django.utils import timezone
from rest_framework.exceptions import ParseError

def delete_or_400(model, text, **kwargs):
    """"Удаляем объект или возвращаем код 400."""
    if not model.objects.filter(**kwargs).exists():
        raise ParseError(text)
    model.objects.filter(**kwargs).delete()

def make_txt_response(ingredients):
    """Отдаём список покупок в txt формате."""
    shopping_list = 'Купить в магазине:\n'
    for ingredient in ingredients:
        shopping_list += (
            f'{ingredient["ingredient__name"]}: '
            f'({ingredient["ingredient__measurement_unit"]})'
            f' - {ingredient["amount"]} \n'
        )
    now = timezone.now()
    file_name = f'ingredients list{now:%Y-%m-%d}'
    response = HttpResponse(shopping_list, content_type='text/plain')
    response['Content-Disposition'] = (
        f'attachment; filename="{file_name}.txt"')
    return response


import math
from typing import List

def maxSubArray(nums):
    max_sum = None
    sum_table = set()

    if len(nums) == 1:
        return nums[0]

    for start in range(len(nums)):
        for i in range(len(nums) + 1):
            slice_arr = nums[start:i]

            if not slice_arr:
                continue

            curr_sum = sum(slice_arr)

            if curr_sum in sum_table:
                continue

            if max_sum is None:
                max_sum = curr_sum
            else:
                max_sum = max(curr_sum, max_sum)

            sum_table.add(curr_sum)

    return max_sum

def lengthOfLongestSubstring(s):
    window_start = 0
    max_length = 0
    char_index_map = {}

    for window_end in range(len(s)):
        curr_char = s[window_end]

        if curr_char in char_index_map:
            window_start = max(window_start, char_index_map[curr_char] + 1)

        char_index_map[curr_char] = window_end
        max_length = max(max_length, window_end - window_start + 1)

    return max_length

def minSubArrayLen(target, nums):
    start = 0
    min_len = math.inf
    curr_sum = 0

    for end, num in enumerate(nums):
        curr_sum += num

        while curr_sum >= target:
            min_len = min(min_len, end - start + 1)
            curr_sum = curr_sum - nums[start]
            start += 1

    if min_len != math.inf:
        return min_len

    return 0

def findMaxLenSubArray(nums1, nums2):
    max_len = 0
    len1 = len(nums1)
    len2 = len(nums2)

    for i in range(len1 + len2 - 1):
        start1 = max(0, len1 - i - 1)
        start2 = max(0, i - (len1 - 1))
        curr_cons = 0

        while start1 < len1 and start2 < len2:
            if nums1[start1] == nums2[start2]:
                curr_cons += 1
                max_len = max(max_len, curr_cons)
            else:
                curr_cons = 0

            start1 += 1
            start2 += 1

    return max_len

def getLenOfLongestSubstringWithRepeatedChars(str):
    if len(str) == 1:
        return 1

    max_sub_len = 1
    prev_char = str[0]
    cons_chars = 1

    for curr_char in str[1:]:
        if prev_char == curr_char:
            cons_chars += 1
        else:
            cons_chars = 1

        max_sub_len = max(max_sub_len, cons_chars)
        prev_char = curr_char

    return max_sub_len

def getLenOfLongestSubstringWithAtLeastKRepeatedChars(s, k):
    if k == 1:
        return len(s)
    elif len(s) == 1 and k > 1:
        return 0
    elif len(s) == 2 and 0 < k <= 2:
        return 2

    sub_map = set()
    max_sub_len = 0

    for start in range(len(s)):
        count_map = {k: 0 for k in 'abcdefghijklmnopqrstuvwxyz'}

        for end in range(start, len(s)):
            count_map[s[end]] = count_map[s[end]] + 1
            sub_str = s[start:end + 1]
            if sub_str not in sub_map:
                if doesSubStrMeetKCriteria(k, count_map):
                    max_sub_len = max(max_sub_len, len(sub_str))
                sub_map.add(sub_str)

    return max_sub_len

def doesSubStrMeetKCriteria(k, count_map):
    meets_k_count = 0
    letter_count = 0

    for freq in count_map.values():
        if freq > 0:
            letter_count += 1

        if freq >= k:
            meets_k_count += 1

        if meets_k_count != letter_count:
            return False

    return True

# input is a sorted array that removes duplicates in-place and returns new array length
def removeDuplicates(nums):
    if len(nums) == 0:
        return 0
    elif len(nums) == 1:
        return 1

    start_index = 0  # also acts as a unique found counter

    for i in range(1, len(nums)):
        if nums[start_index] != nums[i]:
            start_index += 1
            nums[start_index] = nums[i]

    return start_index + 1

# input is a sorted array that removes duplicates in-place that appeared more than two times and returns new array length
# [1,1,1,2,2,3]
def removeDuplicates2(nums):
    if len(nums) == 0:
        return 0
    elif len(nums) == 1:
        return 1

    start_index = 0  # also acts as a unique found counter
    num_dups_found = 0
    i = 1

    for j in range(2, len(nums)):
        if nums[i - 1] != nums[j]:
            nums[i + 1] = nums[j]
            i += 1

    return i + 1

def mergeSortedArray(nums1, m, nums2, n):
    while m > 0 and n > 0:
        if nums1[m - 1] >= nums2[n - 1]:
            nums1[m + n - 1] = nums1[m - 1]
            m -= 1
        else:
            nums1[m + n - 1] = nums2[n - 1]
            n -= 1
    if n > 0:
        nums1[:n] = nums2[:n]

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def mergeTwoSortedLinkedLists(l1, l2):
    newNodeStart = None
    newNodeCurr = None

    while l1 and l2:
        if l1.val <= l2.val:
            if newNodeStart is None:
                newNodeStart = ListNode(l1.val)
                newNodeCurr = newNodeStart
            else:
                newNodeCurr.next = ListNode(l1.val)
                newNodeCurr = newNodeCurr.next

            l1 = l1.next
        else:
            if newNodeStart is None:
                newNodeStart = ListNode(l2.val)
                newNodeCurr = newNodeStart
            else:
                newNodeCurr.next = ListNode(l2.val)
                newNodeCurr = newNodeCurr.next

            l2 = l2.next

    if newNodeStart:
        if l1 is None and l2:
            newNodeCurr.next = l2
        elif l1 and l2 is None:
            newNodeCurr.next = l1
    elif l1:
        newNodeStart = l1
    else:
        newNodeStart = l2

    return newNodeStart

def shiftingLetters(s: str, shifts: List[int]):
    char_arr = list(s)
    sum_shifts = 0

    for char_index in reversed(range(len(char_arr))):
        sum_shifts += shifts[char_index]
        char_pos_in_alphabet = ord(s[char_index]) - ord('a')
        num_shifts = sum_shifts % 26

        new_pos = char_pos_in_alphabet + num_shifts

        if new_pos > 25:
            new_pos = new_pos - 26

        new_char = chr(ord('a') + new_pos)
        char_arr[char_index] = new_char

    s = ''.join(char_arr)
    return s

# l1 = ListNode(1, ListNode(2, ListNode(4, None)))
# l2 = ListNode(1, ListNode(3, ListNode(4, None)))
# mergeTwoSortedLinkedLists(l1, l2)


"""
Author: Hayle
Description: Preprocess some stuff idk
I put EFFORT in but guess we will j b sheeple who use tutorials
"""
import nltk
import heapq
import matplotlib.pyplot as plt
import matplotlib.cm as c
import os
import math
from nltk.stem import WordNetLemmatizer
import re
from nltk.corpus import stopwords
from wordcloud import WordCloud
import json
import zlib
import base64
import pickle

ZIPJSON_KEY = 'base64(zip(o))'

def json_zip(j, fp):
    j = {
        ZIPJSON_KEY: base64.b64encode(
            zlib.compress(
                json.dump((j).encode('utf-8'), fp)
            )
        ).decode('ascii')
    }

    return j

NUMBER_OF_WORDS = 200
PATH_TO_NEWS_GROUP = 'C:\\Users\\Zacha\\Desktop\\20_newsgroups'

class TotalCorp(object):
    def __init__(self, path_to_news_group=PATH_TO_NEWS_GROUP, folder_name='alt.atheism', b='51060', lemma=False):
        self.p = path_to_news_group
        self.folder = folder_name
        self.corpus = []
        self.word_freq_dict = {}
        self.lemmatizer = WordNetLemmatizer()
        self.lemma = lemma
        self.tokenizer = nltk.tokenize.RegexpTokenizer(r'\w+')  # drops everything except alphanumeric characters
        self.total_words = 0
        self.break_at = b
        self.word_dict = {}

    def create_corp(self):
        total_documents = len(os.listdir(os.path.join(self.p, self.folder)))
        for idx, f in enumerate(os.listdir(os.path.join(self.p, self.folder))):
            print("{}_{}".format(idx, total_documents))
            a = open(os.path.join(self.p, self.folder, f), 'r')
            self.corpus = self.corpus + (nltk.sent_tokenize(a.read()))
            self.word_freq_dict[f] = {}
            self.word_dict[f] = []
            self.word_freq_dict[f]['frequencies'], self.word_freq_dict[f]['total_words'], self.word_freq_dict[
                f]['comma_seperated_words'], self.word_freq_dict[f]['sentence_vectors'] = self.find_frequency()
            # _, _, _, self.word_freq_dict[f]['sentence)vectors'] = self.find_frequency()
            if str(f) == self.break_at:  # it takes a really long time to run so I j did this
                break

    def save(self):
        print("SAVING CORP")
        if self.lemma:
            pickle.dump(self.word_freq_dict, open("{}_{}.p".format("NO_LEMMA", self.folder), "wb"))
        else:
            pickle.dump(self.word_freq_dict, open("{}_{}.p".format("NO_LEMMA", self.folder), "wb"))

    def find_frequency(self):
        freq_dict = {}
        word_dict = []
        total_words = 0
        sentence_vecs = []
        for idx, cor in enumerate(self.corpus):
            self.corpus[idx] = cor.lower().replace("_", "")
            tokens = self.tokenizer.tokenize(self.corpus[idx])
            tokens = [re.sub('\S*@\S*\s?', '', sent) for sent in tokens]
            tokens = [re.sub('\s+', ' ', sent) for sent in tokens]
            tokens = [re.sub("\'", "", sent) for sent in tokens]

            if self.lemma:
                stop_words = set(stopwords.words('english'))
                tokens = [w for w in tokens if not w in stop_words]
            tokens_ = []
            for token in tokens:
                if self.lemma:
                    token = self.lemmatizer.lemmatize(token)

                if token not in freq_dict.keys():
                    freq_dict[token] = 1
                else:
                    freq_dict[token] += 1
                total_words += 1
                word_dict.append(token)
                tokens_.append(token)
            sentence_vecs.append(tokens_)

        # print("example of processed token:{}".format(tokens))  # prints example of word tokens can be taken out later
        return freq_dict, total_words, word_dict, sentence_vecs

class BagOfWords(object):
    def __init__(self, corpus, word_freq_dict, words=NUMBER_OF_WORDS):
        self.words = words
        self.corpus = corpus
        self.wordfreq = word_freq_dict
        self.sentence_vecs = []
        self.tokenizer = nltk.tokenize.RegexpTokenizer(r'\w+')  # drops everything except alphanumeric characters

    def create_sentence_vectors(self):
        if self.wordfreq == {}:
            raise ValueError("Create the frequency dictionary in the corpus class pls")
        most_freq = heapq.nlargest(NUMBER_OF_WORDS, self.wordfreq, key=self.wordfreq.get)

        for sentence in self.corpus:
            sentence_tokens = self.tokenizer.tokenize(sentence)
            sent_vec = []
            for token in most_freq:
                if token in sentence_tokens:
                    sent_vec.append(1)
                else:
                    sent_vec.append(0)
            self.sentence_vecs.append(sent_vec)

    def plot_vectors(self, c_map='jet'):
        """this is hella ugly i will try to make it better eventually lol """
        cmap = getattr(c, c_map)
        plt.imshow(self.sentence_vecs, cmap=cmap)
        plt.show()

class TFIDF(object):
    def __init__(self, corpus, wordfreq):
        self.corpus = corpus
        self.wordfreq = wordfreq
        self.tf_scores = {}
        self.tfidf_scores = {}
        self.word_instances = {}

    def compute_tf(self):
        """Frequency of term in doc/ total number of terms in the doc"""
        for k in self.wordfreq.keys():
            self.tf_scores[k] = {}
            for k2 in self.wordfreq[k]['frequencies'].keys():  # k2 = word name

                word_count = self.wordfreq[k]['frequencies'][k2]
                self.tf_scores[k][k2] = word_count / self.wordfreq[k]['total_words']

    def compute_tfidf(self):
        """ln(total number of docs/ number of docs with term in it) """
        self.compute_tf()
        total_docs = len(self.wordfreq.keys())
        for k in self.wordfreq.keys():
            self.tfidf_scores[k] = {}
            for k2 in self.wordfreq[k]['frequencies'].keys():
                if k2 in self.word_instances.keys():
                    self.tfidf_scores[k][k2] = self.tf_scores[k][k2] * math.log(total_docs / self.word_instances[k2])
                else:
                    self.tfidf_scores[k][k2] = self.tf_scores[k][k2] * math.log(
                        total_docs / self.find_total_occurrences(k2))

    def find_total_occurrences(self, word):
        instance = 0
        for k in self.wordfreq.keys():
            if word in self.wordfreq[k]['frequencies'].keys():
                instance += 1

        self.word_instances[word] = instance
        return instance

aethism = TotalCorp()
aethism.create_corp()

# bag_aethism = BagOfWords(aethism.corpus, aethism.word_freq_dict['comma_seperated_words'])
# bag_aethism.create_sentence_vectors()
"""
for c in os.listdir(PATH_TO_NEWS_GROUP):
    print(c)
    corp = TotalCorp(lemma=False, folder_name=c, b='')
    corp.create_corp()
    corp.save()

wordcloud = WordCloud()
wordcloud.generate_from_frequencies(aethism.word_freq_dict['51060']['frequencies'])
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
bag_aethism = BagOfWords(aethism.corpus, aethism.word_freq_dict['51060']['frequencies'])
bag_aethism.create_sentence_vectors()

TFIDF_aethism = TFIDF(aethism.corpus, aethism.word_freq_dict)
TFIDF_aethism.compute_tfidf()
"""


from utils import console, get_input, submit

cnt = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

def part1(inp):
    res = 0
    for i in inp:
        ln = len(i) // 2
        c = set(i[:ln]).intersection(set(i[ln:])).pop()
        res += cnt.index(c)
    return res

def part2(inp):
    res = 0
    for i in range(0, len(inp), 3):
        c = (
            set(inp[i])
            .intersection(set(inp[i + 1]))
            .intersection(set(inp[i + 2]))
            .pop()
        )
        res += cnt.index(c)
    return res

assert (
    part1(
        """vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw""".splitlines()
    )
    == 157
)
console.log(part1(get_input(2022, 3)))
submit(year=2022, day=3, level=1, answer=part1(get_input(2022, 3)))

assert (
    part2(
        """vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw""".splitlines()
    )
    == 70
)
console.log(part2(get_input(2022, 3)))
submit(year=2022, day=3, level=2, answer=part2(get_input(2022, 3)))


from itertools import (
    permutations,
    starmap,
)

from inttools.special_numbers import is_polygonal_number

def is_polygonal_representative_set(int_set, poly_reps):
    """
        If P is a set of polygonal side lengths n, a set S is called a
        P-polygonal representative set, or simply P-polygonal, if S
        consists of a different n-gonal number for every n in P, e.g.
        the set {2882, 8128, 8281} is {3,4,5}-polygonal because it
        contains the triangular number 8128, the square number 8281 and
        the pentagonal number 2882.
    """
    return any(
        (
            False not in starmap(is_polygonal_number, zip(int_set, poly_rep_perm))
            for poly_rep_perm in permutations(poly_reps)
        )
    )


# Convenience python script for generating correctly formatted
# lines of the two key tables in the main static file
# Dashed off by Dylan Morris in July 2016

# Feel free to use, modify, and improve!

import datetime as dt
import pytz as tz

def suffix(natural_number):
        if (natural_number % 100) in [11, 12, 13]:
            suffix = "th"
        elif (natural_number % 10) == 1:
            suffix = "st"
        elif (natural_number % 10) == 2:
            suffix = "nd"
        elif (natural_number % 10) == 3:
            suffix = "rd"
        else:
            suffix = "th"
        return suffix

the_timezone = tz.timezone("US/Eastern")
start_date = dt.datetime(2016, 9, 7, 12, 30, 0)

the_date = the_timezone.localize(start_date)

schedule_string = """
<time datetime="{1}">{2}{3} – 12:30pm</time>	Available
"""

for k in range(18):
    print(schedule_string.format(
        the_date.strftime("%Y-%m-%d"),
        the_date.isoformat(),
        the_date.strftime("%a. %B %-d"),
        suffix(the_date.day)))
    the_date += dt.timedelta(7)

title_abs_string = """
<time datetime="{1}">{2}{3} – 12:30pm</time>

Speaking slot available

Back to schedule
"""

the_date = the_timezone.localize(start_date)
for k in range(18):
    print(title_abs_string.format(
              the_date.strftime("%Y-%m-%d"),
              the_date.isoformat(),
              the_date.strftime("%a. %B %-d"),
              suffix(the_date.day)))
    the_date += dt.timedelta(7)


#-*- encoding: utf-8 -*-. -

import cv2

def make_thumbnail(file_name):
    video_dir = "/home/taehyeon/capstone-2021-23/mysite/notification/video/"
    thumbnail_dir = "/home/taehyeon/capstone-2021-23/mysite/notification/thumbnail/"

    cap = cv2.VideoCapture(video_dir + file_name)
    count = 0

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

        if not ret:
            print("can not read video")

        if count > 50:
            cv2.imwrite(f"{thumbnail_dir + file_name.split('.')[0]}.jpg", frame)
            break

        count += 1

    return f"{file_name.split('.')[0]}.jpg"

# if __name__ == "__main__":
#     make_thumbnail("stop.mp4")


import sqlite3
from django.shortcuts import render
from raterprojectapi.models import Review
from raterprojectreports.views import Connection

def topreviewers_count(request):
    if request.method == 'GET':
        # Connect to project database
        with sqlite3.connect(Connection.db_path) as conn:
            conn.row_factory = sqlite3.Row
            db_cursor = conn.cursor()

            # Query for all games, with related rating info.
            db_cursor.execute("""
                  SELECT COUNT(u.username) as count, u.username
                  FROM raterprojectapi_review r
                  JOIN raterprojectapi_game g ON r.game_id = g.id
                  JOIN raterprojectapi_player p ON r.player_id = p.id
                  JOIN auth_user u ON p.user_id = u.id
                  GROUP BY player_id
                  ORDER BY COUNT(u.username) DESC
                  LIMIT 3
            """)

            dataset = db_cursor.fetchall()

            top_reviewers = []

            for row in dataset:
                review = Review()
                review.username = row["username"]
                review.count = row["count"]

                top_reviewers.append(review)

        # Specify the Django template and provide data context
        template = 'reviews/top_reviewers.html'
        context = {
            'topreviewers_count': top_reviewers
        }

        return render(request, template, context)


import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("startup_cleaned.csv")

df['date'] = pd.to_datetime(df['date'],errors='coerce')
df['year'] = df['date'].dt.year

# extracting month from date column
df['month'] = df['date'].dt.month

st.set_page_config(layout='wide')

def load_overall_analysis():

    st.title("Overall Analysis")
    col1,col2,col3,col4 = st.columns(4)

    with col1:
        # Total Investment
        total = round(df['amount'].sum())
        st.metric('Total (in Cr)', total )
    with col2:
        # Highest Investment
        max = df.groupby('startup')['amount'].max().sort_values(ascending = False).head(1)
        st.metric('Max (in Cr)', max.values[0] , max.index[0])
    with col3:
        # Avg funding
        avg_funding = round(df.groupby('startup')['amount'].sum().mean())
        st.metric("Avg Funding(in Cr)",avg_funding)
    with col4:
        # No. of startups funded
        n_startups = df['startup'].nunique()
        st.metric("Total Startups",n_startups)

    # month on month graphs
    st.subheader('Month on Month Graph')
    mom_bnt = st.selectbox('Select Type',['Total','Count'])

    #Total no.of startups by month on month
    if mom_bnt == 'Total':
        temp_df = df.groupby(['year','month'])['amount'].sum().reset_index()
    else:
        temp_df = df.groupby(['year','month'])['amount'].count().reset_index()

    temp_df['x_axis'] = temp_df['month'].astype('str') + '-' + temp_df['year'].astype('str')

    fig , ax = plt.subplots(figsize=(10,5))
    ax.plot(temp_df['x_axis'],temp_df['amount'])
    ax.set_xlabel('Year')
    #ax.set_ylabel('Total No. of Startups')
    st.pyplot(fig)

def load_inverstor_details(investor):
    st.title(investor)
    # loading the Top 5 recent investments
    st.subheader('Most Recent Investments')
    top5_df = df[df['Investors'].str.contains(investor)].head()[['date','startup','vertical','City  Location','round','amount']]
    st.dataframe(top5_df)

    col1 , col2 = st.columns(2)
    with col1:
        # loading the Biggest investments
        st.subheader('Biggest Investments')
        big_df = df[df['Investors'].str.contains(investor)].groupby('startup')['amount'].sum().sort_values(ascending = False).head()

        fig , ax = plt.subplots(figsize=(5,4))
        plot = ax.bar(big_df.index,big_df.values)
        ax.set_xlabel('StartUps')
        ax.set_ylabel('Amount (Cr)')
        ax.bar_label(plot,big_df.values)
        st.pyplot(fig)

    with col2:
        st.subheader('Sectors Invested in')
        vertical_series = df[df['Investors'].str.contains(investor)].groupby('vertical')['amount'].sum()

        fig1 , ax1 = plt.subplots(figsize=(3,5))
        plot = ax1.pie(vertical_series,labels=vertical_series.index,autopct='%0.01f%%')
        st.pyplot(fig1)

    col1 , col2 = st.columns(2)
    with col1:

        st.subheader('City')
        city_series = df[df['Investors'].str.contains(investor)].groupby('City  Location')['amount'].sum()

        fig2 , ax2 = plt.subplots(figsize=(3,5))
        plot = ax2.pie(city_series,labels=city_series.index,autopct='%0.01f%%')
        st.pyplot(fig2)

    with col2:
        st.subheader('Stage')
        stage_series = df[df['Investors'].str.contains(investor)].groupby('round')['amount'].sum()

        fig3 , ax3 = plt.subplots(figsize=(3,5))
        plot = ax3.pie(stage_series,labels=stage_series.index,autopct='%0.01f%%')
        st.pyplot(fig3)

    # Year on Year line Plot

    st.subheader('Year on Year Investments')
    yoy_df = df[df['Investors'].str.contains(investor)].groupby('year')['amount'].sum()

    fig4 , ax4 = plt.subplots(figsize=(10,5))
    plot = ax4.plot(yoy_df.index,yoy_df.values)
    ax4.set_xlabel('Year')
    ax4.set_ylabel('Amount (Cr)')

    st.pyplot(fig4)

st.sidebar.title('Startup Funding Analysis')

option = st.sidebar.selectbox('Select One',['Overall Analysis','StartUp','Investor'])

if option == 'Overall Analysis':
    load_overall_analysis()

elif option == 'StartUp':
    st.sidebar.selectbox('Select StartUp',sorted(df["startup"].unique().tolist()))
    st.title("StartUp Analysis")
    btn1 = st.sidebar.button("Find StartUp Details")

else:
    seleted_investor = st.sidebar.selectbox('Select Investor',sorted(set(df["Investors"].str.split(',').sum())))
    st.title("Inveator Analysis")
    btn2 = st.sidebar.button("Find Investor Details")
    if btn2:
        load_inverstor_details(seleted_investor)


import json
from compensation_info import CompensationInfo

survey_2_field_mapper = {
    'salary': 'Total Base Salary in 2018 (in USD)',
    'employment_type': 'Employment Type',
    'vacation_weeks': 'Annual Vacation (in Weeks)',
    'company': 'Company Name',
    'job_title': 'Job Title In Company'
}

def get_data(file_path):
    """Reads JSON file from path and returns Python object"""

    with open(file_path) as f:
        data = json.load(f)

    return data

def get_normalized_records(file_path = 'salary_survey-2.json'):
    """Normalizes field names from list of dicts into friendly/consistent field names"""
    survey_2_data = get_data(file_path)

    records = [
        { k : x[survey_2_field_mapper[k]] for k in survey_2_field_mapper }
        for x in survey_2_data
    ]

    return records

def get_records(request_args):
    """Gets records that match the request arguments.

    Args:
        request_args (ImmutableMultiDict): Request query params for specifying data to return.
        data_file_path (str): Optional; The relative path to the JSON data file.

    Returns:
        list: List of records as dicts.
    """

    records = get_normalized_records()

    sort_field = request_args.get('sort')
    limit = request_args.get('limit')

    records = filter_by(request_args, records)
    if sort_field is not None:
        records = sort_by(sort_field, records)
    if limit is not None:
        records = limit_by(limit, records)

    return records

def get_record(id):
    """Returns dict from list by its index"""
    records = get_normalized_records()
    try:
        return records[id]
    except IndexError:
        return None

def get_gte(records, field, requested_value):
    """Returns list of records with field value greater than or equal to field and value requested"""

    return [x for x in records if float(x[field]) >= int(requested_value)]

def get_match(records, field, requested_value):
    """Returns list of records that match the field and value requested"""

    return [x for x in records if x[field].lower() == requested_value.lower()]

def filter_by(filter_args, records):
    """Returns list of records matching requested filter arguments"""

    for k, v in filter_args.items():
        if k[-5:] == '[gte]':
            records = get_gte(records, k[:-5], v)
        elif k in survey_2_field_mapper.keys():
            records = get_match(records, k, v)

    return records

def sort_by(field, records):
    return sorted(records, key=lambda k: k[field])

def limit_by(limit, records):
    return records[:int(limit)]

def validate_request_args(request_args):
    """Validates field and value of request arguments.

    Args:
        request_args (ImmutableMultiDict): Request query params.

    Returns:
        None

    Raises:
        ValueError: Unknown field, or invalid value, or invalid value type was provided.
    """

    sort_field = request_args.get('sort')
    valid_fields = survey_2_field_mapper.keys()
    if sort_field is not None and sort_field not in valid_fields:
        raise ValueError(f'Invalid sort argument: "{sort_field}". Must be one of: {list(valid_fields)}')

    integer_type_fields = ['limit', 'salary', 'salary[gte]', 'vacation_weeks']
    for arg in integer_type_fields:
        val = request_args.get(arg)
        if val is not None:
            try:
                int(val)
            except:
                raise ValueError(f'Invalid value passed for "{arg}": "{val}" must be an integer.')


import os
import sys
import json
import pickle
import numpy as np

from src.attributers.attributer import Attributer
from src import exptutil

import warnings
warnings.filterwarnings("ignore")

nominal_gamma = 1e-2
seed = 1234

dataname, num_anom, modeltype, scoretype, attrtype = \
    sys.argv[1], int(sys.argv[2]), sys.argv[3], sys.argv[4], sys.argv[5]

if len(sys.argv) > 6:
    if attrtype not in ['comp', 'ASH', 'ASHexact']:
        raise ValueError('setting gamma for this attrtype does not make sense')
    gamma = float(sys.argv[6])
else:
    gamma = nominal_gamma

if (modeltype=='dagmm' or (modeltype=='vae' and scoretype=='negelbo')) \
    and (attrtype=='marg' or attrtype=='SFE'):
    raise ValueError('incompatible pair of detector and attributor')

if gamma==nominal_gamma:
    print('start %s na%d_%s_%s_%s' % (dataname, num_anom, modeltype, scoretype, attrtype))
else:
    print('start %s na%d_%s_%s_%s_%0.1e' % (dataname, num_anom, modeltype, scoretype, attrtype, gamma))

datadir = os.path.join('data', 'processed', dataname)

# load data
data_train, _, data_test = exptutil.load_data(datadir)
dim_x = data_test.shape[1]

# use only normal part (first half) of test data
data_test = data_test[:int(data_test.shape[0]/2)]

# load best model
with open(os.path.join('models', dataname, modeltype, 'detection', 'best_model.json'), 'r') as fp:
    best_model = json.load(fp)
model = exptutil.load_model(best_model[scoretype], modeltype)

# some settings
if dataname=='lympho':
    num_cases = 6
    num_tries = 20
else:
    num_cases = 60
    num_tries = 2
ub = 2.0
lb = 1.0

# create perturbed data
np.random.seed(seed)
case_indices = np.random.permutation(data_test.shape[0])
case_all = []
feat_all = []
target_all = []
for i in range(num_cases):
    for j in range(num_tries):
        case_all.append(case_indices[i])

        # target features
        feat_indices = np.random.permutation(data_test.shape[1])
        target_feat = feat_indices[:num_anom]

        # perturb values
        target = np.copy(data_test[case_indices[i]])
        for idx in target_feat:
            if dataname=='lympho':
                target[idx] = 1-target[idx]
            else:
                sign=[-1,1]; sign = sign[np.random.choice(2)]
                perturbation = sign*(np.random.rand()*(ub-lb)+lb)
                target[idx] += perturbation

        feat_all.append(target_feat)
        target_all.append(target)

# set attributer
if modeltype=='gmm':
    detector_type = 'GMM'
elif modeltype=='vae' and scoretype=='recerr':
    detector_type='VAE-r'
elif modeltype=='vae' and scoretype=='negelbo':
    detector_type='VAE-e'
elif modeltype=='dagmm':
    detector_type='DAGMM'
else:
    raise ValueError('unknown model/score type')
AT = Attributer(detector_type, model, data_train, False if dataname=='lympho' else True)

# do attribution
np.random.seed(seed+1)
attr_all = []
info_all = []
for i in range(len(target_all)):
    attr, info = AT.attribute(target_all[i], attrtype, gamma=gamma)
    attr_all.append(attr)
    info_all.append(info)
    # print('\r  attributed #%03d/%d' % (i+1, len(target_all)), end='')

# save
outdir = os.path.join('out', 'expt_synth', dataname)
os.makedirs(outdir, exist_ok=True)
if gamma==nominal_gamma:
    outname = os.path.join(outdir, 'na%d_%s_%s_%s.pickle' % (num_anom, modeltype, scoretype, attrtype))
else:
    outname = os.path.join(outdir, 'na%d_%s_%s_%s_%0.1e.pickle' % (num_anom, modeltype, scoretype, attrtype, gamma))
with open(outname, 'wb') as fp:
    pickle.dump([attr_all, info_all, case_all, feat_all], fp)

if gamma==nominal_gamma:
    print('finish %s na%d_%s_%s_%s' % (dataname, num_anom, modeltype, scoretype, attrtype))
else:
    print('finish %s na%d_%s_%s_%s_%0.1e' % (dataname, num_anom, modeltype, scoretype, attrtype, gamma))


import time
import cv2
import imutils
from imutils.video import VideoStream
from img_aux import filter_colour, track_ball, draw_frame
import paho.mqtt.client as mqtt

MQTT_BROKER = "192.168.0.117"
MQTT_PORT = 1883
MQTT_KEEPALIVE_INTERVAL = 6000

command_motor_direction = "objectFinderBot/motor/command/direction"
command_motor_speed = "objectFinderBot/motor/command/speed"

def get_broadrcaster():
    global broadrcaster
    broadrcaster = mqtt.Client()
    print("connecting with the server")
    broadrcaster.connect(MQTT_BROKER, MQTT_PORT, MQTT_KEEPALIVE_INTERVAL)
    print("Server connected")
    return broadrcaster

def module_img_ai(title, camera, ifImg):
    videoStream = cv2.VideoCapture('http://192.168.0.117:8081')
    print("PLEASE WAIT WHILE MODULE INITIALIZE THE CAMERA MODILE")
    time.sleep(2.0)
    global broadrcaster, command_motor_direction, command_motor_speed
    broadrcaster = get_broadrcaster()
    while True:
        _, frame = videoStream.read()
        blurred = cv2.GaussianBlur(frame, (11, 11), 0)
        hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)

        mask = filter_colour(frame)
        location, _ = track_ball(mask)
        frame = draw_frame(mask, frame)
        x, y, w, h = location
        if(x >= 1):
            if(x <= 200):
                print("left movement x")
                broadrcaster.publish(command_motor_direction, 1)
        if(x >= 401):
            if(x <= 600):
                print("right movement x")
                broadrcaster.publish(command_motor_direction, 3)
        if(x >= 201):
            if(x <= 400):
                print("forworad movment")
                broadrcaster.publish(command_motor_direction, 0)
        if(x == 0):
            print("object not found")
            broadrcaster.publish(command_motor_direction, 4)
        if ifImg:
            cv2.imshow(title, frame)
            # cv2.imshow("maskFrame", hsv)
            key = cv2.waitKey(1) & 0xFF
            if key == ord("q"):
                break
    videoStream.stop()
    cv2.destroyAllWindows()
    return

module_img_ai("module_img_ai", 0, True)


import torch
import torchvision.transforms as transforms
from torchvision.datasets import ImageFolder,\
    CIFAR10, \
    CIFAR100, \
    MNIST
from torch.utils.data import DataLoader, random_split, Subset, ConcatDataset
import numpy as np
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
from custom_archs import wfmodels_lora as wfmodels

unl_class = 0
total_images_number = 5000
dataset = 'cifar10'
model_name = 'vit_tiny'

if 'cifar10' in dataset:
    if 'tiny' in model_name:
        ours_ckp = f"/mnt/beegfs/work/dnai_explainability/unlearning/icml2023/alpha_matrices/checkpoints_acm/cifar10-vit_tiny_16224-1-1-0/2023-04-28/0.1-100/best_CLASS-{unl_class}.pt"
        loss_diff_ckp = f"/mnt/beegfs/work/dnai_explainability/unlearning/icml2023/alpha_matrices/checkpoints_acm/cifar10-vit_tiny_16224-1-1-0/2023-04-28/0.1-100/best_CLASS-{unl_class}.pt"
        gold_ckp = f"/mnt/beegfs/work/dnai_explainability/ssarto/checkpoints_gold/CIFAR10/vit_tiny/cifar10_vit_tiny-4-ckpt_original_{unl_class}.t7"
    else:
        ours_ckp = f"/mnt/beegfs/work/dnai_explainability/unlearning/icml2023/alpha_matrices/checkpoints_acm/cifar10-vit_small_16224-1-1-0/2023-04-28/0.1-100/best_CLASS-{unl_class}.pt"
        loss_diff_ckp = f"/mnt/beegfs/work/dnai_explainability/lbaraldi/alpha_matrices/vit_small_neggrad_64_0.0001_1.0_0.01/2023-04-30/cifar10/difference/1.0-0.01/best_CLASS-{unl_class}.pt"
        # gold_ckp = f"/mnt/beegfs/work/dnai_explainability/ssarto/checkpoints_gold/CIFAR10/vit_tiny/cifar10_vit_tiny-4-ckpt_original_{unl_class}.t7"
    c_number = 10
else:
    if 'tiny' in model_name:
        ours_ckp = f"/mnt/beegfs/work/dnai_explainability/lbaraldi/unlearning/icml2023/alpha_matrices/checkpoints_acm/vit_tiny_16224_lora_zero_3way_fixed_l1_AB_256_0.01_0.001_1.0/2023-05-03/0.001-1.0/best_CLASS-{unl_class}.pt"
        loss_diff_ckp = f"/mnt/beegfs/work/dnai_explainability/lbaraldi/unlearning/icml2023/alpha_matrices/checkpoints_acm/vit_tiny_16224_neggrad_256_0.0001_1.0_0.005/2023-05-03/1.0-0.005/best_CLASS-{unl_class}.pt"
        gold_ckp = f"/mnt/beegfs/work/dnai_explainability/ssarto/checkpoints_gold/CIFAR10/vit_tiny/cifar10_vit_tiny-4-ckpt_original_{unl_class}.t7"
    else:
        ...
    c_number = 20

# Define the PyTorch model

if model_name == 'vit_tiny':
    kind = wfmodels.vit_tiny_16224
else:
    kind = wfmodels.vit_small_16224

model = wfmodels.WFTransformer(
    kind=kind, pretrained=True,
    resume=ours_ckp,
    dataset=dataset.lower(), alpha=False
)
model = model.arch

if 'cifar10' in dataset and 'tiny' in model_name:
    loss_diff_ckp = \
        f"/mnt/beegfs/work/dnai_explainability/unlearning/icml2023/alpha_matrices/checkpoints_acm/debug_instance_prod_64_5e-05_2.5e-05_1.0/2023-05-02/2.5e-05-1.0/best_CLASS-0.pt"
ldiff = wfmodels.WFTransformer(
    kind=kind, pretrained=True,
    resume=loss_diff_ckp,
    dataset=dataset.lower(), alpha=False
)
ldiff = ldiff.arch

general = wfmodels.WFTransformer(
    kind=kind, pretrained=False,
    resume=None,
    dataset=dataset.lower(), alpha=False
)
standard = general.arch

# gold = wfmodels.WFTransformer(
#     kind=wfmodels.vit_tiny_16224, pretrained=True,
#     resume=gold_ckp,
#     dataset=dataset.lower(), alpha=False
# )
# gold = gold.arch

if 'cifar10' in dataset:
    size = 32
    T = transforms.Compose([
        transforms.RandomCrop(32, padding=4),
        transforms.Resize(size),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
    ])
    inverse_transform = transforms.Compose([
        transforms.Normalize((-0.4914/0.2023, -0.4822/0.1994, -0.4465/0.2010), (1/0.2023, 1/0.1994, 1/0.2010)),
    ])

    transform_test = transforms.Compose([
        transforms.Resize(size),
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
    ])

    _train = CIFAR10(
        root='/work/dnai_explainability/unlearning/datasets/cifar10_classification/train',
        transform=T, download=True, train=True
    )

    _val = CIFAR10(
        root='/work/dnai_explainability/unlearning/datasets/cifar10_classification/val',
        transform=transform_test, download=True, train=False
    )

    unlearning_ids = np.where(np.isin(np.array(
        _val.targets
        ), unl_class))[0]
    unlearning_set = Subset(_val, unlearning_ids)
    unlearning_set.targets = torch.Tensor(_val.targets).long()[unlearning_ids].tolist()

    retaining_ids = np.where(~np.isin(np.array(
        _val.targets
        ), unl_class))[0]
    retaining_set = Subset(_val, retaining_ids)
    retaining_set.targets = torch.Tensor(_val.targets).long()[retaining_ids].tolist()

    # Define the data loader
    unlearning_loader = DataLoader(unlearning_set, batch_size=256, shuffle=True)
    unlearning_loader_iter = iter(unlearning_loader)
    c_number = 10

elif 'cifar20' in dataset.lower():

        class_mapping_dict = \
                {0: 4,
                1: 1,
                2: 14,
                3: 8,
                4: 0,
                5: 6,
                6: 7,
                7: 7,
                8: 18,
                9: 3,
                10: 3,
                11: 14,
                12: 9,
                13: 18,
                14: 7,
                15: 11,
                16: 3,
                17: 9,
                18: 7,
                19: 11,
                20: 6,
                21: 11,
                22: 5,
                23: 10,
                24: 7,
                25: 6,
                26: 13,
                27: 15,
                28: 3,
                29: 15,
                30: 0,
                31: 11,
                32: 1,
                33: 10,
                34: 12,
                35: 14,
                36: 16,
                37: 9,
                38: 11,
                39: 5,
                40: 5,
                41: 19,
                42: 8,
                43: 8,
                44: 15,
                45: 13,
                46: 14,
                47: 17,
                48: 18,
                49: 10,
                50: 16,
                51: 4,
                52: 17,
                53: 4,
                54: 2,
                55: 0,
                56: 17,
                57: 4,
                58: 18,
                59: 17,
                60: 10,
                61: 3,
                62: 2,
                63: 12,
                64: 12,
                65: 16,
                66: 12,
                67: 1,
                68: 9,
                69: 19,
                70: 2,
                71: 10,
                72: 0,
                73: 1,
                74: 16,
                75: 12,
                76: 9,
                77: 13,
                78: 15,
                79: 13,
                80: 16,
                81: 19,
                82: 2,
                83: 4,
                84: 6,
                85: 19,
                86: 5,
                87: 5,
                88: 8,
                89: 19,
                90: 18,
                91: 1,
                92: 2,
                93: 15,
                94: 6,
                95: 0,
                96: 17,
                97: 8,
                98: 14,
                99: 13
                }

        class CIFAR20(CIFAR100):

            def __init__(self, root, c_to_del=[], train=True, transform=None, target_transform=None, download=False):
                super().__init__(root, train, transform, _cifar100_to_cifar20, download)

        def _cifar100_to_cifar20(target):
            mapping = class_mapping_dict[target]
            return mapping

        def _cifar20_from_cifar100(target):
            mapping = _cifar100_to_cifar20(target)
            demapping = [x for x,v in mapping if v==target[0]]

            return demapping

        means = (0.4914, 0.4822, 0.4465)
        stds = (0.2023, 0.1994, 0.2010)
        size = 32
        T = transforms.Compose([
            transforms.RandomCrop(32, padding=4),
            transforms.Resize(size),
            transforms.RandomHorizontalFlip(),
            transforms.ToTensor(),
            transforms.Normalize(means, stds),
        ])

        transform_test = transforms.Compose([
            transforms.Resize(size),
            transforms.ToTensor(),
            transforms.Normalize(means, stds),
        ])

        # _train = CIFAR20(
        #     root='/work/dnai_explainability/unlearning/datasets/cifar20_classification/train',
        #     transform=T, download=True, train=True
        # )

        _val = CIFAR20(
            root='/work/dnai_explainability/unlearning/datasets/cifar20_classification/val',
            transform=transform_test, download=True, train=False
        )
        c_number = 20

# whole_loader = DataLoader(Subset(_val, tuple(range(len(_val)))), batch_size=256, shuffle=True)
both = ConcatDataset((_train,_val))
both.datasets[0].targets = torch.ones(len(_train))
both.datasets[1].targets = torch.zeros(len(_val))
whole_loader = DataLoader(both, batch_size=16, shuffle=True)
# whole_loader = DataLoader(Subset(_val, tuple(range(total_images_number))), batch_size=256, shuffle=True)
# total_lenght = len(whole_loader.dataset)

# Set the model to evaluation mode
model.eval()

# Define the selected layer from which to extract activations

# Extract the activations from the selected layer
ours_act, ldiff_act, std_act, gold_act = [], [], [], []

labels = []
print('forwards')

model=model.cuda()
standard = standard.cuda()
ldiff = ldiff.cuda()

from tqdm import tqdm
# with torch.no_grad():
for inputs, targets in tqdm(whole_loader):
    inputs, targets = inputs.cuda(), targets.cuda()
    inputs.requires_grad_(True)

    outputs = model(inputs)
    ours_act.append(outputs)

    outputs = standard(inputs)
    std_act.append(outputs)

    outputs = ldiff(inputs)
    ldiff_act.append(outputs)

    # outputs = gold(inputs)
    # gold_act.append(outputs)

    labels.append(targets.detach().cpu().numpy())

ours_act = np.concatenate(ours_act, axis=0)
ldiff_act = np.concatenate(ldiff_act, axis=0)
std_act = np.concatenate(std_act, axis=0)
# gold_act = np.concatenate(gold_act, axis=0)
labels = np.concatenate(labels, axis=0)

# Apply t-SNE to the activations to obtain a lower-dimensional representation
tsne = TSNE(n_components=2, random_state=0)

ours_act = ours_act.reshape(total_lenght,-1)
ldiff_act = ldiff_act.reshape(total_lenght,-1)
std_act = std_act.reshape(total_lenght,-1)
# gold_act = gold_act.reshape(total_lenght,-1)

print('tsne')
ours_emb = tsne.fit_transform(ours_act)
ldiff_emb = tsne.fit_transform(ldiff_act)
std_emb = tsne.fit_transform(std_act)
# gold_emb = tsne.fit_transform(gold_act)

# Visualize the embedding with the labels

idx = labels == unl_class

plt.figure()
plt.scatter(ours_emb[~idx, 0], ours_emb[~idx, 1], c=labels[~idx], s=10)
plt.scatter(ours_emb[idx, 0], ours_emb[idx, 1], c='crimson', marker='X', s=10)
# plt.axis('off')
plt.xticks([])
plt.yticks([])
plt.savefig(f'tsne_ours-{unl_class}_{dataset}_{model_name}.pdf', bbox_inches='tight')

plt.figure()
plt.scatter(ldiff_emb[~idx, 0], ldiff_emb[~idx, 1], c=labels[~idx], s=10)
plt.scatter(ldiff_emb[idx, 0], ldiff_emb[idx, 1], c='crimson', marker='X', s=10)
# plt.axis('off')
plt.xticks([])
plt.yticks([])
plt.savefig(f'tsne_ldiff-{unl_class}_{dataset}_{model_name}.pdf', bbox_inches='tight')

plt.figure()
plt.scatter(std_emb[~idx, 0], std_emb[~idx, 1], c=labels[~idx], s=10)
plt.scatter(std_emb[idx, 0], std_emb[idx, 1], c='crimson', marker='X', s=10)
# plt.axis('off')
plt.xticks([])
plt.yticks([])
plt.savefig(f'tsne_std-{unl_class}_{dataset}_{model_name}.pdf', bbox_inches='tight')

# plt.figure()
# plt.scatter(gold_emb[~idx, 0], gold_emb[~idx, 1], c=labels[~idx], s=10)
# plt.scatter(gold_emb[idx, 0], gold_emb[idx, 1], c='crimson', marker='X', s=10)
# # plt.axis('off')
# plt.xticks([])
# plt.yticks([])
# plt.savefig(f'tsne_gold-{unl_class}_{dataset}.pdf', bbox_inches='tight')


import numpy as np
import scipy.io.wavfile as wio
import matplotlib.pyplot as plt
import pitch_extraction as pitch

def power_spectol(data, Fs):
    # fundamental frequency
    spectol = np.fft.fft(data, Fs)
    power_spec = np.log(np.abs(spectol))
    return power_spec

def cepstrum(data, Fs):
    power_spec = power_spectol(data, Fs)
    cepstrum = np.fft.ifft(power_spec, Fs)
    return cepstrum

def envelope(data, Fs):
    c = cepstrum(data, Fs)
    c[45:] = 0
    env = np.fft.fft(c)
    return env

# +6 dB/oct
def high_enphasis(data):
    ret = np.copy(data)
    for k in range(data.shape[0] - 1):
        ret[k+1] = data[k+1] - 0.97 * data[k]
    return ret

if __name__ == '__main__':
    def draw_envelope(filename, **kwarg):
        Fs, data = wio.read(filename)
        env = envelope(data, Fs)
        plt.plot(np.abs(env[:Fs/2]), **kwarg)
        plt.xlabel('Frequency[Hz]')
    draw_envelope('../data/wav/A_a.wav', label='A')
    draw_envelope('../data/wav/B_a.wav', label='B')
    draw_envelope('../data/wav/C_a.wav', label='C')
    plt.legend()
    plt.savefig('../data/img/envelopes.png')
    plt.show()