from collections import OrderedDict

from couler.core import states, utils

def config_defaults(name_salter=None, service_account: str = None):
    """
    Config couler defaults.
    :param name_salter: function to salt workflow names.
    :param service_account: name of the default Kubernetes
        ServiceAccount with which to run workflows
    :return:
    """
    if name_salter is not None:
        states._workflow_name_salter = name_salter

    if service_account is not None:
        states.default_service_account = service_account

def config_workflow(
    name=None,
    user_id=None,
    timeout=None,
    time_to_clean=None,
    cluster_config_file=None,
    cron_config=None,
    service_account=None,
):
    """
    Config some workflow-level information.
    :param name: name of the workflow.
    :param user_id: user information.
    :param timeout: maximum running time(seconds).
    :param time_to_clean: time to keep the workflow after completed(seconds).
    :param cluster_config_file: cluster specific config
    :param cron_config: for cron scheduling
    :param service_account: name of the Kubernetes ServiceAccount which
        runs this workflow
    :return:
    """
    if name is not None:
        states.workflow.name = states._workflow_name_salter(name)

    if user_id is not None:
        states.workflow.user_id = user_id

    if timeout is not None:
        states.workflow.timeout = timeout

    if time_to_clean is not None:
        states.workflow.clean_ttl = time_to_clean

    if cluster_config_file is not None:
        import os

        os.environ["couler_cluster_config"] = cluster_config_file
        states.workflow.cluster_config = utils.load_cluster_config()

    if cron_config is not None:
        if isinstance(cron_config, OrderedDict):
            raise SyntaxError("Cron config would be a dict")

        if "schedule" not in cron_config:
            raise SyntaxError("require the cron schedule")

        schedule = cron_config["schedule"]
        concurrency_policy = cron_config.get("concurrency_policy", "Allow")
        successful_jobs_history_limit = cron_config.get(
            "successful_jobs_history_limit", 3
        )
        failed_jobs_history_limit = cron_config.get(
            "failed_jobs_history_limit", 1
        )
        starting_deadline_seconds = cron_config.get(
            "starting_deadline_seconds", 10
        )
        suspend = cron_config.get("suspend", "false")
        timezone = cron_config.get("timezone", "Asia/Shanghai")
        _config_cron_workflow(
            schedule,
            concurrency_policy,
            successful_jobs_history_limit,
            failed_jobs_history_limit,
            starting_deadline_seconds,
            suspend,
            timezone,
        )

    states.workflow.service_account = (
        service_account
        if service_account is not None
        else states.default_service_account
    )

def _config_cron_workflow(
    schedule,
    concurrency_policy='"Allow"',
    successful_jobs_history_limit=3,  # Default 3
    failed_jobs_history_limit=1,  # Default 1
    starting_deadline_seconds=10,
    suspend="false",
    timezone="Asia/Shanghai",
):
    """
    Config the CronWorkflow, see example
    https://github.com/argoproj/argo/blob/master/docs/cron-workflows.md
    """

    cron_config = {
        "schedule": schedule,
        "concurrencyPolicy": concurrency_policy,
        "successfulJobsHistoryLimit": successful_jobs_history_limit,
        "failedJobsHistoryLimit": failed_jobs_history_limit,
        "startingDeadlineSeconds": starting_deadline_seconds,
        "suspend": suspend,
        "timezone": timezone,
    }

    states.workflow.config_cron_workflow(cron_config)


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

class CandidateEmail:

    Emailbutton = "//a[@id='btn-email']"
    EmailSubject = "//input[@name='subject']"
    emailIframe = "//div[@class='tox-edit-area']/iframe"
    EmailBody = "//*[@id='tinymce']"
    AddCCEmailOption = "//*[text()='Add CC Emails']"
    AddCCTextBox = "//label[text()='CC']/following-sibling::div//input"
    AddCCEmailValue = "//*[@aria-label='test+06@getbrokerkit.com']"
    CancelAndHideOption = "//a[text()='Cancel and hide']"
    AddAttachmentBtn = "//div[text()='Add Attachment']"
    SelectTemplateDropdown = "//div[text()='Select a template']"
    SelectTemplateOptions = "//*[text()='Mail with all variables']"

    def __init__(self,driver):
        self.driver = driver

    def AddCandidateStatusEmail(self,subject,body):
        print("set subject & body of email")
        self.driver.find_element_by_xpath(self.Emailbutton).click()
        time.sleep(5)
        self.driver.find_element_by_xpath(self.EmailSubject).send_keys(subject)
        time.sleep(5)
        self.driver.switch_to_frame(self.driver.find_element_by_xpath(self.emailIframe))

        self.driver.find_element_by_xpath(self.EmailBody).send_keys(body)
        self.driver.switch_to_default_content()
        time.sleep(5)

    def ClickAddCCEmailOption(self):
        print("Click on add cc email option")
        self.driver.find_element_by_xpath(self.AddCCEmailOption).click()
        time.sleep(5)

    def SetAddCCTextBox(self,CCemail):
        print("set value for cc email")
        time.sleep(2)
        self.driver.find_element_by_xpath(self.AddCCTextBox).send_keys(CCemail)
        time.sleep(2)
        self.driver.find_element_by_xpath(self.AddCCTextBox).send_keys(Keys.ENTER)

        time.sleep(2)

    def ClickAddCCEmailValue(self):
        print("Click on Add cc email value")
        self.driver.find_element_by_xpath(self.AddCCEmailValue).click()
        time.sleep(3)

    def ClickCancelAndHideOption(self):
        print("Click on cancel hide options")
        self.driver.find_element_by_xpath(self.CancelAndHideOption).click()
        time.sleep(2)

    def ClickAddAttachmentBtn(self):
        print("Click on add attachment button & upload attachment")
        self.driver.find_element_by_xpath(self.AddAttachmentBtn).click()
        time.sleep(5)

    def SetEmailTemplate(self):
        print("Set email template")
        self.driver.find_element_by_xpath(self.SelectTemplateDropdown).click()
        time.sleep(2)
        self.driver.find_element_by_xpath(self.SelectTemplateOptions).click()


import hardware

async def set_rtc_time(secrets):

    import rtc
    import time
    import asyncio
    print("Setting NTP server...")
    hardware.espwifi.esp.sntp_config(True, secrets['timezone'], secrets['ntp_server'])
    # Get the time, check the year, if it is 1970 then retry every 10 seconds
    t = hardware.espwifi.esp.sntp_time
    while '1970' in t:
        print("Time not set, retrying...")
        t = hardware.espwifi.esp.sntp_time
        # print(time)
        await asyncio.sleep(10)
    # Convert the time to a string
    t = t.decode('ascii')
    print("Time received: {}".format(t))
    # Convert the time to a datetime object
    date_time = await convert_time(t)
    # Set the RTC
    boardclock = rtc.RTC()
    boardclock.datetime = time.struct_time((date_time.year, date_time.month, date_time.day, date_time.hour, date_time.minute, date_time.second, date_time.weekday(), 0, -1))

async def convert_time(t):

    # Convert the time to a datetime object using the datetime module
    # Extract individual components
    # day_of_week = t[:3]
    month = t[4:7]
    day = int(t[8:10])
    hour = int(t[11:13])
    minute = int(t[14:16])
    second = int(t[17:19])
    year = int(t[20:])

    # Map month abbreviation to month number
    month_map = {
        'Jan': 1,
        'Feb': 2,
        'Mar': 3,
        'Apr': 4,
        'May': 5,
        'Jun': 6,
        'Jul': 7,
        'Aug': 8,
        'Sep': 9,
        'Oct': 10,
        'Nov': 11,
        'Dec': 12
    }
    month_number = month_map[month]

    # Create datetime object
    from adafruit_datetime import datetime
    date_time = datetime(year, month_number, day, hour, minute, second)

    return date_time


import random
import discord
import os
from discord.ext import commands

class Imgspam(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def cat(self, ctx):
        rand = random.choice(os.listdir("/root/TomodachAI/cats"))
        await ctx.send(file=discord.File("cats/" + rand))

    @commands.command()
    async def think(self, ctx):
        rand = random.choice(os.listdir("/root/TomodachAI/think"))
        await ctx.send(file=discord.File("think/" + rand))

    @commands.command()
    async def smug(self, ctx):
        rand = random.choice(os.listdir("/root/TomodachAI/smug"))
        await ctx.send(file=discord.File("smug/" + rand))

    @commands.command()
    async def dance(self, ctx):
        rand = random.choice(os.listdir("/root/TomodachAI/dance"))
        try:
            await ctx.send(file=discord.File("dance/" + rand))
        except Exception:
            await ctx.send('command aint workin boss')
            return

    @commands.command()
    async def scatter(self, ctx):
        await ctx.send(file=discord.File("/root/TomodachAI/SCATTER.mp4"))

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


import unittest
from microservices import postgres_mode as pm
from microservices.xml_handler import XmlReport as XHXmlReport
from microservices.xml_handler import XmlRequest
from bs4 import BeautifulSoup

class XHUnitTestXmlReport(XHXmlReport):
    def __init__(self):
        pass

class TestManager(unittest.TestCase):

    def setUp(self):
        order_id = 1
        self.manager = TestManager()

        sql = ("INSERT INTO "
               "concurent_site.main_order "
               f"VALUES ({order_id}, 0, 0, 2, 1, 3) ")

        pm.custom_request_to_database_without_return(sql)

        sql = ("INSERT INTO "
               "concurent_site.main_request "
               f"VALUES "
               f"(1, 'Lasik', 0, 0, 0, 0, 0, 0, 0, 0, 'in work', 0, 0, 0, 0, 0, '', 0, 0, 255, {order_id}), "
               f"(2, 'Коррекция зрения', 0, 0, 0, 0, 0, 0, 0, 0, 'in work', 0, 0, 0, 0, 0, '', 0, 0, 255, {order_id}),"
               f"(3, 'ФРК', 0, 0, 0, 0, 0, 0, 0, 0, 'in work', 0, 0, 0, 0, 0, '', 0, 0, 255, {order_id}),"
               f"(4, 'Smile', 0, 0, 0, 0, 0, 0, 0, 0, 'in work', 0, 0, 0, 0, 0, '', 0, 0, 255, {order_id})")

        pm.custom_request_to_database_without_return(sql)

        file = open("text_files_for_tests/first_xml_answer", "r")
        xml = file.read()
        file.close()

        sql = ("INSERT INTO "
               "concurent_site.main_requestqueue "
               f"VALUES (DEFAULT, FALSE, 255, 1)")

        pm.custom_request_to_database_without_return(sql)

        sql = ("INSERT INTO "
               "concurent_site.main_handledxml "
               f"VALUES "
               f"(DEFAULT, '{xml}', 'in work', 0, 0, 0, 0, 255, 1),"
               f"(DEFAULT, '{xml}', 'in work', 0, 0, 0, 0, 255, 2),"
               f"(DEFAULT, '{xml}', 'in work', -1, 1, 0, 0, 255, 3),"
               f"(DEFAULT, '{xml}', 'in work', 0, 4, 0, 0, 255, 4)")

        pm.custom_request_to_database_without_return(sql)

        file = open("text_files_for_tests/second_xml_answer", "r")
        xml = file.read()
        file.close()

        sql = ("INSERT INTO "
               "concurent_site.main_requestqueue "
               f"VALUES (DEFAULT, FALSE, 255, 2)")

        pm.custom_request_to_database_without_return(sql)

        sql = ("INSERT INTO "
               "concurent_site.main_domain "
               "VALUES "
               "('test-domain-one.ru', 8, 400, 800, 'complete', 0),"
               "('test-domain-two.ru', 12, 600, 1200, 'pending', 1),"
               "('test-domain-three.ru', 45, 100500, 1000000, 'fake', 2)")

        pm.custom_request_to_database_without_return(sql)

    def tearDown(self):
        SCHEMA = 'concurent_site'
        test_domains = ('test-domain-one.ru', 'test-domain-two.ru', 'test-domain-three.ru')
        sql = (f'DELETE FROM {SCHEMA}.main_order; '
               f'DELETE FROM {SCHEMA}.main_handledxml; '
               f'DELETE FROM {SCHEMA}.main_requestqueue; '
               f'DELETE FROM {SCHEMA}.main_request; '
               f'DELETE FROM {SCHEMA}.main_domain WHERE name in {test_domains};')

        pm.custom_request_to_database_without_return(sql)

    def test_setup_insertion_main_order(self):
        sql = "SELECT id FROM concurent_site.main_order;"
        database_return = pm.custom_request_to_database_with_return(sql, 'one')
        id = database_return[0]

        self.assertEqual(id, 1)

    def test_setup_insertion_main_request(self):
        sql = "SELECT id, text FROM concurent_site.main_request;"
        database_return = pm.custom_request_to_database_with_return(sql)

        first_request = database_return[0]
        second_request = database_return[1]

        self.assertEqual(first_request[0], 1)
        self.assertEqual(first_request[1], 'Lasik')
        self.assertEqual(second_request[0], 2)
        self.assertEqual(second_request[1], 'Коррекция зрения')

    def test_setup_insertion_main_requestqueue(self):
        sql = "SELECT request_id FROM concurent_site.main_requestqueue;"
        database_return = pm.custom_request_to_database_with_return(sql)

        first_request = database_return[0]
        second_request = database_return[1]

        self.assertEqual(first_request[0], 1)
        self.assertEqual(second_request[0], 2)

    def test_setup_insertion_main_handledxml(self):
        sql = "SELECT request_id FROM concurent_site.main_handledxml;"
        database_return = pm.custom_request_to_database_with_return(sql)

        first_request = database_return[0]
        second_request = database_return[1]

        self.assertEqual(first_request[0], 1)
        self.assertEqual(second_request[0], 2)

    def test_get_requests_from_queue(self):
        handler_object = XHUnitTestXmlReport()
        handler_object.requests = list()
        handler_object.get_requests_from_queue()

        request = handler_object.requests[0]
        self.assertEqual('Lasik', request.text)

        request = handler_object.requests[1]
        self.assertEqual('Коррекция зрения', request.text)

    def test_get_requests_for_recheck(self):
        handler_object = XHUnitTestXmlReport()
        handler_object.requests = list()
        handler_object.get_requests_for_recheck()

        request = handler_object.requests[0]
        self.assertEqual('ФРК', request.text)

    def test_add_url_to_dataset(self):
        request_datasets = (XmlRequest(text='Lasik', region_id=255),
                            XmlRequest(text='ФРК', region_id=10))

        handler_object = XHUnitTestXmlReport()
        handler_object.requests = request_datasets
        handler_object.add_url_to_dataset()

        self.assertEqual(
            'http://xmlriver.com/search_yandex/xml?user=1391&key=893df7feb2a0f02343085ea6bc9e5424056aa945&query=Lasik',
            handler_object.requests[0].xml_url)
        self.assertEqual(
            'http://xmlriver.com/search_yandex/xml?user=1391&key=893df7feb2a0f02343085ea6bc9e5424056aa945&query=ФРК&lr=10',
            handler_object.requests[1].xml_url)

    def test_get_ads_block(self):
        file = open("text_files_for_tests/first_xml_answer", "r")
        xml = file.read()
        file.close()

        xml = BeautifulSoup(xml, 'html.parser')
        handler_object = XHUnitTestXmlReport()
        _, ads_count = handler_object.get_ads_block(xml, 'topads')
        self.assertEqual(4, ads_count)

        handler_object = XHUnitTestXmlReport()
        _, ads_count = handler_object.get_ads_block(xml, 'bottomads')
        self.assertEqual(5, ads_count)

    def test_get_real_ads_count(self):
        handler_object = XHUnitTestXmlReport()
        overcaped_bottom_ads_count, bottom_ads_count, top_ads_count = handler_object.get_real_ads_count(9)
        self.assertEqual(5, bottom_ads_count)
        self.assertEqual(4, top_ads_count)
        self.assertEqual(4, overcaped_bottom_ads_count)

    def test_count_ads(self):
        file = open("text_files_for_tests/first_xml_answer", "r")
        xml = file.read()
        file.close()

        handler_object = XHUnitTestXmlReport()
        overcaped_ads_count, top_ads_count, bottom_ads_count, bottom_ads_block = handler_object.count_ads(xml)
        self.assertEqual(0, overcaped_ads_count)
        self.assertEqual(4, top_ads_count)
        self.assertEqual(5, bottom_ads_count)

        file = open("text_files_for_tests/first_xml_answer_with_overcap", "r")
        xml = file.read()
        file.close()

        handler_object = XHUnitTestXmlReport()
        overcaped_ads_count, top_ads_count, bottom_ads_count, bottom_ads_block = handler_object.count_ads(xml)
        self.assertEqual(4, overcaped_ads_count)
        self.assertEqual(4, top_ads_count)
        self.assertEqual(5, bottom_ads_count)

    def test_validate_quotes_for_sql(self):
        handler_object = XHUnitTestXmlReport()
        string = "Д'Артаньян"
        string_for_sql = handler_object.validate_quotes_for_sql(string)
        self.assertEqual("Д''Артаньян", string_for_sql)

    def test_edit_xml_answer_text(self):
        file = open("text_files_for_tests/first_xml_answer_with_overcap", "r")
        xml = file.read()
        file.close()
        soup = BeautifulSoup(xml, 'html.parser')

        handler_object = XHUnitTestXmlReport()
        bottom_ads_block, _ = handler_object.get_ads_block(soup, 'bottomads')
        edited_xml_text = handler_object.edit_xml_answer_text(4, bottom_ads_block, xml)

        soup = BeautifulSoup(edited_xml_text, 'html.parser')
        top_ads = soup.find('topads')
        top_ads_count = len(top_ads.find_all('query'))
        bottom_ads = soup.find('bottomads')
        bottom_ads_count = len(bottom_ads.find_all('query'))

        self.assertEqual(9, edited_xml_text.count('<query>'))
        self.assertEqual(4, top_ads_count)
        self.assertEqual(5, bottom_ads_count)

        file = open("text_files_for_tests/second_xml_answer_with_overcap", "r")
        xml = file.read()
        file.close()
        soup = BeautifulSoup(xml, 'html.parser')

        handler_object = XHUnitTestXmlReport()
        bottom_ads_block, _ = handler_object.get_ads_block(soup, 'bottomads')
        edited_xml_text = handler_object.edit_xml_answer_text(2, bottom_ads_block, xml)

        soup = BeautifulSoup(edited_xml_text, 'html.parser')
        top_ads = soup.find('topads')
        top_ads_count = len(top_ads.find_all('query'))
        bottom_ads = soup.find('bottomads')
        bottom_ads_count = len(bottom_ads.find_all('query'))

        self.assertEqual(7, edited_xml_text.count('<query>'))
        self.assertEqual(2, top_ads_count)
        self.assertEqual(5, bottom_ads_count)

        file = open("text_files_for_tests/third_xml_answer_with_overcap", "r")
        xml = file.read()
        file.close()
        soup = BeautifulSoup(xml, 'html.parser')

        handler_object = XHUnitTestXmlReport()
        bottom_ads_block, _ = handler_object.get_ads_block(soup, 'bottomads')
        edited_xml_text = handler_object.edit_xml_answer_text(0, bottom_ads_block, xml)

        soup = BeautifulSoup(edited_xml_text, 'html.parser')
        top_ads = soup.find('topads')
        top_ads_count = len(top_ads.find_all('query'))
        bottom_ads = soup.find('bottomads')
        bottom_ads_count = len(bottom_ads.find_all('query'))

        self.assertEqual(5, edited_xml_text.count('<query>'))
        self.assertEqual(0, top_ads_count)
        self.assertEqual(5, bottom_ads_count)

    def test_get_refresh_timer_and_reruns_count(self):
        handler_object = XHUnitTestXmlReport()
        reruns_count, refresh_timer = handler_object.get_refresh_timer_and_reruns_count(4, 5)
        self.assertEqual(4, reruns_count)
        self.assertEqual(0, refresh_timer)

        reruns_count, refresh_timer = handler_object.get_refresh_timer_and_reruns_count(4, 4)
        self.assertEqual(1, reruns_count)
        self.assertEqual(10, refresh_timer)

        self.assertRaises(ValueError, handler_object.get_refresh_timer_and_reruns_count, 14, 5)

    def test_is_rerun(self):

        handler_object = XHUnitTestXmlReport()
        request = XmlRequest(reruns_count=0)
        is_rerun = handler_object.check_is_rerun(request)
        self.assertEqual(None, is_rerun)

        request = XmlRequest(reruns_count=2)
        is_rerun = handler_object.check_is_rerun(request)
        self.assertEqual(True, is_rerun)

    def test_found_more_ads_then_before(self):

        handler_object = XHUnitTestXmlReport()
        request = XmlRequest(top_ads_count=4, bottom_ads_count=5)
        found_more = handler_object.check_found_more_ads_then_before(request, 4, 5)
        self.assertEqual(None, found_more)

        handler_object = XHUnitTestXmlReport()
        request = XmlRequest(top_ads_count=4, bottom_ads_count=5)
        found_more = handler_object.check_found_more_ads_then_before(request, 3, 4)
        self.assertEqual(None, found_more)

        handler_object = XHUnitTestXmlReport()
        request = XmlRequest(top_ads_count=0, bottom_ads_count=5)
        found_more = handler_object.check_found_more_ads_then_before(request, 1, 5)
        self.assertEqual(True, found_more)

    def test_finalize_dataset(self):
        handler_object = XHUnitTestXmlReport()
        request = XmlRequest()
        handler_object.finalize_dataset(request, 'hello', 10, 1, 5, 4)
        self.assertEqual('hello', request.validated_text)
        self.assertEqual('in work', request.status)
        self.assertEqual(10, request.refresh_timer)
        self.assertEqual(1, request.reruns_count)
        self.assertEqual(4, request.top_ads_count)
        self.assertEqual(5, request.bottom_ads_count)


from functools import cmp_to_key

def in_order(a, b):
    if type(a) != type(b):
        # one int and one list
        if type(a) == int:
            a = [a]
        else:
            b = [b]
        return in_order(a, b)
    if type(a) == int:
        # two ints
        return a - b
    else:
        # two lists
        l = min(len(a), len(b))
        for i in range(l):
            t = in_order(a[i], b[i])
            if t == 0:
                continue
            return t
        return len(a) - len(b)

packets = []
packets.append([[2]])
packets.append([[6]])
i = 0
pair_index = 1
total = 0
lines = open("inputs/day13.in").readlines()
while i < len(lines):
    a = eval(lines[i])
    b = eval(lines[i + 1])
    i += 3
    if in_order(a, b) < 0:
        total += pair_index
    pair_index += 1
    packets.append(a)
    packets.append(b)
print("Part 1:", total)

packets.sort(key=cmp_to_key(in_order))
a = packets.index([[2]]) + 1
b = packets.index([[6]]) + 1
print("Part 2:", a * b)


from tkinter import *
from tkinter import ttk
from bittrex.bittrex import Bittrex
from firebase import firebase

def login(*args):
	try:
		# value = apikey.get()
		bittrex = Bittrex(apikey.get(), apisecret.get())
		print(bittrex.get_balances())
		# meters.set((0.3048 * value * 10000.0 + 0.5) / 10000.0)
	except ValueError:
		pass

if __name__ == '__main__':

	authentication = firebase.FirebaseAuthentication()
	bittrex = None

	root = Tk()
	root.title("Trade Watcher")

	mainframe = ttk.Frame(root, padding="3 3 12 12")
	mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
	mainframe.columnconfigure(0, weight=1)
	mainframe.rowconfigure(0, weight=1)

	apikey = StringVar()
	apisecret = StringVar()
	meters = StringVar()

	apikey_entry = ttk.Entry(mainframe, width=7, textvariable=apikey)
	apikey_entry.grid(column=2, row=1, sticky=(W, E))
	apisecret_entry = ttk.Entry(mainframe, width=7, textvariable=apisecret)
	apisecret_entry.grid(column=3, row=1, sticky=(W, E))

	ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))
	ttk.Button(mainframe, text="Calculate", command=login).grid(column=3, row=3, sticky=W)

	# ttk.Label(mainframe, text="feet").grid(column=3, row=1, sticky=W)
	# ttk.Label(mainframe, text="is equivalent to").grid(column=1, row=2, sticky=E)
	# ttk.Label(mainframe, text="meters").grid(column=3, row=2, sticky=W)

	for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

	apikey_entry.focus()
	root.bind('<Return>', login)

	root.mainloop()


# -*- coding: utf-8 -*-
import django_filters
from ipware import get_client_ip
from django_filters import rest_framework as filters
from django.conf.urls import url, include
from django.shortcuts import get_list_or_404, get_object_or_404
from rest_framework import generics
from rest_framework import authentication, viewsets, permissions, status
from rest_framework.response import Response

from shared_foundation.custom.drf.permissions import IsAuthenticatedAndIsActivePermission
from tenant_api.filters.vehicle_type import VehicleTypeFilter
from tenant_api.pagination import TinyResultsSetPagination
from tenant_api.permissions.tag import (
   CanListCreateTagPermission,
   CanRetrieveUpdateDestroyTagPermission
)
from tenant_api.serializers.vehicle_type import (
    VehicleTypeListCreateSerializer,
    VehicleTypeRetrieveUpdateDestroySerializer
)
from tenant_foundation.models import VehicleType

class VehicleTypeListCreateAPIView(generics.ListCreateAPIView):
    serializer_class = VehicleTypeListCreateSerializer
    pagination_class = TinyResultsSetPagination
    permission_classes = (
        permissions.IsAuthenticated,
        IsAuthenticatedAndIsActivePermission,
        CanListCreateTagPermission
    )

    def get_queryset(self):
        """
        List
        """
        # Fetch all the queries.
        queryset = VehicleType.objects.all().order_by('text')

        # The following code will use the 'django-filter'
        filter = VehicleTypeFilter(self.request.GET, queryset=queryset)
        queryset = filter.qs

        # Return our filtered list.
        return queryset

    def post(self, request, format=None):
        """
        Create
        """
        serializer = VehicleTypeListCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

class VehicleTypeRetrieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = VehicleTypeRetrieveUpdateDestroySerializer
    pagination_class = TinyResultsSetPagination
    permission_classes = (
        permissions.IsAuthenticated,
        IsAuthenticatedAndIsActivePermission,
        CanRetrieveUpdateDestroyTagPermission
    )

    def get(self, request, pk=None):
        """
        Retrieve
        """
        vt = get_object_or_404(VehicleType, pk=pk)
        self.check_object_permissions(request, vt)  # Validate permissions.
        serializer = VehicleTypeRetrieveUpdateDestroySerializer(vt, many=False)
        return Response(
            data=serializer.data,
            status=status.HTTP_200_OK
        )

    def put(self, request, pk=None):
        """
        Update
        """
        vt = get_object_or_404(VehicleType, pk=pk)
        self.check_object_permissions(request, vt)  # Validate permissions.
        serializer = VehicleTypeRetrieveUpdateDestroySerializer(vt, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)

    def delete(self, request, pk=None):
        """
        Delete
        """
        client_ip, is_routable = get_client_ip(self.request)
        vt = get_object_or_404(VehicleType, pk=pk)
        self.check_object_permissions(request, vt)  # Validate permissions.
        vt.is_archived = True
        vt.last_modified_by = request.user
        vt.last_modified_from = client_ip
        vt.last_modified_from_is_public = is_routable
        vt.save()
        return Response(data=[], status=status.HTTP_200_OK)


from django.forms import Textarea,TextInput,Select
from django import forms

db_type_choice = (
    ("","请选择"),
    ("mysql","MySQL"),
    ("oracle","Oracle"),
    ("postgresql","PostgreSQL")
)

class RdsInstanceSearchForm(forms.Form):
    search_instance_name = forms.CharField(
        widget = TextInput(attrs = {"id":"search_instance_name","class":"form-control",})
    )
    search_db_type = forms.CharField(
        widget = Select(attrs = {"id":"search_db_type","class":"form-control"},choices = db_type_choice)
    )

class RdsInstanceAddForm(forms.Form):
    instance_name = forms.CharField(
        widget = TextInput(attrs = {"id":"instance_name","class":"form-control","placeholder":"请输入实例名称"})
    )
    instance_url = forms.CharField(
        widget = TextInput(attrs = {"id":"instance_url","class":"form-control","placeholder":"请输入实例地址"})
    )
    instance_port = forms.CharField(
        widget = TextInput(attrs = {"id":"instance_port","class":"form-control","placeholder":"请输入实例地址"})
    )
    db_type = forms.CharField(
        widget = Select(attrs = {"id":"db_type","class":"form-control"},choices = db_type_choice)
    )
    instance_desc = forms.CharField(
        widget = Textarea(attrs = {"id":"instance_desc","class":"form-control","placeholder":"请输入实例描述"})
    )


from sqlalchemy import select
from fin.adapters.db.db_schemas.db_model import Target
from fin.adapters.repository.target.error import TargetNotFoundError
from fin.adapters.repository.repository import Repository

class TargetRepository(Repository):

    def __init__(self, db_session) -> None:
        """Init."""
        self._db_session = db_session

    async def add(self, target: Target):
        """Add new Target"""
        async with self._db_session() as session:
            session.add(target)
            await session.commit()
            await session.refresh(target)
        return target

    async def is_obj_exist(self, trg_id: int):
        """Checking is target exist"""
        try:
            target = await self.get_object(trg_id)
            if target:
                return True
        except TargetNotFoundError:
            return False
        return False

    async def get_object(self, trg_id: int):
        """Get target info"""
        async with self._db_session() as session:
            targets = await session.execute(
                select(Target).filter(
                    Target.target_id == trg_id
                )
            )
            target = targets.fetchone()
            if not target:
                raise TargetNotFoundError(trg_id)
            else:
                return target[0]

    async def get_objects(self, unit_id: str, targets_cnt_id: list, offset=0, limit=100):
        """Get all targets"""
        async with self._db_session() as session:
            statement = select(
                Target,
            ).filter(
                Target.target_cnt_id.in_(targets_cnt_id),
            ).offset(offset).limit(limit)
            result = await session.execute(statement)
            return result.all()


from sys import path
path.insert(1, '/marconi/home/userexternal/crodrigu/Plasma/prod/2D_FELTOR_Analysis/')

from Analysis          import Analyse
from os.path           import join, exists, isdir
from os                import chdir
from numpy             import average, shape, amax, absolute
from time              import time
# from scipy.io          import savemat, loadmat
from matplotlib.pyplot import show, subplots, savefig, plot, clf, subplot, suptitle

home_dir     = '/marconi_scratch/userexternal/crodrigu/'
# chdir(join(home_dir, 'Statistics/'))
output_dir_1 = 'hdiff_outputs/DIR_128_ly_0.0001_nu_x2_mpi/'
output_dir_2 = 'hdiff_outputs/DIR_128_ly_0.0001_nu_x2_new/'
Dir_1        = join(home_dir, output_dir_1)
Dir_2        = join(home_dir, output_dir_2)

if 'Mix' in output_dir_1:
    models = ['HW_ord', 'HW_mod']
if 'tanh' in output_dir_1:
    models = ['IC_HW_mod', 'IC_HW_ord', 'HW_mod_IC', 'HW_ord_IC']
else:
    models = ['IC', 'HW_mod', 'HW_ord']

nt_md = {'IC':1086, 'HW_mod':1247, 'HW_ord':330}

for model in models:

    File_1 = join(Dir_1, f'output_{model}.nc')
    File_2 = join(Dir_2, f'output_{model}.nc')
    # tic    = time()

    Analitics_1 = Analyse(File_1)
    nt1, nx1, ny1 = shape(Analitics_1.ions)
    print(average(Analitics_1.Mass), Analitics_1.Mass[0])
    Analitics_2 = Analyse(File_2)
    nt2, nx2, ny2 = shape(Analitics_2.ions)

    assert (nx2 == nx1 and ny2 == ny1), 'They do not even have the same spacial shape, bro!'

    print(f'The shape of the output {output_dir_1} is {(nt1, nx1, ny1)} and the last mesaured time is {Analitics_1.time[-1]}')
    print(f'The shape of the output {output_dir_2} is {(nt2, nx2, ny2)} and the last mesaured time is {Analitics_2.time[-1]}')

    nt1 = nt_md[model]

    if nt1 == nt2:
        dens_diff = average((Analitics_1.ions        - Analitics_2.ions)        ** 2)
        last_diff = average((Analitics_1.ions[-1]    - Analitics_2.ions[-1])    ** 2)
    elif nt1 < nt2:
        dens_diff = average((Analitics_1.ions[:nt1]  - Analitics_2.ions[:nt1])  ** 2)
        last_diff = average((Analitics_1.ions[nt1-1] - Analitics_2.ions[nt1-1]) ** 2)
    elif nt1 > nt2:
        dens_diff = average((Analitics_1.ions[:nt2]  - Analitics_2.ions[:nt2])  ** 2)
        last_diff = average((Analitics_1.ions[nt2-1] - Analitics_2.ions[nt2-1]) ** 2)

    print(f'The average error in density is {dens_diff}')
    print(f'The error at the position {nt1} point is {last_diff}')
    print(f'out of {max(amax(absolute(Analitics_1.ions)), amax(absolute(Analitics_2.ions)))}')

    plot(Analitics_1.time, Analitics_1.Mass)
    show()


#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4 nu
# maintainer: Fadiga

from __future__ import (
    unicode_literals, absolute_import, division, print_function)

from datetime import datetime

from peewee import (DateTimeField, IntegerField, CharField, FloatField,
                    BooleanField, ForeignKeyField, TextField)
from Common.models import BaseModel, FileJoin, Owner

FDATE = u"%c"
NOW = datetime.now()

class ProviderOrClient(BaseModel):

    """ Represents the company emmiting the invoices
    """
    # class Meta:
    #     order_by = ('name',)

    CLT = 'Client'
    FSEUR = 'Fournisseur'
    TYPES = [CLT, FSEUR]

    name = CharField(unique=True, verbose_name=("Nom de votre entreprise"))
    address = TextField(
        null=True, verbose_name=("Adresse principale de votre société"))
    phone = CharField(
        verbose_name=("Numero de téléphone de votre entreprise"), default="")
    email = CharField(
        null=True, verbose_name=("Adresse électronique de votre entreprise"))
    legal_infos = TextField(
        null=True, verbose_name=("Informations légales"))
    type_ = CharField(max_length=30, choices=TYPES, default=CLT)
    picture = ForeignKeyField(
        FileJoin, null=True, related_name='file_joins_pictures',
        verbose_name=("image de la societe"))

    # def invoices(self):
    #     return Invoice.select().where(Invoice.client == self)

    # def buys(self):
    #     return Buy.select().where(Buy.provd_or_clt == self)

    # def invoices_items(self):
    #     return Report.select().where(Report.type_ == Report.S,
    #                                  Report.invoice.client == self)

    def is_indebted(self):
        flag = False
        if self.last_remaining() > 0:
            flag = True
        return flag

    # def last_refund(self):
    #     try:
    #         return Refund.select().where(Refund.provider_client == self).order_by(
    #             Refund.date.desc()).get()
    #     except Exception as e:
    #         return None

    def last_remaining(self):
        last_r = self.last_refund()
        return last_r.remaining if last_r else 0

    def __str__(self):
        return u"{}, {}".format(self.name, self.phone)

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

    @classmethod
    def get_or_create(cls, name, phone, typ):
        try:
            ctct = cls.get(name=name, phone=phone, type_=typ)
        except cls.DoesNotExist:
            ctct = cls.create(name=name, phone=phone, type_=typ)
        return ctct

class Disbursement(BaseModel):

    created_date = DateTimeField(verbose_name=("Date"), default=NOW)
    owner = ForeignKeyField(Owner, verbose_name=("Utilisateur"))
    # provider_clt = ForeignKeyField(ProviderOrClient)
    created_date = DateTimeField(verbose_name=("Date"), default=NOW)
    taux = FloatField(verbose_name=("Date"))
    valeur = FloatField(verbose_name=("Valeur"))
    description = CharField()
    number = CharField()
    date = DateTimeField(verbose_name=("Date decaissement"))
    num_client = CharField(default=0)
    recever_name = CharField()
    amount = IntegerField(default=0)
    registered_on = datetime.now()
    deleted = BooleanField(default=False)

    def __unicode__(self):
        return "{}{}".format(self.num_client, self.amount)

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

    def display_name(self):
        return self.__unicode__()

    def save(self):
        """
        Calcul du cost en stock après une operation."""
        self.owner = Owner.get(Owner.islog == True)

        super(Disbursement, self).save()

class Collection(BaseModel):

    """ docstring for Payment """

    USD = "U"
    EUR = "E"
    VER = "V"
    RET = "R"
    AUT = "A"
    TYPES = ((USD, "USD"), (EUR, "EUROS"),
             (VER, "VERSEMENT"), (RET, "RETRAIT"), (AUT, "AUTRES"))

    class Meta:
        order_by = ('date',)

    owner = ForeignKeyField(Owner, verbose_name=("Utilisateur"))
    # provider_clt = ForeignKeyField(ProviderOrClient)
    created_date = DateTimeField(verbose_name=("Date"), default=NOW)
    type_ = CharField(choices=TYPES, default=AUT)
    taux = FloatField(verbose_name=("Date"))
    valeur = FloatField(verbose_name=("Valeur"))
    description = CharField()
    number = CharField()
    date = DateTimeField(verbose_name=("Date Encaissement"))
    num_client = CharField(default=0)
    recever_name = CharField()
    amount = IntegerField(default=0)
    registered_on = datetime.now()
    deleted = BooleanField(default=False)

    def __unicode__(self):
        return "{}{}".format(self.num_client, self.amount)

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

    def display_name(self):
        return self.__unicode__()

    def save(self):
        """
        Calcul du cost en stock après une operation."""
        self.owner = Owner.get(Owner.islog == True)

        super(Collection, self).save()

    def carat24(self):
        return (self.carat * self.weight) / 24

    def totals_amout(self):
        return self.base * self.carat24()

    def deletes_data(self):
        self.delete_instance()

    def restore(self):
        pass


from domain.auth import AuthScheme
from framework.rest.blueprints.meta import MetaBlueprint
from quart import request
from services.mfp.mfp_service import MyFitnessPalService

myfitnesspal_bp = MetaBlueprint('myfitnesspal_bp', __name__)

@myfitnesspal_bp.configure('/api/mfp/diary/sync', methods=['POST'], auth_scheme=AuthScheme.Sync)
async def backfill(container):
    service: MyFitnessPalService = container.resolve(
        MyFitnessPalService)

    days = request.args.get('days')

    return await service.sync(
        days=days)

@myfitnesspal_bp.configure('/api/mfp/diary/daily', methods=['GET'], auth_scheme=AuthScheme.Read)
async def daily_summaries(container):
    service: MyFitnessPalService = container.resolve(
        MyFitnessPalService)

    start = request.args.get('start')
    end = request.args.get('end')

    return await service.get_daily_summaries(
        start_date=start,
        end_date=end)


"""“add_correct_upload_flow”

Revision ID: bba506e94efd
Revises: 4d8618cc75d4
Create Date: 2023-01-08 21:56:30.201614

"""
import sqlalchemy_utils
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'bba506e94efd'
down_revision = '4d8618cc75d4'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('upload_user_files',
    sa.Column('id', sqlalchemy_utils.types.uuid.UUIDType(), nullable=False),
    sa.Column('user_id', sa.String(length=255), nullable=True),
    sa.Column('data_file_url', sa.String(length=255), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.add_column('Songs', sa.Column('origin_url', sa.String(length=255), nullable=True))
    op.add_column('Songs', sa.Column('clean_url', sa.String(length=255), nullable=True))
    op.add_column('Songs', sa.Column('instrumental_url', sa.String(length=255), nullable=True))
    op.add_column('Songs', sa.Column('cover_photo', sa.String(length=255), nullable=True))
    op.drop_column('user', 'cover_photo')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('user', sa.Column('cover_photo', sa.VARCHAR(length=255), autoincrement=False, nullable=True))
    op.drop_column('Songs', 'cover_photo')
    op.drop_column('Songs', 'instrumental_url')
    op.drop_column('Songs', 'clean_url')
    op.drop_column('Songs', 'origin_url')
    op.drop_table('upload_user_files')
    # ### end Alembic commands ###


#Main class for the game

#Important modules
import sys
import pygame
from settings import *
from ship import *
from bullet import *
from alien import *
from time import sleep
from game_stats import GameStats
from button import *
from scoreboard import *

class AlienInvasion:
	"""Class to manage the game"""

	def __init__(self):

		pygame.init()
		self.settings = Settings()

		#Defining the dimensions of the game window - Full Screen / pretty cool stuff ;)
		self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
		self.settings.screen_width = self.screen.get_rect().width
		self.settings.screen_height = self.screen.get_rect().height

		#Title of the window
		pygame.display.set_caption("Alien Invasion")

		#Creating an instance to score game statistics and a scoreboard
		self.stats = GameStats(self)
		self.sb = Scoreboard(self)

		#Entering the ship in the main game
		self.ship = Ship(self) #aqui é preciso por o self para o ship ter acesso aos recursos do jogo

		#Group to manage the bullets already fired
		self.bullets = pygame.sprite.Group()

		#Group to handle the alien ships
		self.aliens = pygame.sprite.Group()

		#Method for the alien fleet
		self._create_fleet()

		#Adding the button
		self.play_button = Button(self,"Click here to play or Press P")

		#Background color
		self.bg_color = (230,230,230)

	def run_game(self):
		#Main loop of the game

		while True:
			#This is the event manager.
			self._check_events()

			if self.stats.game_active:
				self.ship.update()
				self._update_bullets()
				self._update_aliens()

			self._update_screen()

	def _check_events(self):
		#Responding to Keyboard and mouse movements
		for event in pygame.event.get():

			#Events triggered by pressing on the keyboard
			if event.type == pygame.KEYDOWN:
				self._check_keydown_events(event)

			#Events triggered by releasing a key on the keyboard
			elif event.type == pygame.KEYUP:
				self._check_keyup_events(event)

			#Quit the game by pressing X on the top right corner
			elif event.type == pygame.QUIT:
				self._quit_game()
				sys.exit()

			elif event.type == pygame.MOUSEBUTTONDOWN:
				mouse_pos = pygame.mouse.get_pos()
				self._check_play_button(mouse_pos)

	def _check_play_button(self,mouse_pos):
		#Start a new game when the player clicks Play

		button_clicked = self.play_button.rect.collidepoint(mouse_pos)

		if button_clicked and not self.stats.game_active:
			self.settings.initialize_dynamic_settings()
			self._start_game()

			self.sb.prep_score()
			self.sb.prep_level()
			self.sb.prep_ships()

			#Reset the game statistics
			self.stats.reset_stats()

	def _check_keydown_events(self,event):
		#Refactor of the check_keydown events
		if event.key == pygame.K_RIGHT:
		#Move the ship to the right
			self.ship.moving_right = True

		#Move the ship to the left
		elif event.key == pygame.K_LEFT:
			self.ship.moving_left = True

		#Quit the game by pressing Q on the keyboard
		elif event.key == pygame.K_q:
			self._quit_game()
			sys.exit()

		#Fire a bullet when Spacebar is pressed
		elif event.key == pygame.K_SPACE:
			self._fire_bullet()

		elif event.key == pygame.K_p:
			self._start_game()

	def _quit_game(self):
		#Storing the High Score in a file
		f = open("high_score.txt","w+")
		f.write(str(self.stats.high_score))
		f.close()

	def _start_game(self):
		#Method for starting the game in 2 different ways

		#Resetting the game
		self.stats.reset_stats()

		#Activate the game after pressing Play
		self.stats.game_active = True

		#Get rid of any remaining aliens and bullets
		self.aliens.empty()
		self.bullets.empty()

		#Create a new fleet and center the ship
		self._create_fleet()
		self.ship.center_ship()

		#Hide the mouse cursor
		pygame.mouse.set_visible(False)

	def _check_keyup_events(self,event):
		if event.key == pygame.K_RIGHT:
			self.ship.moving_right = False

		elif event.key == pygame.K_LEFT:
			self.ship.moving_left = False

	def _fire_bullet(self):

		#Here we make sure that no more than the nr of allowed bullets are created and on the screen
		if len(self.bullets) < self.settings.bullets_allowed:
			#Create a new bullet and add it to the screen
			new_bullet = Bullet(self)
			#The add method here is similar to append, but specific for Pygames
			self.bullets.add(new_bullet)

	def _update_bullets(self):
		#Updating the position of the bullets and get rid of old bullets
		self.bullets.update()

		#Delete the bullets after they reached the top of the screen
		#We use the copy() method here because it is not possible to loop through dynamic lists
		for bullet in self.bullets.copy():
			if bullet.rect.bottom <= 0:
				self.bullets.remove(bullet)

		self._check_bullet_alien_collisions()

	def _check_bullet_alien_collisions(self):
		#Responding to bullet-alien collisions

		#Remove any bullets and aliens
		collisions = pygame.sprite.groupcollide(
			self.bullets,self.aliens,False,True)

		if collisions:

			#Msking sure that each allien hit counts for the score
			for aliens in collisions.values():
				self.stats.score += self.settings.alien_points * len(aliens)

			self.sb.prep_score()

			#Each time an alien is hit, check and compare the high score
			self.sb.check_high_score()

		#If the fleet is destroyed, activate this option to create a whole new one
		if not self.aliens:
			self.bullets.empty()
			self._create_fleet()
			self.settings.increase_speed()

			#Increase level
			self.stats.level += 1
			self.sb.prep_level()

	def _create_fleet(self):
		#Creating a new fleet of aliens

		#Crearing an alien to know the spacing between aliens
		alien = Alien(self)
		alien_width,alien_height = alien.rect.size

		#Available space between aliens and max number of them in one row
		available_space_x = self.settings.screen_width - (2*alien_width)
		number_of_aliens = available_space_x // (2* alien_width)

		#Determine the number of rows of aliens fitting the screen
		ship_height = self.ship.rect.height
		available_space_y = self.settings.screen_height - (3*alien_height)-ship_height
		number_rows = available_space_y // (2*alien_height)

		#Create the full fleet of aliens
		for row_number in range(number_rows):
			for alien_number in range(number_of_aliens):
				self._create_alien(alien_number,row_number)

	def _create_alien(self,alien_number,row_number):
		alien = Alien(self)
		alien_width, alien_height = alien.rect.size
		alien.x = alien_width + 2*alien_width*alien_number
		alien.rect.x = alien.x
		alien.rect.y = alien.rect.height+2*alien.rect.height*row_number
		self.aliens.add(alien)

	def _update_aliens(self):
		self._check_fleet_edges()
		self.aliens.update()

		#Check if the ship and fleet collided
		if pygame.sprite.spritecollideany(self.ship,self.aliens):
			self._ship_hit()

		#Look for aliens hitting the bottom of the screen
		self._check_aliens_bottom()

	def _check_aliens_bottom(self):
		#Check if any aliens have reached the bottom of the screen

		screen_rect = self.screen.get_rect()

		for alien in self.aliens.sprites():
			if alien.rect.bottom >= screen_rect.bottom:
				#The same thing as if the ship is hit
				self._ship_hit()
				break

	def _ship_hit(self):
		#Response when the shit collides with an allien

		self._quit_game()

		if self.stats.ships_left > 0:
			#Decrement ships left
			self.stats.ships_left -= 1

			#The gamer loses a life/ship so the prep_ship needs to be called
			#Update the scoreboard
			self.sb.prep_ships()

			#Get rid of any remaining aliens and bullets
			self.aliens.empty()
			self.bullets.empty()

			#Create a new fleet and center the ship
			self._create_fleet()
			self.ship.center_ship()

			#Pause
			sleep(0.5)

		else:
			self.stats.game_active = False
			pygame.mouse.set_visible(True)

	def _check_fleet_edges(self):
		#Response if any of the aliens reached an edge
		for alien in self.aliens.sprites():
			if alien.check_edges():
				self._change_fleet_direction()
				break

	def _change_fleet_direction(self):
		#Drop the fleet and change its direction
		for alien in self.aliens.sprites():
			alien.rect.y += self.settings.fleet_drop_speed

		self.settings.fleet_direction *= -1

	def _update_screen(self):
		#Redraw the screen after each event
		#Ter em atenção a ordem em que se coloca estes parametros!!!
		self.screen.fill(self.settings.bg_color)

		#Include the ship
		self.ship.blitme()

		#Returns a list of all sprites in the group bullets
		for bala in self.bullets.sprites():
			bala.draw_bullet()

		#Display the alien fleet
		self.aliens.draw(self.screen)

		#Draw the score information
		self.sb.show_score()

		#Draw the play button
		if not self.stats.game_active:
			self.play_button.draw_button()

		#Make the most recently drawn screen
		pygame.display.flip()

if __name__ == '__main__':
	#Make the game instance and run it
	ai = AlienInvasion()
	ai.run_game()


from sanic.response import json
from sanic import Blueprint

from Base.MongoDB.mac import query_mac_change_by_ip, query_mac_change_by_owner
from Decorators import permission
from documentation.log.mac_change_doc import (
    MacChangeGetLogByUsernameDoc,
    MacChangeGetLogByIpDoc,
)

bp_log_mac = Blueprint("log-mac")

@MacChangeGetLogByUsernameDoc
@bp_log_mac.route("/mac/<username>", strict_slashes=True)
@permission("api.log.mac.get")
async def mac_get_by_owner(request, username):
    result = await query_mac_change_by_owner(username)
    return json(result)

@MacChangeGetLogByIpDoc
@bp_log_mac.route("/ip/mac/<ip>", strict_slashes=True)
@permission("api.log.mac.get")
async def mac_get_by_ip(request, ip):
    result = await query_mac_change_by_ip(ip)
    return json(result)


import pygame

class Controls:

    def __init__(self):
        self.forward = False
        self.left = False
        self.right = False
        self.reverse = False

    def update(self, event):
        if event.key == pygame.K_LEFT:
            self.left = not self.left

        if event.key == pygame.K_RIGHT:
            self.right = not self.right

        if event.key == pygame.K_DOWN:
            self.reverse = not self.reverse

        if event.key == pygame.K_UP:
            self.forward = not self.forward

    def set(self, directions):
        self.forward = directions[0]
        self.reverse = directions[1]
        self.left = directions[2]
        self.right = directions[3]

    def reset(self):
        self.forward = False
        self.left = False
        self.right = False
        self.reverse = False


import argparse
import os
from datasets import llp_variant_generation
import pandas as pd
import numpy as np
from copy import deepcopy
from sklearn.preprocessing import MinMaxScaler
from sklearn.cluster import KMeans
from datasets import llp_variant_generation
from datasets_gen_info import CANDIDATES
from sklearn.datasets import fetch_covtype

def compute_proportions_multiclass(bags, y):
    """Compute the proportions (multiclass) for each bag given.
    Parameters
    ----------
    bags : {array-like}
    y : {array-like}

    Returns
    -------
    proportions : {array}
        An array of type np.float
    """
    num_bags = int(max(bags)) + 1
    n_classes = len(np.unique(y))
    proportions = np.empty((num_bags, n_classes), dtype=float)
    for i in range(num_bags):
        bag = np.where(bags == i)[0]
        for j in range(n_classes):
            proportions[i, j] = np.count_nonzero(y[bag] == j) / len(bag)
    return proportions

def load_base_dataset(base_dataset, random_state=None):
    """
    Load the base dataset and return the X and y.

    Parameters
    ----------
    base_dataset : {str}
        The base dataset to load.
    random_state : {int}
        The random state to use.

    Returns
    -------
    X : {array-like}
        The features.
    y : {array-like}
        The labels.
    """
    if base_dataset == "covtype":
        covtype = fetch_covtype(random_state=random_state, shuffle=True)
        X = covtype.data
        y = covtype.target
        y -= 1 # We want the labels to be in [0, 6]
    elif base_dataset == "cifar-10-grey":
        df = pd.read_parquet("base-datasets/cifar-10-grey.parquet")
        df = df.sample(frac=1, random_state=random_state)
        X = deepcopy(df.drop(columns=["label"]).values)
        y = deepcopy(df["label"].values)
    elif base_dataset == "adult":
        df = pd.read_parquet("base-datasets/adult.parquet")
        df.drop(columns=["educational-num"], inplace=True)
        df.gender.replace({"Male": 0, "Female": 1}, inplace=True)
        df.income.replace({"<=50K": 0, ">50K": 1}, inplace=True)
        df = pd.get_dummies(df, columns=
                            ["age", "workclass", "education", "marital-status", \
                             "occupation", "relationship", "race", "native-country"])
        df = df.sample(frac=1, random_state=random_state)
        X = deepcopy(df.drop(columns=["income"]).values)
        y = deepcopy(df["income"].values)
    elif base_dataset == "cifar-10-grey-animal-vehicle":
        df = pd.read_parquet("base-datasets/cifar-10-grey.parquet")
        df = df.sample(frac=1, random_state=random_state)
        df.label = df.label.apply(lambda x: 0 if x in [0, 1, 8, 9] else 1)
        X = deepcopy(df.drop(columns=["label"]).values)
        y = deepcopy(df["label"].values)
    else:
        raise ValueError("Base dataset not found.")

    X = MinMaxScaler().fit_transform(X)

    return X, y

def get_clusters(X, clustering_method, n_clusters, random_state):
    if clustering_method == "kmeans":
        clusters = KMeans(n_clusters=n_clusters, n_init="auto", random_state=random_state).fit_predict(X)
    else:
        raise ValueError("Clustering method has to be kmeans.")

    # If some clusters are empty, we terminate the program
    for i in range(n_clusters):
        if np.count_nonzero(clusters == i) == 0:
            print("Some clusters are empty. Please try again with a different clustering method.")
            exit()

    return clusters

def generate_llp_dataset(X, y, clusters, proportions_target, bags_sizes_target, llp_variant, random_state):
    if llp_variant == "naive":
        bags = llp_variant_generation(X, llp_variant="naive", bags_size_target=bags_sizes_target,
                                    random_state=random_state)
    elif llp_variant == "simple":
        bags = llp_variant_generation(X, y, llp_variant="simple", bags_size_target=bags_sizes_target,
                                    proportions_target=proportions_target,
                                    random_state=random_state)
    elif llp_variant == "intermediate":
        bags = llp_variant_generation(X, y, llp_variant="intermediate", bags_size_target=bags_sizes_target,
                                    proportions_target=proportions_target, clusters=clusters,
                                    random_state=random_state)
    elif llp_variant == "hard":
        bags = llp_variant_generation(X, y, llp_variant="hard", bags_size_target=bags_sizes_target,
                                    proportions_target=proportions_target, clusters=clusters,
                                    random_state=random_state)
    return bags

random_state=6738921
random = np.random.RandomState(random_state)
n_jobs=-1
VARIANTS = ["naive", "simple", "intermediate", "hard"]

# Argparse
parser = argparse.ArgumentParser()
parser.add_argument("--base_dataset", "-bd", type=str, required=True, choices=["covtype", "cifar-10-grey", "cifar-10-grey-animal-vehicle", "adult"])
parser.add_argument("--clustering_method", "-cm", type=str, required=True, choices=["kmeans"])
parser.add_argument("--n_clusters", "-nc", type=int, required=True)
args = parser.parse_args()

base_dataset = args.base_dataset
clustering_method = args.clustering_method
n_clusters = args.n_clusters

try:
    os.mkdir("datasets-ci-multiclass")
except:
    pass

X, y = load_base_dataset(base_dataset, random_state=random_state)
clusters = get_clusters(X, clustering_method, n_clusters, random_state)

# Setting the proportions and bags sizes target
n_bags = 1000
n_items = X.shape[0]
n_classes = len(np.unique(y))
n_bags_type = "massive"
bags_size_type = "equal"
proportions_type = "close-global"
#(1000, 10)

proportions_global = np.zeros((n_classes), dtype=float)
for j in np.unique(y):
    proportions_global[j] = np.count_nonzero(y == j) / len(y)

proportions_target = np.array([proportions_global] * n_bags)
bags_sizes_target = np.array([n_items // n_bags] * n_bags)
bags_sizes_target_naive = np.array([n_items // n_bags] * n_bags)

# Check if proportions_target is valid
print(f"Does the proportions target have stochastic rows?: {np.isclose(proportions_target.sum(axis=1), 1).all()}\n")

# Saving the base datasets (it will be the same for all variants)
df_base = pd.DataFrame(X, columns=[str(i) for i in range(X.shape[1])])
df_base["y"] = y
df_base["y"] = df_base["y"].astype(int)
df_base.to_parquet("datasets-ci-multiclass/{}.parquet".format(base_dataset), index=False)

# Rescale the bags sizes to sum the same as the number of instances
bags_sizes_target = [int(bags_sizes_target[i] * X.shape[0] / sum(bags_sizes_target)) for i in range(len(bags_sizes_target))]
bags_sizes_target_naive = [int(bags_sizes_target_naive[i] * X.shape[0] / sum(bags_sizes_target_naive)) for i in range(len(bags_sizes_target_naive))]
n_bags = len(proportions_target)

# Generating the datasets
for llp_variant in VARIANTS:
    bags = generate_llp_dataset(X, y, clusters, proportions_target, bags_sizes_target if llp_variant != "naive" else bags_sizes_target_naive, llp_variant, random_state)
    unique_bags, bags_sizes = np.unique(bags, return_counts=True)
    if len(unique_bags) != n_bags:
        print("\n\n")
        print(base_dataset)
        print(llp_variant)
        print(n_bags_type)
        print(bags_size_type)
        print(proportions_type)
        print(unique_bags)
        print(n_bags)
        raise Exception("ERROR: The number of bags is not correct")

    # Saving only the bags (saving space)
    df = pd.DataFrame(bags, columns=["bag"], dtype=int)

    filename = "datasets-ci-multiclass/{}-{}-{}-{}-{}-cluster-{}-{}.parquet".format(base_dataset, llp_variant, n_bags_type, \
                        bags_size_type,
                        proportions_type if llp_variant != "naive" else "None", \
                        clustering_method if llp_variant in ["intermediate", "hard"] else "None", \
                        n_clusters if llp_variant in ["intermediate", "hard"] else "None")
    df.to_parquet(filename, index=False)
    print("Dataset {} generated".format(filename))
    print("Proportions: {}".format(compute_proportions_multiclass(bags, y)))
    print("Bag sizes: {}".format(np.bincount(bags)))
    print("\n------------------------\n")


import boto3
from flask import Flask, render_template, request
import base64
import os
import json

app = Flask(__name__)

# Get AWS credentials from environment variables
aws_access_key_id = os.environ["AWS_ACCESS"]
aws_secret_access_key = os.environ["AWS_SECRET"]

# Create a new session using the credentials
session = boto3.Session(
    aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key
)

client = boto3.client("lambda", region_name="us-east-1")

# ALLOWED_EXTENSIONS = {'jpg', 'jpeg', 'png', 'gif'}

# def allowed_file(filename):
#     return '.' in filename and \
#            filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route("/", methods=["GET", "POST"])
def predict():
    if request.method == "POST":
        print("Classifying image...")
        # Read the image file from the request
        image_file = request.files["image"]

        # Check if file is a valid image
        #if not allowed_file(image_file.filename):
        #    return "Invalid file type"

        image_data = image_file.read()

        # Encode the image data in base64 format
        encoded_image = base64.b64encode(image_data).decode("utf-8")

        # Create the payload for the Lambda function
        event = {"body": encoded_image}

        # Invoke the Lambda function
        response = client.invoke(FunctionName="classify", Payload=json.dumps(event))

        # Parse the response from the Lambda function
        response_dict = json.loads(response["Payload"].read().decode("utf-8"))
        # predictions = response_dict.get('predictions')
        predictions = json.loads(response_dict.get("body"))

        # return json.loads(response_dict.get('body'))
        return render_template("preds.html", results=predictions, image_src=request.form.get('image_src'))
        # return render_template('preds.html', results=response_dict.get('body'))

    # render the home template for GET requests
    return render_template("index.html")

@app.route('/health')
def is_healthy():
    # for app runner health check error
    return True

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080, debug=True)


import sys
from collections import deque
h, w = map(int, input().split())

# 가능한 패턴
ptn1 = 'WB' * 4
ptn2 = 'BW' * 4

# 칠해야 할 칸의 수를 표시
cnt1 = deque([0 for _ in range((w-7)*(h-7))])
cnt2 = deque([0 for _ in range((w-7)*(h-7))])
# i행 j열에서 시작하는 체스판의 index n = i*(w-7) + j

for i in range(h):
    color = input()
    if (i%2):
        str1 = ptn1; str2 = ptn2
    else:
        str1 = ptn2; str2 = ptn1
    for j in range(h-7):
        for x in range(w-7):
            diff1 = 0
            diff2 = 0
            for y in range(8):
                if color[x+y] != str1[y]:
                    diff1 += 1
                if color[x+y] != str2[y]:
                    diff2 += 1
            if i in range(j,j+8):
                cnt1[(w-7)*j+x] += diff1
                cnt2[(w-7)*j+x] += diff2

print(min(min(cnt1), min(cnt2)))

백준/Silver/1018. 체스판 다시 칠하기/체스판 다시 칠하기.py

체스판 다시 칠하기.py


from bs4 import BeautifulSoup as bs
import pandas as pd
with open('onion_data.xls', 'r') as f:
    content = f.read()

soup = bs(content, 'html5lib')
data = []
table = soup.find('table')
for tr in table.findAll('tr'):
    row = []
    count = 0
    for td in tr.findAll('td'):
        if count != 0:
            row.append(td.span.text)
        count += 1
    data.append(row)

print(len(data))
print(data[:5])
data_dict = []
for row in data:
    row_dict = {}
    row_dict['DISTRICT'] = row[0]
    row_dict['MARKET'] = row[1]
    row_dict['COMMODITY'] = row[2]
    row_dict['VARIETY'] = row[3]
    row_dict['GRADE'] = row[4]
    row_dict['MIN'] = row[5]
    row_dict['MAX'] = row[6]
    row_dict['MODAL'] = row[7]
    row_dict['DATE'] = row[8]
    data_dict.append(row_dict)

df = pd.DataFrame(data= data_dict)
df.to_csv("full_onion_data.csv")


#from datetime import datetime
from datetime import datetime, timedelta
import pytz

from tqdm import tqdm

import ccxt

import numpy as np
import pandas as pd

from itrader.price_handler.BINANCE_Live import BINANCELiveStreamer
from .base import PriceHandler
from .base import SqlHandler

import logging
logger = logging.getLogger('TradingSystem')

class CCXT_data_provider(PriceHandler):
    """
    CCXT_data_provider is designed to download data from the defined
    exchange. It contains Open-High-Low-Close-Volume (OHLCV) data
    for each pair and streams those to the provided events queue as BarEvents.

    Parameters
    ----------
    exchange: `str`
        Exchange from where download datas.
    symbols: `list`
            The list of symbols to be downloaded.
    timeframes: `str`
        The time frame for the analysis
    start_dt: `str`
        The start date of the analysis
    end_dt: `str`
        The End date of the analysis
    global_queue: 'object'
        The global queue of the trading system
    base_currency: `str`
        The base currency for the downloaded data
    """

    def __init__(self, exchange,symbols=[], timeframe=None, start_dt='', end_dt='',
                global_queue = None, base_currency='BUSD'):

        self.base_currency = base_currency

        self.exchange = self._set_exchange(exchange)
        self.set_symbols(symbols)
        self.set_timeframe(timeframe)
        self.start_date = start_dt
        self.end_date = end_dt

        self.sql_handler = SqlHandler()
        self.live_data = BINANCELiveStreamer(global_queue)

        logger.info('PRICE HANDLER: CCXT => OK')

    def download_data(self):
        """
        Download price data with CCXT and store them in a dict with
        the following format: {'ticker' : DataFrame}
        """
        logger.info('PRICE HANDLER: Downoalding data')

        PriceHandler.prices={}
        # Read the list of coins stored in the db
        sql_symblos = self.sql_handler.get_symbols_SQL()
        symbols = list(map(lambda x: x.lower(), PriceHandler.symbols))

        for symbol in tqdm(symbols):
            if symbol in sql_symblos:
                # Symbol already present in the SQL db
                PriceHandler.prices[symbol.upper()] = self.sql_handler.read_prices(symbol)
            else:
                # Symbol not present in the SQL db. Download them with CCXT
                self._get_data_CCXT(symbol, self.start_date)

        # Update data to tha last available date
        #self.update_data()

    def update_data(self):
        """
        Update the price data
        """
        logger.info('PRICE HANDLER: Updating data...')
        timezone = pytz.timezone('Europe/Paris')

        while True: # repeat until we get all historical bars
            update=0
            for ticker in tqdm(self.prices.keys()):
                # Get the current UTC time
                now = pd.to_datetime(datetime.utcnow())

                # Make it timezone aware
                now = now.replace(tzinfo=pytz.utc).astimezone(timezone)

                # Calculate the bar expiration time
                now = now - timedelta(microseconds = now.microsecond)
                last_date = self.prices[ticker].index[-1]

                if now - last_date > self.tf_delta :
                    update += 1
                    #print(ticker + ' UPDATED')
                    self._get_data_CCXT(ticker, last_date, replace=False)

            if update == 0:
                logger.info('PRICE HANDLER: Price updated')
                break

    def set_symbols(self, tickers: list):
        """
        Recive the tickers to be downloaded from the Strategy Handler
        when a static universe is used

        Parameters
        ----------
        symbols: `list`
            The list of symbols to be downloaded.
        """
        symbols = np.unique(tickers)

        if 'all' in symbols:
            PriceHandler.symbols = self.get_all_symbols()
        else:
            PriceHandler.symbols = symbols

    def set_timeframe(self, timeframe: str):
        """
        Set the timeframe as a string and timedelta object in the
        parent class.

        Parameters
        ----------
        timeframe: `str`
            The timeframe of the price data.
        """
        if timeframe is not None:
            PriceHandler.timeframe = timeframe
            PriceHandler.tf_delta = self._get_delta(timeframe)

#******* Data Manipulation ***************

    def resample_price(self, df: pd.DataFrame, timedelta: timedelta):
        """
        Resample the prices in another timeframe

        Parameters
        ----------
        df: `DataFrime`
            The DataFrame to be resampled.
        timeframe: `timedelta`
            The new timeframe after resample.

        Returns
        -------
        prices: `DataFrame`
            DataFrame with Date-OHLCV bars.
        """
        return df.resample(timedelta, label='right').agg(
            {'open':'first',
            'high':'max',
            'low':'min',
            'close':'last',
            'volume': 'sum'})

    def get_bar(self, ticker: str, time: pd.Timestamp):
        """
        Get a specific bar at a specified time in the time series.

        Parameters
        ----------
        ticker: `str`
            The ticker symbol, e.g. 'BTCUSD'.
        time: `timestamp`
            Time of the bar to get

        Returns
        -------
        prices: `DataFrame`
            DataFrame with  Date-OHLCV bars for the requested symbol
        """
        if ticker in PriceHandler.prices.keys():
            try:
                last_prices = PriceHandler.prices[ticker].loc[time]
                return last_prices
            except:
                logger.error('PRICE HANDLER: data for %s at time %s not found', ticker, str(time))
                return None
        else:
            logger.error('PRICE HANDLER: data for %s not found', ticker)

    def get_bars(self, ticker: str, start_dt: pd.Timestamp = None, end_dt:pd.Timestamp = None) -> pd.DataFrame:
        """
        Slice the dataframe for a defined tickerbetwen the start
        and the end date.

        Parameters
        ----------
        ticker: `str`
            The ticker symbol, e.g. 'BTCUSD'.
        start_dt: `timestamp`
            Time for the dataframe slice
        end_dt: `timestamp`
            Time for the dataframe slice

        Returns
        -------
        prices: `DataFrame`
            DataFrame with  Date-OHLCV for the requested symbol
        """
        if ticker not in PriceHandler.prices.keys():
            logger.error('PRICE HANDLER: data for %s not found', ticker)
            return
        if start_dt is not None and end_dt is not None:
            return PriceHandler.prices[ticker].loc[start_dt : end_dt]
        elif start_dt is not None and end_dt is None:
            return PriceHandler.prices[ticker].loc[start_dt : ]
        elif start_dt is None and end_dt is not None:
            return PriceHandler.prices[ticker].loc[ : end_dt]
        else:
            return PriceHandler.prices[ticker]

    def get_and_resample_bars(self, time, ticker, tf_delta, window) -> pd.DataFrame:
        """
        Load the price data from the price handler before to execute
        the strategy.
        If the timeframe of the stored data is different from the
        strategy's timeframe, resample the data.

        Parameters
        ----------
        time: `timestamp`
            Event time
        ticker: `str`
            The ticker symbol, e.g. 'BTCUSD'.
        tf_delta: `timedelta object`
            Timeframe of the strategy
        window: `int`
            Number of bars to loock back in the resampled timeframe

        Returns
        -------
        prices: `DataFrame`
            The resampled dataframe
        """
        # Check if the requested timeframe is the same of the stored data
        if tf_delta != PriceHandler.tf_delta:
            ratio = tf_delta / PriceHandler.tf_delta
            start_dt = (time - PriceHandler.tf_delta * window * ratio)
            return self.resample_price(self.get_bars(ticker, start_dt+tf_delta, time+tf_delta), tf_delta).head(window)
        else:
            start_dt = time - tf_delta * window
            return self.get_bars(ticker, start_dt+tf_delta, time)

    def get_megaframe(self, time: pd.Timestamp, tf_delta: pd.Timedelta, window: int):
        """
        Put all the price data in a MultiIndex DataFrame with 2 levels
        columns: 1st = symbol and 2nd = OHLCV data.
        If the timeframe of the stored data is different from the
        screener's timeframe, resample the data.

        Parameters
        ----------
        time: `timestamp`
            Event time
        tf_delta: `timedelta object`
            Timeframe of the strategy
        window: `int`
            Number of bars to loock back in the resampled timeframe

        Returns
        -------
        frame: 'DataFrame'
            DataFrame with prices data of all the stored symbols
        """
        df_list=[]
        for symbol in self.prices.keys():
            df = self.get_and_resample_bars(time, symbol, tf_delta, window)
            df.name = symbol

            if df.index.tz is not None:
                df_list.append(df)

        frame = pd.concat(df_list, axis=1, keys=self.prices.keys())
        return frame

# ******* CCXT methods ******
    def _set_exchange(self, exchange):
        """
        Set the exchange from where download the data

        Parameters
        ----------
        exchange: `str`
            Name of the eschange
        """
        exchange = getattr(ccxt, exchange)()
        test = exchange.fetch_ticker('ETH/BTC')
        return exchange

    def get_all_symbols(self):
        """
        Obtain the list of all pairs prices available in the
        exchange defined for CCXT.

        Returns
        -------
        `list[str]`
            The list of all coins.
        """
        # Download all the symbols available in the defined exchange
        symbols = self.exchange.symbols

        # Define symbols to be excluded
        contains = ['UP', 'DOWN','BEAR','BULL']
        if self.base_currency == 'USDT':
            exclude = [
                'BUSD/USDT','TUSD/USDT','GBP/USDT','BTCST/USDT', 'BTG/USDT'
                'USDP/USDT','USDC/USDT','PAX/USDT','USDS/USDT','USDSB/USDT','UST/USDT',
                '1INCH/USDT', 'T/USDT', 'PAXG/USDT', 'USTC/USDT', 'EUR/USDT', 'AUD/USDT',
                'USDP/USDT']
        elif self.base_currency == 'BUSD':
            exclude = [
                'BUSD/BUSD','TUSD/BUSD','GBP/BUSD','BTCST/BUSD', 'BTG/BUSD'
                'USDP/BUSD','USDC/BUSD','PAX/BUSD','USDS/BUSD','USDSB/BUSD','UST/BUSD',
                '1INCH/BUSD', 'T/BUSD', 'PAXG/BUSD', 'USTC/BUSD', 'EUR/BUSD', 'AUD/BUSD',
                'USDP/BUSD', 'WBTC/BUSD', 'BETH/BUSD']
        else:
            logger.error('PRICE HANDLER: Base currency %s not supported', self.base_currency)

        # Filter only tradeble assets
        relevant = []
        for symbol in symbols:
            # Exclude ticker that is not in the base currency
            if not symbol.endswith(self.base_currency):
                continue
            # Exclude symbol in the black list 'exclude'
            if symbol in exclude:
                continue
            # Exclude futures symbols
            if any(substring in symbol for substring in contains):
                continue
            relevant.append(symbol)

        # Remove the slash
        relevant = list(map(lambda x: x.replace('/',''), relevant))
        return relevant

    def _transform_data(self, data: pd.DataFrame):
        """
        Clean and format the data downloaded from CCXT.

        Returns
        -------
        df: `DataFrame`
            Dataframe with Date-OHLCV.
        """
        data.columns=['date','open','high','low','close','volume']
        data = data.set_index('date')
        data.index = pd.to_datetime(data.index, unit='ms', utc=True)# + timedelta(hours=1)
        data.index = data.index.tz_convert('Europe/Paris')

        # change data type and deal with NaN values or duplicates
        data = data.astype(float)
        data = data.drop_duplicates()
        data.fillna(method='ffill', inplace=True)

        # Resample index for missing data
        df_resampled = data.iloc[:, :4].resample(self.tf_delta).ffill()
        df_resampled['volume'] = data['volume']
        df_resampled['volume'] = df_resampled['volume'].fillna(0)

        #data.index.freq = data.index.inferred_freq
        return df_resampled

    def _get_data_CCXT(self, symbol: str, start_date: pd.Timestamp, replace=True):
        """
        Download and format the data for the defined tickers.

        Parameters
        ----------
        symbol: `str`
            The ticker symbol, e.g. 'BTCUSDT'
        start_date: `Timestamp`
            Start date since when to download the price data
        replace: `bool`
            Define if replace the old data or not
        """
        # Convert start_date to UNIX format
        if isinstance(start_date, str):
            since = round(datetime.strptime(str(start_date), '%Y-%m-%d %H:%M').timestamp()*1000)
        else:
            dt_utc = start_date.astimezone(pytz.UTC)
            since = round(dt_utc.timestamp() * 1000)

        ccxt_symbol = symbol.upper()[:-4] + '/' + symbol.upper()[-4:]

        if self.end_date == '':
            ohlcv_list = []
            if self.exchange.has['fetchOHLCV']:
                ohlcv = self.exchange.fetch_ohlcv(ccxt_symbol, PriceHandler.timeframe, since=since, limit=1000)
                ohlcv_list.extend(ohlcv)
                while(len(ohlcv)==1000):
                    last_ts = ohlcv[-1][0]
                    #time.sleep(1)
                    ohlcv = self.exchange.fetch_ohlcv(ccxt_symbol, PriceHandler.timeframe, since=last_ts, limit=1000)
                    ohlcv_list.extend(ohlcv)
        else:
            print('To be implemented')

        # Convert list to dataframe
        data = pd.DataFrame(ohlcv_list)

        # Transform and store data
        if len(data) > 0 :
            # data = self._transform_data(data)
            if replace:
                #Download new data and replace the old one
                PriceHandler.prices[symbol.upper()] = self._transform_data(data)
            else:
                # Updating data. Append the new ones
                PriceHandler.prices[symbol.upper()] = pd.concat([PriceHandler.prices[symbol.upper()] , self._transform_data(data)])
                # Drop rows with duplicate dates, keeping the most recent one
                PriceHandler.prices[symbol.upper()] = PriceHandler.prices[symbol.upper()][~PriceHandler.prices[symbol.upper()].index.duplicated(keep='last')]

            # Store data in the SQL database
            self.sql_handler.to_database(symbol, PriceHandler.prices[symbol.upper()], replace)


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

__author__ = "You-Sheng Lin"
__copyright__ = "Copyright (C) 2019"
__license__ = "AGPL"
__email__ = "pyquino@gmail.com"

from math import ceil, sqrt, hypot
import matplotlib.pyplot as plt

sampling_time = 0.001
Amax = 2500

def interpolation_2d(ox, oy, x, y, f):

    length = hypot((x - ox), (y - oy))
    Nc = 0
    amax = Amax
    N_start = ceil(f / (amax * sampling_time))
    Tstr = N_start * sampling_time
    L_min = f * Tstr

    Lsblk = 0.0
    Nss = 0.0

    if length <= L_min:
        N_start = ceil(sqrt(length / (amax * sampling_time * sampling_time)))
        Tstr = N_start * sampling_time
        Tc = Nc * sampling_time
        V_cmd = length / Tstr
        Lest = V_cmd * Tstr
    else:
        Nc = ceil((length - L_min) / (f * sampling_time))
        Tc = Nc * sampling_time
        V_cmd = length / (Tstr + Tc)
        Lest = V_cmd * (Tstr + Tc)

    L1 = 0.5 * V_cmd * Tstr
    L2 = V_cmd * (Tstr + Tc)
    step1 = N_start
    step2 = step1 + Nc
    step3 = step2 + N_start
    t0 = 0
    t1 = step1 * sampling_time
    t2 = step2 * sampling_time
    t3 = step3 * sampling_time

    f = V_cmd
    a = V_cmd / Tstr
    j = a / sampling_time
    s_tmp = []
    v_tmp = []
    acc_tmp = []
    for i in range(step3):

        t = i * sampling_time
        if i < step1:
            acc = a
            fed = acc * t
            pos = 0.5 * acc * t * t

        elif step1 <= i <= step2:
            acc = 0
            fed = f
            pos = L1 + fed * (t - t1)

        else:
            acc = -a
            fed = a * (t3 - t)
            pos = L2 - 0.5 * a * (t3 - t) * (t3 - t)

        s_tmp.append(pos)
        v_tmp.append(fed)
        acc_tmp.append(acc)

    plt.plot(list(i * 0.001 for i in range(len(s_tmp))), s_tmp)
    plt.show()

def s_shape_interplation(ox, oy, x, y, f):

    length = hypot((x - ox), (y - oy))
    Nss = 0
    Nc = 0
    amax = Amax
    # need to define Jmax
    Jmax = 50000
    Lmin = 2 * f * sqrt(f / Jmax)
    Nstr = ceil((Lmin / 2 / Jmax / sampling_time ** 3) ** (1 / 3))
    Tstr = Nstr * sampling_time

    if length <= Lmin:
        Nstr = ceil((length / 2 / Jmax / sampling_time ** 3) ** (1 / 3))
        Tstr = Nstr * sampling_time
        Jmax = length / (2 * Tstr ** 3)
        amax = Jmax * Tstr
        Vcmd = amax * Tstr
    else:
        Tc = length / f - 2 * Tstr
        Nc = ceil(Tc / sampling_time)
        Tc = Nc * sampling_time
        Vcmd = length / (2 * Tstr + Tc)
        amax = Vcmd / Tstr
        Jmax = amax / Tstr

    step1 = Nstr
    step2 = step1 + Nstr
    step3 = step2 + Nc
    step4 = step3 + Nstr
    step5 = step4 + Nstr

    t0 = 0
    t1 = step1 * sampling_time
    t2 = step2 * sampling_time
    t3 = step3 * sampling_time
    t4 = step4 * sampling_time
    t5 = step5 * sampling_time

    pos1 = (Jmax * (t1 - t0) ** 3) / 6
    pos2 = pos1 + Vcmd * (t2 - t1) - 0.5 * Jmax * (t2 ** 2 * (t2 - t1) - t2 *
                                                   (t2 ** 2 - t1 ** 2) + (t2 ** 3 - t1 ** 3) / 3)
    pos3 = pos2 + Vcmd * (t3 - t2)
    pos4 = pos3 + Vcmd * (t4 - t3) - (Jmax * (t4 - t3) ** 3 / 6)
    pos5 = pos4 + 0.5 * Jmax * (t5 ** 2 * (t5 - t4) - t5 * (t5 ** 2 - t4 ** 2) + ((t5 ** 3 - t4 ** 3) / 3))

    s_tmp = []
    v_tmp = []
    acc_tmp = []
    jerk_tmp = []

    for j in range(step5):
        t = j * sampling_time
        if j < step1:
            jerk = Jmax
            acc = Jmax * (t - t0)
            fed = 0.5 * Jmax * (t - t0) ** 2
            pos = (Jmax * (t-t0) ** 3)/6
        elif step1 <= j < step2:
            jerk = -Jmax
            acc = Jmax * (t2 - t)
            fed = Vcmd - 0.5 * Jmax * (t2 - t) ** 2
            pos = pos1 + Vcmd * (t - t1) - 0.5 * Jmax * (
                        t2 ** 2 * (t - t1) - t2 * (t ** 2 - t1 ** 2) + (t ** 3 - t1 ** 3) / 3)
        elif step2 <= j < step3:
            jerk = 0
            acc = 0
            fed = Vcmd
            pos = pos2 + Vcmd * (t - t2)
        elif step3 <= j < step4:
            jerk = -Jmax
            acc = -Jmax * (t - t3)
            fed = Vcmd - 0.5 * Jmax * (t - t3) ** 2
            pos = pos3 + Vcmd * (t - t3) - (Jmax * (t - t3) ** 3 / 6)
        elif j >= step4:
            jerk = Jmax
            acc = -Jmax * (t5 - t)
            fed = 0.5 * Jmax * (t5 - t) ** 2
            pos = pos4 + 0.5 * Jmax * (t5 ** 2 * (t - t4) - t5 * (t ** 2 - t4 ** 2) + ((t ** 3 - t4 ** 3) / 3))

        else:
            raise ValueError

        s_tmp.append(pos)
        v_tmp.append(fed)
        acc_tmp.append(acc)
        jerk_tmp.append(jerk)

    return s_tmp, v_tmp, acc_tmp, jerk_tmp

if __name__ == '__main__':
    from nc import nc_reader
    with open("../line.nc") as textfile:
        text = textfile.read()
    s_plot = []
    v_plot = []
    a_plot = []
    j_plot = []
    for ox, oy, x, y, of in nc_reader(text):
        # interpolation_2d(ox, oy, x, y, of)
        s, v, a, j = s_shape_interplation(ox, oy, x, y, of)
        s_plot.extend(s)
        v_plot.extend(v)
        a_plot.extend(a)
        j_plot.extend(j)
    plt.plot(list(i * 0.001 for i in range(len(s_plot))), s_plot)
    plt.show()


"""thin-edge.io client"""
import logging
import json
import time
import re
import os
import threading
from typing import Any, List
import requests
from paho.mqtt.client import Client, MQTTMessage
from .config import Config
from .topics import health_topic
from .management.worker import Worker, Job
from .management import configuration, firmware
from .messages import JSONMessage

log = logging.getLogger(__file__)

def update_url(url: str, replace_url: str) -> str:
    """Modify the url by replacing any reference to a generic 0.0.0.0
    ip or a loopback address with the real ip address of http server
    hosted by thin-edge.io

    Args:
        url (str): Url to be modified
    """
    return re.sub(
        r"^(https?://)?(0\.0\.0\.0|127\.0\.\d+\.\d+|localhost)(:\d+)?",
        replace_url,
        url,
        1,
    )

class TedgeClient:
    """Tedge Client

    The tedge client is used to communicate with thin-edge.io via MQTT and HTTP
    """

    def __init__(self, config: Config) -> None:
        self.mqtt = None
        self.config = config
        self._workers: List[Worker] = []
        self.config.local_id = self.get_id()
        self._subscriptions = []
        self._connected_once = threading.Event()

    def shutdown(self, worker_timeout: float = 10):
        """Shutdown client including any workers in progress

        Args:
            worker_timeout(float): Timeout in seconds to wait for
                each worker (individually). Defaults to 10.
        """
        if self.mqtt and self.mqtt.is_connected():
            self.mqtt.disconnect()
            self.mqtt.loop_stop(True)

        # Stop all workers
        for worker in self._workers:
            worker.join(worker_timeout if worker_timeout and worker_timeout > 0 else 10)

        # Clear workers
        self._workers = []
        self.mqtt = None

    def get_id(self):
        """Get the id to be used for the connector"""
        return (
            os.getenv("CONNECTOR_DEVICE_ID")
            or os.getenv("HOSTNAME")
            or os.getenv("HOST")
            or "tedge_child"
        )

    def connect(self):
        """Connect to the thin-edge.io MQTT broker"""
        if self.mqtt is not None:
            log.info(
                "MQTT client already exists. connected=%s", self.mqtt.is_connected()
            )
            return

        if self.mqtt is None:
            # Don't use a clean session so no messages will go missing
            client = Client(self.config.device_id, clean_session=False)
            client.reconnect_delay_set(10, 120)
            if self.config.device_id:
                client.will_set(
                    health_topic("connector", self.config.device_id),
                    json.dumps({"status": "down"}),
                )

            def _create_on_connect_callback(done):
                _done = done

                def on_connect(_client, _userdata, _flags, result_code):
                    nonlocal _done
                    if result_code == 0:
                        log.info("Connected to MQTT Broker!")
                        _done.set()
                    else:
                        log.info("Failed to connect. code=%d", result_code)

                return on_connect

            def on_disconnect(_client: Client, _userdata: Any, result_code: int):
                log.info("Client was disconnected. result_code=%d", result_code)

            self._connected_once.clear()
            client.on_connect = _create_on_connect_callback(self._connected_once)
            client.on_disconnect = on_disconnect
            # Enable paho mqtt logs to help with any mqtt connection debugging
            client.enable_logger(log)
            log.info(
                "Trying to connect to the MQTT broker: host=%s:%s, client_id=%s",
                self.config.tedge.host,
                self.config.tedge.port,
                self.config.device_id,
            )

            client.connect(self.config.tedge.host, self.config.tedge.port)
            client.loop_start()

            # Only assign client after .connect call (as it can throw an error if the address is not reachable)
            self.mqtt = client

        if not self._connected_once.wait(30):
            log.warning(
                "Failed to connect successfully after 30 seconds. Continuing anyway"
            )
            # TODO: Should an exception be thrown, or just let paho do the reconnect eventually
            # self.shutdown()
            # raise RuntimeError("Failed to connect successfully to MQTT broker")

    def bootstrap(self):
        """Register extra services once the mqtt client is up"""
        configuration.bootstrap(self.config, self.mqtt)

    def register(self):
        """Register the child device to thin-edge.io"""
        # NOTE: Use custom service to provide the registration api. In the future this
        # will be deprecated and supported by thin-edge.io.
        response = requests.post(
            f"{self.config.tedge.registration_api}/register",
            json={
                "name": self.config.local_id,
                "supportedOperations": [
                    "c8y_Firmware",
                    "c8y_ConfigurationUpdate",
                    "c8y_DownloadConfigFile",
                ],
            },
            timeout=30,
        )

        response.raise_for_status()
        data = response.json()
        self.config.device_id = data.get("id")
        log.info(
            "Child device has been registered successfully. id=%s, message=%s",
            self.config.device_id,
            data,
        )

        # FIXME: Wait before trying to connect to broker
        time.sleep(5)

    def subscribe(self):
        """Subscribe to thin-edge.io child device topics and register
        handlers to respond to different operations.
        """
        # get config handler
        handlers = [
            (
                f"tedge/{self.config.device_id}/commands/req/config_snapshot/#",
                configuration.on_config_snapshot_request,
            ),
            (
                f"tedge/{self.config.device_id}/commands/req/config_update/#",
                configuration.on_config_update_request,
            ),
            (
                f"tedge/{self.config.device_id}/commands/req/firmware_update/#",
                firmware.on_firmware_update_request,
            ),
        ]
        for topic, handler in handlers:
            log.info("Registering worker. topic=%s", topic)
            self.register_worker(topic, handler)

        # Only register that the child device is ready now
        # Register health check and bootstrap other plugin settings
        log.info(
            "Publishing health endpoint. device=%s, service=connector",
            self.config.device_id,
        )
        self.mqtt.publish(
            health_topic("connector", self.config.device_id),
            json.dumps({"status": "up"}),
        )

    def register_worker(self, topic: str, target: Job, num_threads: int = 1):
        """Register a worker to handle requests for a specific MQTT topic

        Args:
            topic (str): MQTT topic
            target (Any): Job function to execute for the worker
            num_threads (int, optional): Number of threads. Defaults to 1.
        """
        worker = Worker(target, num_threads=num_threads)
        worker.start()

        def add_job(client, _userdata, message: MQTTMessage):
            log.info("Adding job")
            payload = json.loads(message.payload.decode())
            if isinstance(payload, dict):
                if "url" in payload:
                    payload["url"] = update_url(payload["url"], self.config.tedge.api)

            worker.put(self.config, client, JSONMessage(message.topic, payload))

        self.mqtt.message_callback_add(topic, add_job)
        self.mqtt.subscribe(topic, qos=2)
        self._workers.append(worker)

    def loop_forever(self):
        """Block infinitely"""
        self.mqtt.loop_forever()