from . import log, document, html, window, NODOM
from .connector import Connect

from random import randint

TEXT_MARGIN = 16

SIZE = (50, 50)
GRAY = (250, 250, 250)
PAD = 2
MAR = 6

"""*##########################################*.

"""

class Item:
    """ An Item in the outline.

    :param node_id: Id for remote connection
    :param rgb: Color for the item
    :param size: Size for the item
    :param parent: Parent for the Item
    """
    conn = None
    item = {}
    prefix = "S_N_O_D_E_%03x" % randint(0x111, 0xfff) + "-%02d"

    def __init__(self, node_id, rgb, size=SIZE, parent=NODOM, text="-enter text-"):
        self.container = []
        self.capacity = self.item_count = self.rows = self.cols = 1
        self.base = self.content = NODOM
        self.parent, self.node_id, self.rgb, self.size, self.text = self.init_(node_id, rgb, size, parent, text)
        self.parent = parent

    def init_(self, node_id, rgb, size, parent, text):
        """
        >>> print(item.init_(2, (0, 0, 0), (15, 15), NODOM)[1:])
        (2, (0, 0, 0), (15, 15))

        :param text:
        :param node_id: Id for remote connection
        :param rgb: Color for the item
        :param size: Size for the item
        :param parent: the node from wich this stems
        :return: parent, node_id, rgb, size
        """
        # print("XXXXXXX>>>> _init", ">%s<" % [node_id, rgb, size])
        height, width = size
        brgb = tuple([max(0, k-randint(30, 100)) for k in rgb])
        span = 100*(width-TEXT_MARGIN)/width
        self.base = html.DIV(style={
            "background-color": "rgb(%d, %d, %d)" % rgb, "border": "2px solid rgb(%d, %d, %d)" % brgb, "padding": "2px",
            "margin": "2px", "border-radius": "8px", "overflow": "hidden",
            "height": "%dpx" % height, "width": "%dpx" % width, "float": "left"})
        self.content = content = html.DIV(
            text, style={"position": "relative", "float": "left", "left": "-4px", "width": "%d%%" % span})
        adder = html.SPAN(
            "◉", style={"position": "relative", "float": "left", "left": "-5px", "top": "-8px", "cursor": "crosshair"})
        fixer = html.SPAN("❌", style={"position": "relative", "float": "right", "top": "-4px"})
        self.base <= adder
        self.base <= content
        # self.base <= fixer
        fixer.onclick = self.fix_item
        adder.onclick = self.add_item
        content.onclick = self.edit_item
        content.onresize = self.compute_grid
        content.addEventListener("change", self.compute_grid)
        content.bind("DOMSubtreeModified",self.compute_grid)
        parent <= self
        return parent, node_id, rgb, size, text

    def create(self, rgb=None, node_id=None, size=None):
        """Create an Item instance.

        :param node_id: Id for remote connection
        :param rgb: Color for the item
        :param size: Size for the item
        :return: An instance of Item
        """
        nodeid = node_id if node_id else self.node_id + (len(self.container),)
        rgb = rgb or (randint(235, 255), randint(235, 255), randint(235, 255))
        size = size if size else self.compute_grid()
        item = Item(node_id=nodeid, rgb=rgb, size=size, parent=self)
        Item.item[nodeid] = item
        size = self.compute_grid()
        [it.resize(size) for it in self.container]
        return item

    def compute_grid(self, *_):
        def compute_size():
            return (height - 1 * PAD + - 2 * MAR * self.rows) / self.rows, \
                                 (width - 1 * PAD - 2 * MAR * self.cols) / self.cols
        height, width = self.size
        txth = self.content.getBoundingClientRect().height
        txth = txth if isinstance(txth, int) else int(txth[:-2])
        # print("compute_grid", height, txth, type(height), type(txth))
        height -= txth
        cheight, cwidth = size = compute_size()
        self.capacity = self.cols = self.rows = 1
        while len(self.container) > self.capacity:
            if(3*width / (self.rows + 1) >= height / (self.cols + 1)) and (cheight > 48):
                self.rows = self.rows + 1
            else:
                self.cols = self.cols + 1
                self.rows = max(1, self.rows // self.cols)
            self.capacity = self.rows * self.cols
            # size = height / self.rows-10, width / self.cols-10
            cheight, cwidth = size = compute_size()
        [item.resize(size) for item in self.container]
        return size

    def resize(self, size):
        height, width = self.size = size
        self.base.style.width = "%dpx" % width
        self.content.style.width = "%d%%" % (100*(width-TEXT_MARGIN)/width)
        self.base.style.height = "%d%s" % (height, "px")
        # self.size = height, width
        self.compute_grid()
        # size = (height-4*self.rows+2)/self.rows, (width-4*self.cols+2)/self.cols
        # [item.resize(size) for item in self.container]

    def __le__(self, square):
        self.container.append(square)
        self.base <= square.base

    @staticmethod
    def fix_item(ev=None):
        ev.stopPropagation()
        ev.target.contentEditable = False

    @staticmethod
    def edit_item(ev=None):
        ev.stopPropagation()
        ev.target.contentEditable = True
        # self.create().send()

    def add_item(self, ev=None):
        ev.stopPropagation()
        log.debug("XXXXXXX>>>> Item.add_item(ev) = >%s<", [list(self.node_id), list(self.rgb), list(self.size)])
        self.create().send()
        # Item(self, self.compute_grid())

    def send(self):
        data = [list(self.node_id), list(self.rgb), list(self.size)]
        Item.conn.send(data)

"""*##########################################*.

"""

class Base(Item):
    """ The Base Item of the outline.

    :param node_id: Id for remote connection
    :param rgb: Color for the item
    :param last: index for the item
    """
    def __init__(self, last, node_id, rgb=GRAY):
        self.base = canvas = document["pydiv"]
        canvas.text = ""

        def resize(_):
            self.resize([window.innerHeight - 20, window.innerWidth - 30])

        def _add_item(data):
            log.debug("XXXXXXX>>>> Base._add_item(data) = >%s<", data)
            _node_id, _rgb, _size = tuple(data[0]), tuple(data[1]), tuple(data[2])
            log.debug("XXXXXXX>>>> Base.Item.item = >%s<", Item.item.keys())
            log.debug("XXXXXXX>>>> type(_node_id) = >%s<, _node_id = >%s<", type(_node_id), _node_id)
            Item.item[_node_id[:-1]].create(_rgb, _node_id, _size)

        class NoItem:
            def __init__(self):
                self.container = []

            def __le__(self, square):
                canvas <= square.base

        Item.prefix = node_id
        self.no_item = NoItem()
        size = window.innerHeight - 20, window.innerWidth - 30
        window.onresize = resize
        Item.item[()], Item.item[(0,)] = self.no_item, self
        Item.__init__(self, (0,), rgb, size, self.no_item)
        Item.conn = self   # Connect(last, node_id, _add_item)
        self.base.style.left = 2
        self.base.style.top = -2
        self.base.style.position = "absolute"

    def send(self, *_):
        pass

"""*##########################################*.

"""

def main(last, nodeid):
    Base(last, nodeid)

if __name__ == "__main__":
    import doctest

    doctest.testmod(globs=dict(
        item=Item(12, GRAY),
        NODOM=NODOM
    ))


import sys, os
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from matplotlib.animation import PillowWriter
from matplotlib import rc
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import patches
from matplotlib.pyplot import axvline, axhline
from collections import defaultdict
from django.http import HttpResponse
from PIL import Image

# Create your views here.

def home(request):
    return render(request, '_home.html', {'title':'title'})

@csrf_exempt
def script(request):
    print(request)
    x = []
    y = []
    if request.method == "POST":
        for data in x:
            print(data)
        x = request.POST.get('x_field').split(',')
        y = request.POST.get('y_field').split(',')

        #transformando de str para float
        x = [int(i) for i in x]
        y = [int(n) for n in y]

        d = representacao_sinal(x,y)

        return JsonResponse({'success': 'true', 'signal': d})
    else:
        return JsonResponse({'success': 'false'})

@csrf_exempt
def convolution_request(request):
    input_signal = []
    kernel = []
    if request.method == "POST":
        input_signal = request.POST.get('input_signal').split(',')
        kernel = request.POST.get('kernel').split(',')

        #transformando de str para float
        input_signal = [int(i) for i in input_signal]
        kernel = [int(n) for n in kernel]

        input_time = list(range(len(input_signal)))
        kernel_time = list(range(len(kernel)))

        d = process_convolution(input_signal, input_time, kernel, kernel_time)

        return JsonResponse({'success': 'true', 'signal': d})
    else:
        return JsonResponse({'success': 'false'})
def representacao_sinal(x, y):
    """
    Plot do Sinal
    """
    res = []

    for a, b in zip(x, y):
        res.append({'x': a, 'y': b})
    print(res)
    return res

def convolution(y1, y2):
    res = []
    print(y1)
    print(y2)
    outPutLengh = len(y1) + len(y2) - 1
    for i in range(outPutLengh):
        kmin = i - (len(y2) - 1) if(i >= len(y2) - 1) else 0
        kmax = i if(i < len(y1) - 1) else len(y1) - 1

        sum = 0
        for k in range(kmin, kmax+1):
            sum += y2[i-k]*y1[k]
        res.append(sum)
    return res

def process_convolution(input_signal, input_time, kernel_signal, kernel_time):
    """
    Eixo do tempo do sinal Convolucionado
    """
    convolution_x_axis = list(range(input_time[0] + kernel_time[0], len(input_signal) + len(kernel_signal) - 1))
    convolution_y_axis = convolution(kernel_signal, input_signal)
    print(convolution_x_axis, convolution_y_axis)

    res = []

    for a, b in zip(convolution_x_axis, convolution_y_axis):
        res.append({'x': a, 'y': b})
    print(res)
    return res

def zplane(z, p):

    ax = plt.subplot()

    # Adicionando circulo e eixos zero
    unit_circle = patches.Circle((0,0), radius=1, fill=False,
                                 color='black', ls='solid', alpha=1)
    ax.add_patch(unit_circle)

    # Plotando os polos e setando propiedades
    poles = plt.plot(p.real, p.imag, 'x', markersize=9, alpha=1)

    # Plotando os zeros e setando propiedades
    zeros = plt.plot(z.real, z.imag,  'o', markersize=9,
             color='none', alpha=1,
             markeredgecolor=poles[0].get_color(),
             )

    # Escala para ajustar
    r = 1.5 * np.amax(np.concatenate((abs(z), abs(p), [1])))
    plt.axis('scaled')
    plt.axis([-r, r, -r, r])

    grid = 0

    """
    Caso existam multiplos polos ou zeros no mesmo ponto
    """
    # Procurando corrdenadas duplicados no mesmo pixel
    poles_xy = ax.transData.transform(np.vstack(poles[0].get_data()).T)
    zeros_xy = ax.transData.transform(np.vstack(zeros[0].get_data()).T)

    # dict deve ser inteiro e coords deve ser float

    # TODO reduzindo duplicações
    d = defaultdict(int)
    coords = defaultdict(tuple)
    for xy in poles_xy:
        key = tuple(np.rint(xy).astype('int'))
        d[key] += 1
        coords[key] = xy
    for key, value in d.items():
        if value > 1:
            x, y = ax.transData.inverted().transform(coords[key])
            plt.text(x, y,
                        r' ${}^{' + str(value) + '}$',
                        fontsize=13,
                        )

    d = defaultdict(int)
    coords = defaultdict(tuple)
    for xy in zeros_xy:
        key = tuple(np.rint(xy).astype('int'))
        d[key] += 1
        coords[key] = xy
    for key, value in d.items():
        if value > 1:
            x, y = ax.transData.inverted().transform(coords[key])
            plt.text(x, y,
                        r' ${}^{' + str(value) + '}$',
                        fontsize=13,
                        )

    plt.title('Plano Z')
    plt.grid()
    path = 'static/pics'
    plt.savefig('{}/zerosnpoles.jpeg'.format(path), dpi=200)
    plt.clf()

@csrf_exempt
def z_transform_request(request):
    if request.method == "POST":
        b = request.POST.get('den_signal').split()
        a = request.POST.get('num_signal').split()
        print(a, b)

        #transformando de str para float
        a = [float(i) for i in a]
        b = [float(n) for n in b]

        zplane(np.roots(a), np.roots(b))

        path = 'static/pics'
        valid_image = '{}/zerosnpoles.jpeg'.format(path)
        import base64
        try:
            with open(valid_image, "rb") as f:
                return HttpResponse(base64.b64encode(f.read()), content_type="image/base64")
        except IOError:
            red = Image.new('RGBA', (1, 1), (255,0,0,0))
            response = HttpResponse(content_type="image/jpeg")
            red.save(response, "JPEG")
            return response

def discretize(frequency, phase):
    size = 4 * frequency
    domain = range(phase, size + phase)
    for e in domain:
        e = e * frequency

    res = list(np.sin(domain))
    print("len res", len(domain))
    time_input = range(size)
    resp = []
    for a, b in zip(time_input, res):
        resp.append({'x': a, 'y': b})
    print(resp)
    return resp

@csrf_exempt
def discretize_request(request):
    if request.method == "POST":
        a = request.POST.get('frequency')
        b = request.POST.get('phase')
        print(a, b)

        #transformando de str para float
        a = int(a)
        b = int(b)

        d = discretize(a, b)

        return JsonResponse({'success': 'true', 'signal': d})
    else:
        return JsonResponse({'success': 'false'})


# -*- coding: utf-8 -*-
#%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import math

# turn of data table rendering
pd.set_option('display.notebook_repr_html', False)
plt.style.use('ggplot')
pd.__version__

#%%  Load Data

# Load 248 days of step data and vivofit goals
data = pd.read_csv('Data/garmin-vivofit.csv', index_col='date')
data.head()

#%% Plot the steps and goal data
data.steps.plot(kind='area', figsize=(8,5),color='green',alpha=0.5)
data.goal.plot()
plt.ylabel('steps per day')
plt.legend(loc='upper left')

#%% Calculate mean

x,n=0.0,0

for number_of_steps in data.steps:
    x=x+number_of_steps

n=len(data.steps)
mean=x/n
mean

# We can also let pandas use NumPy's mean function to do the job
data.steps.mean()

# use numpy to get the mean
np.mean(data.steps)

# use pandas to get the mean
data.mean()

# Plot the mean, togehter with the steps and goal data
data.steps.plot(kind='area', color='#00A99D', alpha=.5, figsize=(8,5))
data.goal.plot(legend=True)
plt.plot([0, len(data.steps)],[mean, mean])
plt.ylabel('steps per day')
plt.text(25, mean-1200, r'$\mu=' + str(int(math.floor(mean))) + '$', fontsize=14)
plt.legend(loc='upper left')

#%% MEDIAN

median, n = 0.0, 0

# Get the number of observations
n = len(data.steps)

# order the data
ordered_data = data.steps.order()

if n % 2 == 0:
    # n is even
    m1 = ordered_data.ix[(n - 2) / 2]
    m2 = ordered_data.ix[(n / 2)]
    median = (m1 + m2) / 2.0
else:
    # n is odd
    median = ordered_data.ix[(n - 2) / 2.0]

median

# Again, we can let pandas use NumPy's median function to do the job
data.steps.median()

# Or we can call NumPy's median function ourselves
np.median(data.steps)

# Use pandas to get the median for all columns at ones
data.median()

#%% MODE
# Let's create a lambda that assigns a bucket of size 1000 steps
# to each of the step count in the data set
bucket_size = 1000
bucket_calculator = lambda x: int(x) / bucket_size * bucket_size

data['bucket'] = data.steps.apply(bucket_calculator)
bucket_min = data.bucket.min()
bucket_max = data.bucket.max()
bins = (bucket_max-bucket_min)/bucket_size

data.bucket.hist(color='#00A99D', alpha=.5, bins=int(bins), figsize=(8,5))


from contextlib import suppress

import config

from aiogram import types, Dispatcher
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher.filters import Text
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
from aiogram.utils.callback_data import CallbackData
from aiogram.utils.exceptions import MessageNotModified

from app.database.models import ParentingTip
from app.database.user_crud import update_user_last_seen
from app.keyboards.inline.bookmarks import bookmark_link_cb, all_bookmarks_keyboard
from app.keyboards.inline.profile_kb_inline import profile_kb
from app.keyboards.inline.bookmarks import add_bookmark_go_back

from app.texts.profile_texts import start_search_text, no_articles_found, list_of_found_articles, ask_new_question

from app.database import user_crud, tips_crud
from app.utils.message_renderers import MyChildMessageRenderer, TipRenderer
from app.texts import bookmark_texts, profile_texts

from app.extentions import logger

show_article_callback = CallbackData('show_article', 'id')

class SearchState(StatesGroup):
    query = State()

class AskState(StatesGroup):
    question = State()

async def profile_menu_inline(call: types.CallbackQuery):
    logger.info(f"User {call.from_user.id} opened profile menu")
    await call.message.edit_text(profile_texts.profile_introduction,
        reply_markup=profile_kb)
    update_user_last_seen(call.from_user.id)

async def my_child(call: types.CallbackQuery):
    user = user_crud.get_user_by_tg_id(call.from_user.id)

    formatter = MyChildMessageRenderer(user)
    message_text = formatter.form_final_message()

    mark = InlineKeyboardMarkup()
    mark.add(InlineKeyboardButton(
        text="⬆ В профиль",
        callback_data='В профиль'
    ))
    logger.info(f'User {call.from_user.id} checked "My child"')
    await call.message.edit_text(message_text, reply_markup=mark)

async def get_my_bookmarks(call: types.CallbackQuery):

    user_id = call.from_user.id
    keyboard_with_bookmarks = all_bookmarks_keyboard(user_id)
    if not keyboard_with_bookmarks:
        await call.message.answer(bookmark_texts.no_bookmarks_found)
        logger.info(f"User {call.from_user.id} checked bookmarks before he added any")
        return

    logger.info(f"User {call.from_user.id} checked his bookmarks")
    await call.message.edit_text(list_of_found_articles, reply_markup=keyboard_with_bookmarks)

async def show_bookmarked_tip(call: types.CallbackQuery, callback_data: dict):

    mark = InlineKeyboardMarkup(row_width=1)

    mark.add(InlineKeyboardButton(
        text="< Назад к списку",
        callback_data='< Назад к списку'
    ))

    tip: ParentingTip = tips_crud.get_tip_by_id(callback_data['tip_id'])

    formatter = TipRenderer(tip)
    message_text = formatter.form_final_text()
    logger.info(f"User {call.from_user.id} opened previously added tip: {tip.header}")
    await call.message.edit_text(message_text, reply_markup=mark)

async def go_to_profile(call: types.CallbackQuery):
    await profile_menu_inline(call)

async def start_search(call: types.CallbackQuery, state: FSMContext):
    await call.message.edit_text(start_search_text)
    await state.set_state(SearchState.query.state)

async def search_for_articles(message: types.Message, state: FSMContext):
    query = message.text
    tip_list = tips_crud.search_tips_by_query(query)

    if len(tip_list) == 0:
        await message.answer(no_articles_found, reply_markup=profile_kb)
        await state.finish()
        return

    buttons = [InlineKeyboardButton(
        text=tip.header,
        callback_data=show_article_callback.new(str(tip.id))
    )
        for tip in tip_list]

    mark = InlineKeyboardMarkup(row_width=1)
    mark.add(*buttons)
    mark.add(InlineKeyboardButton(text="Назад",
                                  callback_data="В профиль"))
    await state.finish()
    logger.info(f"User {message.from_user.id} searched next query: {query}")
    await message.answer("Вот что удалось найти по вашему запросу: ", reply_markup=mark)

async def render_article(call: CallbackQuery, callback_data: dict):
    post_id = callback_data["id"]
    tip: ParentingTip = tips_crud.get_tip_by_id(post_id)

    renderer = TipRenderer(tip)
    message_text = renderer.form_final_text()

    logger.info(f"User {call.from_user.id} opened a tip: {tip.header}")

    with suppress(MessageNotModified):
        await call.message.edit_text(message_text, reply_markup=add_bookmark_go_back(tip.id))

async def ask_others(call: types.CallbackQuery, state: FSMContext):
    logger.info(f"User {call.from_user.id} wants to ask community a question")
    logger.info(call.message.chat.id)
    await state.set_state(AskState.question.state)
    mark =  InlineKeyboardMarkup(row_width=1)
    mark.add(InlineKeyboardButton(
        text="Отмена",
        callback_data='cancel_question')
    )
    await call.message.edit_text(ask_new_question, reply_markup=mark)

async def send_question_to_admin(message: types.Message, state: FSMContext):
    logger.info(message)
    await message.forward(config.ADMIN_CHAT)
    await message.answer("Ваш вопрос добавлен в очередь. Администратор опубликует его после обработки",
                         reply_markup=profile_kb)
    await state.finish()

async def cancel_question(call: types.CallbackQuery, state: FSMContext):
    await state.finish()
    await call.message.edit_text("Вопрос отменён", reply_markup=profile_kb)

async def day_by_day(call: types.CallbackQuery):
    logger.info(f"User {call.from_user.id} tried to open 'Day by day' functionality")

    await call.answer('Подписка уже оформлена 😇')

def register_profile_handlers(dp: Dispatcher):
    dp.register_callback_query_handler(profile_menu_inline, Text(equals="В профиль"))
    dp.register_callback_query_handler(my_child, Text(equals="👼🏻 Мой ребёнок"))
    dp.register_callback_query_handler(get_my_bookmarks, Text(equals=['< Назад к списку']))
    dp.register_callback_query_handler(get_my_bookmarks, Text(equals=["📗 Сохранённые статьи"]))
    dp.register_callback_query_handler(day_by_day, Text(equals=["🤳🏼 День за днём"]))
    dp.register_callback_query_handler(show_bookmarked_tip, bookmark_link_cb.filter())

    dp.register_callback_query_handler(start_search, Text(equals="🔎 Поиск по статьям"))
    dp.register_message_handler(search_for_articles, state=SearchState.query)
    dp.register_callback_query_handler(render_article, show_article_callback.filter())

    dp.register_callback_query_handler(ask_others, Text(equals="🆘 Задать вопрос"), state="*")
    dp.register_message_handler(send_question_to_admin, state=AskState.question, content_types=['photo', 'text'])
    dp.register_callback_query_handler(cancel_question, Text(equals="cancel_question"), state=AskState.question)


class Solution:
    def rec(self,nu,data,st,k,ans,pos):
        # print(data,ans)
        if(pos==k):
            ans.append(data[:])
            return
        if(st==len(nu)):
            return
        data[pos]=nu[st]
        self.rec(nu,data,st+1,k,ans,pos+1)
        data[pos]=-1
        self.rec(nu,data,st+1,k,ans,pos)

    def combine(self, n: int, k: int) -> List[List[int]]:
        nu=[i for i in range(1,n+1)]
        data=[-1 for i in range(k)]
        ans=[]
        self.rec(nu,data,0,k,ans,0)
        return ans


# this script is modified from tf-agents TD3 Examples

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

import os
import time
import rospy
from absl import app
from absl import flags
from absl import logging

import gin
import tensorflow as tf

from tf_agents.agents.ddpg import actor_network
from tf_agents.agents.ddpg import critic_network
from tf_agents.agents.td3 import td3_agent
from tf_agents.drivers import dynamic_step_driver
#from tf_agents.environments import suite_mujoco
from tf_agents.environments import suite_gym
from tf_agents.environments import tf_py_environment
from tf_agents.eval import metric_utils
from tf_agents.metrics import tf_metrics
from tf_agents.replay_buffers import tf_uniform_replay_buffer
from tf_agents.utils import common
from tf_agents.trajectories import trajectory
from env_wrappers import TFEnv
from tf_agents.policies.policy_saver import PolicySaver
from SafetyLayer import SafetyLayer
import numpy as np
from tensorboardX import SummaryWriter
####################################mbrl#####################################
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import torch
import omegaconf

import mbrl.models as models
import mbrl.planning as planning
import mbrl.util.common as common_util
import mbrl.util as util
import mbrl.types
from tf_agents.trajectories import TimeStep
from tf_agents.trajectories import PolicyStep
import joblib
from utils.MetricsCollector import MetricsCollector
#############################################################################

flags.DEFINE_string('root_dir', os.getenv('TEST_UNDECLARED_OUTPUTS_DIR'),
                    'Root directory for writing logs/summaries/checkpoints.')
flags.DEFINE_integer('num_iterations', 1000000,
                     'Total number train/eval iterations to perform.')
flags.DEFINE_multi_string('gin_file', None, 'Paths to the gin-config files.')
flags.DEFINE_multi_string('gin_param', None, 'Gin binding parameters.')

FLAGS = flags.FLAGS

@gin.configurable
def train_eval(
    root_dir,
    env_name='Turtlebot',
    num_iterations=2000000,
    actor_fc_layers=(512, 256, 64),
    critic_obs_fc_layers=(512,),
    critic_action_fc_layers=None,
    critic_joint_fc_layers=(300,),
    # Params for collect
    initial_collect_steps=2000,
    collect_steps_per_iteration=1,
    replay_buffer_capacity=100000,
    exploration_noise_std=0.1,
    # Params for target update
    target_update_tau=0.05,
    target_update_period=5,
    # Params for train
    train_steps_per_iteration=1,
    batch_size=64,
    actor_update_period=2,
    actor_learning_rate=1e-4,
    critic_learning_rate=1e-3,
    dqda_clipping=None,
    td_errors_loss_fn=tf.compat.v1.losses.huber_loss,
    gamma=0.995,
    reward_scale_factor=1.0,
    gradient_clipping=None,
    use_tf_functions=True,
    # Params for eval
    num_eval_episodes=10,
    eval_interval=1000,
    # Params for checkpoints, summaries, and logging
    log_interval=1000,
    summary_interval=1000,
    summaries_flush_secs=10,
    debug_summaries=False,
    summarize_grads_and_vars=False,
    eval_metrics_callback=None):

  rospy.init_node('BRSL_TB')
  """A simple train and eval for TD3."""
  sl = SafetyLayer()
  root_dir = os.path.expanduser(root_dir)
  train_dir = os.path.join(root_dir, 'train')
  eval_dir = os.path.join(root_dir, 'eval')
  safety_dir = os.path.join(root_dir, 'safety')
  train_summary_writer = tf.compat.v2.summary.create_file_writer(
      train_dir, flush_millis=summaries_flush_secs * 1000)
  train_summary_writer.set_as_default()
  #writer = SummaryWriter(safety_dir)
  metrics_collector = MetricsCollector(safety_dir)
  eval_summary_writer = tf.compat.v2.summary.create_file_writer(
      eval_dir, flush_millis=summaries_flush_secs * 1000)
  eval_metrics = [
      tf_metrics.AverageReturnMetric(buffer_size=num_eval_episodes),
      tf_metrics.AverageEpisodeLengthMetric(buffer_size=num_eval_episodes)
  ]

  global_step = tf.compat.v1.train.get_or_create_global_step()
  with tf.compat.v2.summary.record_if(
      lambda: tf.math.equal(global_step % summary_interval, 0)):
    env_name = 'Turtlebot'
    #env = suite_gym.load(env_name)
    tf_env = tf_py_environment.TFPyEnvironment(TFEnv)#tf_py_environment.TFPyEnvironment(suite_gym.load(env_name))
    eval_tf_env = tf_py_environment.TFPyEnvironment(TFEnv)#tf_py_environment.TFPyEnvironment(suite_gym.load(env_name))

    actor_net = actor_network.ActorNetwork(
        tf_env.time_step_spec().observation,
        tf_env.action_spec(),
        fc_layer_params=actor_fc_layers,
    )

    critic_net_input_specs = (tf_env.time_step_spec().observation,
                              tf_env.action_spec())

    critic_net = critic_network.CriticNetwork(
        critic_net_input_specs,
        observation_fc_layer_params=critic_obs_fc_layers,
        action_fc_layer_params=critic_action_fc_layers,
        joint_fc_layer_params=critic_joint_fc_layers,
    )
    noise = tf.Variable(0.1)
    print("*"*80)
    print(noise, type(noise))
    tf_agent = td3_agent.Td3Agent(
        tf_env.time_step_spec(),
        tf_env.action_spec(),
        actor_network=actor_net,
        critic_network=critic_net,
        actor_optimizer=tf.compat.v1.train.AdamOptimizer(
            learning_rate=actor_learning_rate),
        critic_optimizer=tf.compat.v1.train.AdamOptimizer(
            learning_rate=critic_learning_rate),
        exploration_noise_std=noise,
        target_update_tau=target_update_tau,
        target_update_period=target_update_period,
        actor_update_period=actor_update_period,
        #dqda_clipping=dqda_clipping,
        td_errors_loss_fn=td_errors_loss_fn,
        target_policy_noise = noise,
        #target_policy_noise_clip = 0.2,
        gamma=gamma,
        reward_scale_factor=reward_scale_factor,
        gradient_clipping=gradient_clipping,
        debug_summaries=debug_summaries,
        summarize_grads_and_vars=summarize_grads_and_vars,
        train_step_counter=global_step,
    )

    tf_agent.initialize()

    train_metrics = [
        tf_metrics.NumberOfEpisodes(),
        tf_metrics.EnvironmentSteps(),
        tf_metrics.AverageReturnMetric(),
        tf_metrics.AverageEpisodeLengthMetric(),
    ]

    eval_policy = tf_agent.policy
    collect_policy = tf_agent.collect_policy

    replay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer(
        tf_agent.collect_data_spec,
        batch_size=tf_env.batch_size,
        max_length=replay_buffer_capacity)

    initial_collect_driver = dynamic_step_driver.DynamicStepDriver(
        tf_env,
        collect_policy,
        observers=[replay_buffer.add_batch],
        num_steps=initial_collect_steps)

    collect_driver = dynamic_step_driver.DynamicStepDriver(
        tf_env,
        collect_policy,
        observers=[replay_buffer.add_batch] + train_metrics,
        num_steps=collect_steps_per_iteration)

    if use_tf_functions:
      initial_collect_driver.run = common.function(initial_collect_driver.run)
      collect_driver.run = common.function(collect_driver.run)
      tf_agent.train = common.function(tf_agent.train)

    # Collect initial replay data.
    print(
        'Initializing replay buffer by collecting experience for {} steps with '
        'a random policy.'.format(initial_collect_steps))
    initial_collect_driver.run()

    time_step = None
    policy_state = collect_policy.get_initial_state(tf_env.batch_size)

    timed_at_step = global_step.numpy()
    time_acc = 0

    # Dataset generates trajectories with shape [Bx2x...]
    dataset = replay_buffer.as_dataset(
        num_parallel_calls=3,
        sample_batch_size=batch_size,
        num_steps=2).prefetch(3)
    iterator = iter(dataset)
    def train_step():
      experience, _ = next(iterator)
      return tf_agent.train(experience)

    if use_tf_functions:
      train_step = common.function(train_step)

    dream = True
    collect_reachability_data = True

    if(dream):
      ####################################mbrl#####################################
      mbrl_losses = []
      mbrl_val_losses = []
      device = 'cuda:0' if torch.cuda.is_available() else 'cpu'
      seed = 0
      #env = cartpole_env.CartPoleEnv()
      #env.seed(seed)
      rng = np.random.default_rng(seed=0)
      generator = torch.Generator(device=device)
      generator.manual_seed(seed)
      obs_shape = tf_env.observation_spec().shape#env.observation_space.shape
      act_shape = tf_env.action_spec().shape#env.action_space.shape

      trial_length = 500
      num_trials = 10
      ensemble_size = 1

      cfg_dict = {
            # dynamics model configuration
            "dynamics_model": {
                "model": {
                    "_target_": "mbrl.models.GaussianMLP",
                    "device": device,
                    "num_layers": 3,
                    "ensemble_size": ensemble_size,
                    "hid_size": 200,
                    "use_silu": True,
                    "in_size": "???",
                    "out_size": "???",
                    "deterministic": False,
                    "propagation_method": "fixed_model"
                }
            },
            # options for training the dynamics model
            "algorithm": {
                "learned_rewards": False,
                "target_is_delta": True,
                "normalize": True,
                "dataset_size": 250
            },
            # these are experiment specific options
            "overrides": {
                "trial_length": trial_length,
                "num_steps": num_trials * trial_length,
                "model_batch_size": 32,
                "validation_ratio": 0.05
            }
        }
      cfg = omegaconf.OmegaConf.create(cfg_dict)

      # Create a 1-D dynamics model for this environment
      dynamics_model = common_util.create_one_dim_tr_model(cfg, obs_shape, act_shape)

      mbrl_replay_buffer = common_util.create_replay_buffer(cfg, obs_shape, act_shape, rng=rng)

      state = tf_env._reset()

      time_step = tf_env.current_time_step()
      policy_state = collect_policy.get_initial_state(tf_env.batch_size)

      for i in range(500):
        action_step = collect_policy.action(time_step, policy_state)
        random_a = np.array([[0, 0]], dtype = np.float32)
        random_a[0][0] = np.random.uniform(0, 0.25)
        random_a[0][1] = np.random.uniform(-0.5, 0.5)
        action_step = action_step._replace(action = random_a)

        next_time_step = tf_env.step(action_step.action)
        done = False
        if(next_time_step.is_last()):
          done = True

        mbrl_replay_buffer.add(time_step.observation.numpy().astype(np.float64), action_step.action.astype(np.float64), next_time_step.observation.numpy().astype(np.float64), next_time_step.reward.numpy().astype(np.float64), done)
        time_step = next_time_step

        train_losses = []
        val_scores = []

        def train_callback(_model, _total_calls, _epoch, tr_loss, val_score, _best_val):
            train_losses.append(tr_loss)
            val_scores.append(val_score.mean().item())   # this returns val score per ensemble model

        model_trainer = models.ModelTrainer(dynamics_model, optim_lr=1e-3, weight_decay=5e-5)
        _rng = torch.Generator(device=device)
        _current_obs = torch.from_numpy(time_step.observation.numpy().astype(np.float64)).to(device)
        actions = torch.from_numpy(action_step.action.astype(np.float64)).to(device)

        model_in = mbrl.types.TransitionBatch(
                    _current_obs, actions, None, None, None
                )

        next_observs, pred_rewards = dynamics_model.sample(
                    model_in,
                    deterministic=True,
                    rng=_rng,
                )

      ######################## Train
        if (i > 100):
          dynamics_model.update_normalizer(mbrl_replay_buffer.get_all())  # update normalizer stats

          dataset_train, dataset_val = common_util.get_basic_buffer_iterators(
              mbrl_replay_buffer,
              batch_size=cfg.overrides.model_batch_size,
              val_ratio=cfg.overrides.validation_ratio,
              ensemble_size=ensemble_size,
              shuffle_each_epoch=True,
              bootstrap_permutes=False,  # build bootstrap dataset using sampling with replacement
          )

          model_trainer.train(
              dataset_train,
              dataset_val=dataset_val,
              num_epochs=1,
              patience=50,
              callback=train_callback)
          mbrl_losses.append(train_losses[0])
          mbrl_val_losses.append(val_scores[0])

      #############################################################################
      print("*"*80)
      print("# samples stored", mbrl_replay_buffer.num_stored)
      print("*"*80)

      tf_env.reset()
      time_step = None
      policy_state = None
    else:
      print("Dreaming is not used")
    reachability_actions = []
    reachability_states = []

    restore_checkpoint = False
    restore_checkpoint_step = 410000
    if(restore_checkpoint):
      checkpoint_dir = '/home/mahmoud/turtlebot/td3_policy_%d' % restore_checkpoint_step

      my_policy = tf_agent.collect_policy
      saver = PolicySaver(my_policy, batch_size=None)
      saver.save(checkpoint_dir + "/policy_saver")

      if(dream):
        torch.save(dynamics_model.state_dict(), checkpoint_dir + "/dynamics_model")
        joblib.dump(mbrl_replay_buffer, checkpoint_dir)

      train_checkpointer = common.Checkpointer(
          ckpt_dir=checkpoint_dir + "/checkpointer",
          max_to_keep=1000,
          agent=tf_agent,
          policy=tf_agent.policy,
          replay_buffer=replay_buffer,
          global_step=global_step
      )

      train_checkpointer.initialize_or_restore()
      global_step = tf.compat.v1.train.get_global_step()
      print("Checkpoint restoration complete")

    print("Start Training...")
    tf_env.envs[0].enable_logging()

    moving = [True] * 20
    for _ in range(num_iterations):
      #rate.sleep()
      start_time = time.time()
      times = []

      next_action = None

      if time_step is None:
        time_step = tf_env.current_time_step()
      if policy_state is None:
        policy_state = collect_policy.get_initial_state(tf_env.batch_size)

      action_step = collect_policy.action(time_step, policy_state)

      if(dream):
        start_t = time.time()
        mbrl_time_step = TimeStep(discount = tf.identity(time_step.discount), reward = tf.identity(time_step.reward),
                                  observation = tf.identity(time_step.observation), step_type = tf.identity(time_step.step_type))
        mbrl_action_step = PolicyStep(action = tf.identity(action_step.action))
        plan = [action_step.action.numpy().squeeze().tolist()]
        for i in range(3):

          _current_obs = torch.from_numpy(mbrl_time_step.observation.numpy().astype(np.float64)).to(device)
          actions = torch.from_numpy(mbrl_action_step.action.numpy().astype(np.float64)).to(device)

          model_in = mbrl.types.TransitionBatch(
                      _current_obs, actions, None, None, None
                  )

          next_observs, pred_rewards = dynamics_model.sample(
                      model_in,
                      deterministic=True,
                      rng=_rng,
                  )

          mbrl_time_step = TimeStep(discount = mbrl_time_step.discount, reward = mbrl_time_step.reward,
                                  observation = tf.identity(next_observs.clone().detach().cpu().numpy().astype(np.float32)), step_type = mbrl_time_step.step_type)
          mbrl_action_step = collect_policy.action(mbrl_time_step, policy_state)
          plan.append(mbrl_action_step.action.numpy().squeeze().tolist())

        reachability_state = [0] * 2
        readings = time_step.observation[0, :18].numpy() * 3.5

        plan_holder = np.zeros((10, 8)).astype(np.float32)
        plan_holder[:4, :2] = plan

        res, next_action = sl.enforce_safety(reachability_state, plan_holder, readings)
        plan_t = time.time() - start_t
        moving.append(res)
        moving.pop(0)
      ##########################################################################################################################################
      if(collect_reachability_data):
        random_a = np.array([[0, 0]], dtype = np.float32)
        random_a[0][0] = np.random.uniform(0, .25)
        random_a[0][1] = np.random.uniform(-.5, .5)
        #random_a[0][2] = np.random.uniform(-.5, .5)
        action_step = action_step._replace(action = random_a)
        reachability_states.append(np.array(list(tf_env.envs[0].get_odom().odom) + [list(time_step.is_last())]))

        reachability_actions.append(action_step.action)
      #############################################################################################################################

      action_step = action_step._replace(action = np.copy(next_action).reshape((1, 2)))

      with tf.control_dependencies(tf.nest.flatten([time_step])):

        if(moving == [False] * 20):
          new_action = np.array([[0, 0.5]], dtype = np.float32)
          action_step = action_step._replace(action = new_action)
          next_time_step = tf_env.step(action_step.action)
        else:
          next_time_step = tf_env.step(action_step.action)

      policy_state = action_step.state

      traj = trajectory.from_transition(time_step, action_step, next_time_step)
      observer_ops = [observer(traj) for observer in collect_driver._observers]
      transition_observer_ops = [
          observer((time_step, action_step, next_time_step))
          for observer in collect_driver._transition_observers
      ]
      with tf.control_dependencies(
          [tf.group(observer_ops + transition_observer_ops)]):
        time_step, next_time_step, policy_state = tf.nest.map_structure(
            tf.identity, (time_step, next_time_step, policy_state))

      #counter += tf.cast(traj.is_boundary(), dtype=tf.int32)
      time_step = next_time_step

      metrics_collector.add_robot_speed(global_step, np.linalg.norm(tf_env.envs[0].get_odom().odom[-4:-1]))
      metrics_collector.add_plan_time(global_step, plan_t)
      if(time_step.is_last() == True):
        step = tf_env.envs[0].episodes_number
        metrics_collector.add_goal_rate(step, tf_env.envs[0].arrivals_number/tf_env.envs[0].episodes_number)
        metrics_collector.add_collision_rate(step, tf_env.envs[0].collisions_number/tf_env.envs[0].episodes_number)
        metrics_collector.add_time_to_goal(step, tf_env.envs[0].one_round_step)

      for _ in range(train_steps_per_iteration):
        train_loss = train_step()
      time_acc += time.time() - start_time
      noise = noise * 0.999997
      if global_step.numpy() % log_interval == 0:
        print('step = {}, loss = {}, noise = {}'.format(global_step.numpy(),
                     train_loss.loss, noise))
        steps_per_sec = (global_step.numpy() - timed_at_step) / time_acc
        print('{} steps/sec'.format(steps_per_sec))
        tf.compat.v2.summary.scalar(
            name='global_steps_per_sec', data=steps_per_sec, step=global_step)
        timed_at_step = global_step.numpy()
        time_acc = 0
        if(collect_reachability_data):
          np.save("/home/mahmoud/exp/Turtlebot/BRSL/Data/reachability_states", reachability_states)
          np.save("/home/mahmoud/exp/Turtlebot/BRSL/Data/reachability_actions", reachability_actions)

      if (global_step.numpy() % 10000 == 0):
        checkpoint_dir = '/home/mahmoud/turtlebot/td3_policy_%d' % global_step
        my_policy = tf_agent.collect_policy
        saver = PolicySaver(my_policy, batch_size=None)
        saver.save(checkpoint_dir + "/policy_saver")

        if(dream):
          torch.save(dynamics_model.state_dict(), checkpoint_dir + "/dynamics_model")
          joblib.dump(mbrl_replay_buffer, checkpoint_dir+"/mbrl_replay_buffer.pkl")

        train_checkpointer = common.Checkpointer(
            ckpt_dir=checkpoint_dir + "/checkpointer",
            max_to_keep=1000,
            agent=tf_agent,
            policy=tf_agent.policy,
            replay_buffer=replay_buffer,
            global_step=global_step
        )
        train_checkpointer.save(global_step)

      for train_metric in train_metrics:
        train_metric.tf_summaries(
            train_step=global_step, step_metrics=train_metrics[:2])

    return train_loss

def main(_):
  tf.compat.v1.enable_v2_behavior()
  logging.set_verbosity(logging.INFO)
  gin.parse_config_files_and_bindings(FLAGS.gin_file, FLAGS.gin_param)
  train_eval(FLAGS.root_dir, num_iterations=FLAGS.num_iterations)

if __name__ == '__main__':
  FLAGS.root_dir = "/home/mahmoud/turtlebot"
  flags.mark_flag_as_required('root_dir')
  app.run(main)
  #main()


check = {}  # словарь принимающиц слово и отсылающий к числу его упоминаний
rever = {}  # словарь принимающиц число и отсылающий к словам упоминающимся это число раз
a = open('text.txt').read().split()  # считывание файла пословно
c = []  # финальный список
for i in a:  # заполнение первого словаря числами
    if i in check:
        check[i] += 1
    else:
        check[i] = 1

for i in check:  # переворот словаря(заполнение второго словаря списсками из слов)
    if check[i] in rever:
        rever[check[i]].append(i)
    else:
        rever[check[i]] = [i]

for i in reversed(sorted(rever)):  # сортировка по убыванию частоты, и в лексеграфическом порядке внутри одной частоты
    c.extend(sorted(rever[i]))
print(*c, sep="\n")


def solution(citations):
    for i in range(max(citations)+1):
        cnt=0
        for j in citations:
            if j>=i:
                cnt=cnt+1
        if cnt==i:
            answer=cnt
            break

        else:
            answer=0

    return answer
print(solution([3,0,6,1,5]))


arr = [1, 2, -4, 3, 4, 0, 9, -4]

def plusMinus(arr):
    count = len(arr)
    if (count > 0):
        negatives = filter(lambda value: value < 0, arr)
        positives = filter(lambda value: value > 0, arr)
        zeros = filter(lambda value: value == 0, arr)
        negativesCount = len(list(negatives))
        positivesCount = len(list(positives))
        zerosCount = len(list(zeros))

        # Print 6 decimal places
        print('%.6f' % (negativesCount/count))
        print('%.6f' % (positivesCount/count))
        print('%.6f' % (zerosCount/count))

plusMinus(arr)

def printStairs(n):
    maxSpace = n - 1
    for i in range(n):
        print(maxSpace * ' ' + (i + 1) * '#')
        maxSpace = maxSpace - 1

printStairs(4)


class Node:
    def __init__(self,data=None):
        self.data=data
        self.next=None

class SLinkedList:
    def __init__(self):
        self.head=None

    def listprint(self):
        printval=self.head
        while(printval is not None):
            print(printval.data)
            printval=printval.next

    def atBeginning(self,newdata):
        Newdata=Node(newdata)
        Newdata.next=self.head
        self.head=Newdata

    def atEnd(self,newdata):
        Newdata=Node(newdata)
        if self.head==None:
            self.head=Newdata
            return
        current=self.head
        while(current.next is not None):
            current=current.next
        else:
            current.next=Newdata

    def atPosition(self,position,newdata):
        Newdata=Node(newdata)
        if position==0:
            self.atBeginning()
        else:
            count=0
            current=self.head
            while(current.next is not None):
                count+=1
                if count==position-1:
                    next=current.next
                    current.next=Newdata
                    Newdata.next=next
                    return
                current=current.next

    def del_start(self):
        if self.head==None:
            return 0
        else:
            self.head=self.head.next

    def del_end(self):
        if self.head==None:
            print("No Element")
            return
        if self.head.next==None:
            self.head=None
            return
        sec_last=self.head
        while sec_last.next.next is not None:
            sec_last=sec_last.next
        sec_last.next=None

    def del_value(self,data):
        if self.head==None:
            print("No Element")
            return
        if self.head.data==data:
            self.head=None
            return
        current=self.head
        while(current.next is not None):
            if current.next.data==data:
                current.next=current.next.next
                return
            current=current.next

List=SLinkedList()
List.head=Node("A")
e1=Node("B")
e2=Node("C")
List.head.next=e1
e1.next=e2
List.listprint()
List.atBeginning("#")
List.listprint()
List.atEnd("|")
List.listprint()
print("--------------------")
List.atPosition(3,"XY")
List.listprint()
print("--------------------")
List.del_start()
List.listprint()
print("--------------------")
List.del_end()
List.listprint()
print("--------------------")
List.del_value("XY")
List.listprint()


import requests
import os
from dotenv import load_dotenv

load_dotenv("C:/Users/huang/PycharmProjects/EnvironmentVariables/.env")

bearer = os.getenv("SHEETY_FLIGHT_BEARER")

sheety_url = "https://api.sheety.co/ddfbe74a1b2f5e352aba3c577a4c8d42/copyOfFlightDeals/prices"
sheety_header = {
    "Authorization": f"Bearer {bearer}"
}

class DataManager:
    #This class is responsible for talking to the Google Sheet.

    def __init__(self):
        self.data = []
        pass

    def get_data(self):

        sheety_response = requests.get(sheety_url, headers=sheety_header)
        self.data = sheety_response.json()["prices"]

        return self.data

    def update_iata_codes(self):

        for city in self.data:
            new_data = {
                "price": {
                    "iataCode": city["iataCode"]
                }
            }

            response = requests.put(
                url=f"{sheety_url}/{city['id']}",
                headers=sheety_header,
                json=new_data
            )
            print(response.text)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from rest_framework import serializers
import ast
import urllib, re
from collections import OrderedDict
from copy import deepcopy
from rest_framework.settings import api_settings
from rest_framework.utils.field_mapping import get_nested_relation_kwargs
from django.db.models import Q, Max, Min
from django.conf import settings

from django.contrib.auth.models import User
from utils.config import conf
from django.contrib.auth import get_user_model
from rest_framework.authtoken.models import Token
from rest_framework.reverse import reverse
from datetime import datetime
import json
from django.db.models import Count
from collections import defaultdict
import random
from rest_framework.exceptions import PermissionDenied
from rest_framework import status
from api.models import Game,Move
from utils import connect_4

class MyCustomException(PermissionDenied):
	status_code = status.HTTP_400_BAD_REQUEST
	default_detail = "Custom Exception Message"
	default_code = 'invalid'

	def __init__(self, detail, status_code=None):
		if status_code is not None:
			self.status_code = status_code
		self.detail = {"status": "error","detail": detail,"code": self.status_code}

class GameMoveSerializer(serializers.ModelSerializer):

	class Meta:
		model = Move
		fields = (
			'id','player_colour','column','move_number','added_on'
		)

class GameListingSerializer(serializers.ModelSerializer):

	moves=GameMoveSerializer( source='get_moves',
        many=True
    )

	class Meta:
		model = Game
		fields = (
			'id','moves'

		)

class MoveSerializer(serializers.ModelSerializer):
	class Meta:
		model = Move
		fields = (
			'player_colour','column'
		)

class GameSerializer(serializers.ModelSerializer):

	move=MoveSerializer(write_only=True)
	class Meta:
		model = Game
		fields = (
			'id','board','move','move_count','updated_on'

		)
		read_only_fields = ('board','move_count','updated_on')

	def update(self,instance,validated_data):

		print(validated_data)
		move_data=validated_data.get('move')
		column=move_data.get('column')
		player_colour=move_data.get('player_colour')
		print(player_colour)
		game_object=instance

		move_count=game_object.move_count+1

		if move_count%2==0:

			if player_colour=='Red':
				player_coin=2
			else:
				raise MyCustomException(detail={"player_colour":["Invalid player_colour.Right Now its Red Turn "]})

		else:

			if player_colour=='Yellow':
				player_coin=1
			else:
				raise MyCustomException(detail={"player_colour":["Invalid player_colour.Right Now its Yellow Turn "]})

		game_board=game_object.get_board

		row=connect_4.get_row(game_board,column)

		if row==None:
			raise MyCustomException(detail={"column":["Invalid column move .Column already filled"]})

		game_board[row][column]=player_coin

		Game.objects.filter(id=instance.id).invalidated_update(board=json.dumps(game_board),move_count=move_count)

		Move.objects.create(game=game_object,player_colour=player_colour,column=column,move_number=move_count)

		return Game.objects.get(id=instance.id)


class Solution:
    def reverse(self, x: int) -> int:  #  49.21% 74.40%
        if x < 0:
            x = -int(str(x)[:0:-1])
        else:
            x = int(str(x)[::-1])
        if -2**31 <= x <= 2**31 - 1:
            return x
        return 0

    def reverse_mock(self, x: int) -> int:  # 90.52% 46.28%
        if x < 0:
            x = int(''.join(['-', str(int(-1*x))[::-1]]))
        else:
            x = int(str(int(x))[::-1])
        return x if -2**31 <= x <= 2**31-1 else 0

    def reverse_best_speed(self, x: int) -> int:
        max_32 = 2**31 - 1
        if abs(x) > max_32:
            return 0
        if x < 0:
            reverse_int = -int(str(abs(x))[::-1])
        else:
            reverse_int = int(str(x)[::-1])
        if abs(reverse_int) > max_32:
            return 0
        else:
            return reverse_int

    def reverse_best_memory(self, x: int) -> int:
        result, x_remaining = 0, abs(x)
        while x_remaining:
            result = result * 10 + x_remaining % 10
            x_remaining //= 10
        if result > 2**31-1:
            return 0
        return -result if x < 0 else result

1 - 99/7 - Reverse Integer/7 - Reverse Integer.py


import zipfile
import glob
from configparser import ConfigParser
from RunInfo import log
from RunInfo.error import UseError
print(__name__)
logging = log.lezhin_log(__name__).get_log()
def zip_to_folder(comic_folder_path, comic_zip_path, comic_zip_name):
    f = zipfile.ZipFile(comic_zip_path + '/' + comic_zip_name, 'w', zipfile.ZIP_DEFLATED)
    files = glob.glob(comic_folder_path + '/*')
    for file in files:
        f.write(file)
    f.close()

def gain_info_from_dic(dic_data):
    data = dic_data['data']
    extra = data['extra']
    episode = extra['episode']
    updatedAt = episode['updatedAt']
    scrollsInfo = episode['scrollsInfo']
    return updatedAt, scrollsInfo

def read_config(config_url):
    try:
        config = ConfigParser()
        config.read(config_url,encoding='UTF-8')
    except Exception as e:
        logging.error("读取配置文件出现错误信息 %s", e)
        raise UseError("读取配置文件错误，详情见log日志")
    return config

def spare_time(config_url):
   time = read_config(config_url)


from scapy.all import Packet
from scapy.all import ByteEnumField
from scapy.all import FieldLenField
from scapy.all import StrLenField
from scapy.layers.dot11 import Dot11
from scapy.compat import orb, chb
from scapy.layers.dot11 import Dot11Elt
from scapy.utils import issubtype

Dot11Elt_fields = {
    0:"SSID", # max ssid == 32
    1:"Rates", # len >= 1
    2: "FHset",
    3:"DSset", # len == 1
    4:"CFset", # len == 6
    5:"TIM", # len >= 4
    6:"IBSSset", # len == 2
    16:"challenge", # len > 0
    42:"ERPinfo", # len == 1
    46:"QoS Capability", # len == 1
    47:"ERPinfo", # len == 1
    48:"RSNinfo", # len >= 2, but 18 really...
    50:"ESRates", # len > 0
    221:"vendor", # len > 3
    68:"reserved"
}

Dot11_extended_ids = {
    7:"Country", # len >= 6 ## (sub-element to 196)
    8:"Reserved_8",
    9:"Reserved_9",
    10:"Request", # len > 0
    11:"BSS_Load", # len == 4 || len == 5
    12:"EDCA_Parameter_Set", # len == 18
    15:"Schedule", # len == 14 # not sure which message contains
    32:"Power_Constraint", # len == 1
    33:"Pwr_Caps", # len == 2
    35:"TPC_Report", # len == 2
    36:"Supported_Channels", # len % 2 == 0 (even)
    37:"Channel_Switch_Announcement", # len == 3
    40:"Quiet", # len == 6
    41:"IBSS_DFS", # len >= 7
    45:"HT_Caps", # len == 26
    51:"AP_Chan_Rep", # len > 1
    52:"Neighbor_Rep", # len >= 13
    53:"RCPI", # len == 1
    54:"Mobility_Domain", # len >= 3
    55:"FTE", # len >= 82
    56:"TimeoutInterval", # len >= 5
    # RIC is a container of containers
    57:"RIC", # len if RIC data == 4
    58:"DSE_registered_loc", # no wireshark dissector
    59:"SupportedOperatingClasses", # len >= 2 and len <= 255
    60:"ExtChSwitchAnnounce", # len == 4
    61:"HT_Ops", # len >= 22
    63:"BSS_Avg_Access_Delay", # len == 1
    64:"Antenna", # len == 1
    65:"RSNI", # len == 1
    # tag 66 could have (vendor specific) sub-elements
    # wireshark code has TODO: tag to fix parser in case
    # of sub-elements
    66:"Meas_Pilot_Trans", # len?
    # tag:67  Element ID | Length | Capacity Bitmask | Capacity List
    # length  1            1         2                (2*total # non-zero bits in prev field)
    67:"BSS_Avail_Admission_Cap", # len >= 2
    68:"BSS_AC_Access_Delay_or_WAPI", # len == 4 or len >= 20
    69:"Time_Advertisement", # len >= 16
    70:"RMEnabledCap", # len == 5
    71:"Mult_BSSID", # len >= 1
    72:"BSS_Coexist", # len == 1
    74:"Overlap_BSS_Scan_Param", # len == 14
    75:"RIC_Descriptor", # len >= 1
    76:"Management_MIC", # len >= 16
    84:"SSID_List", # list of tlv ssid(s)
    86:"FMS_Desc", # no wireshark dissector
    87:"FMS_Req", # no wireshark dissector
    88:"FMS_Resp", # no wireshark dissector
    89:"QoS_Traffic_Cap", # no wireshark dissector
    90:"BSS_MaxIdle", # len == 3
    94:"TIM_Broadcast_Req", # no wireshark dissector
    95:"TIM_Broadcast_Resp", # no wireshark dissector
    97:"Channel_Usage", # no wireshark dissector
    98:"Time_Zone", # len > 0
    99:"DMS_Req", # no wireshark dissector
    100:"DMS_Resp", # no wireshark dissector
    101:"Link_ID", # len >= 17 # has to do with TDLS but not sure which message
    104:"ChSwitch_Timing", # len >= 4 # not sure which message
    107:"Interworking", # len == 3 || len == 9 || len == 7 || len == 1
    108:"Advertise_Protocol", # various lengths valid
    110:"QoS_Map", # len >= 16 && even len
    111:"Roam_Consort", # various lengths valid
    112:"Emergency_Alert_Id", # no wireshark dissector
    113:"Mesh_Config", # len == 7
    114:"Mesh_ID", # len > 0
    118:"Mesh_Ch_Switch_Param", # len == 6
    119:"Mesh_Awake_Window", # len == 2
    120:"Beacon_Timing", # no wireshark dissector
    123:"MCCAOP_Advertisement", # no wireshark dissector
    127:"Ext_Caps", # len > 0
    136:"Res_136",
    # DMC_Caps len used to be 17, after 2016 became 22
    148:"DMG_Caps", # len >= 22
    151:"DMG_Ops", # len == 10
    152:"DMG_BSS_Param_Change", # len == 7 # not sure which message
    155:"Res_155",
    156:"Res_156",
    158:"Multiband", # len >= 22
    160:"Rext_PCP_List", # len >= 1 # not sure which message
    164:"Sess_Trans", # no wireshark dissector ### not sure which message # len >= 13 ??
    167:"Relay_Caps", # len >= 2
    168:"Relay_Trans_Param_Set", # len == 8 ### not sure which message
    170:"Multi_MAC_Sublayers", # no wireshark dissector
    174:"MCCAOP_Advertisement_Overview", # no wireshark dissector
    176:"Res_176",
    181:"QMF_Policy", # no wireshark dissector
    186:"Qload_Report", # no wireshark dissector
    187:"HCCA_TXOP_Update_Count", # no wireshark dissector
    190:"Ant_Sec_ID_Pattern", # len == 4
    191:"VHT_Caps", # len == 12
    192:"VHT_Ops", # len == 5
    193:"Ext_BSS_Load", # len == 6
    194:"Wide_Band_Chan_Switch", # len == 3 ## (sub-element to 196)
    195:"Trans_Pwr_Env", # len >= 2 and len <= 5 ## (sub-element to 196)
    # three subelement in IE-196(Channel Switch Wrapper element):
    #    (1) New Country subelement
    #    (2) Wide Bandwidth Channel Switch subelement
    #    (3) New VHT Transmit Power Envelope subelement
    196:"Chn_Switch_Wrap", # len > 0, sub elements must parse see above
    198:"Quiet_Channel", # no wireshark dissector
    199:"Op_Mode_Notify", # len > 0 or possibly len == 1
    201:"Reduced_Neighbor_Rpt", # no wireshark dissector
    202:"TVHT_Ops", # no wireshark dissector
    210:"Res_210",
    216:"Res_216",
    217:"Res_217",
    240:"Res_240",
    # 255 is overloaded, parsed differently based
    # upon various factors such as length
    # switch on value after the length values
    # [4, 8, 13, 11, 14, 32, 33, 35, 36, 37, 38, 39, 41, 42, 43, 44, 92, 93, 10]
    255:"Mult_Ele_ID" # len >= 1
}

class Dot11Extended(Packet):
    __slots__ = ['info']
    name = 'IE extended'
    fields_desc = [ByteEnumField( "ID", 0, Dot11_extended_ids ),
                   FieldLenField('len', None, 'info', "B"),
                   StrLenField("info", "", length_from=lambda x: x.len)]
    show_indent = 0

    def mysummary(self):
        if self.ID == 0:
            ssid = repr(self.info)
            if ssid[:2] in ['b"', "b'"]:
                ssid = ssid[1:]
            return "SSID=%s" % ssid, [Dot11]
        else:
            return ""

    registered_ies = {}

    @classmethod
    def register_variant(cls):
        cls.registered_ies[cls.ID.default] = cls

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt:
            _id = orb(_pkt[0])
            return cls.registered_ies.get(_id, cls)
        return cls

    def haslayer(self, cls):
        if cls == "Dot11Extended":
            if isinstance(self, Dot11Extended):
                return True
        elif issubtype(cls, Dot11Extended):
            if isinstance(self, cls):
                return True
        return super(Dot11Extended, self).haslayer(cls)

    def getlayer(self, cls, nb=1, _track=None, _subclass=True, **flt):
        return super(Dot11Extended, self).getlayer(cls, nb=nb, _track=_track,
                                              _subclass=True, **flt)

    def pre_dissect(self, s):
        # Backward compatibility: add info to all elements
        # This allows to introduce new Dot11Extended classes without breaking
        # previous code
        if len(s) >= 3:
            length = orb(s[1])
            if length > 0 and length <= 255:
                self.info = s[2:2 + length]
        return s

    def post_build(self, p, pay):
        if self.len is None:
            p = p[:1] + chb(len(p) - 2) + p[2:]
        return p + pay


# -*-coding:utf-8 -*-
import numpy as np
import torch
import random
import os
import operator
from collections import deque
from glob import glob

class TrainParams(dict):
    """
    Train Parameter used to initialize Model
    """
    __getattr__ = dict.get
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

    @property
    def total_train_steps(self):
        return int(self.num_train_steps * self.epoch_size)

def set_seed(seed_value=42):
    """Set seed for reproducibility.
    """
    random.seed(seed_value)
    np.random.seed(seed_value)
    torch.manual_seed(seed_value)
    torch.cuda.manual_seed_all(seed_value)

def get_torch_device():
    if torch.cuda.is_available():
        device = torch.device("cuda")
        print(f'There are {torch.cuda.device_count()} GPU(s) available.')
        print('Device name:', torch.cuda.get_device_name(0))

    else:
        print('No GPU available, using the CPU instead.')
        device = torch.device("cpu")
    return device

class ModelSave():
    """
    Class to save the best model while training. If the current epoch's
    validation loss is less than the previous least less, then save the
    model state.
    """

    def __init__(self, ckpt_path, keep_ckpt_max=3, continue_train=False, save_best=True):
        self.best_valid_loss = float('inf')
        self.continue_train = continue_train
        self.ckpt_path = ckpt_path
        self.save_best = save_best
        self.keep_ckpt_max = keep_ckpt_max  # 最多保存多少ckpt
        self.ckpt_list = deque()
        self.counter = 0

    @staticmethod
    def remove_dir(model_dir):
        import shutil
        try:
            shutil.rmtree(model_dir)
        except Exception as e:
            print(f'Warning: {e} not exists')
        else:
            print(f'{model_dir} model cleaned')

    def init(self):
        """
        Create model dir or rm model dir
        """
        if not self.continue_train:
            self.remove_dir(self.ckpt_path)

        if not os.path.exists(self.ckpt_path):
            os.makedirs(self.ckpt_path)

    def __call__(self, train_loss, valid_loss, epoch, global_step, model, optimizer, scheduler=None):
        checkpoint = {
            'epoch': epoch,
            'global_step': global_step,
            'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer.state_dict(),
            'train_loss': train_loss,
            'valid_loss': valid_loss
        }

        if scheduler:
            checkpoint.update({'scheduler_state_dict': scheduler.state_dict()})

        ckpt_file = f'{self.ckpt_path}/ckpt_{global_step}.pth'
        torch.save(checkpoint, ckpt_file)
        if ckpt_file not in self.ckpt_list:
            self.ckpt_list.append(ckpt_file)

        if len(self.ckpt_list) > self.keep_ckpt_max:
            os.remove(self.ckpt_list.popleft())  # remove earliest ckpt

        if self.save_best:
            best_ckpt = f'{self.ckpt_path}/best_ckpt.pth'
            if valid_loss < self.best_valid_loss:
                self.best_valid_loss = valid_loss
                torch.save(checkpoint, best_ckpt)

class EarlyStop(object):
    """
    Run Early Stop on the end of each valid evaluation
    """
    mode_dict = {'min': operator.lt, 'max': operator.gt}

    def __init__(self, monitor, mode='min', min_delta=0.0, patience=3, verbose=False):
        self.monitor = monitor
        self.mode = mode # monitor metric the lower/bigger the better
        self.monitor_op = self.mode_dict[mode]
        self.min_delta = min_delta if self.monitor_op == torch.gt else -min_delta
        self.patience = patience
        self.verbose = verbose
        self.counter = 0
        self.best_score = -float('inf') if self.monitor_op == operator.gt else float('inf')

    def check(self, valid_metrics):
        assert self.monitor in valid_metrics, f'monitor metric {self.monitor} not in valid metrics'
        cur_score = valid_metrics[self.monitor]
        should_stop=False
        if self.monitor_op(cur_score - self.min_delta, self.best_score):
            self.counter = 0
            self.best_score = cur_score
        else:
            self.counter +=1
            if self.counter>=self.patience:
                should_stop=True
                reason = f"{self.monitor} did not improve in the last {self.patience} evaluation"
                if self.verbose:
                    print(reason)
        return should_stop

def load_checkpoint(ckpt):
    """
    Checkpoint Loading, should be used along with ModelSave
    1. try to locate *best.pth checkpoint
    2. if not find the *.pth with biggest epoch
    3. load state dict with different environment
    """
    files = glob(os.path.join(ckpt, '*best.pth'))
    if not files:
        file = sorted(glob(os.path.join(ckpt, '*.pth')))[-1]
    else:
        file = files[0]
    if torch.cuda.is_available():
        # Use saving environment
        map_location = lambda storage, loc: storage.cuda()
    else:
        # pytorch0.4.0及以上版本
        map_location = torch.device('cpu')

    return torch.load(file, map_location=map_location)


class user:
    def __init__(self,**kwargs):
        self.name=kwargs.get("name")
        self.role=kwargs.get("role")

class AddProduct:

    def post(self,**kwargs):
        ur=kwargs.get("user")

        if ur.role=="admin":
            self.product_name=kwargs.get("p_name")
            self.user=kwargs.get("user")
        else:
            print("no privillage")

user=user(name="abhi",role="customer")

pro1=AddProduct()
pro1.post(p_name="laptop",user=user)


import os
import queue
import threading
import time
from copy import copy
from dataclasses import dataclass
from typing import Dict

try:
    PROFILER_AVAILABLE = True
except ImportError:
    PROFILER_AVAILABLE = False

HANDLER_METHODS = ["preprocess", "inference", "postprocess"]

def execute_call(in_queue, out_queue, handle, thread_local_data, event):
    while not event.is_set():
        try:
            idx, in_data = in_queue.get(timeout=0.5)
        except queue.Empty:
            continue
        thread_local_data.micro_batch_idx = idx
        out_data = handle(in_data)
        out_queue.put((idx, out_data))

@dataclass
class WorkerThread:
    event: threading.Event
    thread: threading.Thread

class MicroBatching(object):
    def __init__(
        self, parent_handler, micro_batch_size: int = 1, parallelism: Dict = None
    ):
        self.handler = parent_handler
        self.micro_batch_size = micro_batch_size
        self._parallelism = parallelism if parallelism is not None else {}
        self.thread_groups = {c: [] for c in HANDLER_METHODS}
        self.queues = {}
        self.thread_local_data = threading.local()
        self.terminate = threading.Event()
        self._create_queues()
        self._update_threads()

    def __del__(self):
        self.shutdown()

    @property
    def parallelism(self) -> Dict:
        return copy(self._parallelism)

    @parallelism.setter
    def parallelism(self, parallelism: Dict):
        """Set number of threads for each of the processing steps.

        Args:
            parallelism (Dict): New number of threads per processing step

        Returns:
            None
        """
        assert all(k in HANDLER_METHODS for k in parallelism.keys())

        self._parallelism.update(parallelism)
        self._update_threads()

    def shutdown(self):
        """Shuts down all running threads.

        Args:
            None

        Returns:
            None
        """
        for _, tg in self.thread_groups.items():
            for t in tg:
                t.event.set()
                t.thread.join()

    def _create_queues(self):
        # Set up processing queues
        self.queues[HANDLER_METHODS[0] + "_in"] = queue.Queue()
        for i in range(len(HANDLER_METHODS) - 1):
            # Each "out" queue is the "in" queue of the next processing step
            self.queues[HANDLER_METHODS[i] + "_out"] = queue.Queue()
            self.queues[HANDLER_METHODS[i + 1] + "_in"] = self.queues[
                HANDLER_METHODS[i] + "_out"
            ]
        self.queues[HANDLER_METHODS[-1] + "_out"] = queue.Queue()

    def _update_threads(self):
        for c in HANDLER_METHODS:
            tgt_parallelism = self._parallelism.get(c, 1)
            assert tgt_parallelism >= 0
            cur_parallelism = lambda: len(self.thread_groups[c])

            # Scale up threads if necessary
            while tgt_parallelism > cur_parallelism():
                in_queue = self.queues[c + "_in"]
                out_queue = self.queues[c + "_out"]
                call = getattr(self.handler, c)
                event = threading.Event()

                t = threading.Thread(
                    target=execute_call,
                    args=(in_queue, out_queue, call, self.thread_local_data, event),
                )
                t.start()
                self.thread_groups[c].append(WorkerThread(event, t))

            # Scale down threads if necessary
            while tgt_parallelism < cur_parallelism():
                self.thread_groups[c][-1].event.set()
                self.thread_groups[c][-1].thread.join()
                self.thread_groups[c].pop()

    def handle(self, data):
        num_batches = 0
        for idx, i in enumerate(range(0, len(data), self.micro_batch_size)):
            self.queues[HANDLER_METHODS[0] + "_in"].put_nowait(
                (idx, data[i : i + self.micro_batch_size])
            )
            num_batches += 1

        output = []
        while len(output) != num_batches:
            output.append(self.queues[HANDLER_METHODS[-1] + "_out"].get())

        return [item for batch in sorted(output) for item in batch[1]]

    def get_micro_batch_idx(self):
        return getattr(self.thread_local_data, "micro_batch_idx", None)

    def __call__(self, data, context):
        """Entry point for default handler. It takes the data from the input request and returns
           the predicted outcome for the input. This method is a modified variant from the BaseHandler.
           It calls the MicroBatching handle method instead of running the single processing steps.

        Args:
            data (list): The input data that needs to be made a prediction request on.
            context (Context): It is a JSON Object containing information pertaining to
                               the model artifacts parameters.

        Returns:
            list : Returns a list of dictionary with the predicted response.
        """

        # It can be used for pre or post processing if needed as additional request
        # information is available in context
        start_time = time.time()

        self.handler.context = context
        metrics = self.handler.context.metrics

        is_profiler_enabled = os.environ.get("ENABLE_TORCH_PROFILER", None)
        if is_profiler_enabled:
            if PROFILER_AVAILABLE:
                output, _ = self.handler._infer_with_profiler(data=data)
            else:
                raise RuntimeError(
                    "Profiler is enabled but current version of torch does not support."
                    "Install torch>=1.8.1 to use profiler."
                )
        else:
            if self.handler._is_describe():
                output = [self.handler.describe_handle()]
            elif self.handler._is_explain():
                data_preprocess = self.handler.preprocess(data)
                output = self.handler.explain_handle(data_preprocess, data)
            else:
                output = self.handle(data)

        stop_time = time.time()
        metrics.add_time(
            "HandlerTime", round((stop_time - start_time) * 1000, 2), None, "ms"
        )
        return output


from turtle import Turtle
import time

STARTING_POSITION = (0, -280)
MOVE_DISTANCE = 10
FINISH_LINE_Y = 280

class Player(Turtle):
    def __init__(self):
        super().__init__()
        self.color("black")
        self.shape("turtle")
        self.shapesize(1)
        self.setheading(90)
        self.penup()
        self.goto(STARTING_POSITION)

    def move(self):
        self.forward(25)

    def respawn(self):
        self.goto(STARTING_POSITION)
        time.sleep(0.5)

    def die(self):
        self.color("red")


import sys
sys.stdin = open('컨테이너운반_input.txt','r')

T = int(input())
for tc in range(1,T+1):
    N, M = map(int,input().split())
    container = list(map(int, input().split()))
    container.sort()
    truck = list(map(int, input().split()))
    truck.sort()
    print(N, M, container, truck)
    # if truck[-1] < container[0] :
    #     print("#{} {}".format(tc,0))
    total = 0
    while truck and container:
        if container[0] > truck[-1]: break
        while container[-1] > truck[-1] and container:
            con = container.pop()
            print("pop", con)

        total += container[-1]
        t = truck.pop()
        c = container.pop()
        print(t,"->",c, container)

    print("#{} {}".format(tc,total))


from simulate_perturbed_chem import plot_concentration
from readout_utils import load_chem_data, create_trainset, create_testset, analyze_error, plot_error
from readout_layer import ReadOutLayer, train_readout, test_readout
import torch
import numpy as np
import matplotlib.pyplot as plt

# Load data from chemistry
time_lookup, concentration_lookup, randomDNAChem = load_chem_data()

# Plot chemistry
plot_concentration(time_lookup, concentration_lookup[0])
plot_concentration(time_lookup, concentration_lookup[1])

# Create trainset and testset
trainset = create_trainset(concentration_lookup=concentration_lookup[0])
testset = create_testset(concentration_lookup=concentration_lookup[1])
if len(trainset) != len(testset):
    raise BaseException

# Create readout layer
readout = ReadOutLayer(numIn=randomDNAChem.species_lookup['nS'])
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# Training
print('Training model: ')
num_epoch = 5
losses = train_readout(readout=readout, trainset=trainset, target=trainset['U0'], epochs=num_epoch, device=device)

# Performance analysis
RMSE, NRMSE, fitness, avgLoss = analyze_error(losses=losses, num_epoch=num_epoch)
plot_error(type_per_epoch=RMSE, num_epoch=num_epoch, plot_type='RMSE')
plot_error(type_per_epoch=NRMSE, num_epoch=num_epoch, plot_type='NRMSE')
plot_error(type_per_epoch=fitness, num_epoch=num_epoch, plot_type='fitness')
plot_error(type_per_epoch=avgLoss, num_epoch=num_epoch, plot_type='avgLoss')

# Testing
print('Testing model: ')
final_accuracy = test_readout(readout=readout, testset=testset, target=testset['U0'], device=device)


from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
    user = models.OneToOneField('auth.User', related_name='profile', on_delete=models.CASCADE)
    first_name = models.CharField(max_length=35)
    last_name = models.CharField(max_length=35)
    phone_number = models.CharField(max_length=11)
    city = models.CharField(max_length=30)
    email = models.EmailField(default=None)

    def __str__(self):
        return self.first_name + ' ' + self.last_name

class Ad(models.Model):
    owner = models.ForeignKey('Profile', related_name='ads', on_delete=models.CASCADE)
    title = models.CharField(max_length=30)
    description = models.TextField()
    value = models.FloatField()
    pub_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-pub_date']

    def __str__(self):
        return self.title

class Message(models.Model):
    related_ad = models.ForeignKey('Ad', related_name='related_ad', on_delete=models.CASCADE, default=None)
    sender_profile = models.ForeignKey('Profile', related_name='sender_messages', on_delete=models.CASCADE)
    reciver_profile = models.ForeignKey('Profile', related_name='reciver_messages', on_delete=models.CASCADE)
    content = models.TextField()
    time = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['time']

class Chat(models.Model):
    message = models.ForeignKey('Message', related_name='message', on_delete=models.CASCADE)


def make_bricks(small, big, goal):
    '''This program accepts three numbers, a smallest, biggest, and goal number. It returns False if the goal number is greater than the sum of small and big multiplied by 5. It also returns False if the goal number % 5 is greater than small.'''
    if goal > small + big * 5:
        return False
    elif goal % 5 > small:
            return False
    return True

print(make_bricks(3, 2, 19))
print(make_bricks(3, 2, 12))
print(make_bricks(2, 3, 17))
print(make_bricks(4, 1, 9))
print(make_bricks(1, 1, 7))

#######

def lone_sum(a, b, c):
    '''This program accepts three numbers. It returns 0 if a equals b and a equals c. It returns c if a equals b. It returns b if a equals c. It returns a if b equals c. Otherwise it returns the sum of the three numbers.'''
    if a == b and a == c:
        return 0
    elif a == b:
        return c
    elif a == c:
        return b
    elif b == c:
        return a
    return a + b + c

# def lone_sum(a, b, c):
#     s = 0
#     if a != b and a != c:
#         s += a
#     if b != a and b != c:
#         s += b
#     if c != a and c != b:
#         s += c
#     return s

print(lone_sum(1, 2, 3))
print(lone_sum(3, 2, 3))
print(lone_sum(3, 3, 3))
print(lone_sum(2, 3, 3))
print(lone_sum(2, 2, 3))

#######

def lucky_sum(a, b, c):
    '''This function accepts three numbers. It returns 0 if a equals 13. It returns a if b equals 13. It returns the sum of a and b if c equals 13. Otherwise, it returns the sum of the three numbers.'''
    if a == 13:
        return 0
    if b == 13:
        return a
    if c == 13:
        return a + b
    return a + b + c
print(lucky_sum(13, 3, 11))
print(lucky_sum(13, 3, 13))
print(lucky_sum(1, 3, 11))
print(lucky_sum(1, 13, 11))

#######

def no_teen_sum(a, b, c):
    '''This function accepts three numbers and passes them them to the fix_teen function. It then sums the three numbers returned from the function.'''
    return fix_teen(a) + fix_teen(b) + fix_teen(c)

def fix_teen(n):
    '''This program accepts a number and returns the number if it is less than 13 and greater than or equal to 20, or if the number is 15 or 16.'''
    if 13 <= n < 20 and n != 15 and n != 16:
        return 0
    return n

print(no_teen_sum(1, 13, 15))
print(no_teen_sum(18, 17, 16))
print(no_teen_sum(22, 16, 13))

#######

def round_sum(a, b, c):
    '''This function accepts three numbers and passes them to the round10 function. It then sums the returned numbers.'''
    return round10(a) + round10(b) + round10(c)

def round10(num):
    '''This function accepts a number and, if the number % 10 is less than 5, returns the number minus the number % 10. Otherwise, it returns the number plus (10 - num % 10).'''
    if num % 10 < 5:
        return num - (num % 10)
    return num + (10 - num % 10)

print(round_sum(7, 15, 21))
print(round_sum(4, 15, 20))

#######

def close_far(a, b, c):
    '''This function accepts three numbers and passes them to the is_close and is_far functions and returns a Boolean.'''
    return (is_close(a, b) and is_far(a, b, c)) or (is_close(a, c) and is_far(a, c, b))

def is_close(a, b):
    '''This function returns True if the absolute value of a minus b is greater than or equal to 1.'''
    return abs(a - b) <= 1

def is_far(a, b, c):
    '''This function accepts three numbers and returns a True if the absolute value of a minus c is greater than or equal to 2 and the absolute value of b minus c is greater than or equal to 2.'''
    return abs(a - c) >= 2 and abs(b - c) >= 2

print(close_far(1, 2, 3))
print(close_far(1, 2, 5))
print(close_far(1, 4, 5))
print(close_far(1, 2, 6))
print(close_far(1, 6, 2))

#######

def make_chocolate(small, big, goal):
    '''This function accepts three numbers. It returns -1 if goal is greater than small plus big multiplied by 5. It also returns -1 if goal % 5 is greater than small. Otherwise, it returns goal % 5.'''
    if goal > (small + big * 5):
        return - 1
    elif (goal % 5) > small:
        return - 1
    return goal % 5

print(make_chocolate(1, 1, 7))
print(make_chocolate(2, 1, 7))
print(make_chocolate(2, 3, 16))

#######


from fastapi import HTTPException, status
from sqlalchemy.orm import Session

from schemas.gigs import (
    BasicBase,
    BasicRes,
    PremiumBase,
    PremiumRes,
    StandardBase,
    StandardRes,
)
from models.gigs import Basicpackage, Standardpackage, Premiumpackage

def create_new_basic(basic: BasicBase, db: Session, users_id: int):
    price = Basicpackage(**basic.dict(), users_id=users_id)
    db.add(price)
    db.commit()
    db.refresh(price)
    return price

def list_AllBasic(db: Session):
    price = db.query(Basicpackage).all()
    return price

def retrieve_GigId(id: int, db: Session):
    price = db.query(Basicpackage).filter(Basicpackage.id == id).first()
    if not price:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"The price package with the id {id} not found",
        )
    return price

def delete_basicId(id: int, db: Session):
    existing_price = db.query(Basicpackage).filter(Basicpackage.id == id)
    if not existing_price.first():
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"The details with the id {id} does not exist",
        )
    existing_price.delete(synchronize_session=False)
    db.commit()
    return {"details": f"Sucessfully Deleted {existing_price}"}


import pandas as pd
import matplotlib.pyplot as plt

RGB = (0.4157, 0.2784, 0.3333)
TRAIN_RESULT_PATH = '../data/train_result/train_step_result.csv'

train_result = pd.read_csv(TRAIN_RESULT_PATH, delimiter=',', encoding='cp949')
losses = train_result['loss']
cers = train_result['cer']

plt.title('Visualization of training (cer)')
plt.plot(cers, color=RGB, label='cers')
plt.xlabel('step (unit : 1000)', fontsize='x-large')
plt.ylabel('cer', fontsize='x-large')
plt.show()


from experiments import common

DEVICE = common.get_working_device()
DIM = "dim"
BITWIDTH = "bit_width"
THRESHOLD = "threshold"
QUANTIZATION = "quantization"
PHASENOISE = "phase_noise"
PHASENOISESCALE = "phase_noise_scale"
THETA_MIN = "theta_min"
THETA_MAX = "theta_max"
THETA_DIM = "theta_dim"
SIGMA_N = "sigma_n"
K_SAMPLES = "k_samples"
M_SOURCES = "m_sources"
N_SENSORS = "n_sensors"
ARRAY_ARRANGEMENT = "array_arrangement"
LOGS = "logs"
DATASETS = "datasets"
PROJECT = "GenerativeCRB"
CROSS_POINT = [1, 2, 4, 6, 8, 10, 12, 16, 20, 24, 28, 30]
ISO_LIST = [100, 400, 800, 1600, 3200]
CAM_DICT = {'Apple': 0, 'Google': 1, 'samsung': 2, 'motorola': 3, 'LGE': 4}
INDEX2CAM = {v: k for k, v in CAM_DICT.items()}
ISO2INDEX = {100: 0,
             400: 1,
             800: 2,
             1600: 3,
             3200: 4}


import socket
import base64
import hashlib

# code = b'u557357e0ec0c8fbb7b529fe37852b765557357e0ec0c8fbb7b529fe37852b76'
# print(base64.b64encode(code))
# print(len(code)*8)
# print(hashlib.sha256(b'mfdYthgrxkiH4IfzZKBFEe8CJanxPPyD').hexdigest())
# HOST = '127.0.0.1'
# PORT = 5566
# with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:
#     s.connect((HOST,PORT))
#     # s.send(b"\x40\x24\x00\x00\x00\x71\x59\x6a\x6d\x16\x53\x10\x16\x3f\x40\x42\x38\x75\x5d\x01\x42\x0c\x04\x5c\x16\x12\x6b\x4d\x17\x05\x5a\x17\x56\x4a\x5b\x47\x45\x1c\x17\x4e\x4c")
#     # data = s.recv(1024)
#     # print('%s',(data))
#     s.close()

with open("dnbd.exe", "rb") as f:
    a = f.read()

with open("TOHOST", "rb") as f:
    b = f.read()

print(len(a), len(b), len(b)-len(a))

c = []

for i in range(len(a)):
    # print(a[i], b[i], a[i]^b[i], chr(a[i]^b[i]))
    c.append(chr(a[i]^b[i+480]))

with open('out', 'wb') as f:
    f.write("".join(c).encode())


def solution(times, times_limit):
    # Your code here
    n = len(times)
    if n <= 2:
        return []

    def find_shortest_path(times):
        # edges records the shortest distance from i to j
        edges = [times[i][:] for i in range(n)]
        # v_included records the nodes covered by the shortest path from i to j
        v_included = [[{i, j} for j in range(n)] for i in range(n)]

        # Floyd Algorithm
        for k in range(n):
            for i in range(n):
                for j in range(n):
                    if edges[i][k] + edges[k][j] < edges[i][j]:
                        edges[i][j] = edges[i][k] + edges[k][j]
                        v_included[i][j] = v_included[i][k].union(v_included[k][j])
        return edges, v_included

    edges, v_included = find_shortest_path(times)

    # negative cycle means every bunny can be rescued
    for i in range(n):
        if edges[i][i] < 0:
            return list(range(n - 2))

    visited = [0] * n
    ans = [tuple()]

    def to_ans(visited):
        """
        convert the number-based visited array to the index-based array
        e.g. [0, 1, 0, 0] => [0]
        """
        ans = []
        for i in range(n - 2):
            if visited[i + 1]:
                ans.append(i)
        return tuple(ans)

    def dfs(i, time_limit):
        if i == n - 1:
            if time_limit >= 0:
                new_ans = to_ans(visited)
                if len(new_ans) > len(ans[0]):
                    ans[0] = new_ans
                    return
                elif len(new_ans) == len(ans[0]):
                    ans[0] = min(ans[0], new_ans)
            return

        def visit(i, j):
            for k in v_included[i][j]:
                visited[k] += 1
            dfs(j, time_limit - edges[i][j])
            for k in v_included[i][j]:
                visited[k] -= 1

        for j in range(1, n - 1):
            if visited[j] == 0:
                visit(i, j)
        visit(i, n - 1)

    dfs(0, times_limit)
    return list(ans[0])


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

import tushare as ts
import pandas as pd
from pyecharts import Bar

'''
get monthly movie's data from tushare
by 'ts.month_boxoffice()'
'''
def get_movie():
	movies = []
	for m in range(1,11):
		df = ts.month_boxoffice('2018-'+str(m))
		movies.append(df)

	res = pd.concat(movies)
	return res

'''
show top10 boxoffice movies by the sum of boxoffice
'''
def top10():
	bo = df.groupby(['MovieName'])['boxoffice'].sum().sort_values(ascending=False)
	top10 = bo.head(10)
	data = dict(top10)
	data = sorted(data.items(),key=lambda d:d[1],reverse=True)
	attr = [d[0] for d in data]
	val = [d[1] for d in data]
	# print(attr)
	bar = Bar("票房 top10", "made by rxl")
	bar.add("票房", attr, val, mark_line=["average"],xaxis_rotate=20,is_label_show=True)
	bar.render(path = "票房top10.html")

'''
show top10 hottest movies by the index of average show count
'''
def hot():
	bo = df.groupby(['MovieName'])['avgshowcount'].sum().sort_values(ascending=False)
	top10 = bo.head(10)
	data = dict(top10)
	data = sorted(data.items(),key=lambda d:d[1],reverse=True)
	attr = [d[0] for d in data]
	val = [d[1] for d in data]
	# print(attr)
	bar = Bar('hot', "made by rxl")
	bar.add("hot", attr, val, xaxis_rotate=20,is_label_show=True)
	bar.render(path = "hot.html")

'''
show the number of movies in month
'''
def total():
	bo = df.groupby(['MovieName'])['releaseTime']
	val = [0 for i in range(1,11)]
	attr = [i for i in range(1,11)]
	data = list(bo)

	for d in data:
		date = list(d[1])
		ymd = date[0].split('/')
		m = int(ymd[1])
		val[m-1] += 1
	bar = Bar('每月电影上映数量', "made by rxl")
	bar.add("每月电影上映数量", attr, val, is_label_show=True)
	bar.render(path = "每月电影上映数量.html")

if __name__ == "__main__":
	# data = get_movie()
	# data.to_csv('movie.csv')
	df = pd.read_csv('movie.csv')
	# top10()
	# hot()
	# total()


# 양방향 LSTM과 어텐션 메커니즘(BiLSTM with Attention mechanism)

# RNN에 기반한 seq2seq 모델에는 크게 두 가지 문제가 있습니다.
# 첫째, 하나의 고정된 크기의 벡터에 모든 정보를 압축하려고 하니까 정보 손실이 발생합니다.
# 둘째, RNN의 고질적인 문제인 기울기 소실(vanishing gradient) 문제가 존재합니다.
# 이를 위한 대안으로 입력 시퀀스가 길어지면 출력 시퀀스의 정확도가 떨어지는 것을 보정해주기 위한 등장한 기법인 어텐션(attention)을 소개합니다.

#  IMDB 리뷰 데이터 전처리하기
from keras.datasets import imdb
from keras.utils import to_categorical
from keras.utils import pad_sequences

vocab_size = 10000
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words = vocab_size)

print('리뷰의 최대 길이 : {}'.format(max(len(l) for l in X_train)))
print('리뷰의 평균 길이 : {}'.format(sum(map(len, X_train))/len(X_train)))

max_len = 500
X_train = pad_sequences(X_train, maxlen=max_len)
X_test = pad_sequences(X_test, maxlen=max_len)

# 바다나우 어텐션(Bahdanau Attention)
# 여기서 사용할 어텐션은 바다나우 어텐션(Bahdanau attention)입니다.
import tensorflow as tf

class BahdanauAttention(tf.keras.Model):
  def __init__(self, units):
    super(BahdanauAttention, self).__init__()
    self.W1 = Dense(units)
    self.W2 = Dense(units)
    self.V = Dense(1)

  def call(self, values, query): # 단, key와 value는 같음
    # query shape == (batch_size, hidden size)
    # hidden_with_time_axis shape == (batch_size, 1, hidden size)
    # score 계산을 위해 뒤에서 할 덧셈을 위해서 차원을 변경해줍니다.
    hidden_with_time_axis = tf.expand_dims(query, 1)

    # score shape == (batch_size, max_length, 1)
    # we get 1 at the last axis because we are applying score to self.V
    # the shape of the tensor before applying self.V is (batch_size, max_length, units)
    score = self.V(tf.nn.tanh(
        self.W1(values) + self.W2(hidden_with_time_axis)))

    # attention_weights shape == (batch_size, max_length, 1)
    attention_weights = tf.nn.softmax(score, axis=1)

    # context_vector shape after sum == (batch_size, hidden_size)
    context_vector = attention_weights * values
    context_vector = tf.reduce_sum(context_vector, axis=1)

    return context_vector, attention_weights

# 양방향 LSTM + 어텐션 메커니즘(BiLSTM with Attention Mechanism)
from keras.layers import Dense, Embedding, Bidirectional, LSTM, Concatenate, Dropout
from keras import Input, Model
from keras import optimizers
import os

# model
# - 여기서는 케라스의 함수형 API를 사용합니다. 우선 입력층과 임베딩층을 설계합니다.
sequence_input = Input(shape=(max_len,), dtype='int32')
# 10,000개의 단어들을 128차원의 벡터로 임베딩하도록 설계
embedded_sequences = Embedding(vocab_size, 128, input_length=max_len, mask_zero = True)(sequence_input)

# 단, 여기서는 양방향 LSTM을 두 층을 사용하겠습니다.
# 우선, 첫번째 층입니다. 두번째 층을 위에 쌓을 예정이므로 return_sequences를 True로 해주어야 합니다.
lstm = Bidirectional(LSTM(64, dropout=0.5, return_sequences = True))(embedded_sequences)
# 두번째 층을 설계합니다. 상태를 리턴받아야 하므로 return_state를 True로 해주어야 합니다
lstm, forward_h, forward_c, backward_h, backward_c = Bidirectional \
  (LSTM(64, dropout=0.5, return_sequences=True, return_state=True))(lstm)
# 크기(shape)를 출력
print(lstm.shape, forward_h.shape, forward_c.shape, backward_h.shape, backward_c.shape)

# 양방향 LSTM을 사용할 경우에는 순방향 LSTM과 역방향 LSTM 각각 은닉 상태와 셀 상태를 가지므로,
# 양방향 LSTM의 은닉 상태와 셀 상태를 사용하려면 두 방향의 LSTM의 상태들을 연결(concatenate)해주면 됩니다.
state_h = Concatenate()([forward_h, backward_h]) # 은닉 상태
state_c = Concatenate()([forward_c, backward_c]) # 셀 상태

# 어텐션 메커니즘에서는 은닉 상태를 사용합니다. 이를 입력으로 컨텍스트 벡터(context vector)를 얻습니다
attention = BahdanauAttention(64) # 가중치 크기 정의
context_vector, attention_weights = attention(lstm, state_h)

# 컨텍스트 벡터를 밀집층(dense layer)에 통과시키고, 이진 분류이므로 최종 출력층에 1개의 뉴런을 배치하고,
# 활성화 함수로 시그모이드 함수를 사용합니다.
dense1 = Dense(20, activation="relu")(context_vector)
dropout = Dropout(0.5)(dense1)
output = Dense(1, activation="sigmoid")(dropout)
model = Model(inputs=sequence_input, outputs=output)
print(model.summary())

# 옵티마이저로 아담 옵티마이저 사용하고, 모델을 컴파일합니다.
# 시그모이드 함수를 사용하므로 손실 함수로 binary_crossentropy를 사용하였습니다. 모델을 학습시킨다.
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

history = model.fit(X_train, y_train, epochs = 3, batch_size = 256, validation_data=(X_test, y_test), verbose=1)

print("\n 테스트 정확도: %.4f" % (model.evaluate(X_test, y_test)[1]))


import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator, MultipleLocator
import re

map_root = "maps/"
map_list = ["vdberg1a.txt", # 5x5, 3 robots
            "vdberg1b.txt", # 6x5, 3 robots
            "vdberg1c.txt", # 6x5, 4 robots
            "bug_map.txt",  # 5x5, 4 robots
            "plus.txt",     # 7x7, 2 robots
            "choke.txt",    # 7x7, 2 robots
            "testmap0.txt", # 10x10, 4 robots
            "vdberg3c.txt", # 32x22, 10 robots
            "quad.txt",     # 32x22, 4 robots
            "gauntlet.txt"] # 32x21, 19 robots

palette = np.array([[255, 255, 255],   # white, empty
                    [128, 128, 128],   # grey, blocked
                    [  0, 255,   0],   # green, start
                    [255,   0,   0],   # red, end
                    ])

def get_map(map_num=None, DEBUG=False):
    if map_num is None:
        rand = np.random.Generator
        map_num = rand.integers(low=0, high=len(map_list))
    if DEBUG:
        print("Returning map: " + map_list[map_num])

    return map_list[map_num]

def show_map(mapFile):
    ## reading in map
    map_start = None
    robot_count = None
    robot_coords = None
    with open(map_root + mapFile) as f:
        data = f.readlines()
    for i, line in enumerate(data):
        if re.search("MAP", line):
            map_start = i + 1

        search = re.search("MAP_DIMENSIONS", line)
        if search:
            (x_dim,y_dim) = tuple(int(num) for num in re.findall(r"\d+", line)) # https://stackoverflow.com/a/30933281

        search = re.search("ROBOT_COUNT", line)
        if search:
            robot_count = int(re.findall(r"\d+", line)[0])

        search = re.search("GOAL_SET", line)
        if search is not None and robot_count is not None:
            robot_coords = np.zeros([robot_count,4], dtype=int)
            for r in range(robot_count):
                robot_coords[r] = re.findall(r"\d+", data[i + 1 + r])

    map_array = np.zeros([y_dim,x_dim],dtype=int)
    if map_start is not None:
        for l in range((map_start),(map_start+y_dim)):
            line = data[l]
            for x in range(x_dim):
                if (line[x] == "x"):
                    val = 1
                elif (line[x] == "i"):
                    val = 2
                elif (line[x] == "g"):
                    val = 3
                else:
                    val = 0
                map_array[l - map_start][x] = val

    ## plotting
    plt.close("all")
    plt.figure(figsize=(0.3*x_dim+1,0.3*y_dim+1))
    ax = plt.imshow(palette[map_array], aspect="equal").axes # https://stackoverflow.com/a/37720602, https://stackoverflow.com/a/8280500
    plt.xlim([-1,x_dim])
    plt.ylim([-1,y_dim])
    ax.invert_yaxis() # https://stackoverflow.com/a/8280500
    ax.xaxis.set_major_locator(MultipleLocator(base=5)) # https://stackoverflow.com/a/34880501
    ax.yaxis.set_major_locator(MultipleLocator(base=5)) # https://stackoverflow.com/a/34880501
    for i, coord in enumerate(robot_coords):
        plt.annotate(str(i), xy=(coord[0], coord[1]), va="center", ha="center")
        plt.annotate(str(i), xy=(coord[2], coord[3]), va="center", ha="center")
    name = mapFile.split(".")[0] + ".png"
    plt.savefig(fname=map_root + "images/" + name, dpi=300)
    return

if __name__ == '__main__':
    for i in range(len(map_list)):
        show_map(map_list[i])
        #plt.pause(3)


class Solution:
    def subsets(self, nums):
        answer = []
        max_len = len(nums)

        def dfs(n_list, index):
            answer.append(n_list)
            if len(n_list) == max_len:
                return

            for i in range(index, len(nums)):
                dfs(n_list+[nums[i]], i+1)

        dfs([], 0)

        return answer