import pygame
import random

from variables import *
import menu

def main():
	global running, playing
	global deltaTime
	global sc_width
	global sc_height
	while running:
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				running = False
		if playing:
			# Draw
			draw()
			# Modification
			keys = pygame.key.get_pressed()
			modification(keys)
			# Update
			update()
		else:
			result = menu.main(screen, sc_width, sc_height)
			if result == 1:
				restart_everything()
			elif result == 2:
				running = False

def draw():
	global screen
	global player_1, player_2, ball
	screen.fill("black")
	#pygame.draw.rect(screen,"white",(200,150,100,50))
	pygame.draw.rect(screen, player_1.color, player_1.rect)
	pygame.draw.rect(screen, player_2.color, player_2.rect)
	pygame.draw.ellipse(screen, ball.color, ball.rect)

def modification(keys):
	global running, first_move
	global player_1, player_2
	global deltaTime

	if keys[pygame.K_ESCAPE]:
		running = False

	# Player 1
	if keys[pygame.K_w]:
		if player_1.top > 0:
			player_1.top -= player_1.velocity * deltaTime
			first_move = True
	if keys[pygame.K_s]:
		if player_1.bottom < (FIXED_HEIGHT):
			player_1.top += player_1.velocity * deltaTime
			first_move = True
	# Player 2
	if keys[pygame.K_UP]:
		if player_2.top > 0:
			player_2.top -= player_2.velocity * deltaTime
			first_move = True
	if keys[pygame.K_DOWN]:
		if player_2.bottom < (FIXED_HEIGHT):
			player_2.top += player_2.velocity * deltaTime
			first_move = True

def update():
	global sc_width, sc_height, deltaTime, playing, first_move
	global player_1, player_2, ball

	player_1.update()
	player_2.update()
	if first_move:
		ball.update()
		ball.collide_with(player_1)
		ball.collide_with(player_2)
	else:
		ball.update(movement = False)

	if ball.collide_with_the_wall != 0:
		playing = False

	sc_width, sc_height = pygame.display.get_surface().get_size()
	pygame.display.flip()
	deltaTime = clock.tick(60) / 1000

def fixW(number):
	global sc_width
	real_number = (number / FIXED_WIDTH) * sc_width
	return real_number

def fixH(number):
	global sc_height
	real_number = (number / FIXED_HEIGHT) * sc_height
	return real_number

class Base():
	def __init__(self):
		#Rect(left, top, width, height)
		self.width = 25
		self.height = 150
		self.left = 50
		self.top = (FIXED_HEIGHT - self.height) / 2
		self.rect = pygame.Rect(fixW(self.left),fixH(self.top), fixW(self.width), fixH(self.height))
		self.bottom = self.top + self.height
		self.right = self.left + self.width

		self.velocity = 500
		self.color = "white"

	def update(self):
		self.rect = pygame.Rect(fixW(self.left),fixH(self.top), fixW(self.width), fixH(self.height))
		self.bottom = self.top + self.height
		self.right = self.left + self.width
		self.centerW = (self.left + self.right) / 2
		self.centerH = (self.top + self.bottom) / 2
class Player(Base):
	pass
class Ball(Base):
	def __init__(self):
		Base.__init__(self)
		self.width = 40
		self.height = 40
		self.left = (FIXED_WIDTH - self.width) / 2
		self.top = (FIXED_HEIGHT - self.height) / 2
		self.rect = pygame.Rect(fixW(self.left),fixH(self.top), fixW(self.width), fixH(self.height))

		self.velocity = 500

		self.facing_x = random.choice([-1,1])
		self.facing_y = random.choice([-1,1])

		self.collide_with_the_wall = 0

	def update(self, movement = True):
		global deltaTime, sc_width, sc_height
		Base.update(self)
		if movement:
			self.left += self.velocity * self.facing_x * deltaTime
			self.top += self.velocity * self.facing_y * deltaTime
			if self.left <= 0 and self.facing_x == -1:
				self.facing_x = 1
				self.collide_with_the_wall = -1
			elif self.right >= FIXED_WIDTH and self.facing_x == 1:
				self.facing_x = -1
				self.collide_with_the_wall = 1
			if self.top <= 0 and self.facing_y == -1:
				self.facing_y = 1
			elif self.bottom >= FIXED_HEIGHT and self.facing_y == 1:
				self.facing_y = -1
	def collide_with(self, other):

		col_left = other.right > self.left and other.left < self.left
		col_right = other.left < self.right and other.right > self.right
		col_top = other.top < self.top and other.bottom > self.top
		col_bottom =  other.bottom > self.bottom and other.top < self.bottom
		col_centerW = other.right > self.centerW and other.left < self.centerW

		# Collide from the left
		if self.facing_x == -1 and col_left and col_top:
			self.facing_x = 1
		if self.facing_x == -1 and col_left and col_bottom:
			self.facing_x = 1

		# Collide from the right
		if self.facing_x == 1 and col_right and col_top:
			self.facing_x = -1
		if self.facing_x == 1 and col_right and col_bottom:
			self.facing_x = -1

		# Collide from the bottom
		if self.facing_y == 1 and col_bottom and col_centerW:
			self.facing_y = -1
			#doesnt make sense, but to the game
			self.facing_x *= -1

		# Collide from the top
		if self.facing_y == -1 and col_top and col_centerW:
			self.facing_y = 1
			#doesnt make sense, but to the game
			self.facing_x *= -1

clock = pygame.time.Clock()
ball = Ball()
player_1 = Player()
player_2 = Player()
player_1.left = 50
player_2.left = FIXED_WIDTH - player_2.width - 50
first_move = False
sc_width = 1366
sc_height = 720

def restart_everything():
	global playing, ball, player_1, player_2, deltaTime, first_move
	playing = True
	ball.__init__()
	player_1.__init__()
	player_2.__init__()
	player_1.left = 50
	player_2.left = FIXED_WIDTH - player_2.width - 50
	deltaTime = 0
	first_move = False

if __name__ == "__main__":
	main()


import cv2
import numpy as np

from function import to_gray

def _calc_var_in_class(binary: np.ndarray, gray: np.ndarray):
    w0 = (binary == 0).mean()
    w1 = (binary == 255).mean()

    mask = (binary == 0)
    masked_img = gray[mask]
    if len(masked_img) > 0:
        M0 = masked_img.mean()
    else:
        M0 = 0
    M1 = gray[~mask].mean()
    return w0 * w1 * (M0 - M1)**2

def threshold_search(gray: np.ndarray):
    candidates = np.arange(0, 255, 1)
    scores = []
    for th in candidates:
        binary = gray.copy()
        binary[binary >= th] = 255
        binary[binary < th] = 0

        score = _calc_var_in_class(binary, gray)
        scores.append(score)
    idx = np.argmax(scores)
    return idx

img = cv2.imread("imori.jpg")
gray = to_gray(img)
threshold = threshold_search(gray)
img2 = gray.copy()
img2[img2 < threshold] = 0
img2[img2 >= threshold] = 255

cv2.imwrite("answer_4.jpg", img2)
cv2.imshow("otsu-binary", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()


"""
Core cog for bot. Can't be unloaded. Contains commands for cog management.
"""

import math
from datetime import datetime

import disnake
from disnake.ext import commands
from disnake.message import Message

import utils
from buttons.system import Dropdown, SystemView
from cogs.base import Base
from config import cooldowns
from config.messages import Messages
from database.error import ErrorLogDB
from features.error import ErrorLogger
from features.git import Git
from permissions import permission_check

boottime = datetime.now().replace(microsecond=0)

class System(Base, commands.Cog):
    def __init__(self, bot):
        super().__init__()
        self.bot = bot
        self.error_log = ErrorLogger()
        self.git = Git()

        self.unloadable_cogs = ["system"]

    @commands.check(permission_check.is_bot_admin)
    @commands.slash_command(name="git")
    async def git(self, inter):
        pass

    @git.sub_command(name="pull", description=Messages.git_pull_brief)
    async def pull(self, inter: disnake.ApplicationCommandInteraction):
        await inter.send("Pulling...")
        message: Message = await inter.original_message()

        pull_result = await self.git.pull()
        pull_parts = utils.cut_string(pull_result, 1900)

        await message.edit(content=f"```{pull_parts[0]}```")

        for part in pull_parts[1:]:
            await inter.send(f"```{part}```")

    @commands.check(permission_check.is_bot_admin)
    @commands.slash_command(name="shutdown", description=Messages.shutdown_brief)
    async def shutdown(self, inter: disnake.ApplicationCommandInteraction):
        await inter.send("Shutting down...")
        await self.bot.close()
        exit(0)

    async def create_selects(self):
        """Slices dictionary of all cogs to chunks for select."""
        cog_files = list(utils.get_all_cogs().keys())
        cog_names = list(utils.get_all_cogs().values())
        all_selects = []

        # 25 is max number of options for one select
        chunks = math.ceil(len(cog_files)/25)
        cog_files = list(utils.split(cog_files, chunks))
        cog_names = list(utils.split(cog_names, chunks))
        for i in range(0, chunks):
            all_selects.append([cog_files[i], cog_names[i]])

        return all_selects

    @commands.check(permission_check.is_bot_admin)
    @commands.slash_command(name="cogs", description=Messages.cogs_brief, guild_ids=[Base.config.guild_id])
    async def cogs(self, inter: disnake.ApplicationCommandInteraction):
        """
        Creates embed with button and select(s) to load/unload/reload cogs.

        Max number of cogs can be 100 (4x25).
        """

        selects = await self.create_selects()
        view = SystemView(self.bot, len(selects), selects)
        embed = Dropdown.create_embed(self, inter.author.color)
        await inter.send(embed=embed, view=view)

        # pass message object to classes
        message = await inter.original_message()
        view.message = message
        for i, cogs in enumerate(selects):
            view.selects[i].msg = message

    @cooldowns.default_cooldown
    @commands.slash_command(name="uptime", description=Messages.uptime_brief)
    async def uptime(self, inter: disnake.ApplicationCommandInteraction):
        now = datetime.now().replace(microsecond=0)
        delta = now - boottime
        count = self.error_log.log_error_date(set=False)
        embed = disnake.Embed(
            title="Uptime",
            description=f"{count} days without an accident.",
            color=0xeee657,
        )
        start_streak, end_streak = ErrorLogDB.get_longest_streak()
        embed.add_field(name=Messages.upsince_title, value=str(boottime))
        embed.add_field(name=Messages.uptime_title, value=str(delta))
        embed.add_field(name=Messages.uptime_latency, value=f"{round (self.bot.latency * 1000)} ms")
        embed.add_field(
            name=Messages.longest_streak,
            value=f"**{(end_streak - start_streak).days} day(s)**\n{start_streak} — {end_streak}",
            inline=False
        )
        self.error_log.set_image(embed, self.bot.user, count)
        await inter.send(embed=embed)

    @pull.error
    @cogs.error
    async def on_command_error(self, ctx: commands.Context, error):
        if isinstance(error, commands.errors.CommandInvokeError):
            if isinstance(error.__cause__, commands.errors.ExtensionAlreadyLoaded):
                await ctx.send(Messages.cog_is_loaded(cog=error.__cause__.name))
                return True
            elif isinstance(error.__cause__, commands.errors.ExtensionNotLoaded):
                await ctx.send(Messages.cog_is_unloaded(cog=error.__cause__.name))
                return True

def setup(bot):
    bot.add_cog(System(bot))


from abc import ABC, abstractmethod
from itertools import product
from typing import Callable, Sequence

import numpy as np

from .mesh import Mesh
from .quadrature import GaussianQuadrature

class Interpolator(ABC):
    """Interpolates scalar functions by returning DOF Vectors."""

    def interpolate(self, function) -> np.ndarray:
        if isinstance(function(0), float) or isinstance(function(0), int):
            return self._interpolate_scalar(function)
        else:
            return np.array(
                [
                    self._interpolate_scalar(lambda x: function(x)[i])
                    for i in range(len(function(0)))
                ]
            ).T

    @abstractmethod
    def _interpolate_scalar(self, function) -> np.ndarray:
        ...

    def __repr__(self) -> str:
        return self.__class__.__name__

class CellAverageInterpolator(Interpolator):
    """Interpolate functions by calculating averages on each cell."""

    _mesh: Mesh
    _quadrature_degree: int

    def __init__(self, mesh: Mesh, quadrature_degree: int):
        self._mesh = mesh
        self._quadrature_degree = quadrature_degree

    def _interpolate_scalar(self, function) -> np.ndarray:
        dof_values = np.zeros(len(self._mesh))

        for i in range(len(dof_values)):
            dof_values[i] = self._cell_average(function, i)

        return dof_values

    def _cell_average(self, function, index: int) -> float:
        cell = self._mesh[index]
        quadrature = GaussianQuadrature(self._quadrature_degree, cell)

        return quadrature.integrate(function) / cell.length

class NodeValuesInterpolator(Interpolator):
    """Interpolate functions by calculating values on given nodes."""

    _nodes: Sequence[float]

    def __init__(self, *nodes: float):
        self._nodes = nodes

    def _interpolate_scalar(self, f: Callable[[float], float]) -> np.ndarray:
        return np.array([f(node) for node in self._nodes])

class TemporalInterpolator:
    """Interpolate time dependent values for a different time evolution."""

    def __call__(
        self, old_time: np.ndarray, values: np.ndarray, new_time: np.ndarray
    ) -> np.ndarray:
        interpolated_values = np.empty((len(new_time), *values[0].shape))

        for index in product(*[range(dim) for dim in values[0].shape]):
            # array[(slice(start, end))]=array[:]
            interpolated_values[(slice(0, len(new_time)), *index)] = np.interp(
                new_time,
                old_time,
                values[(slice(0, len(old_time)), *index)],
            )

        return interpolated_values

class SpatialInterpolator:
    """Interpolate time dependent values on a different grid."""

    def __call__(
        self, old_grid: np.ndarray, values: np.ndarray, new_grid: np.ndarray
    ) -> np.ndarray:
        """Returns an interpolation on the new grid.

        Note, values on new grid points x which are strictly less (or greater) than points in the old grid points xp are set to the first (or the last) value fp, i.e.

        x < xp[0] => f(x)=fp[0]

        x > xp[-1] => f(X)=fp[-1]

        """
        time_dimension = values.shape[0]
        spatial_dimension = values.shape[2:]

        interpolated_values = np.empty(
            (time_dimension, len(new_grid), *spatial_dimension)
        )

        for index in product(
            range(time_dimension), *[range(dim) for dim in spatial_dimension]
        ):
            # array[(slice(start, end))]=array[:]
            interpolated_values[
                (index[0], slice(0, len(new_grid)), *index[1:])
            ] = np.interp(
                new_grid,
                old_grid,
                values[(index[0], slice(0, len(old_grid)), *index[1:])],
            )

        return interpolated_values


import json
import pandas as pd
import requests
import csv
from pprint import pprint
import sqlite3
import bmt
from oaklib.implementations.ubergraph.ubergraph_implementation import UbergraphImplementation
from sqlalchemy import create_engine

oi = UbergraphImplementation()
conn = sqlite3.connect('test.db')
tk = bmt.Toolkit()

def run():

    engine = create_engine('sqlite://',
                           echo=False)

    r = requests.get('https://smart-api.info/api/metakg')
    metakg = r.json()['associations']
    metakg_small = []
    for association in metakg:
        if association.get('api').get('x-translator').get('component') == 'KP':
            assoc = {
                "subject": association.get('subject'),
                "object": association.get('object'),
                "predicate": association.get("predicate"),
                "provided_by": association.get("provided_by"),
                "api_name": association.get("api").get("name"),
                "api_id": association.get("api").get("smartapi").get("id")
            }
            metakg_small.append(assoc)

    metakg_df = pd.DataFrame.from_dict(metakg_small)
    engine.execute("drop table if exists metakg_table")
    metakg_df.to_sql('metakg_table',
                     con=engine)

    df = pd.read_sql(
        'SELECT distinct subject, object, provided_by, predicate, api_name, '
        'api_id from metakg_table where predicate = "ameliorates" or '
        'predicate = "approved_to_treat" or predicate = "treats"',
        engine)
    # write DataFrame to CSV file
    # df.to_csv('metakg.csv', index=False)
    rows = df.to_dict('records')
    return rows

def query_endpoint():
    rows = run()
    for row in rows:
        trapi = make_trapi(row.get('subject'), row.get('object'), row.get('predicate'))
        print(trapi)
    return None

def make_trapi(subject: str, object: str, predicate: str):
    return ""

def get_id_prefixes():
    rows = run()
    for row in rows:
        subject = "biolink:"+row.get('subject')
        element = tk.get_element(subject)
        id_prefixes = []
        if element is None:
            print(subject + " isn't a valid biolink item?")
        elif "id_prefixes" not in element:
            ancestors = tk.get_ancestors(element.name)
            for ancestor in ancestors:
                if tk.get_element(ancestor).id_prefixes is not None:
                    id_prefixes = id_prefixes + tk.get_element(ancestor).id_prefixes
        elif len(element.id_prefixes) != 0:
            resource = id_prefixes[0]
            print(resource)
        else:
            print("id prefixes is empty for: " + subject)


import unittest
import numpy as np
from numpy.polynomial import legendre as L

from sotodlib import core
from sotodlib.tod_ops import azss

def get_scan(n_scans=33, scan_accel=0.025, scanrate=0.025,
             az0=2, az1=2.25, fs=200):
    """
    Returns timestamps and az positions for a CES scan.
    """
    t_scan = (az1-az0)/scanrate
    t_turnaround = 2*scanrate/scan_accel

    t_tot = np.asarray([])
    d_tot = np.asarray([])

    t_scan = np.arange(0, t_scan+1/fs, 1/fs)
    t_turn = np.arange(0, t_turnaround+1/fs, 1/fs)
    ds_right = az0 + t_scan*scanrate
    dt_right = az1 + t_turn * scanrate - 0.5 * scan_accel * t_turn ** 2
    ds_left = az1 - t_scan*scanrate
    dt_left = az0 - t_turn * scanrate + 0.5 * scan_accel * t_turn ** 2

    for i in range(n_scans):
        # right scan
        if i == 0:
            t_tot = np.concatenate((t_tot, t_scan))
        else:
            t_tot = np.concatenate((t_tot, t_tot[-1]+t_scan))
        d_tot = np.concatenate((d_tot, ds_right))
        # right turnaround
        t_tot = np.concatenate((t_tot, t_tot[-1]+t_turn))
        d_tot = np.concatenate((d_tot, dt_right))
        # left scan
        t_tot = np.concatenate((t_tot, t_tot[-1]+t_scan))
        d_tot = np.concatenate((d_tot, ds_left))
        # right turnaround
        t_tot = np.concatenate((t_tot, t_tot[-1]+t_turn))
        d_tot = np.concatenate((d_tot, dt_left))
    return t_tot, d_tot

def make_fake_azss_tod(max_mode=20, noise_amp=1, n_scans=10,
                      ndets=2, input_coeffs=None):
    """
    Makes an axis manager with azimuth synchronous signal
    in it, populated via legendre polynomials plus gaussian noise.
    """
    ts, azpoint = get_scan(n_scans=n_scans)
    az_min, az_max = np.min(azpoint), np.max(azpoint)
    x = ( 2*azpoint - (az_min+az_max) ) / (az_max - az_min)

    fake_signal = np.zeros((ndets, len(ts)))
    if input_coeffs is None:
        input_coeffs = np.random.uniform(-10, 11, size=(ndets, max_mode+1))
    for nd in range(ndets):
        fake_signal[nd] += L.legval(x, input_coeffs[nd])
        noise = np.random.normal(0, noise_amp, size=len(ts))
        fake_signal[nd] += noise

    dets = ['det%i' % i for i in range(ndets)]
    mode_names = []
    for mode in range(max_mode+1):
        mode_names.append(f'legendre{mode}')

    tod_fake = core.AxisManager(core.LabelAxis('dets', vals=dets),
                                core.OffsetAxis('samps', count=len(ts)),
                                core.LabelAxis('modes', vals=mode_names))
    point = core.AxisManager(core.OffsetAxis('samps', count=len(ts)))
    tod_fake.wrap('boresight', point)
    tod_fake.boresight.wrap('az', azpoint, axis_map=[(0, 'samps')])
    tod_fake.wrap('timestamps', ts, axis_map=[(0, 'samps')])
    tod_fake.wrap('signal', np.atleast_2d(fake_signal),
                  axis_map=[(0, 'dets'), (1, 'samps')])
    tod_fake.wrap('input_coeffs', np.atleast_2d(input_coeffs),
                  axis_map=[(0, 'dets'), (1, 'modes')])
    return tod_fake

def get_coeff_metric(tod):
    """
    Evaluates fit is working by comparing coefficients in to out.
    """
    print(tod.input_coeffs[0])
    print(tod.azss_stats.coeffs[0])
    outmetric_num = (tod.azss_stats.coeffs - tod.input_coeffs)**2
    outmetric_denom = (tod.input_coeffs)**2
    return np.max(100*(outmetric_num/outmetric_denom))

class AzssTest(unittest.TestCase):
    "Test the Azimuth Synchronous Signal fitting functions"
    def test_fit(self):
        max_mode = 10
        tod = make_fake_azss_tod(noise_amp=0, n_scans=50, max_mode=max_mode)
        azss_stats, model_sig_tod = azss.get_azss(tod, method='fit', max_mode=max_mode, range=None, bins=100000)
        ommax = get_coeff_metric(tod)
        print(ommax)
        self.assertTrue(ommax < 1.0)

if __name__ == '__main__':
    unittest.main()


import pandas as pd

def remake_file(file_path='all_data/data/allTradesSet.csv'):
    badCols = ['Coin ', 'BuyDate ', 'CloseDate ', 'Quantity ', 'BuyPrice ',
               'SellPrice ', 'Spent USDT ', 'Gained USDT ', 'ProfitUSDT ', 'SellReason ',
               'bvsv ', 'PriceBug ', 'Vd1m ', 'H. Vol ', 'D. Vol']
    df = pd.read_csv(file_path, sep="\t", header=None)
    df.columns = ['Coin ', 'BuyDate ', 'CloseDate ', 'Quantity ', 'BuyPrice ', 'SellPrice ', 'Spent USDT ',
                  'Gained USDT ', 'ProfitUSDT ', 'Profit ', 'ChannelName ', 'SellReason ', 'dBTC ', 'd24BTC ',
                  'dMarket ',
                  'dM24 ', 'bvsv ', 'dBTC5m ', 'Pump1H ', 'Dump1H ', 'd24h ', 'd3h ', 'd1h ', 'd15m ', 'd5m ', 'd1m ',
                  'dBTC1m ', 'PriceBug ', 'Vd1m ', 'H. Vol ', 'D. Vol']

    for col in badCols:
        df.drop(col, inplace=True, axis=1)
    df = df.dropna()
    df.drop(df.index[df['ChannelName '] == '(strategy <d180s1.2 M+ FILTERS>) '], inplace=True)
    df.drop(df.index[df['ChannelName '] == '(strategy <d120s1.2 M+ FILTERS>) '], inplace=True)
    df.drop(df.index[df['ChannelName '] == '(strategy <d120s1.5 M+ FILTERS >) '], inplace=True)
    df.drop(df.index[df['ChannelName '] == '(strategy <d150s1.2 M+ FILTERS>) '], inplace=True)
    df['Profit '] = df['Profit '].apply(lambda x: 0 if float(x[:-2]) <= 0 else 1)
    df.to_csv('all_data/data/allTradesForModel..csv', sep=",")


import socket

# Setting up the connection:

def host_tcp(my_ip="0.0.0.0", port=12345):     # hosts a TCP connection and waits for client
    s = socket.socket()
    s.bind((my_ip, port))
    s.listen(5)
    c, address = s.accept()
    return c

def connect_tcp(ip, port=12345):   # connects to TCP from ip under given port
    s = socket.socket()
    s.connect((ip, port))
    return s

# Ways of sending data without needing to think about data limits:

def send_file(location, recipient):       # makes it possible to send images
    if isinstance(recipient, socket.socket):
        file = open(location, "rb").read()
        send_repeat(file, recipient)
    else:
        raise Exception("Recipient needs to be of the type: socket.socket")
        quit()

def send_text(text, recipient):           # makes it possible to send texts bigger than the max byte size for .send
    if isinstance(recipient, socket.socket):
        byte_text = text.encode()
        send_repeat(byte_text, recipient)
    else:
        raise Exception("Recipient needs to be of the type: socket.socket")
        quit()

def send_repeat(data, r):            # sends data in for loop so that send limit (1406 bytes) isn't exceeded
    split = [data[i:i + 1024] for i in range(0, len(data), 1024)]
    length = len(split)
    r.send(str(length).encode())    # sends over the amount of packages the recipient needs to listen for
    r.recv(1024)                    # makes sure the package arrived
    for i in range(0, length):      # sends over the text in 1024 byte steps
        r.send(split[i])
    r.recv(1024)

# Receiving end of send functions above:

def rcv_data(sender):   # returns data send from other site in byte format(independent of length)
    if isinstance(sender, socket.socket):
        data_len = int(sender.recv(1024).decode())
        sender.send("Received".encode())
        data = sender.recv(1024)                 # receive the image
        for i in range(0, data_len-1):
            data += sender.recv(1024)
        sender.send("Received".encode())        # tells the sender that everything arrived
        return data
    else:
        raise Exception("Sender needs to be of the type: socket.socket")
        quit()

# Written by N-Ziermann


#!/usr/bin/env python3

import os
import sys
import json
import base64
import argparse
import binascii
import pymongo
from dotenv import load_dotenv
from blockchain_parser.block import Block
import bitcoin.rpc
import tna
import util

load_dotenv()

btc_conf_file = os.path.expanduser(os.getenv("BTC_CONF_FILE"))

mongo = pymongo.MongoClient(os.getenv('MONGO_URL'))
db = mongo[os.getenv('MONGO_NAME')]

parser = argparse.ArgumentParser(description="import transactions to bitdb")
parser.add_argument("--start-block", type=int, help="block to start, if not given will go from db.meta.last_block")
parser.add_argument("--end-block", type=int, help="block to finish on, if not given will go until rpc fails")
parser.add_argument("--dry", action="store_true", help="dry run (no inserts)")
parser.add_argument("--verbose", action="store_true", help="show json from tna")
args = parser.parse_args()

rpc = bitcoin.rpc.RawProxy(btc_conf_file=btc_conf_file)

last_block_height = util.meta_get_last_block_height(db)
if not args.start_block:
    if last_block_height is not None:
        args.start_block = last_block_height + 1
    else:
        args.start_block = 0

if last_block_height is not None:
    if args.start_block < last_block_height:
        print("start_block is smaller than last block height in db ({})".format(last_block_height))
        print("this means you are rescanning parts of the blockchain you've already scanned")
        print("the entries will be deleted, and this is safe, it just might take longer")
        if input("press enter to continue, anything else to exit: ") != "":
            sys.exit()
    if args.start_block-1 > last_block_height:
        print("start_block-1 is greater than last block height in db ({})".format(last_block_height))
        print("this might mean you are skipping blocks")
        if input("press enter to continue, anything else to exit: ") != "":
            sys.exit()

# this is just used for printing status
percentage_end_block_count = args.end_block

# if end_block not provided we should keep going until an error occurs
if not args.end_block:
    args.end_block = 999999999
    percentage_end_block_count = rpc.getblockcount()

total_blocks = args.end_block - args.start_block

if not args.dry:
    print('deleted {} txs from gte block {}'.format(
        util.delete_txs_gte(db, args.start_block),
        args.start_block
    ))

for height in range(args.start_block, args.end_block):
    try:
        block_hash = rpc.getblockhash(height)
    except bitcoin.rpc.JSONRPCError as e:
        print('cannot get block hash, breaking')
        break

    raw_block  = binascii.unhexlify(rpc.getblock(block_hash, False)) # set to 0 to get raw hex data

    block = Block(raw_block, height=height)

    documents = []
    for tx in block.transactions:
        res = tna.extract(block, tx)
        if args.verbose:
            print(json.dumps(res, indent=4))
        documents.append(res)

    if args.dry:
        inserted = 0
    else:
        inserted = len(db.confirmed.insert_many(documents).inserted_ids)
        util.meta_update_last_block_height(db, height)

    print("{}%\theight={} inserted={}".format(
        round((block.height-args.start_block) / (percentage_end_block_count-args.start_block) * 100, 2),
        block.height,
        inserted
    ))


import numpy as np
import rospy

from sensor_msgs.msg import PointCloud2
import sensor_msgs.point_cloud2 as pc2
from std_msgs.msg import Header

import os

def _make_point_field(num_field):
    msg_pf1 = pc2.PointField()
    msg_pf1.name = np.str('x')
    msg_pf1.offset = np.uint32(0)
    msg_pf1.datatype = np.uint8(7)
    msg_pf1.count = np.uint32(1)

    msg_pf2 = pc2.PointField()
    msg_pf2.name = np.str('y')
    msg_pf2.offset = np.uint32(4)
    msg_pf2.datatype = np.uint8(7)
    msg_pf2.count = np.uint32(1)

    msg_pf3 = pc2.PointField()
    msg_pf3.name = np.str('z')
    msg_pf3.offset = np.uint32(8)
    msg_pf3.datatype = np.uint8(7)
    msg_pf3.count = np.uint32(1)

    msg_pf4 = pc2.PointField()
    msg_pf4.name = np.str('intensity')
    msg_pf4.offset = np.uint32(16)
    msg_pf4.datatype = np.uint8(7)
    msg_pf4.count = np.uint32(1)

    if num_field == 4:
        return [msg_pf1, msg_pf2, msg_pf3, msg_pf4]

    msg_pf5 = pc2.PointField()
    msg_pf5.name = np.str('label')
    msg_pf5.offset = np.uint32(20)
    msg_pf5.datatype = np.uint8(4)
    msg_pf5.count = np.uint32(1)

    return [msg_pf1, msg_pf2, msg_pf3, msg_pf4, msg_pf5]

#  publishing function for DEBUG
def publish_pc(np_array, frame_id):
    header = Header()
    header.stamp = rospy.Time()
    header.frame_id = frame_id

    x = np_array[:, 0].reshape(-1)
    y = np_array[:, 1].reshape(-1)
    z = np_array[:, 2].reshape(-1)

    # if intensity field exists
    if np_array.shape[1] == 4:
        i = np_array[:, 3].reshape(-1)
    else:
        i = np.zeros((np_array.shape[0], 1)).reshape(-1)

    cloud = np.stack((x, y, z, i))

    # point cloud segments
    # 4 PointFields as channel description
    msg_segment = pc2.create_cloud(header=header,
                                   fields=_make_point_field(4),
                                   points=cloud.T)

    #  publish to /velodyne_points_modified
    pub_velo.publish(msg_segment)  # DEBUG

if __name__ == '__main__':
    test_root = '../data/lidar_2d'
    # test_root = '/home/adam/data/voxel_net/KITTI/testing/velodyne'
    file_list = []
    tmp_list = os.listdir(test_root)
    tmp_list.sort()
    for f in tmp_list:
        cur_file = os.path.join(test_root, f)
        file_list.append(cur_file)

    rospy.init_node('pub_kitti_point_cloud')
    pub_velo = rospy.Publisher("velodyne_points", PointCloud2, queue_size=1)
    rate = rospy.Rate(2)

    pc_num_counter = 0
    while not rospy.is_shutdown():
        rospy.loginfo(file_list[pc_num_counter])

        # pc_data = np.fromfile(file_list[pc_num_counter], dtype=np.float32).reshape(-1, 4)

        pc_data = np.load(file_list[pc_num_counter])
        pc_data = pc_data[:, :, :4]
        pc_data = pc_data.reshape(-1, 4)

        publish_pc(pc_data, 'velodyne')

        pc_num_counter = pc_num_counter + 1
        if pc_num_counter >= len(file_list):
            pc_num_counter = 0
        rate.sleep()


"""Utility functions for testing neurodsp functions."""

from functools import wraps

import numpy as np
import matplotlib.pyplot as plt

from neurodsp.utils.data import compute_nsamples

from neurodsp.tests.settings import N_SECONDS, FS

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

def check_sim_output(sig, n_seconds=None, fs=None):
    """Helper function to check some basic properties of simulated signals."""

    n_seconds = N_SECONDS if not n_seconds else n_seconds
    fs = FS if not fs else fs
    exp_n_samples = compute_nsamples(n_seconds, fs)

    assert isinstance(sig, np.ndarray)
    assert len(sig) == exp_n_samples
    assert sum(np.isnan(sig)) == 0

def plot_test(func):
    """Decorator for simple testing of plotting functions.

    Notes
    -----
    This decorator closes all plots prior to the test.
    After running the test function, it checks an axis was created with data.
    It therefore performs a minimal test - asserting the plots exists, with no accuracy checking.
    """

    @wraps(func)
    def wrapper(*args, **kwargs):

        plt.close('all')

        func(*args, **kwargs)

        ax = plt.gca()
        assert ax.has_data()

    return wrapper

def check_exponent(xs, offset, exp):
    return xs*exp + offset


from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, redirect
from django.views import View
from django.core.paginator import  Paginator

from dashboard.models import Post
from dashboard.forms import PostModelForm

from users.models import get_friendships

def order_post_by_creation(post):
    return post.created

class DashboardView(View, LoginRequiredMixin):

    def get(self, request):
        form = PostModelForm()
        friends = get_friendships(request, email_only=True)
        user_posts = Post.objects.filter(author__email=request.user.email)
        friends_posts = []
        for friend in friends:
            friends_posts += Post.objects.filter(author__email=friend)
        posts = list(user_posts) + friends_posts

        # order posts by creation date
        posts.sort(reverse=True, key=order_post_by_creation)

        # pagination
        paginator = Paginator(posts, 2)
        page_number = request.GET.get('page')
        page_obj = paginator.get_page(page_number)

        context = {
            'form': form,
            'friends': friends,
            'page_obj': page_obj,
        }
        return render(request, 'dashboard/dashboard.html', context)

    def post(self, request):
        form = PostModelForm(request.POST, request.FILES)
        if form.is_valid():
            post = Post()
            post.author = request.user
            post.image = form.cleaned_data['image']
            post.comment = form.cleaned_data['comment']
            post.save()
            return redirect('dashboard:dashboard')
        return redirect('dashboard:dashboard')

def delete_post(request, pk):
    post = Post.objects.get(pk=pk)
    post.delete()
    return redirect('dashboard:dashboard')


import torch
import torch as T
import numpy as np
import torch.nn as nn
from matplotlib import pyplot as plt
from torch.autograd import Variable
from tqdm import tqdm
import os
import seaborn as sns
from src.data_helper import *
import pandas as pd
from src.evaluator import Evaluator
from torch.optim.lr_scheduler import ReduceLROnPlateau
from src.utils import *

class Trainer:
    def __init__(self, model, device=T.device("cpu"),
                 save_dir="./trained_models",
                 save_name="model.pt",
                 verbose=True):
        self.model = model
        self.device = device
        self.save_dir = save_dir
        self.save_name = save_name
        self.verbose = verbose
        self.device = device
        self.evaluator = Evaluator()

        self.train_losses = []
        self.valid_losses = []
        self.test_losses = []
        self.train_acc = []
        self.valid_acc = []
        self.test_acc = []
        self.valid_loss_min = np.Inf
        self.valid_acc_max = -np.Inf

        self.set_model_path(save_dir, save_name)

    def set_model_path(self, save_dir, save_name):
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)

        self.model_path = os.path.join(save_dir, save_name)

    def set_data(self, train_x, train_y, val_x, val_y):
        self.train_x = train_x
        self.train_y = train_y
        self.val_x = val_x
        self.val_y = val_y

    def split_batch(self, x, y, batch_size, shuffle=True):
        batches = []
        if shuffle:
            indices = np.random.permutation(len(x))
            dataset = [x[i] for i in indices]
            labelset = [y[i] for i in indices]
        else:
            dataset = x
            labelset = y
        for i in range(0, len(dataset), batch_size):
            batches.append((np.array(dataset[i:i + batch_size]), np.array(labelset[i:i + batch_size])))

        return batches

    def eval(self, val_loader):
        val_losses = []
        val_accuracies = []

        self.model.eval()
        for inp, lab in val_loader:
            inp = Variable(torch.FloatTensor(inp), requires_grad=False)
            lab = Variable(torch.FloatTensor(lab), requires_grad=False)
            inp, lab = inp.to(self.device).detach(), lab.to(
                self.device).detach()
            out = self.model(inp).detach()
            loss = self.model.loss(out.detach(), lab.detach())
            out = out.cpu().numpy()
            out = [x[::-1][:int(sum(lab[i]).item())]
                   for i, x in enumerate(out.argsort())]
            for i, x in enumerate(out):
                out_vec = np.zeros(self.model.num_classes)
                out_vec[x] = 1
                out[i] = out_vec

            acc = self.evaluator.multilabel_accuracy(out, lab.cpu().numpy())
            val_losses.append(loss.item())
            val_accuracies.append(acc)

        self.model.train()

        return np.mean(val_losses), np.mean(val_accuracies)

    def test(self, audio_file_path=None,
             label_file_path=None, data_config=None,
            k=1, plot=False):
        self.model.to(self.device)
        self.model.eval()
        #Going through each data_filename within a label
        audio, sr = librosa.load(audio_file_path, sr=data_config['sr'])
        data = audio_to_tensor(audio, data_config)

        inp = Variable(torch.FloatTensor(np.array([data])).to(self.device), requires_grad=False)
        prob_out = self.model(inp).detach().cpu().numpy()[0]
        labels = np.array(['E' + ('0' if (i % 44)+1 < 10 else '') + str(i + 1) for i in range(44)]
                          + ['J' + ('0' if (i % 44)+1 < 10 else '') + str(i + 1) for i in range(44)])
        if plot:
            df = pd.DataFrame({'probability': prob_out, 'labels': labels})
            ax = sns.barplot(x='labels', y='probability',
                             data=df, errwidth=0)
            plt.xticks(color='w')
            plt.savefig('images/' +
                        os.path.basename(audio_file_path).replace('wav', 'png'))
            plt.show()
        ans = labels[np.argsort(prob_out)[::-1]][:k]
        strans = '[' + ", ".join(['"%s"' % x for x in ans]) + ']'
        print(strans)

    def train(self, optimizer='adam', training_params=None):
        # utility for running the training process
        self.model.to(self.device)
        epochs = training_params['epochs']
        batch_size = training_params['batch_size']
        self.model.set_loss_function(training_params['loss_function'])
        self.model.set_optimizer(
            optimizer, lr=training_params['learning_rate'])
        # print options
        counter = 0
        print_every = 5
        clip = 5

        self.model.train()
        # scheduler = ReduceLROnPlateau(self.model.optimizer, factor=0.5, patience=0, verbose=True)

        val_loader = self.split_batch(
            self.val_x, self.val_y, batch_size=batch_size, shuffle=False)

        for i in range(epochs):
            train_loader = self.split_batch(
                self.train_x, self.train_y, batch_size=batch_size, shuffle=True)
            t = tqdm(train_loader)
            tot_loss = 0
            counter = 0
            for inputs, labels in t:
                counter += 1
                inputs = Variable(torch.FloatTensor(
                    inputs), requires_grad=True)
                labels = Variable(torch.FloatTensor(labels))
                inputs, labels = inputs.to(self.device), labels.to(self.device)

                self.model.zero_grad()
                output = self.model(inputs)
                loss = self.model.loss(output, labels.detach())
                loss.backward()
                nn.utils.clip_grad_norm_(self.model.parameters(), clip)
                self.model.step()
                tot_loss += loss.item()
                if counter % print_every == 0:
                    t.set_postfix(loss=tot_loss / counter)

            val_loss, val_acc = self.eval(val_loader)

            if self.verbose:
                print('Epoch/batch: {}/{}'.format(i + 1, epochs))
                print('Val accuracy:', val_acc)
                print('Val loss:', val_loss)
            if val_loss <= self.valid_loss_min:
                print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.
                      format(self.valid_loss_min, val_loss))
                torch.save(self.model.state_dict(), self.model_path)
                self.valid_loss_min = val_loss
            elif val_acc > self.valid_acc_max:
                self.valid_acc_max = val_acc
                torch.save(self.model.state_dict(), self.model_path)
            # scheduler.step(val_loss)

        return (self.model)

    def load_model_from_path(self, path, device=None):
        if device is None:
            device = "cuda" if torch.cuda.is_available() else "cpu"
        self.model.load_state_dict(T.load(path, map_location=device))
        print("Model loaded sucessful!")

    def save_train_losses(self):
        plt.plot(self.train_losses)
        out_dir = 'output/train_losses'
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)
        plt.savefig("{}/{}_{}".format(out_dir,
                    self.model.name, 'train_losses.png'))


op = input().upper()

matrix = []
total = []

for line in range(12):
    matrix.append([])
    for column in range(12):
        float_ = (float(input()))
        matrix[line].append(float_)
        if column < line:
            total.append(float_)

if op == "S":
    print(sum(total))
elif op == "M":
    print(f"{(sum(total)/66):.1f}")


import pygame
from math import hypot
from pygame import *
from world import collider

pygame.init()
player_img = pygame.image.load("Resources/char1.png")
player_img = pygame.transform.scale(player_img,(64,64))
class Weapons(pygame.sprite.Sprite):
    def __init__(self,wp_x,wp_y,wp_image):
        pygame.sprite.Sprite.__init__(self)
        self.image = wp_image
        self.image = pygame.transform.scale(self.image,(20,20))
        self.rect = self.image.get_rect()
        self.rect.x = wp_x
        self.rect.y = wp_y
        self.visible = True
weapon_sprites = pygame.sprite.Group()
torch = Weapons(200,200,pygame.image.load("Resources/main_character_torch/torch.png"))
weapon_sprites.add(torch)

class Player():
    def __init__(self,x,y,screen):
        self.screen = screen
        self.image = player_img
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.index = 0
        self.counter = 0
        self.direction = 0 # 0 = down // 1 = right // 2 = left // 3 = up
        self.active_weapon = 0 # 0 nothing// 1 torch // 2 .... // 3 is ...
        self.run_right = []
        self.run_left = []
        self.run_up = []
        self.run_down = []
        self.run_right_t = []
        self.run_left_t = []
        self.run_up_t = []
        self.run_down_t = []
        self.walk_cooldown = 5
        for number in range(1,3):
            images_rr = pygame.image.load(f"character/right/tile{number}.png")
            images_rl = pygame.image.load(f"character/left/tile{number}.png")
            images_ru = pygame.image.load(f"character/up/tile{number}.png")
            images_rd = pygame.image.load(f"character/down/tile{number}.png")
            images_rr = pygame.transform.scale(images_rr,[64,64])
            images_rl = pygame.transform.scale(images_rl,[64,64])
            images_rd = pygame.transform.scale(images_rd,[64,64])
            images_ru = pygame.transform.scale(images_ru,[64,64])
            self.run_right.append(images_rr)
            self.run_left.append(images_rl)
            self.run_up.append(images_ru)
            self.run_down.append(images_rd)
        for number in range(1,3):
            images_rr_t = pygame.image.load(f"Resources/main_character_torch/right/{number}.png")
            images_rl_t = pygame.image.load(f"Resources/main_character_torch/left/{number}.png")
            images_rd_t = pygame.image.load(f"Resources/main_character_torch/down/{number}.png")
            images_ru_t = pygame.image.load(f"Resources/main_character_torch/up/{number}.png")
            images_rr_t = pygame.transform.scale(images_rr_t,[64,64])
            images_rl_t = pygame.transform.scale(images_rl_t,[64,64])
            images_rd_t = pygame.transform.scale(images_rd_t,[64,64])
            images_ru_t = pygame.transform.scale(images_ru_t,[64,64])
            self.run_right_t.append(images_rr_t)
            self.run_left_t.append(images_rl_t)
            self.run_up_t.append(images_ru_t)
            self.run_down_t.append(images_rd_t)

    def update(self):
        self.hitbox = pygame.Rect(self.rect.x + 15,self.rect.y,32,64)
        key = pygame.key.get_pressed()
        if key[K_RIGHT] and key[K_UP] == False and key[K_DOWN] == False:
            self.rect.x += 1
            self.counter += 1
            self.direction = 1
        if key[K_LEFT] and key[K_UP] == False and key[K_DOWN] == False:
            self.rect.x -= 1
            self.counter += 1
            self.direction = 2
        if key[K_UP] and key[K_RIGHT] == False and key[K_LEFT] == False:
            self.rect.y -= 1
            self.counter += 1
            self.direction = 3
        if key[K_DOWN] and key[K_RIGHT] == False and key[K_LEFT] == False:
            self.rect.y += 1
            self.counter += 1
            self.direction = 0
        if key[K_1]:
            self.active_weapon = 0
        if key[K_2] and torch.visible == False:
            self.active_weapon = 1
        if hypot(self.rect.x - torch.rect.x , self.rect.y - torch.rect.y) < 40:
            if key[K_f]:
                self.active_weapon = 1
                torch.visible = False
        for collide in collider:
            if self.hitbox.colliderect(collide):
                if self.direction == 0:
                    self.rect.y -= 1
                if self.direction == 1:
                    self.rect.x -= 1
                if self.direction == 2:
                    self.rect.x += 1
                if self.direction == 3:
                    self.rect.y += 1
        if key[K_RIGHT] == False and key[K_LEFT] == False and key[K_DOWN] == False and key[K_UP] == False and key[K_SPACE] == False:
            self.counter = 0
            self.index = 0
            if self.active_weapon == 1:
                if self.direction == 0:
                    self.image = self.run_down_t[self.index]
                if self.direction == 1:
                    self.image = self.run_right_t[self.index]
                if self.direction == 2:
                    self.image = self.run_left_t[self.index]
                if self.direction == 3:
                    self.image = self.run_up_t[self.index]
            elif self.active_weapon == 0:
                if self.direction == 0:
                    self.image = self.run_down[self.index]
                if self.direction == 1:
                    self.image = self.run_right[self.index]
                if self.direction == 2:
                    self.image = self.run_left[self.index]
                if self.direction == 3:
                    self.image = self.run_up[self.index]
        if self.counter > self.walk_cooldown:
            self.counter = 0
            self.index += 1
            if self.index >= 2:
                self.index = 0
            if self.active_weapon == 1:
                if self.direction == 0:
                    self.image = self.run_down_t[self.index]
                if self.direction == 1:
                    self.image = self.run_right_t[self.index]
                if self.direction == 2:
                    self.image = self.run_left_t[self.index]
                if self.direction == 3:
                    self.image = self.run_up_t[self.index]
            elif self.active_weapon == 0:
                if self.direction == 0:
                    self.image = self.run_down[self.index]
                if self.direction == 1:
                    self.image = self.run_right[self.index]
                if self.direction == 2:
                    self.image = self.run_left[self.index]
                if self.direction == 3:
                    self.image = self.run_up[self.index]

class Display_gui:
    def __init__(self,player,screen):
        self.player = player
        self.screen = screen
        self.surface = pygame.surface.Surface((1280,720))
        self.surface.set_colorkey((0,0,0))
        self.fistimage = pygame.image.load("character/gui/fistgui.png")
        self.fistimage = pygame.transform.scale(self.fistimage,(200,200))
        self.torchimage = pygame.image.load("character/gui/torchgui.png")
        self.torchimage = pygame.transform.scale(self.torchimage,(200,200))
    def update(self):
        if self.player.active_weapon == 0:
            self.surface.blit(self.fistimage,(-53,-53))
            self.screen.blit(self.surface,(0,0))
        if self.player.active_weapon == 1:
            self.surface.blit(self.torchimage,(-53,-53))
            self.screen.blit(self.surface,(0,0))


import torch.nn.functional as F
import tqdm
from utils.prep_data import load_data
from sklearn.model_selection import train_test_split
from utils.skeleton import *
from sklearn.metrics import confusion_matrix, accuracy_score
from datetime import datetime
import time
import os
import logging
from model.rh_net import *
from torch.utils.data import DataLoader
from model.temp_calibration import ModelWithTemperature

# ensure reproducibility
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False

def init_data_loader(args, logger, t_data, v_data=None):
    if v_data is None:
        data_set, label_set, state_set = load_data(data_path=t_data, num_frame=args.frame_size)
        logger.info("Splitting data into train and test sets...")
        train_data, val_data, train_label, val_label, train_state, val_state = \
            train_test_split(data_set, label_set, state_set, test_size=0.2, stratify=label_set)
    else:
        logger.info("Segmenting training data from csv...")
        train_data, train_label, train_state = load_data(data_path=t_data, num_frame=args.frame_size)
        logger.info("\nSegmenting test data from csv...")
        val_data, val_label, val_state = load_data(data_path=v_data, num_frame=args.frame_size)

    aug = True
    if aug:
        logger.info("\nUsing data noise augmentation")

    train_dataset = SkeletonData(train_data, train_label, train_state, mode='train', use_data_aug=aug)

    test_dataset = SkeletonData(val_data, val_label, val_state, mode='test')

    train_data_loader = DataLoader(train_dataset,
                                   batch_size=args.batch_size, shuffle=True,
                                   num_workers=args.workers, pin_memory=False)

    val_data_loader = DataLoader(test_dataset,
                                 batch_size=args.batch_size, shuffle=False,
                                 num_workers=args.workers, pin_memory=False)

    return train_data_loader, val_data_loader

def initialise_model(args, model):
    class_num = 10  # including null class
    state_num = 5
    joint_num = 11
    input_dim = 7
    save_att = False

    init_model = model(num_classes=class_num, num_states=state_num, joint_num=joint_num, input_dim=input_dim,
                       window_size=args.frame_size, dp_rate=args.dp_rate, plot_att=save_att)
    device = torch.device("cuda")
    init_model = torch.nn.DataParallel(init_model).to(device)

    return init_model

def model_forward(batched_sample, model, criterion1, criterion2):
    device = torch.device("cuda")

    data = batched_sample[0]
    data = data.to(device)

    class_labels = batched_sample[1]
    class_labels = class_labels.type(torch.LongTensor)

    state_labels = batched_sample[2]
    state_labels = state_labels.type(torch.LongTensor)

    class_labels = class_labels.to(device)
    state_labels = state_labels.to(device)

    class_prob, state_prob = model(data)

    loss1 = criterion1(class_prob, class_labels)
    loss2 = criterion2(state_prob, state_labels)

    total_loss = 0.8 * loss1 + 0.2 * loss2

    return class_prob, state_prob, total_loss

def get_cm(scores, label):
    device = torch.device('cpu')
    scores = scores.to(device).data.numpy()
    label = label.to(device).data.numpy()
    outputs = np.argmax(scores, axis=1)
    # print(label)
    # print(outputs)
    m = confusion_matrix(label.flatten(), outputs.flatten(), normalize='true')
    acc = accuracy_score(label.flatten(), outputs.flatten())
    return m, acc

def get_logger(path):
    log = logging.getLogger(path)
    log.setLevel(logging.INFO)

    stream = logging.StreamHandler()
    stream.setLevel(logging.INFO)
    file_handle = logging.FileHandler(path)
    file_handle.setLevel(logging.INFO)

    log.addHandler(stream)
    log.addHandler(file_handle)

    return log

def train_model(arguments, model_type, name, t_data, v_data=None):
    if arguments.training:
        # folder for saving trained model...
        # change this path to the fold where you want to save your pre-trained model
        name = datetime.now().strftime('%d%m%y') + '_' + name
        path = os.getcwd()
        model_fold = f"{path}/{name}"

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

        # get logger ready
        logger = get_logger(model_fold + "/train.log")

        train_loader, val_loader = init_data_loader(arguments, logger, t_data, v_data)

        logger.info("\nInput Parameters:")
        logger.info(arguments)

        logger.info("\nInitialising model.............")
        model = initialise_model(arguments, model_type)
        optimiser = torch.optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=arguments.learning_rate)
        loss_criterion1 = torch.nn.CrossEntropyLoss().cuda()
        loss_criterion2 = torch.nn.CrossEntropyLoss().cuda()

        train_data_num = len(train_loader.dataset)
        valid_data_num = len(val_loader.dataset)
        iter_per_epoch = math.ceil(train_data_num / arguments.batch_size)
        logger.info("Current device is: {}"
                    .format(torch.cuda.get_device_name(torch.cuda.current_device())))
        logger.info("training data num: {}".format(train_data_num))
        logger.info("test data num: {}".format(valid_data_num))
        logger.info("batch size: {}".format(arguments.batch_size))
        logger.info("num of workers: {}".format(arguments.workers))

        # parameters recording training log
        max_acc = 0
        min_loss = 100
        no_improve_epoch = 0
        n_iter = 0

        logger.info("\n*** Starting Training ***")
        for epoch in range(arguments.epochs):
            # Training Step
            model.train()
            start_time = time.time()
            train_loss = 0
            for i, sample_batched in enumerate(train_loader):
                n_iter += 1
                label = sample_batched[1]
                state_truth = sample_batched[2]
                if i + 1 > iter_per_epoch:
                    continue
                cls, state, loss = model_forward(sample_batched, model, loss_criterion1, loss_criterion2)
                train_loss += loss.item()
                model.zero_grad()
                loss.backward()
                # clip_grad_norm_(model.parameters(), 0.1)
                optimiser.step()

                if i == 0:
                    score_list = cls
                    label_list = label
                    state_score = state
                    state_list = state_truth
                else:
                    score_list = torch.cat((score_list, cls), 0)
                    label_list = torch.cat((label_list, label), 0)
                    state_score = torch.cat((state_score, state), 0)
                    state_list = torch.cat((state_list, state_truth), 0)

            train_loss /= (i + 1)
            train_cm, train_acc = get_cm(score_list, label_list)
            train_state_cm, train_state_acc = get_cm(state_score, state_list)

            logger.info("\nCurrent Epoch: [%2d] time: %4.4f, "
                        "train_loss: %.4f  train_acc: %.4f  train_state_acc: %.4f"
                        % (epoch + 1, time.time() - start_time,
                           train_loss, train_acc, train_state_acc))
            start_time = time.time()

            # adjust_learning_rate(model_solver, epoch + 1, args)
            # print(print(model.module.encoder.gcn_network[0].edg_weight))

            # Validation Step
            with torch.no_grad():
                val_loss = 0
                model.eval()
                for i, sample_batched in enumerate(val_loader):
                    label = sample_batched[1]
                    state_truth = sample_batched[2]
                    cls, state, loss = model_forward(sample_batched, model, loss_criterion1, loss_criterion2)
                    val_loss += loss.item()

                    if i == 0:
                        score_list = cls
                        label_list = label
                        state_score = state
                        state_list = state_truth
                    else:
                        score_list = torch.cat((score_list, cls), 0)
                        label_list = torch.cat((label_list, label), 0)
                        state_score = torch.cat((state_score, state), 0)
                        state_list = torch.cat((state_list, state_truth), 0)

                val_loss /= (i + 1)
                val_cm, val_acc = get_cm(score_list, label_list)
                val_state_cm, val_state_acc = get_cm(state_score, state_list)

                logger.info("Current Epoch: [%2d], "
                            "val_loss: %.4f  val_acc: %.4f val_state_acc: %.4f"
                            % (epoch + 1, val_loss, val_acc, val_state_acc))

                total_acc = val_acc * 0.8 + val_state_acc * 0.2
                # save best model
                if total_acc > max_acc:
                    # if val_loss < min_loss:
                    total_acc = round(total_acc, 3)
                    no_improve_epoch = 0
                    min_loss = val_loss
                    max_acc = total_acc
                    val_loss = round(val_loss, 3)
                    total_acc = round(total_acc, 3)
                    best_model = "ep_{}_acc_{}_{}".format(epoch + 1, total_acc,
                                                          datetime.now().strftime('%H%M%S'))
                    torch.save(model.module.state_dict(), f'{model_fold}/{best_model}.pt')
                    logger.info(
                        "Performance improve, saving new model. Best average accuracy: {}".format(total_acc))
                    # print(val_cm)
                    logger.info(val_cm.diagonal() / val_cm.sum(axis=1))
                    # logger.info(val_state_cm.diagonal()/val_state_cm.sum(axis=1))

                else:
                    no_improve_epoch += 1
                    logger.info("No_improve_epoch: {} Best accuracy {}".format(no_improve_epoch, max_acc))

                if no_improve_epoch == arguments.patience:
                    logger.info("*** Stop Training ***")
                    break

    if arguments.inference:
        print("\n*** Start Inference ***")
        try:
            model_path = f'{model_fold}/{best_model}'
        except NameError:
            model_fold = "saved_models/saved_model_240323_RH_model_20f_scale_1-2_256_0.8"
            best_model = "ep_7_acc_0.948_134202_scaled"
            model_path = f'{model_fold}/{best_model}.pt'
            logger = get_logger(model_fold + "/train.log")

            val_data, val_label, val_state = load_data(data_path=v_data, num_frame=arguments.frame_size)
            test_dataset = SkeletonData(val_data, val_label, val_state, mode='test')
            val_loader = DataLoader(test_dataset,
                                    batch_size=arguments.batch_size, shuffle=False,
                                    num_workers=arguments.workers, pin_memory=False)
        loss_criterion1 = torch.nn.CrossEntropyLoss().cuda()
        loss_criterion2 = torch.nn.CrossEntropyLoss().cuda()
        model = initialise_model(arguments, model_type)
        model = ModelWithTemperature(model).to(torch.device('cuda'))
        model.load_state_dict(torch.load(model_path))

        with torch.no_grad():
            val_loss = 0
            model.eval()
            for i, sample in enumerate(val_loader):
                label = sample[1]
                state_truth = sample[2]
                cls, state, loss = model_forward(sample, model, loss_criterion1, loss_criterion2)
                val_loss += loss
                if i == 0:
                    score_list = cls
                    label_list = label
                    state_score = state
                    state_list = state_truth
                else:
                    score_list = torch.cat((score_list, cls), 0)
                    label_list = torch.cat((label_list, label), 0)
                    state_score = torch.cat((state_score, state), 0)
                    state_list = torch.cat((state_list, state_truth), 0)

            val_loss = val_loss / float(i + 1)
            val_cm, val_acc = get_cm(score_list, label_list)
            val_state_cm, val_state_acc = get_cm(state_score, state_list)

            print(f"Test set loss: {val_loss}")
            print("\nClass Accuracy: %.4f"
                  "\nState Accuracy: %.4f"
                  % (val_acc, val_state_acc))

        return torch.argmax(score_list, dim=1), label_list, val_state_cm

    if arguments.calibration:
        try:
            model_path = f'{model_fold}/{best_model}.pt'
        except NameError:
            model_fold = f"{os.getcwd()}/131123_RH_model_20f_noise_1-2_256"
            best_model = "ep_1_acc_0.887_153402"
            model_path = f'{model_fold}/{best_model}.pt'
            logger = get_logger(model_fold + "/train.log")
            train_loader, val_loader = init_data_loader(arguments, logger, t_data, v_data)
        model = initialise_model(arguments, model_type)
        model.module.load_state_dict(torch.load(model_path))

        epoch = 5
        scaled_model = ModelWithTemperature(model)

        for i in range(epoch):
            scaled_model, before_nll, before_ece, after_nll, after_ece = scaled_model.set_temperature(val_loader)

            logger.info('Before temperature - NLL: %.3f, ECE: %.3f' % (before_nll, before_ece))
            logger.info('After temperature - NLL: %.3f, ECE: %.3f' % (after_nll, after_ece))
            logger.info('Optimal temperature: %.3f' % scaled_model.temperature.item())

        torch.save(scaled_model.state_dict(), f'{model_fold}/{best_model}_scaled.pt')

        print(f"Final Temperature: {scaled_model.temperature.item()}")
        print("\nModel calibrated SUCCESSFULLY!")


from pwn import *

sla = lambda x,y : p.sendlineafter(x,y)
sa = lambda x,y : p.sendafter(x,y)

def change_name(name):
	sla('>','1')
	sa(':',name)

def change_national(nation):
	sla('>','2')
	sa(':',nation)

def change_age(age):
	sla('>','3')
	sla(':',str(age))

if __name__ == '__main__':
	#context.log_level = 'debug'
	e = ELF('./challenge')
	#p = process('./challenge')
	p = remote('svc.pwnable.xyz',30031)

	s2 = [0x11, 0xDE, 0xCF, 0x10, 0xDF, 0x75, 0xBB, 0xA5, 0x43, 0x1E, 0x9D, 0xC2, 0xE3, 0xBF, 0xF5, 0xD6, 0x96, 0x7F, 0xBE, 0xB0, 0xBF, 0xB7, 0x96, 0x1D, 0xA8, 0xBB, 0x0A, 0xD9, 0xBF, 0xC9, 0x0D, 0xFF, 0x00]
	main_opcode = [85, 72, 137, 229, 72, 131, 236, 80, 100, 72, 139, 4, 37, 40, 0, 0, 0, 72, 137, 69, 248, 49, 192, 232, 36, 254, 255, 255, 72, 141, 69, 192]
	flag = ''
	for i in range(32):
		for j in range(256):
			if ((((j >> 4) | (j << 4)) ^ main_opcode[i]) & 0xff) == s2[i]:
				flag += chr(j)
				break
	log.info('check : ' + flag)
	change_name(flag)
	sla('>','4')

	p.interactive()