from . import ClinvSourceBaseTestClass, ClinvGenericResourceTests
from clinv.sources import risk_management
from unittest.mock import patch, call

import unittest

class RiskManagementSourceBaseTestClass(ClinvSourceBaseTestClass):
    """
    Abstract Base class to ensure that all the RiskManagement sources have the
    same interface.

    Must be combined with a unittest.TestCase that defines:
        * self.module_name: the name of the module file.
        * self.source_obj: the name of the source class to test.
        * self.resource_obj: the name of the resource class to test.
        * self.resource_id: the id of the resource class to test.
        * self.resource_type: the type of the resource class to test.
    """

    def setUp(self):
        self.module_name = "risk_management"
        super().setUp()
        self.resource_patch = patch(
            "clinv.sources.risk_management.{}".format(self.resource_obj),
            autospect=True,
        )
        self.resource = self.resource_patch.start()

        # Initialize object to test
        source_data = {}
        user_data = {}
        self.src = self.source_obj(source_data, user_data)

    def tearDown(self):
        super().tearDown()
        self.resource_patch.stop()

    def test_generate_source_data_creates_expected_source_data_attrib(self):
        expected_source_data = {}

        generated_source_data = self.src.generate_source_data()

        self.assertEqual(
            self.src.source_data, expected_source_data,
        )
        self.assertEqual(
            generated_source_data, expected_source_data,
        )

    def test_generate_user_data_creates_expected_user_data_attrib(self):
        expected_user_data = {}

        generated_user_data = self.src.generate_source_data()

        self.assertEqual(
            self.src.user_data, expected_user_data,
        )
        self.assertEqual(
            generated_user_data, expected_user_data,
        )

    def test_generate_inventory_return_empty_dict_if_no_data(self):
        self.src.user_data = {}
        self.assertEqual(self.src.generate_inventory(), {})

    def test_generate_inventory_creates_resource_objects(self):
        self.src.user_data = {self.resource_id: "tbd"}

        desired_mock_input = "tbd"

        desired_inventory = self.src.generate_inventory()
        self.assertEqual(
            self.resource.assert_called_with({self.resource_id: desired_mock_input},),
            None,
        )

        self.assertEqual(
            desired_inventory, {self.resource_id: self.resource.return_value},
        )

class TestProjectSource(RiskManagementSourceBaseTestClass, unittest.TestCase):
    """
    Test the Project implementation in the inventory.
    """

    def setUp(self):
        self.source_obj = risk_management.Projectsrc
        self.resource_obj = "Project"
        self.resource_id = "pro_01"
        self.resource_type = "projects"
        super().setUp()

    def tearDown(self):
        super().tearDown()

class TestServiceSource(RiskManagementSourceBaseTestClass, unittest.TestCase):
    """
    Test the Service implementation in the inventory.
    """

    def setUp(self):
        self.source_obj = risk_management.Servicesrc
        self.resource_obj = "Service"
        self.resource_id = "ser_01"
        self.resource_type = "services"
        super().setUp()

    def tearDown(self):
        super().tearDown()

class TestInformationSource(
    RiskManagementSourceBaseTestClass, unittest.TestCase,
):
    """
    Test the Information implementation in the inventory.
    """

    def setUp(self):
        self.source_obj = risk_management.Informationsrc
        self.resource_obj = "Information"
        self.resource_id = "inf_01"
        self.resource_type = "informations"
        super().setUp()

    def tearDown(self):
        super().tearDown()

class TestPeopleSource(RiskManagementSourceBaseTestClass, unittest.TestCase):
    """
    Test the People implementation in the inventory.
    """

    def setUp(self):
        self.source_obj = risk_management.Peoplesrc
        self.resource_obj = "People"
        self.resource_id = "peo_01"
        self.resource_type = "people"
        super().setUp()

    def tearDown(self):
        super().tearDown()

class ClinvActiveResourceTests(ClinvGenericResourceTests):
    """Must be combined with a unittest.TestCase that defines:
    * self.resource as a ClinvActiveResource subclass instance
    * self.raw as a dictionary with the data of the resource
    * self.id as a string with the resource id"""

    def setUp(self):
        self.module_name = "risk_management"
        super().setUp()

    def tearDown(self):
        super().tearDown()

    def test_get_instance_responsible(self):
        self.assertEqual(self.resource.responsible, "responsible@clinv.com")

class TestProject(ClinvActiveResourceTests, unittest.TestCase):
    def setUp(self):
        super().setUp()

        self.id = "pro_01"
        self.raw = {
            "pro_01": {
                "aliases": "Awesome Project",
                "description": "This is the description",
                "informations": ["inf_01",],
                "links": {"homepage": "www.homepage.com"},
                "responsible": "responsible@clinv.com",
                "members": {
                    "developers": ["developer_1",],
                    "devops": ["devops_1"],
                    "po": "product owner",
                    "stakeholders": ["stakeholder_1"],
                    "ux": None,
                    "qa": None,
                },
                "people": ["peo_01",],
                "name": "resource_name",
                "services": ["ser_01"],
                "state": "active",
            }
        }

        self.resource = risk_management.Project(self.raw)

    def tearDown(self):
        super().tearDown()

    def test_get_services(self):
        self.assertEqual(self.resource.services, ["ser_01"])

    def test_get_informations(self):
        self.assertEqual(self.resource.informations, ["inf_01"])

    def test_get_aliases(self):
        self.assertEqual(self.resource.aliases, ["Awesome Project"])

    def test_search_by_aliases(self):
        self.assertTrue(self.resource.search("Awesome Project"))

    def test_search_by_aliases_doesn_not_work_if_alias_is_none(self):
        self.resource.raw["aliases"] = None
        self.assertFalse(self.resource.search("Awesome Project"))

    def test_print_resource_information(self):
        self.resource.print()
        print_calls = (
            call("pro_01"),
            call("  Name: resource_name"),
            call("  Aliases: Awesome Project"),
            call("  Description: This is the description"),
            call("  State: active"),
            call("  Services: ser_01"),
            call("  Informations: inf_01"),
        )

        for print_call in print_calls:
            self.assertIn(print_call, self.print.mock_calls)
        self.assertEqual(7, len(self.print.mock_calls))

class TestInformation(ClinvActiveResourceTests, unittest.TestCase):
    def setUp(self):
        super().setUp()

        self.id = "inf_01"
        self.raw = {
            "inf_01": {
                "description": "This is the description",
                "name": "resource_name",
                "personal_data": True,
                "responsible": "responsible@clinv.com",
                "state": "active",
            }
        }

        self.resource = risk_management.Information(self.raw)

    def tearDown(self):
        super().tearDown()

    def test_get_personal_data(self):
        self.assertEqual(self.resource.personal_data, True)

    def test_print_resource_information(self):
        self.resource.print()
        print_calls = (
            call("inf_01"),
            call("  Name: resource_name"),
            call("  Description: This is the description"),
            call("  State: active"),
            call("  Personal Information: True"),
        )

        for print_call in print_calls:
            self.assertIn(print_call, self.print.mock_calls)
        self.assertEqual(5, len(self.print.mock_calls))

class TestService(ClinvActiveResourceTests, unittest.TestCase):
    def setUp(self):
        super().setUp()

        self.id = "ser_01"
        self.raw = {
            "ser_01": {
                "access": "public",
                "authentication": {"2fa": True, "method": "Oauth2"},
                "aws": {"ec2": ["i-01"],},
                "description": "This is the description",
                "dependencies": ["ser_02"],
                "endpoints": ["https://endpoint1.com"],
                "informations": ["inf_01",],
                "links": {
                    "docs": {
                        "internal": "https://internaldocs",
                        "external": "https://internaldocs",
                    },
                },
                "name": "resource_name",
                "responsible": "responsible@clinv.com",
                "state": "active",
            }
        }

        self.resource = risk_management.Service(self.raw)

    def tearDown(self):
        super().tearDown()

    def test_get_access(self):
        self.assertEqual(self.resource.access, "public")

    def test_get_informations(self):
        self.assertEqual(self.resource.informations, ["inf_01"])

    def test_get_aws(self):
        self.assertEqual(self.resource.aws, {"ec2": ["i-01"]})

    def test_get_dependencies(self):
        self.assertEqual(self.resource.dependencies, ["ser_02"])

    def test_search_matches_aws_resources(self):
        self.assertTrue(self.resource.search("i-01"))

    def test_search_matches_service_dependencies(self):
        self.assertTrue(self.resource.search("ser_02"))

    def test_search_works_without_defined_dependencies(self):
        self.resource.raw.pop("dependencies")
        self.assertFalse(self.resource.search("ser_02"))

    def test_print_resource_information(self):
        self.resource.print()
        print_calls = (
            call("ser_01"),
            call("  Name: resource_name"),
            call("  Description: This is the description"),
            call("  State: active"),
            call("  Access: public"),
            call("  Informations: inf_01"),
            call("  Related resources:"),
            call("    ec2:"),
            call("      i-01"),
        )

        for print_call in print_calls:
            self.assertIn(print_call, self.print.mock_calls)
        self.assertEqual(9, len(self.print.mock_calls))

class TestPeople(ClinvGenericResourceTests, unittest.TestCase):
    def setUp(self):
        self.module_name = "risk_management"
        super().setUp()

        self.id = "peo_01"
        self.raw = {
            "peo_01": {
                "description": "This is the description",
                "name": "resource_name",
                "state": "active",
                "email": "user@email.org",
                "iam_user": "iamuser_user1",
            }
        }

        self.resource = risk_management.People(self.raw)

    def tearDown(self):
        super().tearDown()

    def test_get_iam_user(self):
        self.assertEqual(self.resource.iam_user, "iamuser_user1")

    def test_get_email(self):
        self.assertEqual(self.resource.email, "user@email.org")

    def test_search_by_email(self):
        self.assertTrue(self.resource.search(".*@email.org"))

    def test_search_by_iam_user(self):
        self.assertTrue(self.resource.search("iamuser.*"))

    def test_print_resource_information(self):
        self.resource.print()
        print_calls = (
            call("peo_01"),
            call("  Name: resource_name"),
            call("  Description: This is the description"),
            call("  Email: user@email.org"),
            call("  State: active"),
            call("  IAM User: iamuser_user1"),
        )

        for print_call in print_calls:
            self.assertIn(print_call, self.print.mock_calls)
        self.assertEqual(6, len(self.print.mock_calls))


def preberi(ime_datoteke):
    d = {}
    f = open(ime_datoteke).readlines()
    for i, line in zip(range(1, len(f) + 1), f):
        d[i] = []
        for x in line.split():
            d[i].append(int(x))
        d[i] = d[i][d[i].index(min(d[i])):] + d[i][:d[i].index(min(d[i]))]
    return d

def mozna_pot(pot, zemljevid):
    if len(zemljevid[pot[0]]) != 1 or len(zemljevid[pot[-1]]) != 1:
        return False
    for x in pot[1:-1]:
        if len(zemljevid[x]) == 1:
            return False
    for i, j in zip(pot, pot[1:]):
        if j not in zemljevid[i] or i == j:
            return False
    return True

def hamiltonova(pot, zemljevid):
    for i in zemljevid.keys():
        if len(zemljevid[i]) > 1:
            if pot.count(i) != 1:
                return False
    return mozna_pot(pot, zemljevid)

def navodila(pot, zemljevid):
    return [(zemljevid[pot[i]].index(pot[i+1]) - zemljevid[pot[i]].index(pot[i-1])) % len(zemljevid[pot[i]]) for i in range(1,len(pot) - 1)]

def prevozi(zacetek, navodila, zemljevid):
    res = [zacetek, zemljevid[zacetek][0]]
    for i in navodila:
        res.append(zemljevid[res[-1]] [(zemljevid[res[-1]].index(res[-2]) + i) % len(zemljevid[res[-1]])])
    return res

"""
def sosedi(doslej, zemljevid):
    s = []
    for i in list(doslej):
        s += zemljevid[i]
    return set(s).difference(doslej)
"""

def sosedi(doslej, zemljevid):
    return set([j for i in doslej for j in zemljevid[i]]).difference(doslej)

"""
def razdalja(x, y, zemljevid): #Dijkstra's algorithm
    used = [False] * len(zemljevid.keys())
    used[x - 1] = True
    dist = [100000000000] * len(zemljevid.keys())
    dist[x - 1] = 0
    queue = [x]
    while len(queue):
        for j in zemljevid[queue[0]]:
            if dist[j - 1] > dist[queue[0] - 1] + 1:
                dist[j - 1] = dist [queue[0] - 1] + 1
            if not used[j - 1]:
                queue.append(j)
                used[j - 1] = True
        del queue[0]
    return dist[y - 1]
"""

def razdalja(x, y, zemljevid):
    dist = {x}
    i = 0
    while y not in dist:
        dist = dist.union(sosedi(dist, zemljevid))
        i += 1
    return i

def najkrajsa_navodila(x, y, zemljevid):  #Dijkstra's algorithm (array "used" saves the road)
    used = [-1] * len(zemljevid.keys())
    used[x - 1] = 0
    dist = [100000000000] * len(zemljevid.keys())
    dist[x - 1] = 0
    queue = [x]
    while len(queue):
        for j in zemljevid[queue[0]]:
            if used[j - 1] == -1:
                queue.append(j)
            if dist[j - 1] > dist[queue[0] - 1] + 1:
                dist[j - 1] = dist [queue[0] - 1] + 1
                used[j - 1] = queue[0]
        del queue[0]
    road = [y]
    while y != x:
        road.append(used[y - 1])
        y = used[y - 1]
    return navodila(road[::-1], zemljevid)

import unittest
from random import randint
import os

class Test06(unittest.TestCase):
    maxDiff = 100000

    def test_01_preberi(self):
        self.assertEqual(
            preberi("zemljevid.txt"),
            {1: [3],
             2: [4],
             3: [1, 8, 7, 6, 4],
             4: [2, 3, 6, 5],
             5: [4, 11, 10],
             6: [3, 11, 4],
             7: [3, 8, 11],
             8: [3, 16, 9, 7],
             9: [8, 16, 14, 11],
             10: [5, 11, 13],
             11: [5, 6, 7, 9, 14, 10],
             12: [13],
             13: [10, 14, 12],
             14: [9, 16, 13, 11],
             15: [16],
             16: [8, 15, 14, 9]})

        fname = "z{:05}.bla".format(randint(10000, 99999))
        with open(fname, "w") as f:
            f.write("2\n3 1\n2")
        try:
            self.assertEqual(preberi(fname), {1:[2], 2: [1, 3], 3: [2]})
        finally:
            try:
                os.remove(fname)
            except:
                print("Ne morem pobrisati {}. (Je na Dropboxu?) Briši sam(a).".format(fname))

    def test_02_mozna_pot(self):
        zemljevid = preberi("zemljevid.txt")
        self.assertTrue(mozna_pot([1, 3, 7, 3, 4, 2], zemljevid))
        self.assertTrue(mozna_pot([1, 3, 7, 3, 4, 2][::-1], zemljevid))
        self.assertTrue(mozna_pot([1, 3, 7, 3, 4, 5, 4, 3, 1], zemljevid))
        self.assertTrue(mozna_pot([1, 3, 7, 3, 4, 5, 4, 3, 1][::-1], zemljevid))
        self.assertTrue(mozna_pot([1, 3, 8, 16, 15], zemljevid))
        self.assertTrue(mozna_pot([1, 3, 8, 16, 15][::-1], zemljevid))
        self.assertTrue(mozna_pot([15, 16, 15], zemljevid))

        # Ne začne/konča se na vhodih/izhodih
        self.assertFalse(mozna_pot([1, 3, 7, 11, 14, 16], zemljevid))
        self.assertFalse(mozna_pot([3, 7, 11, 14, 16, 15], zemljevid))

        # Vmes gre ven
        self.assertFalse(mozna_pot([1, 3, 6, 4, 2, 4, 5, 11, 14, 13, 12], zemljevid))
        self.assertFalse(mozna_pot([1, 3, 6, 4, 2, 2, 4, 5, 11, 14, 13, 12], zemljevid))

        # Ponovi eno križišče
        self.assertFalse(mozna_pot([1, 3, 8, 8, 16, 15], zemljevid))

        # Ni povezave
        self.assertFalse(mozna_pot([1, 3, 16, 15], zemljevid))
        self.assertFalse(mozna_pot([1, 15], zemljevid))

        zemljevid2 = {1: [2], 2: [1, 3], 3: [2]}
        self.assertTrue(mozna_pot([1, 2, 3], zemljevid2))
        self.assertFalse(mozna_pot([1, 3], zemljevid2))

        zemljevid2 = {1: [2], 2: [1, 3], 3: [2, 4], 4: [3]}
        self.assertTrue(mozna_pot([1, 2, 3, 4], zemljevid2))
        self.assertTrue(mozna_pot([4, 3, 2, 1], zemljevid2))
        self.assertFalse(mozna_pot([1, 3, 4], zemljevid2))
        self.assertFalse(mozna_pot([1, 4], zemljevid2))

    def test_03_hamiltonova(self):
        zemljevid = preberi("zemljevid.txt")
        self.assertTrue(hamiltonova([1, 3, 7, 8, 16, 9, 14, 11, 6, 4, 5, 10, 13, 12], zemljevid))
        self.assertTrue(hamiltonova([1, 3, 7, 8, 16, 9, 14, 11, 6, 4, 5, 10, 13, 12][::-1], zemljevid))

        # Ena manjka
        self.assertFalse(hamiltonova([1, 3, 8, 16, 9, 14, 11, 6, 4, 5, 10, 13, 12], zemljevid))

        # Ni začetka/konca
        self.assertFalse(hamiltonova([3, 8, 16, 9, 14, 11, 6, 4, 5, 10, 13, 12], zemljevid))
        self.assertFalse(hamiltonova([1, 3, 7, 8, 16, 9, 14, 11, 6, 4, 5, 10, 13], zemljevid))

        # Ponavljenje
        self.assertFalse(hamiltonova([1, 3, 8, 16, 9, 14, 11, 6, 4, 5, 10, 11, 14, 13, 12], zemljevid))
        self.assertFalse(hamiltonova([1, 3, 7, 8, 16, 9, 14, 11, 6, 3, 4, 5, 10, 13, 12], zemljevid))

        zemljevid2 = {1: [2], 2: [1, 3], 3: [2, 4], 4: [3]}
        self.assertTrue(hamiltonova([1, 2, 3, 4], zemljevid2))
        self.assertTrue(hamiltonova([4, 3, 2, 1], zemljevid2))
        self.assertFalse(hamiltonova([1, 2, 4], zemljevid2))

class Test07(unittest.TestCase):
    maxDiff = 100000

    def test_01_navodila(self):
        zemljevid = preberi("zemljevid.txt")
        self.assertEqual(navodila([1, 3, 8, 16, 15], zemljevid), [1, 1, 1])
        self.assertEqual(navodila([1, 3, 6, 4, 2], zemljevid), [3, 2, 2])
        self.assertEqual(navodila([1, 3, 6, 11, 14, 16, 15], zemljevid), [3, 1, 3, 2, 3])
        self.assertEqual(navodila([12, 13, 14, 11, 9, 8, 7, 3, 4, 2], zemljevid), [2, 1, 5, 1, 1, 2, 2, 3])
        self.assertEqual(navodila([2, 4, 2], zemljevid), [0])
        self.assertEqual(navodila([15, 16, 14, 11, 9, 16, 14, 11, 9, 16, 15], zemljevid), [1, 2, 5, 2, 3, 2, 5, 2, 2])

class Test08(unittest.TestCase):
    maxDiff = 100000

    def test_01_prevozi(self):
        zemljevid = preberi("zemljevid.txt")
        self.assertEqual(prevozi(1, [1, 1, 1], zemljevid), [1, 3, 8, 16, 15])
        self.assertEqual(prevozi(1, [3, 2, 2], zemljevid), [1, 3, 6, 4, 2])
        self.assertEqual(prevozi(1, [3, 1, 3, 2, 3], zemljevid), [1, 3, 6, 11, 14, 16, 15])
        self.assertEqual(prevozi(12, [2, 1, 5, 1, 1, 2, 2, 3], zemljevid), [12, 13, 14, 11, 9, 8, 7, 3, 4, 2])
        self.assertEqual(prevozi(2, [0], zemljevid), [2, 4, 2])
        self.assertEqual(prevozi(15, [1, 2, 5, 2, 3, 2, 5, 2, 2], zemljevid), [15, 16, 14, 11, 9, 16, 14, 11, 9, 16, 15])

class Test09(unittest.TestCase):
    maxDiff = 100000

    def test_01_sosedi(self):
        zemljevid = preberi("zemljevid.txt")
        self.assertEqual(sosedi({15}, zemljevid), {16})
        self.assertEqual(sosedi({15, 16}, zemljevid), {14, 9, 8})
        self.assertEqual(sosedi({15, 16, 14, 9, 8}, zemljevid), {3, 7, 11, 13})
        self.assertEqual(sosedi({15, 16, 14, 9, 8, 3, 7, 11, 13}, zemljevid), {1, 4, 6, 5, 10, 12})
        self.assertEqual(sosedi({15, 16, 14, 9, 8, 3, 7, 11, 13, 1, 4, 6, 5, 10, 12}, zemljevid), {2})
        self.assertEqual(sosedi({15, 16, 14, 9, 8, 3, 7, 11, 13, 1, 4, 6, 5, 10, 12, 2}, zemljevid), set())

        self.assertEqual(sosedi({6}, zemljevid), {4, 3, 11})
        self.assertEqual(sosedi({6, 4, 3, 11}, zemljevid), {2, 5, 1, 7, 8, 9, 14, 10})

    def test_02_razdalja(self):
        zemljevid = preberi("zemljevid.txt")
        self.assertEqual(razdalja(15, 16, zemljevid), 1)

        self.assertEqual(razdalja(15, 14, zemljevid), 2)
        self.assertEqual(razdalja(15, 9, zemljevid), 2)
        self.assertEqual(razdalja(15, 8, zemljevid), 2)

        self.assertEqual(razdalja(15, 7, zemljevid), 3)
        self.assertEqual(razdalja(15, 13, zemljevid), 3)

        self.assertEqual(razdalja(15, 5, zemljevid), 4)
        self.assertEqual(razdalja(15, 10, zemljevid), 4)

        self.assertEqual(razdalja(15, 2, zemljevid), 5)

        self.assertEqual(razdalja(6, 4, zemljevid), 1)
        self.assertEqual(razdalja(6, 5, zemljevid), 2)
        self.assertEqual(razdalja(6, 10, zemljevid), 2)
        self.assertEqual(razdalja(6, 13, zemljevid), 3)
        self.assertEqual(razdalja(6, 12, zemljevid), 4)

class Test10(unittest.TestCase):
    maxDiff = 100000

    def test_01_najkrajsa_pot(self):
        zemljevid = preberi("zemljevid.txt")
        self.assertEqual(najkrajsa_navodila(1, 15, zemljevid), [1, 1, 1])
        self.assertEqual(najkrajsa_navodila(1, 2, zemljevid), [4, 3])
        self.assertEqual(najkrajsa_navodila(2, 15, zemljevid), [1, 2, 1, 1])
        self.assertEqual(najkrajsa_navodila(2, 12, zemljevid), [3, 2, 2, 2])
        self.assertEqual(najkrajsa_navodila(15, 12, zemljevid), [1, 1, 1])

        self.assertEqual(najkrajsa_navodila(15, 1, zemljevid), [3, 3, 4])
        self.assertEqual(najkrajsa_navodila(2, 1, zemljevid), [1, 1])
        self.assertEqual(najkrajsa_navodila(15, 2, zemljevid), [3, 3, 3, 3])
        self.assertEqual(najkrajsa_navodila(12, 2, zemljevid), [1, 1, 1, 1])
        self.assertEqual(najkrajsa_navodila(12, 15, zemljevid), [2, 3, 3])

        navodila = najkrajsa_navodila(1, 12, zemljevid)
        self.assertEqual(len(navodila), 5)
        self.assertEqual(prevozi(1, navodila, zemljevid)[-1], 12)

        navodila = najkrajsa_navodila(12, 1, zemljevid)
        self.assertEqual(len(navodila), 5)
        self.assertEqual(prevozi(12, navodila, zemljevid)[-1], 1)

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


from flask import Flask
from controller.controller import form
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Register the Blueprint
app.register_blueprint(form, url_prefix='/api')
@app.route("/")
def trail():
    return "second12"

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


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('member', '0004_auto_20160317_1559'),
    ]

    operations = [
        migrations.RenameField(
            model_name='teamrole',
            old_name='role',
            new_name='title',
        ),
        migrations.AlterField(
            model_name='teamrole',
            name='order',
            field=models.PositiveIntegerField(editable=False, db_index=True),
        ),
        migrations.AlterUniqueTogether(
            name='teamrole',
            unique_together=set([('member', 'team')]),
        ),
    ]


import os
import cwcn_instruments

# ACTIVE_PAIRS = [__ for __ in list(cwcn_instruments.POLONIEX_MAP.values()) if 'USDT_' in __]
# print(ACTIVE_PAIRS)
# input("stop!")
PH1_KEMU_MIN_VELOCITY=10 # in seconds
FARM_CONFIG_FOLDER='{}/../wajyu_data_farm/FARM'.format(os.path.dirname(os.path.abspath(__file__)))
FARM_CONFIG_EXTENSION='.poloniexdata'
# --- --- --- --- --- ---
PAPER_TRADING = True
# --- --- --- --- --- ---
class WAJYU_KEMU_CONFIG:
    _instrument_filters = [
        (lambda km: km._velocity is not None and km._velocity <= PH1_KEMU_MIN_VELOCITY),
        (lambda km: [not km._load_phils[__]['loop_failure'] for __ in list(km._load_phils.keys())])
    ]
    _data_interpret_map = { # very much carefull, depends on the state
        'instrument':0,
        'price':1,
        'price.delta':2,
        'timestamp':-1,
        'lowprice_24':-4,
        'highprice_24':-5,
        'highest_bid':-10,
        'lowest_ask':-11,
    }
    class PHI1:
        phi1_shang_HOURS_HORIZONS = [ # (SEQ_LEN, #HOURS)
            (450,1.5),
            (300,1),
            (150,0.5),
            (30,0.1),
        ]
        dafult_value=0.0
    class PHI2:
        phi2_shang_HOURS_HORIZON = 1
        phi2_xia_HOURS_HORIZON = 1
        phi2_shang_SEQ_LEN = 300
        phi2_xia_SEQ_LEN = int(phi2_shang_SEQ_LEN*phi2_xia_HOURS_HORIZON/phi2_shang_HOURS_HORIZON)
        class phi2_HILBER_CONFIG:
            phi2_hilbert_s = 0.25
            phi2_hilbert_n = 12
            phi2_base = 'tanh'
class WAJYU_WIKIMYEI_CONFIG:
    # --- --- ---
    ACTIVE_AHPA=['long','short']
    UWAABO_NEAR_PERIOD_HOURS=0.0 # how often to update positions [in hours]
    # --- --- ---
    RISK_INSTRUMENT_CAPITAL={
        'risk.long':20.0, # the capital to put in every instrument
        'risk.short':20.0, # the capital to put in every instrument
    }
    BREAK_SCORE={
        'break_score.long':0.5,
        'break_score.short':3.5,
    }
    HALT_SCORE={
        'halt_score.long':0.15, # in terms of score, how much score adventaje to shift (replace) positions
        'halt_score.short':1.5, # in terms of score, how much score adventaje to shift (replace) positions
    }
    MINIMUN_HOLDING_BALANCE={
        'min_hold_balance.long':5.0, # in USDT
        'min_hold_balance.short':5.0, # in USDT
    }
    class SIMULATION:
        initial_balance=200.0 # in USDT (the same for all _acta)
        buy_comission=0.01 # in % meaning [from 100 to 0] (the same for all instruments (active_pairs))
        sell_comission=0.01 # in % meaning [from 100 to 0] (the same for all instruments (active_pairs))
class CWCN_COLORS:
    HEADER = '\033[95m'
    BLUE = '\033[94m'
    CYAN = '\033[96m'
    GOOD = '\033[92m'
    GREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    REGULAR = '\033[0m'
    GROSS = '\033[1m'
    DANGER = '\033[41m'
    RED = '\033[31m'
    BAD = '\033[31m'
    UNDERLINE = '\033[4m'
    PRICE = '\033[0;32m'
    YELLOW = '\033[1;33m'
    DARKGRAY = '\033[1;30m'
    GRAY = '\033[0;37m'
    WHITE = '\033[1;37m'
    COLOR_ACTA = {
        'color.long':'\033[44m',
        'color.short':'\033[41m',
    }
class CWCN_CURSOR: #FIXME not in use
    UP='\033[A'
    DOWN='\033[B'
    LEFT='\033[D'
    RIGHT='\033[C'
    CLEAR_LINE='\033[K'
    CARRIER_RETURN='\r'
    NEW_LINE='\n'

ACTIVE_PAIRS = [
    'USDT_DYDX',
    'USDT_AAVE',
    'USDT_ADABULL',
    'USDT_ALICE',
    # 'USDT_API3',
    'USDT_ATOM',
    # 'USDT_AVA',
    'USDT_AXS',
    'USDT_BAT',
    'USDT_BCH',
    # 'USDT_BCHBULL',
    # 'USDT_BCHSV',
    'USDT_BEAR',
    # 'USDT_BID',
    'USDT_BNB',
    # 'USDT_BSVBULL',
    'USDT_BTC',
    'USDT_BTT',
    'USDT_BULL',
    # 'USDT_BZRX',
    # 'USDT_C98',
    'USDT_CHR',
    'USDT_CHZ',
    'USDT_DASH',
    # 'USDT_DEGO',
    'USDT_DOGE',
    'USDT_DOT',
    'USDT_ELON',
    'USDT_ENJ',
    'USDT_EOS',
    # 'USDT_EOSBEAR',
    # 'USDT_EOSBULL',
    'USDT_ETH',
    'USDT_ETHBULL',
    # 'USDT_FCT2',
    'USDT_FIL',
    'USDT_FRONT',
    'USDT_GALA',
    # 'USDT_GLYPH', # FENOMENAL!
    # 'USDT_GRT',
    # 'USDT_GTC',
    # 'USDT_HGET',
    'USDT_IDIA',
    # 'USDT_INJ',s
    'USDT_JST',
    'USDT_KLV',
    'USDT_LINK',
    'USDT_LINKBULL',
    'USDT_LPT',
    'USDT_LRC',
    'USDT_LTC',
    'USDT_LTCBEAR',
    'USDT_LTCBULL',
    'USDT_MANA',
    'USDT_MATIC',
    'USDT_MKR',
    'USDT_NEO',
    'USDT_NU',
    'USDT_OCEAN',
    'USDT_QTUM',
    'USDT_RD',
    'USDT_REEF',
    'USDT_REN',
    'USDT_RSR',
    'USDT_SAND',
    'USDT_SC',
    'USDT_SENSO',
    'USDT_SHIB',
    'USDT_SNX',
    'USDT_SRM',
    'USDT_STPT',
    'USDT_STR',
    'USDT_SUSHI',
    'USDT_SWINGBY',
    'USDT_SXP',
    'USDT_TOKE',
    'USDT_TRX',
    'USDT_TRXBULL',
    'USDT_TUSD',
    'USDT_UMA',
    'USDT_UNI',
    'USDT_WBTC',
    'USDT_WIN',
    'USDT_WNXM',
    'USDT_WOO',
    'USDT_WRX',
    'USDT_XCAD',
    'USDT_XEM',
    'USDT_XLMBEAR',
    'USDT_XLMBULL',
    'USDT_XMR',
    'USDT_XRP',
    'USDT_XRPBULL',
    'USDT_XTZ',
    'USDT_YFI',
    'USDT_YGG',
    'USDT_ZEC',
    'USDT_ZRX',
]

class WAJYU_FARM_CONFIG:
    RESET_FOLDER = True
    FARM_FOLDER = FARM_CONFIG_FOLDER
    FARM_EXTENSION = FARM_CONFIG_EXTENSION
    INSTRUMENT_FILES=dict([(__,
            os.path.join(FARM_CONFIG_FOLDER,'{}/{}{}'.format(
                __,__,
                FARM_CONFIG_EXTENSION))
        ) for __ in ACTIVE_PAIRS])
    FARM_WEBSOCKETS = [r'{"command": "subscribe", "channel": 1002}']


#!/usr/bin/env python3

from evdev import InputDevice, categorize, ecodes, list_devices
from asyncio import Queue

import asyncio

STICK_MAX = 255

class Event:
    def __init__(self, code, state):
        self.code = code
        self.state = state

    def __repr__(self):
        return str({
            "code": self.code,
            "state": self.state
        })

axis = {
    0: 'ABS_X',
    1: 'ABS_Y',
    2: 'ABS_RX',
    5: 'ABS_RY',
    9: 'ABS_Z',
    10: 'ABS_RZ',
    16: 'ABS_HAT0X',
    17: 'ABS_HAT0Y',
}

button = {

}

q = Queue()

async def get_gamepad():
    return await q.get()

async def run_controller():
    global q
    dev = None
    while True:
        if dev is None:
            devices = list_devices()
            if len(devices) == 0:
                print("Device not found... Trying again in 3s")
                await asyncio.sleep(3)

            dev = InputDevice(devices[0])

        async for event in dev.async_read_loop():
            if event.type == ecodes.EV_KEY and event.value == 1:
                # print(f"EV_KEY {event.code}: {event.value}")
                if event.code in button.keys():
                    await q.put(Event(button[event.code], value))

            elif event.type == ecodes.EV_ABS:
                if event.code in axis.keys():
                    if axis[event.code] in ["ABS_X", "ABS_Y", "ABS_RX", "ABS_RY"]:
                        value = min(event.value, STICK_MAX) * 2 / STICK_MAX - 1.0
                    elif axis[event.code] in ["ABS_HAT0X", "ABS_HAT0Y"]:
                        value = event.value
                    else:
                        value = event.value/STICK_MAX

                    if abs(value) < 0.01:
                        value = 0.0
                    # print(f"EV_ABS {event.code}: {axis[event.code]} {value}")
                    await q.put(Event(axis[event.code], value))

async def debug_consumer():
    while True:
        event = await get_gamepad()
        if event:
            print(event)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(run_controller(), debug_consumer()))


# Yuchen Shi
# ITP115, Spring 2018
# Lab L7
# yuchensh@usc.edu

import random
num=[0, 1, 2]
item=["rock", "paper", "scissor"]

def main():
    counterCWin=0
    counterYWin=0
    counterTie=0
    gameGoOn = True

    while gameGoOn is True:
        displayMenu()
        computerChoice=getComputerChoice()
        playerChoice=getPlayerChoice()
        if playRound(computerChoice,playerChoice)==0:
            counterTie=counterTie+1
        elif playRound(computerChoice,playerChoice)==1:
            counterYWin=counterYWin+1
        elif playRound(computerChoice, playerChoice)==-1:
            counterCWin=counterCWin+1
        print("You choose", item[playerChoice]+".\nThe computer choose", item[computerChoice]+".")
        if computerChoice==playerChoice:
            print("It's a tie.")
        elif computerChoice==0 and playerChoice==1:
            print("Paper covers rock. You win!")
        elif computerChoice==0 and playerChoice==2:
            print("Rock smashes scissor. Computer wins!")
        elif computerChoice==1 and playerChoice==0:
            print("Paper covers rock. Computer wins!")
        elif computerChoice==1 and playerChoice==2:
            print("Scissor cuts paper. You win!")
        elif computerChoice==2 and playerChoice==0:
            print("Rock smashes scissor. You win!")
        elif computerChoice==2 and playerChoice==1:
            print("Scissor cuts paper. Computer wins!")
        gameGoOn=continueGame()
    print("You won", counterYWin, "game(s).\nThe computer won", counterCWin, "game(s).\nYou tied with the computer", counterTie, "time(s).\nThanks for playing!")

def displayMenu():
    print("Welcome! Let's play rock, paper, scissors.\nThe rules of the game are:\n\tRock smashes scissors\n\tScissors cut paper\n\tPaper covers rock\n\tIf both the choices are the same, it's a tie")
def getComputerChoice():
    return random.choice(num)
def getPlayerChoice():
    choice=int(input("Please choose (0) for rock, (1) for paper or (2) for scissors\n"))
    while choice not in [0, 1, 2]:
        choice=int(input("Please choose (0) for rock, (1) for paper or (2) for scissors\n"))
    return choice
def playRound(int1, int2):
    if int1==int2:
        return 0
    elif int1==0 and int2==1:
        return 1
    elif int==0 and int2==2:
        return -1
    elif int==1 and int2==0:
        return -1
    elif int1==1 and int2==2:
        return 1
    elif int1==2 and int2==0:
        return 1
    elif int1==2 and int2==1:
        return -1
def continueGame():
    goOn=input("Do you want to continue playing? Enter (y) for yes or (n) for no.\n")
    while goOn.lower() not in ["y", "n"]:
        goOn = input("Do you want to continue playing? Enter (y) for yes or (n) for no.\n")
    if goOn.lower()=="y":
        return True
    else:
        return False

main()


from pyecharts import options as opts
from pyecharts.charts import Geo
from pyecharts.faker import Faker
from pyecharts.globals import ChartType,CurrentConfig,NotebookType
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB
from openpyxl import load_workbook
import requests

#定义一个字典
city_code = {}
#用load_workbook方法来打开这个xlsx文件，并且返回这个xlsx文件的内容
sheet = load_workbook('AMap_adcode_citycode.xlsx').active
#去定位这个表格的所有行
for row in sheet.rows:
    #定义这个row的值，city就是row的A列的内容，code就是row的B列所有内容，_就是row的c列的所有内容
    city,code, _ = row
    #再给city赋值
    city = city.value
    #给code赋值
    code = code.value
    try:
        #写一个判断语句当city里面出现了市或者自治区这几个字的时候在list列表里面添加city的值
        if city[-1] == '市' or city[-3] == '自治区':
            list.append(city)
            #用字典的形式，给每个city加上对应的code
            city_code[city] = code
    except:
        pass

city_weather = []
#items( )用于 返回一个字典的拷贝列表，这句话的意思就是city_code.items()变成一个可以打印的字典，city就是这个字典的key，code就是这个字典的value
for city,code in city_code.items():
    #请求这个API接口
    req = requests.get('https://restapi.amap.com/v3/weather/weatherInfo?key=e151ce35ee68dca653fa2a301b9f5050&city={}'.format(code))
    #返回一个json的格式
    result = req.json()
    #再去定位这个json的位置
    city_weather.append([city,result['lives'][0]['temperature']])
#进行数据可视化操作
c = (
    #是否忽视不存在的坐标，默认值为false，这里用TRUE的话就是忽视的意思
    Geo(is_ignore_nonexistent_coord=True)
    #定义这个地图类型
    .add_schema(maptype="china")
    .add(
        #系列名称，就是你要用什么类型的可视化就用这个可视化类型的名称
        "geo",
        #数据项（坐标点名称，坐标点值）
        city_weather,
        # GeoType.GeoType.EFFECT_SCATTER，GeoType.HEATMAP，GeoType.LINES
        type_=ChartType.HEATMAP,
        #标签配置项
        label_opts=opts.LabelOpts(is_show=False)
    )
    .set_global_opts(
        visualmap_opts=opts.VisualMapOpts(),
        #确定这个图表的标题
        title_opts=opts.TitleOpts(title="Geo-HeatMap"),
    )
    #生成一个名为weather_map.html动态交互网页
    .render('weather_map.html')
)


import os
import pickle
import numpy as np
import torch
import time
import config
from model import BiDAF
from utils import clean_text, word_tokenize, discretize

device = torch.device("cuda" if config.cuda else "cpu")

def eval(context, question):
    start=time.time()
    with open(os.path.join(config.data_dir, "train", "word2idx.pkl"), "rb") as wi, \
         open(os.path.join(config.data_dir, "train", "trained_char2idx.pkl"), "rb") as ci, \
         open(os.path.join(config.data_dir, "train", "combined_word_embeddings.pkl"), "rb") as wb, \
         open(os.path.join(config.data_dir, "train", "trained_char_embeddings.pkl"), "rb") as cb:
        word2idx = pickle.load(wi)
        char2idx = pickle.load(ci)
        word_embedding_matrix = pickle.load(wb)
        char_embedding_matrix = pickle.load(cb)

    # transform them into Tensors
    word_embedding_matrix = torch.from_numpy(np.array(word_embedding_matrix)).type(torch.float32)
    char_embedding_matrix = torch.from_numpy(np.array(char_embedding_matrix)).type(torch.float32)
    idx2word = dict([(y, x) for x, y in word2idx.items()])

    context = clean_text(context)
    context = [w for w in word_tokenize(context) if w]

    question = clean_text(question)
    question = [w for w in word_tokenize(question) if w]

    if len(context) > config.max_len_context:
        print("The context is too long. Maximum accepted length is", config.max_len_context, "words.")
    if max([len(w) for w in context]) > config.max_len_word:
        print("Some words in the context are longer than", config.max_len_word, "characters.")
    if len(question) > config.max_len_question:
        print("The question is too long. Maximum accepted length is", config.max_len_question, "words.")
    if max([len(w) for w in question]) > config.max_len_word:
        print("Some words in the question are longer than", config.max_len_word, "characters.")
    if len(question) < 3:
        print("The question is too short. It needs to be at least a three words question.")

    context_idx = np.zeros([config.max_len_context], dtype=np.int32)
    question_idx = np.zeros([config.max_len_question], dtype=np.int32)
    context_char_idx = np.zeros([config.max_len_context, config.max_len_word], dtype=np.int32)
    question_char_idx = np.zeros([config.max_len_question, config.max_len_word], dtype=np.int32)

    # replace 0 values with word and char IDs
    for j, word in enumerate(context):
        if word in word2idx:
            context_idx[j] = word2idx[word]
        else:
            context_idx[j] = 1
        for k, char in enumerate(word):
            if char in char2idx:
                context_char_idx[j, k] = char2idx[char]
            else:
                context_char_idx[j, k] = 1

    for j, word in enumerate(question):
        if word in word2idx:
            question_idx[j] = word2idx[word]
        else:
            question_idx[j] = 1
        for k, char in enumerate(word):
            if char in char2idx:
                question_char_idx[j, k] = char2idx[char]
            else:
                question_char_idx[j, k] = 1

    model = BiDAF(word_vectors=word_embedding_matrix,
                  char_vectors=char_embedding_matrix,
                  hidden_size=config.hidden_size,
                  drop_prob=config.drop_prob)

    try:
        if config.cuda:
            model.load_state_dict(torch.load(os.path.join(config.squad_models, "final_combined_model.pkl"))["state_dict"])
        else:
            model.load_state_dict(torch.load(os.path.join(config.squad_models, "final_combined_model.pkl"),
                                             map_location=torch.device('cpu'))["state_dict"])
        print("Model weights successfully loaded.")
    except:
        pass
        print("Model weights not found, initialized model with random weights.")
    model.to(device)
    model.eval()
    with torch.no_grad():
        context_idx, context_char_idx, question_idx, question_char_idx = torch.tensor(context_idx, dtype=torch.int64).unsqueeze(0).to(device),\
                                                                         torch.tensor(context_char_idx, dtype=torch.int64).unsqueeze(0).to(device),\
                                                                         torch.tensor(question_idx, dtype=torch.int64).unsqueeze(0).to(device),\
                                                                         torch.tensor(question_char_idx, dtype=torch.int64).unsqueeze(0).to(device)

        pred1, pred2 = model(context_idx, context_char_idx, question_idx, question_char_idx)
        starts, ends = discretize(pred1.exp(), pred2.exp(), 15, False)
        prediction = " ".join(context[starts.item(): ends.item() + 1])
    end = time.time()
    print(f"Runtime of the program is {end - start}")

    end=time.time()
    diff=end-start

    return prediction,diff
if __name__ == "__main__":
    context = "'The Normans (Norman: Nourmands; French: Normands; Latin: Normanni) were the people who in the 10th and 11th centuries gave their name to Normandy, a region in France. They were descended from Norse (Norman comes from Norseman) raiders and pirates from Denmark, Iceland and Norway who, under their leader Rollo, agreed to swear fealty to King Charles III of West Francia. Through generations of assimilation and mixing with the native Frankish and Roman-Gaulish populations, their descendants would gradually merge with the Carolingian-based cultures of West Francia. The distinct cultural and ethnic identity of the Normans emerged initially in the first half of the 10th century, and it continued to evolve over the succeeding centuries.'"

    questions = ["In what country is Normandy located?",
                 "When were the Normans in Normandy?"]

    print("C:", context, "\n")

    for q in questions:
        print("Q:", q)
        answer = eval(context, q)
        print("A:", answer, "\n")


import string
import io

def dict_from_file(filename):
    d = {}
    with io.open(filename, encoding = "ISO-8859-1") as f:
        for line in f:
            line = line.split()
            if len(line) > 0:
                d[line[0]] = 1
    return d

def encode_string_to_int_list(s):
    ints = range(27)
    letters = list(string.ascii_lowercase)
    letters.append(' ')
    d = dict(zip(letters, ints))
    s_list = list(s)
    result = []
    for char in s_list:
        result.append(d[char])
    return result

def decode_int_list_to_string(i_list):
    ints = range(27)
    letters = list(string.ascii_lowercase)
    letters.append(' ')
    d = dict(zip(ints, letters))
    result = []
    for i in i_list:
        result.append(d[i])
    return ''.join(result)

def check_validity(l, d):
    tokens = str.split(l)
    for w in tokens:
        if w not in d:
            return False
    return True

# ##### Test cases
# print encode_string_to_int_list('food')
# # Should return [5, 14, 14, 3]
# print decode_int_list_to_string([6, 14, 14, 3, 26, 5, 14, 14, 3])
# # Should return 'good food'
#
# d = dict_from_file('brit-a-z.txt')
# l1 = 'the quick brown fox jumped over the lazy dog'
# l2 = 'the quick brown fox jumped over the lazy dob'
#
# print check_validity(l1, d)
# # Should yield True
# print check_validity(l2, d)
# # Should yield False

HW5 - Gibbs Sampling and HMMs/text_utils.py


def longestAbsolutePath(fs: str) -> int:
    paths = fs.split('\n')
    max_len = 0
    path_lengths = {0: 0}
    depth = 0
    for path in paths:
        name = path.strip()
        depth = len(path)-len(name)
        if '.' in name:
            max_len = max(max_len, path_lengths[depth] + len(name))
        else:
            path_lengths[depth+1] = path_lengths[depth] + len(name) + 1
    return max_len

if __name__=='__main__':
    fsys= [
    "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext", \
    "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext"
    ]
    for fs in fsys:
        print(longestAbsolutePath(fs))


import sqlite3

query1 = 'SELECT Name, Platform FROM games LIMIT 5'
query2 = 'SELECT Name, Platform, Year_of_Release FROM games WHERE Year_of_Release > 2000 LIMIT 10'
query3 = 'SELECT Name, Platform, Year_of_Release FROM games WHERE Year_of_Release > 2000 AND Platform = "PS2" LIMIT 20'

query4 = 'INSERT INTO games(Name, Platform, Year_of_Release,Genre, Publisher, Global_Sales) VALUES (?, ?, ?, ?, ?, ?)'

connection = sqlite3.connect('database.db')
cursor = connection.cursor()

from csv import reader
vg = []
with open('Video_Games_Sales_2016 - Copy.csv', encoding='utf-8') as file:
    csv_reader = reader(file)
    for row in csv_reader:
        vg.append(row)

for row in vg:
    cursor.execute(query4, row)

connection.commit()

for i in cursor.execute(query3):

    print(i)


import os
import json
import scrapy

class UbatItemSpider(scrapy.Spider):
    name = "ubat_item"

    def start_requests(self):
        with open('ubat_list_2016_2019.json') as json_file:
            item_db = json.load(json_file)

        for item in item_db:
            if item['event_no1'] == '2015' or item['event_no1'] == '2016':
                continue
            if not os.path.exists(UbatItemSpider.get_save_path(item)):
                yield self.request(item)

    @classmethod
    def get_save_path(cls, item):
        return f'{item["event_no1"]}/{item["courtnum"]}_{item["event_no1"]}_{item["event_no2"]}_{item["obj_id"]}.html'

    def parse(self, response, item):
        with open(UbatItemSpider.get_save_path(item), 'wb') as fp:
            fp.write(response.body)

    def request(self, item):
        url = f'http://www.ubat.co.kr/auctionInfo/view_print.php?courtNo={item["courtnum"]}&courtNo2=&eventNo1={item["event_no1"]}&eventNo2={item["event_no2"]}&objNo={item["obj_id"]}'
        return scrapy.Request(url, lambda response: self.parse(response, item))


import copy
import logging
import math
import sys

import json_tricks
import numpy as np
from schema import Schema, Optional

from ....nni import ClassArgsValidator
from ....nni.common.hpo_utils import validate_search_space
from ....nni.runtime.common import multi_phase_enabled
from ....nni.runtime.msg_dispatcher_base import MsgDispatcherBase
from ....nni.runtime.protocol import CommandType, send
from ....nni.utils import NodeType, OptimizeMode, MetricType, extract_scalar_reward
from ....nni import parameter_expressions

_logger = logging.getLogger(__name__)

_next_parameter_id = 0
_KEY = 'TRIAL_BUDGET'
_epsilon = 1e-6

def create_parameter_id():
    """Create an id

    Returns
    -------
    int
        parameter id
    """
    global _next_parameter_id
    _next_parameter_id += 1
    return _next_parameter_id - 1

def create_bracket_parameter_id(brackets_id, brackets_curr_decay, increased_id=-1):
    """Create a full id for a specific bracket's hyperparameter configuration

    Parameters
    ----------
    brackets_id: string
        brackets id
    brackets_curr_decay:
        brackets curr decay
    increased_id: int
        increased id

    Returns
    -------
    int
        params id
    """
    if increased_id == -1:
        increased_id = str(create_parameter_id())
    params_id = '_'.join([brackets_id,
                          str(brackets_curr_decay),
                          increased_id])
    return params_id

def json2parameter(ss_spec, random_state):
    """Randomly generate values for hyperparameters from hyperparameter space i.e., x.

    Parameters
    ----------
    ss_spec:
        hyperparameter space
    random_state:
        random operator to generate random values

    Returns
    -------
    Parameter:
        Parameters in this experiment
    """
    if isinstance(ss_spec, dict):
        if NodeType.TYPE in ss_spec.keys():
            _type = ss_spec[NodeType.TYPE]
            _value = ss_spec[NodeType.VALUE]
            if _type == 'choice':
                _index = random_state.randint(len(_value))
                chosen_params = json2parameter(ss_spec[NodeType.VALUE][_index], random_state)
            else:
                chosen_params = getattr(parameter_expressions, _type)(*(_value + [random_state]))
        else:
            chosen_params = dict()
            for key in ss_spec.keys():
                chosen_params[key] = json2parameter(ss_spec[key], random_state)
    elif isinstance(ss_spec, list):
        chosen_params = list()
        for _, subspec in enumerate(ss_spec):
            chosen_params.append(json2parameter(subspec, random_state))
    else:
        chosen_params = copy.deepcopy(ss_spec)
    return chosen_params

class Bracket():
    """A bracket in Hyperband, all the information of a bracket is managed by an instance of this class

    Parameters
    ----------
    bracket_id: string
        The id of this bracket, usually be set as '{Hyperband index}-{SH iteration index}'
    s: int
        The current SH iteration index.
    s_max: int
        total number of SH iterations
    eta: float
        In each iteration, a complete run of sequential halving is executed. In it,
		after evaluating each configuration on the same subset size, only a fraction of
		1/eta of them 'advances' to the next round.
    R:
        the budget associated with each stage
    optimize_mode: str
        optimize mode, 'maximize' or 'minimize'
    """

    def __init__(self, bracket_id, s, s_max, eta, R, optimize_mode):
        self.bracket_id = bracket_id
        self.s = s
        self.s_max = s_max
        self.eta = eta
        self.n = math.ceil((s_max + 1) * (eta ** s) / (s + 1) - _epsilon)
        self.r = R / eta ** s
        self.i = 0
        self.hyper_configs = []  # [ {id: params}, {}, ... ]
        self.configs_perf = []  # [ {id: [seq, acc]}, {}, ... ]
        self.num_configs_to_run = []  # [ n, n, n, ... ]
        self.num_finished_configs = []  # [ n, n, n, ... ]
        self.optimize_mode = OptimizeMode(optimize_mode)
        self.no_more_trial = False

    def is_completed(self):
        """check whether this bracket has sent out all the hyperparameter configurations"""
        return self.no_more_trial

    def get_n_r(self):
        """return the values of n and r for the next round"""
        return math.floor(self.n / self.eta ** self.i + _epsilon), math.floor(self.r * self.eta ** self.i + _epsilon)

    def increase_i(self):
        """i means the ith round. Increase i by 1"""
        self.i += 1
        if self.i > self.s:
            self.no_more_trial = True

    def set_config_perf(self, i, parameter_id, seq, value):
        """update trial's latest result with its sequence number, e.g., epoch number or batch number

        Parameters
        ----------
        i: int
            the ith round
        parameter_id: int
            the id of the trial/parameter
        seq: int
            sequence number, e.g., epoch number or batch number
        value: int
            latest result with sequence number seq

        Returns
        -------
        None
        """
        if parameter_id in self.configs_perf[i]:
            if self.configs_perf[i][parameter_id][0] < seq:
                self.configs_perf[i][parameter_id] = [seq, value]
        else:
            self.configs_perf[i][parameter_id] = [seq, value]

    def inform_trial_end(self, i):
        """If the trial is finished and the corresponding round (i.e., i) has all its trials finished,
        it will choose the top k trials for the next round (i.e., i+1)

        Parameters
        ----------
        i: int
            the ith round
        """
        global _KEY
        self.num_finished_configs[i] += 1
        _logger.debug('bracket id: %d, round: %d %d, finished: %d, all: %d', self.bracket_id, self.i, i,
                      self.num_finished_configs[i], self.num_configs_to_run[i])
        if self.num_finished_configs[i] >= self.num_configs_to_run[i] \
                and self.no_more_trial is False:
            # choose candidate configs from finished configs to run in the next round
            assert self.i == i + 1
            this_round_perf = self.configs_perf[i]
            if self.optimize_mode is OptimizeMode.Maximize:
                sorted_perf = sorted(this_round_perf.items(), key=lambda kv: kv[1][1], reverse=True)  # reverse
            else:
                sorted_perf = sorted(this_round_perf.items(), key=lambda kv: kv[1][1])
            _logger.debug('bracket %s next round %s, sorted hyper configs: %s', self.bracket_id, self.i, sorted_perf)
            next_n, next_r = self.get_n_r()
            _logger.debug('bracket %s next round %s, next_n=%d, next_r=%d', self.bracket_id, self.i, next_n, next_r)
            hyper_configs = dict()
            for k in range(next_n):
                params_id = sorted_perf[k][0]
                params = self.hyper_configs[i][params_id]
                params[_KEY] = next_r  # modify r
                # generate new id
                increased_id = params_id.split('_')[-1]
                new_id = create_bracket_parameter_id(self.bracket_id, self.i, increased_id)
                hyper_configs[new_id] = params
            self._record_hyper_configs(hyper_configs)
            return [[key, value] for key, value in hyper_configs.items()]
        return None

    def get_hyperparameter_configurations(self, num, r, searchspace_json, random_state):
        """Randomly generate num hyperparameter configurations from search space

        Parameters
        ----------
        num: int
            the number of hyperparameter configurations

        Returns
        -------
        list
            a list of hyperparameter configurations. Format: [[key1, value1], [key2, value2], ...]
        """
        global _KEY
        assert self.i == 0
        hyperparameter_configs = dict()
        for _ in range(num):
            params_id = create_bracket_parameter_id(self.bracket_id, self.i)
            params = json2parameter(searchspace_json, random_state)
            params[_KEY] = r
            hyperparameter_configs[params_id] = params
        self._record_hyper_configs(hyperparameter_configs)
        return [[key, value] for key, value in hyperparameter_configs.items()]

    def _record_hyper_configs(self, hyper_configs):
        """after generating one round of hyperconfigs, this function records the generated hyperconfigs,
        creates a dict to record the performance when those hyperconifgs are running, set the number of finished configs
        in this round to be 0, and increase the round number.

        Parameters
        ----------
        hyper_configs: list
            the generated hyperconfigs
        """
        self.hyper_configs.append(hyper_configs)
        self.configs_perf.append(dict())
        self.num_finished_configs.append(0)
        self.num_configs_to_run.append(len(hyper_configs))
        self.increase_i()

class HyperbandClassArgsValidator(ClassArgsValidator):
    def validate_class_args(self, **kwargs):
        Schema({
            'optimize_mode': self.choices('optimize_mode', 'maximize', 'minimize'),
            Optional('exec_mode'): self.choices('exec_mode', 'serial', 'parallelism'),
            Optional('R'): int,
            Optional('eta'): int
        }).validate(kwargs)

class Hyperband(MsgDispatcherBase):
    """
    Hyperband inherit from MsgDispatcherBase rather than Tuner, because it integrates both tuner's functions and assessor's functions.
    This is an implementation that could fully leverage available resources or follow the algorithm process,
    i.e., high parallelism or serial.
    A single execution of Hyperband takes a finite budget of (s_max + 1)B.

    Parameters
    ----------
    R: int
        the maximum amount of resource that can be allocated to a single configuration
    eta: int
        the variable that controls the proportion of configurations discarded in each round of SuccessiveHalving
    optimize_mode: str
        optimize mode, 'maximize' or 'minimize'
    exec_mode: str
        execution mode, 'serial' or 'parallelism'
    """

    def __init__(self, R=60, eta=3, optimize_mode='maximize', exec_mode='parallelism'):
        """B = (s_max + 1)R"""
        super(Hyperband, self).__init__()
        self.R = R
        self.eta = eta
        self.brackets = dict()  # dict of Bracket
        self.generated_hyper_configs = []  # all the configs waiting for run
        self.completed_hyper_configs = []  # all the completed configs
        self.s_max = math.floor(math.log(self.R, self.eta) + _epsilon)
        self.curr_s = self.s_max
        self.curr_hb = 0
        self.exec_mode = exec_mode
        self.curr_bracket_id = None

        self.searchspace_json = None
        self.random_state = None
        self.optimize_mode = OptimizeMode(optimize_mode)

        # This is for the case that nnimanager requests trial config, but tuner cannot provide immediately.
        # In this case, tuner increases self.credit to issue a trial config sometime later.
        self.credit = 0

        # record the latest parameter_id of the trial job trial_job_id.
        # if there is no running parameter_id, self.job_id_para_id_map[trial_job_id] == None
        # new trial job is added to this dict and finished trial job is removed from it.
        self.job_id_para_id_map = dict()

    def handle_initialize(self, data):
        """callback for initializing the advisor
        Parameters
        ----------
        data: dict
            search space
        """
        self.handle_update_search_space(data)
        send(CommandType.Initialized, '')

    def handle_request_trial_jobs(self, data):
        """
        Parameters
        ----------
        data: int
            number of trial jobs
        """
        self.credit += data

        for _ in range(self.credit):
            self._request_one_trial_job()

    def _request_one_trial_job(self):
        ret = self._get_one_trial_job()
        if ret is not None:
            send(CommandType.NewTrialJob, json_tricks.dumps(ret))
            self.credit -= 1

    def _get_one_trial_job(self):
        """get one trial job, i.e., one hyperparameter configuration."""
        if not self.generated_hyper_configs:
            if self.exec_mode == 'parallelism' or \
               (self.exec_mode == 'serial' and (self.curr_bracket_id is None or self.brackets[self.curr_bracket_id].is_completed())):
                if self.curr_s < 0:
                    self.curr_s = self.s_max
                    self.curr_hb += 1
                _logger.debug('create a new bracket, self.curr_hb=%d, self.curr_s=%d', self.curr_hb, self.curr_s)
                self.curr_bracket_id = '{}-{}'.format(self.curr_hb, self.curr_s)
                self.brackets[self.curr_bracket_id] = Bracket(
                    self.curr_bracket_id, self.curr_s, self.s_max, self.eta, self.R, self.optimize_mode)
                next_n, next_r = self.brackets[self.curr_bracket_id].get_n_r()
                _logger.debug('new bracket, next_n=%d, next_r=%d', next_n, next_r)
                assert self.searchspace_json is not None and self.random_state is not None
                generated_hyper_configs = self.brackets[self.curr_bracket_id].get_hyperparameter_configurations(next_n, next_r,
                                                                                self.searchspace_json,
                                                                                self.random_state)
                self.generated_hyper_configs = generated_hyper_configs.copy()
                self.curr_s -= 1
            else:
                ret = {
                    'parameter_id': '-1_0_0',
                    'parameter_source': 'algorithm',
                    'parameters': ''
                }
                send(CommandType.NoMoreTrialJobs, json_tricks.dumps(ret))
                return None

        assert self.generated_hyper_configs
        params = self.generated_hyper_configs.pop(0)
        ret = {
            'parameter_id': params[0],
            'parameter_source': 'algorithm',
            'parameters': params[1]
        }
        return ret

    def handle_update_search_space(self, data):
        """data: JSON object, which is search space
        """
        validate_search_space(data)
        self.searchspace_json = data
        self.random_state = np.random.RandomState()

    def _handle_trial_end(self, parameter_id):
        """
        Parameters
        ----------
        parameter_id: parameter id of the finished config
        """
        bracket_id, i, _ = parameter_id.split('_')
        hyper_configs = self.brackets[bracket_id].inform_trial_end(int(i))
        if hyper_configs is not None:
            _logger.debug('bracket %s next round %s, hyper_configs: %s', bracket_id, i, hyper_configs)
            self.generated_hyper_configs = self.generated_hyper_configs + hyper_configs
        for _ in range(self.credit):
            self._request_one_trial_job()

    def handle_trial_end(self, data):
        """
        Parameters
        ----------
        data: dict()
            it has three keys: trial_job_id, event, hyper_params
            trial_job_id: the id generated by training service
            event: the job's state
            hyper_params: the hyperparameters (a string) generated and returned by tuner
        """
        hyper_params = json_tricks.loads(data['hyper_params'])
        self._handle_trial_end(hyper_params['parameter_id'])
        if data['trial_job_id'] in self.job_id_para_id_map:
            del self.job_id_para_id_map[data['trial_job_id']]

    def handle_report_metric_data(self, data):
        """
        Parameters
        ----------
        data:
            it is an object which has keys 'parameter_id', 'value', 'trial_job_id', 'type', 'sequence'.

        Raises
        ------
        ValueError
            Data type not supported
        """
        if 'value' in data:
            data['value'] = json_tricks.loads(data['value'])
        # multiphase? need to check
        if data['type'] == MetricType.REQUEST_PARAMETER:
            assert multi_phase_enabled()
            assert data['trial_job_id'] is not None
            assert data['parameter_index'] is not None
            assert data['trial_job_id'] in self.job_id_para_id_map
            self._handle_trial_end(self.job_id_para_id_map[data['trial_job_id']])
            ret = self._get_one_trial_job()
            if data['trial_job_id'] is not None:
                ret['trial_job_id'] = data['trial_job_id']
            if data['parameter_index'] is not None:
                ret['parameter_index'] = data['parameter_index']
            self.job_id_para_id_map[data['trial_job_id']] = ret['parameter_id']
            send(CommandType.SendTrialJobParameter, json_tricks.dumps(ret))
        else:
            value = extract_scalar_reward(data['value'])
            bracket_id, i, _ = data['parameter_id'].split('_')

            # add <trial_job_id, parameter_id> to self.job_id_para_id_map here,
            # because when the first parameter_id is created, trial_job_id is not known yet.
            if data['trial_job_id'] in self.job_id_para_id_map:
                assert self.job_id_para_id_map[data['trial_job_id']] == data['parameter_id']
            else:
                self.job_id_para_id_map[data['trial_job_id']] = data['parameter_id']

            if data['type'] == MetricType.FINAL:
                # sys.maxsize indicates this value is from FINAL metric data, because data['sequence'] from FINAL metric
                # and PERIODICAL metric are independent, thus, not comparable.
                self.brackets[bracket_id].set_config_perf(int(i), data['parameter_id'], sys.maxsize, value)
                self.completed_hyper_configs.append(data)
            elif data['type'] == MetricType.PERIODICAL:
                self.brackets[bracket_id].set_config_perf(int(i), data['parameter_id'], data['sequence'], value)
            else:
                raise ValueError('Data type not supported: {}'.format(data['type']))

    def handle_add_customized_trial(self, data):
        pass

    def handle_import_data(self, data):
        pass


from consulting.forms import RegisterForm
from django.shortcuts import render, redirect
from courses_category.models import Category

def home_page(request):
    categories = Category.objects.all()

    register_form = RegisterForm()
    context = {
        'categories': categories,
        'form': register_form

    }
    # context.update(register_form)
    return render(request, "home_page.html", context)


from bottle import post, response, request
import g
import pymysql

##############################
@post("/follow/<follow_user_id>/<follows_user_id>")
@post("/<language>/follow/<follow_user_id>/<follows_user_id>")
def _(language="en", follow_user_id=None, follows_user_id=None):
    try:
        if f"{language}_server_error" not in g.ERRORS : language = "en"
        follow_user_id, error = g._IS_DIGIT(follow_user_id, language)
        if error: return g._SEND(400, error)
        follows_user_id, error = g._IS_DIGIT(follows_user_id, language)
        if error: return g._SEND(400, error)
    except Exception as ex:
        print(ex)
        return g._SEND(500, g.ERRORS[f"{language}_server_error"])

    try:
        follow = (
            follow_user_id,
            follows_user_id
        )

        db_connect = pymysql.connect(**g.DB_CONFIG)
        db = db_connect.cursor()
        query = """
                INSERT INTO follows
                (
                    follow_user_id,
                    follows_user_id
                )
                VALUES(%s, %s)
        """
        db.execute(query, follow)
        counter = db.rowcount
        if not counter: return g._SEND(204, "")

        db.execute("UPDATE users SET user_total_follows = user_total_follows + 1 WHERE user_id = %s", (follow_user_id,))
        counter = db.rowcount
        if not counter: return g._SEND(204, "")

        db.execute("UPDATE users SET user_total_followers = user_total_followers + 1 WHERE user_id = %s", (follows_user_id,))
        counter = db.rowcount
        if not counter: return g._SEND(204, "")

        db_connect.commit()
        response.status = 201
        return {"follow_user_id": follow_user_id, "follows_user_id": follows_user_id}
    except Exception as ex:
        print(ex)
        return g._SEND(500, g.ERRORS[f"{language}_server_error"])

    finally:
        db.close()


#!/usr/bin/python3

from audioop import add
from io import IncrementalNewlineDecoder
import random
import math
import time
from enum import Enum
import numpy as np
from dataclasses import dataclass

#Enum-like things
DIRECTIONS = ("North", "East", "South", "West")

## helper functions
def PrintFifoInfo(asic):
  print("\033[4m" + f"asic ({asic.row},{asic.col}) Local Fifo" + "\033[0m")
  print(f'  data: {asic._localFifo._data} (should be empty if interrogation/calibration was successful)')
  print(f'  did it reach max capacity?: {asic._localFifo._full}')
  print(f'  max size: {asic._localFifo._maxSize}')
  print(f'  total writes: {asic._localFifo._totalWrites}')

  print("\033[4m" + f"asic ({asic.row},{asic.col}) Remote Fifos (NESW)" + "\033[0m")
  print(f'  data: ', end="")
  for remoteFifo in asic._remoteFifos:
    print(f'{remoteFifo._data} ', end="")
  print(f'\n  did it reach max capacity?: ', end="")
  for remoteFifo in asic._remoteFifos:
    print(f'{remoteFifo._full} ', end="")
  print(f'\n  max size:', end="")
  for remoteFifo in asic._remoteFifos:
    print(f'{remoteFifo._maxSize} ', end="")
  print(f'\n  total writes: ', end="")
  for remoteFifo in asic._remoteFifos:
    print(f'{remoteFifo._totalWrites} ', end="")
  print('\n')
##

class QPExcpetion(Exception):
  pass

class AsicDirMask(Enum):
  North = 0
  East = 1
  South = 2
  West = 3

class AsicState(Enum):
  """
  Enum class based on the QpixRoute.vhd FSM states. Transitions to and from these
  states should be modeled on the inputs defined in QpixRoute.vhd.
  """
  Idle = 0
  TransmitLocal = 1
  TransmitRemote = 2
  TransmitReg = 3
  Finish = 4

class AsicWord(Enum):
  """
  Enum class to represent the different types of word types that a QPByte class
  can receive.

  These word types are 4 bits and their values are defined in QPixPkg.vhd
  """
  DATA = 1
  REGREQ = 3
  REGRESP = 4
  EVTEND = 5

@dataclass
class AsicConfig():
  """
  Struct like class that is based on the QpixConfigType record defined in QpixPkg.vhd

  This struct manages the configuration values stored in the QpixRegFile.vhd and should
  determine enables, timeouts, and directional routing
  ARGS:
    frq - frequency of asic frequency, required to determine number of timeout clicks
    timeout - number of ticks that an asic should undergo before leaving transmitRemote state
    DirMask - directional mask
    ManRoute - flag to enable manual routing, or use default routing
    EnableSnd - enable send flag
    EnableRcv - enable receive flag
    EnableReg - enagle register flag
  """
  DirMask: AsicDirMask
  timeout: int
  ManRoute = False
  EnableSnd = True
  EnableRcv = True
  EnableReg = True
  something = False

class QPByte:
  """
  This struct-style class stores no more than the 64 bit information transfered
  on a 64 bit Tx/Rx Endeavor protocol.

  ARGS:
    wordType    : 4 bit regWord type
    originRow   : 4 bit value representing x position
    originCol   : 4 bit value representing y position
    # if wordtype == AsicWord.REGREQ
      Dest    : bool, true if writing to individual ASIC, false if broadcast
      OpWrite : bool, true if writing an ASIC
      OpRead  : bool, true if reading an ASIC (not OpWrite)
      ReqID   : int, keep track of last request-ID received from DaqNode at ASICs
      SrcDaq  : bool, true if coming from DAQNode
      config  : AsicConfig, struct containing ASIC configuration
    # else this is a data word
      timeStamp   : 32 bit time stamp
      channelList : 16 bit channel map
    data        : extra value for simulation

  NOTE: refactored PixelHit object! Data that are transferred are Bytes~ NOT
  'hits'. A hit is always a time stamp, but what is transferred is the more
  generic byte.

  NOTE: 2 bits are currently reserved, and formating is defined in QpixPkg.vhd
  """
  def __init__(self, wordType, originRow, originCol, timeStamp=None, channelList=None, data=None,
              XDest=None, YDest=None, Dest=False, ReqID=-1, OpRead=False, OpWrite=False,
              config=AsicConfig(AsicDirMask.North, 1.5e4)):

    if not isinstance(wordType, AsicWord):
      print('WARNING!! undefined word type in current byte!')

    self.wordType  = wordType
    self.originRow = originRow
    self.originCol = originCol
    self.SrcDaq = bool(originCol is None and originRow is None)
    self.data = data

    # if the wordType is a reg request, then build destination members
    if self.wordType == AsicWord.REGREQ:
      self.Dest = Dest
      self.OpWrite = OpWrite
      self.OpRead = OpRead
      self.XDest = XDest
      self.YDest = YDest
      self.ReqID = ReqID
      self.config = config
    elif self.wordType == AsicWord.REGRESP:
      self.config = config
    else:
      self.timeStamp = timeStamp
      self.channelMask = 0
      if channelList is not None:
        for ch in channelList:
          self.channelMask |= 0x1 << ch

  def __repr__(self):
    """
    how to represent a Byte when print out
    """
    msg = f"({self.originRow},{self.originCol}): {self.wordType}  - {self.data}"
    return msg

  def AddChannel(self, channel):
    self.channelMask |= 0x1 << channel

class QPFifo:
  """
  FIFO class to store and manage incoming QPByte data between ASIC connections

  A FIFO can only do two things: Read and Write. Therefore, there should only
  be two implemented public functions for this class: Read and Write.
  """
  def __init__(self, maxDepth=256):
    self._data = []
    self._maxSize = 0
    self._curSize = 0
    self._maxDepth = maxDepth
    self._full = False
    self._totalWrites = 0

  def Write(self, data: QPByte) -> int:
    """
    Implements a write feature to the Fifo
    ARGS:
      Ensure that the data being stored in the FIFO matches the QPByte
    Returns:
      current number of events stored in the FIFO
    """

    if not isinstance(data, QPByte):
      raise QPException("Can not add this data-type to a QPFifo!")

    self._data.append(data)
    self._curSize += 1
    self._totalWrites += 1

    if self._curSize > self._maxSize:
      self._maxSize = self._curSize

    if self._curSize > self._maxDepth:
      self._full = True

    return self._curSize

  def Read(self) -> QPByte:
    """
    Implements a Readout feature for the FIFO.
    ARGS:
      None
    Returns:
      oldest stored event (First In, First Out)
    """
    if self._curSize > 0:
      self._curSize -= 1
      return self._data.pop(0)
    else:
      return None

class ProcItem:
  '''
  Process item controlled by ProcQueue.
  0 - asic, the ASIC being pushed to
  1 - direction, where the data came from
  2 - QPByte, a QPByte object
  3 - inTime, time that the data would be received, or that the sending asic completes sending QPByte
  4 - command, flag to determine how individual ASIC receiving data should behave
  '''
  def __init__(self, asic, dir, QPByte, inTime, command=None):
    self.asic = asic
    self.dir = dir
    self.QPByte = QPByte
    self.inTime = inTime
    self.command = command
    self._nextItem = None

  def __gt__(self, otherItem):
    '''
    define that comparing process items based on what inTime the item should be
    processed
    '''
    if isinstance(otherItem, ProcItem):
      return self.inTime > otherItem.inTime
    else:
      return NotImplementedError

class ProcQueue:
  """
  ProcQueue class is the main class which defines the simulation flow.

  It is designed to store ProcItem class objects, which are the basic unit of an ASIC transaction.
  """
  def __init__(self, procItem=None):
    self._curItem = procItem
    self._entries = 0

  def AddQueueItem(self, asic, dir, QPByte, inTime, command=None):
    '''
    refactor
    '''
    procItem = ProcItem(asic, dir, QPByte, inTime, command)
    self._AddQueueItem(procItem)

  def _AddQueueItem(self, procItem):
    '''
    include a new process item, inserting into list at appropriate time
    '''
    newItem = procItem
    curItem = self._curItem
    self._entries += 1

    if curItem is None:
      self._curItem = newItem
    elif curItem > newItem:
      h = self._curItem
      self._curItem = newItem
      self._curItem._nextItem = h
    else:
      while newItem > curItem and curItem._nextItem is not None:
        curItem = curItem._nextItem
      newItem._nextItem = curItem._nextItem
      curItem._nextItem = newItem

    return self._entries

  def PopQueue(self):
    if self._curItem is None:
        return None
    self._entries -= 1
    data = self._curItem
    self._curItem = self._curItem._nextItem
    return data

  def SortQueue(self):
    '''
    deprecated
    '''
    pass

  def Length(self):
    return self._entries

class QPixAsic:
  """
  A Q-Pix ASIC fundamentally consists of:
  An oscillator of nominal frequency (~50 MHz)
  A number of channels (nominally 16 or 32)
    - When a given channel is "hit", a timestamp is generated

  -- ARGS/params:
  fOsc          - Oscillator Frequency in Hz
  tOsc          - clock period in seconds
  nPixels       - number of analog channels
  config        - AsicConfig struct class containing configuration members
  randomRate    - Poisson Rate of random background hits
  row           - x position within array
  col           - y position within array
  transferTicks - number of clock cycles governed in a transaction, which is determined by Endeavor protocol parameters
  debugLevel    - float flag which has print statements, > 0 values will cause prints
  ## tracking params
  state         - AsicState Enum class, based on QpixRoute.vhd FSM states
  state_times   - list of tuples that store transition times of ASIC states based on the
  ## Buffers
  _localFifo   - QPFifo class to manage Read and Write of local data
  _remoteFifos - QPFifo list of four QPFifo class' to manage write of remote ASIC data / transactions
  _rxFifos     - QPFifo list of four QPFifo class' to manage read of adjacent ASIC transactions
  connections  - list of pointers to adjacent asics
  """
  def __init__(self, fOsc=50e6, nPixels=16, randomRate=20.0 / 1., timeout=1000, row=None, col=None,
               isDaqNode = False, transferTicks=4*66, debugLevel=0):
    # basic asic parameters
    self.fOsc           = fOsc
    self.tOsc           = 1.0/fOsc
    self.nPixels        = 16
    self.randomRate     = randomRate
    self.row            = row
    self.col            = col
    self.connections    = [None] * 4
    self._command       = None

    # timing, absolute and relative with random starting phase
    self.timeoutStart   = 0
    self.config         = AsicConfig(AsicDirMask.North, timeout)
    self.transferTicks  = transferTicks
    self.transferTime   = self.transferTicks * self.tOsc
    self.lastAbsHitTime = [0] * self.nPixels
    self._absTimeNow    = 0
    self.relTimeNow     = (random.random()-0.5) * self.tOsc
    self._startTime     = self.relTimeNow
    self.relTicksNow    = 0

    self.state_times = []
    self._changeState(AsicState.Idle)

    # daq node Configuration
    self.isDaqNode      = isDaqNode
    self._reqID = -1

    # Queues / FIFOs
    self._localFifo   = QPFifo(maxDepth=256)
    self._remoteFifos = [QPFifo(maxDepth=256), QPFifo(maxDepth=256), QPFifo(maxDepth=256), QPFifo(maxDepth=256)]
    self._rxFifo      = [QPFifo(maxDepth=2), QPFifo(maxDepth=2), QPFifo(maxDepth=2), QPFifo(maxDepth=2)]

    # additional / debug
    self._debugLevel = debugLevel
    self._hitReceptions = 0
    self._measuredTime = []

    # useful things for InjectHits
    self._times = []
    self._channels = []
    self._lastAsicHitTime = 0

  def __repr__(self):
    self.PrintStatus()
    return ""

  def _changeState(self, newState: AsicState):
    """
    function manages when the ASIC transitions from one state to another.

    This function records relative and absolute times of when the FSM in the
    QpixRoute.vhd state transition occurs.

    The purpose of recording state transitions is for testing verification to
    ensure that the ASIC's state transitions match with what is expected.

    NOTE: State changes should be called after UpdateTime, as state changes
    after transactions are complete!
    """
    assert isinstance(newState, AsicState), "Incorrect state transition!"
    self.state = newState
    self.state_times.append((self.state, self.relTimeNow, self._absTimeNow))

  def PrintStatus(self):
    print("ASIC ("+str(self.row)+","+str(self.col)+") ", end="")
    print("STATE:"+str(self.state),end=' ')
    print(f"locFifoSize: {self._localFifo._curSize}")
    print("Remote Sizes (N,E,S,W):",end=' ')
    for d in range(4):
      print(str(self._remoteFifos[d]._curSize) + ",",end=' ')
    print(f"absTime = {self._absTimeNow:0.2e}, trel = {self.relTimeNow:0.2e}")
    print(f"ticks = {self.relTicksNow}")

  def CountConnections(self):
    nConnected = 0
    for conn in self.connections:
      if conn:
        nConnected += 1
    return nConnected

  def HasConnection(self, dir):
    if self.connections[dir]:
      return 1
    else:
      return 0

  def ReceiveByte(self, queueItem:ProcItem):
    """
    Receive data from a neighbor
    queueItem - tuple of (asic, dir, byte, inTime)

    The byte that's received in this function should simulate the behavior of
    the logic found in QpixParser.vhd
    """
    inDir     = queueItem.dir
    inByte    = queueItem.QPByte
    inTime    = queueItem.inTime
    inCommand = queueItem.command

    if self.connections[inDir] is None:
      print("WARNING receiving data from non-existent connection!")

    outList = []

    # if the incomming word is a register request, it's from the DAQNODE
    if inByte.wordType == AsicWord.REGREQ:

      # received this request already?
      if self._reqID == inByte.ReqID:
        return []
      else:
        self._reqID = inByte.ReqID
        # dynamic routing if manual routing not enabled
        if not self.config.ManRoute:
          self.config.DirMask = AsicDirMask(inDir)

      isBroadcast = not inByte.Dest
      # currently ALL register requests are broadcast..
      transactionCompleteTime = inTime + self.transferTime
      self.UpdateTime(transactionCompleteTime)
      for i, connection in enumerate(self.connections):
        if i != inDir and connection is not None:
          outList.append((connection, (i+2)%4, inByte, transactionCompleteTime, inCommand))

      # is this word relevant to this asic?
      forThisAsic = (inByte.XDest == self.row and inByte.YDest == self.col) or isBroadcast
      if forThisAsic:

        # if register write
        if inByte.OpWrite:
          self.config = inByte.config

        # if register read
        elif inByte.OpRead:
          finishTime = inTime + self.transferTime
          self.UpdateTime(finishTime)
          byteOut = QPByte(AsicWord.REGRESP, self.row, self.col, config=self.config)
          destAsic = self.connections[self.config.DirMask.value]
          toDir = self.config.DirMask.value+2
          fromDir = (toDir)%4
          outlist.append((destAsic, fromDir, byteOut, finishTime))

        # if it's not a read or a write, it's a command interrogation
        else:
          self._changeState(AsicState.TransmitLocal)
          self._measuredTime.append(self.relTimeNow)
          self._command = inCommand
          if inCommand == "Interrogate":
            # self._GeneratePoissonHits(inTime)
            self._ReadHits(inTime)

    # all data that is not a register request gets stored on remote fifos
    else:
      self._remoteFifos[inDir].Write(inByte)

    return outList

  def _GeneratePoissonHits(self, targetTime):
    """
    Generate Poisson hits for the time step ##
    Distribution of inter-arrival times can be modeled by throwing
    p = Uniform(0,1) and feeding it to -ln(1.0 - p)/aveRate
    General strategy for moving forward to some timestep is:
      for each channel:
        currentTime = now
        while currentTime < targetTime:
          generate nextHitTime from distribution above
          if currentTime + nextHitTime < targetTime:
            Calculate number of ticks for timestamp and add it to the current queue
          else:
            this is last hit for this pixel, add the next time to the alternate queue
      Sort the overall list by timestamp
      foreach unique entry in the timestamp list, create a hit with proper parameters,
      add it to the queue (A or B)
    """
    # print(f'Generating Poisson Hits for ({self.row}, {self.col}) at target time {targetTime}')
    newHits = []

    for ch in range(self.nPixels):
      currentTime = self.lastAbsHitTime[ch]
      while currentTime < targetTime:

        # generate a posion distribution of absolute / reletive times
        p = random.random() #prints random real between 0 and 1
        nextAbsHitTime = currentTime + (-math.log(1.0 - p) / self.randomRate) # math.log is the natural log
        nextRelHitTime = int(math.floor(nextAbsHitTime / self.tOsc))

        # if hit happens before target time, add a new hit to the list
        if nextAbsHitTime < targetTime:
          newHits.append([ch, nextRelHitTime])
          currentTime = nextAbsHitTime
          self.lastAbsHitTime[ch] = currentTime
        elif nextAbsHitTime > targetTime:
          currentTime             = targetTime
          self.lastAbsHitTime[ch] = targetTime

    if not newHits:
      return 0

    # sort the new hits by time, group the channels with the same hit time, then add
    # them into the FIFO
    newHits.sort(key=lambda x : x[1], reverse=False)
    prevByte = QPByte(AsicWord.DATA, self.row, self.col, newHits[0][1], [newHits[0][0]])

    #check to see if the hit time of the every new hit after the first is
    #the same as the first hit time, then check with second hit, then third ...
    for ch, hitTime in newHits[1:]:
      if timestamp == prevByte.timestamp:
        prevByte.AddChannel(ch)
      else:
        self._localFifo.Write(prevByte)
        prevByte = QPByte(AsicWord.DATA, self.row, self.col, timestamp, [ch])

    #write in the last byte
    self._localFifo.Write(prevByte)

    # print(f'giving asic ({self.row}, {self.col}) {len(newHits)} hits')
    return len(newHits)

  def InjectHits(self, times, channels=None):
    """
    user function to place all injected times and channels into asic specific
    time and channel arrays

    then sort each according to time
    """
    print(f'injecting hits for ({self.row}, {self.col})')

    # place all of the injected times and channels into self._times and self._channels
    self._times.extend(times)

    # include default channels
    if channels is None:
      channels = [[1,3,8]] * len(times)
    else:
      self._channels.extend(channels)

    #sort the times and channels
    self._times, self._channels = zip(*sorted(zip(self._times, self._channels)))

    # print(f'injected hits are at times {self._times} and ch {self._channels}')

  def _ReadHits(self, targetTime):
    """
    make times and channels arrays to contain all hits within the last asic hit
    time and the target time

    read all of the hits in the times/channels arrays, with times before
    targetTime

    then write hits to local fifos
    """
    if not(len(self._times) ==  len(self._channels)):
      print('times and channels not the same length - something has gone horribly wrong')

    if len(self._times):
      self._times = np.asarray(self._times)
      #index times and channels such that they are within last asic hit time and target time
      TimesIndex = np.logical_and(self._times > self._lastAsicHitTime, self._times <= targetTime)
      times = self._times[TimesIndex]
      channels = []
      for i in range(len(self._channels)):
        if TimesIndex[i]:
          channels.append(self._channels[i])

      newhitcount = 0
      for inTime, ch in zip(times, channels):
        if type(ch) is list:
          prevByte = QPByte(AsicWord.DATA, self.row, self.col, inTime, [ch[0]])
          for addCh in ch[1:]:
            prevByte.AddChannel(addCh)
        else:
          prevByte = QPByte(AsicWord.DATA, self.row, self.col, inTime, [ch])
        self._localFifo.Write(prevByte)
        newhitcount+=1

      self._lastAsicHitTime = targetTime

      return newhitcount

    else:
      # print(f'there are no hits for asic ({self.row}, {self.col})')
      return 0

  def Process(self, targetTime):
    """
    This function simulates the FSM within QpixRoute.vhd.
    ARGS:
      targetTime - time to push the FSM foward.
    """
    # nothing to process if DAQ or if target time is in past
    if self.isDaqNode or self._absTimeNow > targetTime:
      return []

    # Process incoming commands first
    # all commands move ASIC into transmit local state local queues, and the
    # command should build up any 'hit' of interest
    if self._command == "Calibrate":
      self._command = None
      self._changeState(AsicState.TransmitLocal)
      curTicks = self.relTicksNow
      self._localFifo.Write(QPByte(AsicWord.REGRESP, self.row, self.col, curTicks, [], data=self._measuredTime[-1]))

    # an ASIC timestamp request
    elif self._command == "Interrogate":
      self._command = None
      self._changeState(AsicState.TransmitLocal)

    ## QPixRoute State machine
    elif self.state == AsicState.Idle:
      return self._processMeasuringState(targetTime)

    elif self.state == AsicState.TransmitLocal:
      return self._processTransmitLocalState(targetTime)

    elif self.state == AsicState.Finish:
      return self._processFinishState(targetTime)

    elif self.state == AsicState.TransmitRemote:
      return self._processTransmitRemoteState(targetTime)

    else:
      # undefined state
      print("WARNING! ASIC in undefined state")
      self._changeState(AsicState.Idle)
      return []

  def _processMeasuringState(self, targetTime):
    """
    Function simulates the IDLE state with QpixRoute.vhd. In this case the only
    thing to be done is to update the time.
    """
    self.UpdateTime(targetTime)
    return []

  def _processRegisterResponse(self, targetTime):
    """
    This function simulates the register response state within QpixRoute.vhd

    This state sends a REGRESP word back to the local fifo and then returns to
    the IDLE/measuring state.
    """
    transactionCompleteTime = self._absTimeNow + self.transferTime
    self.UpdateTime(transactionCompleteTime)
    self._changeState(AsicState.Idle)
    respByte = QPByte(AsicWord.REGRESP, self.row, self.col, 0, [0])
    return [(self.connections[self.config.DirMask.value], (self.config.DirMask.value+2)%4, respByte, transactionCompleteTime)]

  def _processTransmitLocalState(self, targetTime):
    """
    helper function for sending local data where it needs to go
    sends a single local state queue item into the outlist
    """

    transactionCompleteTime = self._absTimeNow + self.transferTime

    # read an event from our local FIFO, if there is something in it, transmit it
    hit = self._localFifo.Read()
    if hit is not None:
      self.UpdateTime(transactionCompleteTime)
      return [(self.connections[self.config.DirMask.value], (self.config.DirMask.value+2)%4, hit, transactionCompleteTime)]
    else:
      self._changeState(AsicState.Finish)
      return []

  def _processFinishState(self, targetTime):
    """
    Finish state based on QpixRoute.vhd state. Should pack a single word into
    the event fifo, send it, and proceed to the transmit remote state.
    """
    # send the finish packet word
    transactionCompleteTime = self._absTimeNow + self.transferTime
    self.UpdateTime(transactionCompleteTime)
    finishByte = QPByte(AsicWord.EVTEND, self.row, self.col, 0, [0])
    self.timeoutStart = self._absTimeNow

    # after sending the word we go to the Transmit remote state
    self._changeState(AsicState.TransmitRemote)

    return [(self.connections[self.config.DirMask.value], (self.config.DirMask.value+2)%4, finishByte, transactionCompleteTime)]

  def _processTransmitRemoteState(self, targetTime):
    """
    process state is based on QpixRoute.vhd REP_REMOTE_S state. This state should always
    bring the asic back to the idle state after a timeout
    """

    # If we're timed out, just kill it
    if self._absTimeNow - self.timeoutStart > self.config.timeout / self.fOsc:
      self._changeState(AsicState.Idle)
      if self._localFifo._curSize > 0:
          print("Lost "+str(len(self._localFifo._curSize))+" hits that were left to forward!")
      return []

    hitsToForward = False
    for remote_fifo in self._remoteFifos:
      if remote_fifo._curSize > 0:
        hitsToForward = True

    # If there's nothing to forward, just bring us up to requested time
    if not(hitsToForward):
      self.UpdateTime(targetTime)
      if self._absTimeNow - self.timeoutStart > self.config.timeout / self.fOsc:
        self._changeState(AsicState.Idle)
      return []

    else:
      hitlist = []
      for remote_fifo in self._remoteFifos:
        hit = remote_fifo.Read()
        if hit is not None:
          completeTime = self._absTimeNow + self.transferTime
          if self._absTimeNow - self.timeoutStart > self.config.timeout / self.fOsc:
            self.UpdateTime(completeTime)
            self._changeState(AsicState.Idle)
            return hitlist
          else:
            hitlist.append((self.connections[self.config.DirMask.value], (self.config.DirMask.value+2)%4 , hit, completeTime))
            self.UpdateTime(completeTime)
      return hitlist

    return []

  def UpdateTime(self, absTime):
    """
    How an ASIC keep track of its relative times.
    ARGS:
        absTime - absolute time of the simulation, that an ASIC is asked to process up to

    NOTE:
    should only move forward in time and update if the ASIC is not already this
    far forward in time.
    """

    if absTime > self._absTimeNow:
      self._absTimeNow = absTime

      # only update the relTime if the asic needs to
      if self._absTimeNow > self.relTimeNow:
        t_diff =  self._absTimeNow - self.relTimeNow
        cycles = int(t_diff/self.tOsc) + 1

        # update the local clock cycles
        self.relTimeNow += cycles * self.tOsc
        self.relTicksNow += cycles

class DaqNode(QPixAsic):
  def __init__(self, fOsc = 50e6, nPixels = 16, randomRate = 20.0 / 1., timeout=1000, row=None, col=None,
               transferTicks = 4*66, debugLevel=0):
    # makes itself basically like a qpixasic
    super().__init__(fOsc, nPixels, randomRate, timeout, row, col,
                    transferTicks, debugLevel)
    # new members here
    self.isDaqNode = True
    self.hitData = {}
    self.regData = {}
    self.daqData = {}
    self.daqHits = 0
    # make sure that the starting daqNode ID is different from the ASIC default
    self._reqID += 1

  def ReceiveByte(self, queueItem:ProcItem):
    """
    Records Byte to daq
    """
    inDir     = queueItem.dir
    inByte    = queueItem.QPByte
    inTime    = queueItem.inTime
    inCommand = queueItem.command
    inWord    = inByte.wordType

    # how a DAQNode records and stores data to its local FIFO
    AsicKey = f"({inByte.originRow}, {inByte.originCol})"
    if AsicKey not in self.daqData:
      self.daqData[AsicKey] = []

    self.UpdateTime(queueItem.inTime)
    self.daqHits += 1
    self._localFifo.Write(inByte)

    # Put all of the attributes of the QPByte into a list
    if inWord == AsicWord.DATA:
      self.hitData[AsicKey].append((self.relTicksNow, inByte))
    elif inWord == AsicWord.REGRESP:
      self.regData[AsicKey].append((self.relTicksNow, inByte))
    elif inWord == AsicWord.EVTEND:
      pass
    else:
      print(f"WARNING! there is no associated wordType with this byte {inWord} @ {AsicKey}")
    self.daqData[AsicKey].append((self.relTicksNow, inByte))

    if self._debugLevel > 0:
      print(f"DAQ-{self.relTicksNow} ",end=' ')
      print(f"from: ({inByte.originRow},{inByte.originCol})",end='\n\t')
      print(f"Hit Time: {inByte.timestamp} "+format(inByte.channelMask,'016b'),end='\n\t')
      print(f"absT: {inTime}", end='\n\t')
      print(f"tDiff (ns): {(self.relTimeNow-inTime)*1e9:2.2f}")

    return []


# 将news-sentence-cut.txt 去除停用词

def get_stopwords():
    stopwords = set()
    with open('./哈工大停用词表.txt', 'r', encoding='utf-8') as f:
        for word in f:
            stopwords.add(word.strip('\n'))
    return stopwords

def del_stopwords(read_path, save_path):
    save = open(save_path, 'w', encoding='utf-8')
    stopwords = get_stopwords()
    with open(read_path, 'r', encoding='utf-8') as f:
        line = f.readline()
        while line:
            article = ''
            line = line.strip('\n').split(' ')
            for word in line:
                if word not in stopwords:
                    article += word+' '
            save.write(article+'\n')
            line = f.readline()

    save.close()

if __name__=='__main__':
    read_path = 'news-sentences-cut.txt'
    save_path = './final-news-sentences-cut.txt'
    del_stopwords(read_path, save_path)
    with open(save_path,'r',encoding='utf-8') as f:
        print(f.readline())


for _ in range(4):
    a0, a1, a2, a3, a4, a5, a6, a7 = map(int, input().split())
    if a3 < a5 or a2 < a4 or a1 > a7 or a0 > a6:
        result = 'd'
    elif (a3 == a5 and (a0 == a6 or a2 == a4)) or (a1 == a7 and (a0 == a6 or a2 == a4)):
        result = 'c'
    elif a3 == a5 or a2 == a4 or a1 == a7 or a0 == a6:
        result = 'b'
    else:
        result = 'a'
    print(result)


from django.urls import path
from . import views

app_name = 'quiz'

urlpatterns = [
    path('java_login/',views.java_login,name = 'java_login'),
    path('c_login/',views.c_login,name = 'c_login'),
    path('cpp_login/',views.cpp_login,name = 'cpp_login'),
    path('vb_login/',views.vb_login,name = 'vb_login'),
    path('ca_login/',views.ca_login,name = 'ca_login'),
    path('os_login/',views.os_login,name = 'os_login'),
    path('dm_login/',views.dm_login,name = 'dm_login'),
    # path('staff_categories/',views.staff_categories,name = 'staff_categories'),
    # path('register/',views.register,name = 'register'),
    path('index/',views.index,name='index'),
    # path('categories/',views.categories,name = 'categories'),
    path('dbms_login/',views.dbms_login,name = 'dbms_login'),
    path('quiz/',views.quiz,name = 'quiz'),
    path('dbms_db/',views.dbms_db,name = 'dbms_db'),
    path('dbms_regno/',views.dbms_regno,name='dbms_regno'),
    path('os_db/',views.os_db,name = 'os_db'),
    path('os_regno/',views.os_regno,name='os_regno'),
    path('ca_db/',views.ca_db,name = 'ca_db'),
    path('ca_regno/',views.ca_regno,name='ca_regno'),
    path('c_db/',views.c_db,name = 'c_db'),
    path('c_regno/',views.c_regno,name='c_regno'),
    path('cpp_db/',views.cpp_db,name = 'cpp_db'),
    path('cpp_regno/',views.cpp_regno,name='cpp_regno'),
    path('java_db/',views.java_db,name = 'java_db'),
    path('java_regno/',views.java_regno,name='java_regno'),
    path('vb_db/',views.vb_db,name = 'vb_db'),
    path('vb_regno/',views.vb_regno,name='vb_regno'),
    path('dm_db/',views.dm_db,name = 'dm_db'),
    path('dm_regno/',views.dm_regno,name='dm_regno'),
    path('os_quiz/',views.os_quiz,name='os_quiz'),
    path('ca_quiz/',views.os_quiz,name='ca_quiz'),
    path('c_quiz/',views.os_quiz,name='c_quiz'),
    path('cpp_quiz/',views.os_quiz,name='cpp_quiz'),
    path('java_quiz/',views.os_quiz,name='java_quiz'),
    path('vb_quiz/',views.os_quiz,name='vb_quiz'),
    path('dm_quiz/',views.os_quiz,name='dm_quiz'),
    path('dbms_quiz/',views.os_quiz,name='dbms_quiz'),
]


#!/usr/bin/python3

def main():

	if (len(sys.argv) != 2):
		print("Usage: %s <config file>"%(sys.argv[0]))
		sys.exit()

	config = read_config_simple(sys.argv[1])

	fin = open("out.txt", "r")

	reals = []
	imags = []

	for line in fin:
		real, imag = line.split()
		reals.append(float(real))
		imags.append(float(imag))

	for real in reals:
		update_rrd()

	fin.close()

main()