import datetime

from jsonschema.exceptions import ValidationError

from pykechain.enums import (
    PropertyType, ScopeStatus,
    KEChainPages,
    ScopeMemberActions,
    ScopeRoles,
    ScopeCategory,
)
from pykechain.exceptions import NotFoundError, MultipleFoundError, IllegalArgumentError
from pykechain.models import Team, Scope
from pykechain.models.sidebar.sidebar_manager import SideBarManager
from pykechain.utils import is_url
from tests.classes import TestBetamax

class TestScopes(TestBetamax):
    """
    Test retrieval and scope attributes and methods.
    """

    def test_scope_attributes(self):
        attributes = [
            "_client",
            "_json_data",
            "id",
            "name",
            "created_at",
            "updated_at",
            "ref",
            "process",
            "workflow_root",
            "description",
            "status",
            "category",
            "tags",
            "start_date",
            "due_date",
        ]

        obj = self.project
        for attribute in attributes:
            with self.subTest(attribute):
                self.assertTrue(
                    hasattr(obj, attribute),
                    f"Could not find '{attribute}' in the object: '{obj.__dict__.keys()}'",
                )

    def test_retrieve_scopes(self):
        self.assertTrue(self.client.scopes())

    def test_retrieve_scope_with_refs(self):
        # setup
        scope_ref = "bike-project"
        scope_name = "Bike Project"
        scope = self.client.scope(ref=scope_ref)

        # testing
        self.assertIsInstance(scope, Scope)
        self.assertTrue(scope.name, scope_name)

    def test_retrieve_scope_with_kwargs(self):
        retrieve_scopes_with_kwargs = self.client.scopes(name__icontains="Bike")
        self.assertTrue(retrieve_scopes_with_kwargs)
        self.assertTrue(len(retrieve_scopes_with_kwargs) >= 1)

    def test_retrieve_single_unknown(self):
        with self.assertRaises(NotFoundError):
            self.client.scope("123lladadwd")

    def test_retrieve_single_multiple(self):
        with self.assertRaises(MultipleFoundError):
            self.client.scope()

    def test_team_property_of_scope(self):
        """Test for the property 'team' of a scope."""
        team = self.project.team

        self.assertIsNone(team)

    def test_side_bar(self):
        side_bar_manager = self.project.side_bar()

        self.assertIsInstance(side_bar_manager, SideBarManager)

    def test_root_properties(self):
        for value in [
            self.project.workflow_root_process,
            self.project.catalog_root_process,
            self.project.app_root_process,
            self.project.product_root_model,
            self.project.product_root_instance,
            self.project.catalog_root_model,
            self.project.catalog_root_instance,
        ]:
            with self.subTest(""):
                self.assertIsNotNone(value)

class TestScopeMembers(TestBetamax):
    """
    Tests user assignment to a scope.
    """

    DEFAULTS = {
        ScopeRoles.MANAGER: [
            "superuser",
            "testmanager",
        ],
        ScopeRoles.LEADMEMBER: [
            "superuser",
            "testlead",
        ],
        ScopeRoles.SUPERVISOR: ["supervisor"],
        ScopeRoles.MEMBER: [
            "testuser",
        ],
    }

    def _reset_members(self):
        """Reset the scope members by removing all members and adding the defaults"""
        [
            self.project.remove_member(member=member["username"])
            for member in self.project.members()
        ]

        for role in [
            ScopeRoles.MANAGER,
            ScopeRoles.LEADMEMBER,
            ScopeRoles.MEMBER,
            ScopeRoles.SUPERVISOR,
        ]:
            for member in self.DEFAULTS[role]:
                self.project._update_scope_project_team(ScopeMemberActions.ADD, role, member)

    def setUp(self):
        super().setUp()
        self._reset_members()

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

    def test_reset_members(self):
        """Test `_reset_members` method of the test class"""
        self.assertTrue(True)

    def test_members(self):
        scope = self.project

        # Helper function:
        def get_member_names(**kwargs):
            return [member["username"] for member in scope.members(**kwargs)]

        all_members = set(get_member_names())
        managers = set(get_member_names(is_manager=True))
        supervisors = set(get_member_names(is_supervisor=True))
        non_managers = set(get_member_names(is_manager=False))
        leads = set(get_member_names(is_leadmember=True))
        non_leads = set(get_member_names(is_leadmember=False))
        basic_members = set(get_member_names(is_manager=False, is_leadmember=False))

        self.assertEqual(5, len(all_members), msg=",".join(all_members))
        self.assertTrue(
            basic_members and leads and managers and supervisors,
            msg="Test scope must have a member of every type!",
        )

        all_roles = basic_members | leads | managers | supervisors
        remaining_non_leads = all_roles - leads
        remaining_non_managers = all_roles - managers

        self.assertSetEqual(
            all_roles, all_members, msg="The sum of all roles should equal all members."
        )
        self.assertSetEqual(remaining_non_leads, non_leads)
        self.assertSetEqual(remaining_non_managers, non_managers)

    def test_add_member(self):
        member_to_be_added = "anotheruser"
        self.project.add_member(member_to_be_added)
        self.project = self.client.scope(pk=self.project.id)
        project_members = self.project.members()

        # testing
        self.assertTrue(member_to_be_added in [member["username"] for member in project_members])

    def test_add_member_by_id(self):
        member_id = 4
        with self.assertRaises(IllegalArgumentError):
            # noinspection PyTypeChecker
            self.project.add_member(member_id)

    def test_add_non_existing_member(self):
        member_to_be_added = "Nobody"
        with self.assertRaises(NotFoundError):
            self.project.add_member(member_to_be_added)

    def test_remove_member(self):
        member_to_be_removed = "anotheruser"
        # setUp
        self.project.add_member(member_to_be_removed)
        # testing
        self.project.remove_member(member_to_be_removed)
        self.project = self.client.scope(pk=self.project.id)
        project_members = self.project.members()
        self.assertTrue(
            member_to_be_removed not in [member["username"] for member in project_members]
        )

    def test_add_manager(self):
        manager_to_be_added = "anotheruser"
        # testing
        self.project.add_manager(manager_to_be_added)
        self.project = self.client.scope(pk=self.project.id)
        project_managers = self.project.members(is_manager=True)
        self.assertTrue(
            manager_to_be_added in [manager["username"] for manager in project_managers]
        )

    def test_remove_manager(self):
        manager_to_be_removed = "anotheruser"
        # setUp
        self.project.add_manager(manager_to_be_removed)
        # testing
        self.project.remove_manager(manager_to_be_removed)
        self.project = self.client.scope(pk=self.project.id)
        project_managers = self.project.members(is_manager=True)
        self.assertTrue(
            manager_to_be_removed not in [manager["username"] for manager in project_managers]
        )
        project_managers = self.project.members(is_manager=False)
        self.assertTrue(
            manager_to_be_removed in [manager["username"] for manager in project_managers]
        )

    def test_add_leadmember(self):
        leadmember_to_be_added = "anotheruser"
        # testing
        self.project.add_leadmember(leadmember_to_be_added)
        self.project = self.client.scope(pk=self.project.id)
        project_leadmembers = self.project.members(is_leadmember=True)
        self.assertTrue(
            leadmember_to_be_added
            in [leadmember["username"] for leadmember in project_leadmembers]
        )

    def test_remove_leadmember(self):
        leadmember_to_be_removed = "anotheruser"
        # setUp
        self.project.add_leadmember(leadmember_to_be_removed)
        # testing
        self.project.remove_leadmember(leadmember_to_be_removed)
        self.project = self.client.scope(pk=self.project.id)
        project_leadmembers = self.project.members(is_leadmember=True)
        self.assertTrue(
            leadmember_to_be_removed
            not in [leadmember["username"] for leadmember in project_leadmembers]
        )
        project_leadmembers = self.project.members(is_leadmember=False)
        self.assertTrue(
            leadmember_to_be_removed
            in [leadmember["username"] for leadmember in project_leadmembers]
        )

    def test_add_supervisor(self):
        supervisor_to_be_added = "anotheruser"
        # testing
        self.project.add_supervisor(supervisor_to_be_added)
        self.project = self.client.scope(pk=self.project.id)
        project_supervisors = self.project.members(is_supervisor=True)
        self.assertTrue(
            supervisor_to_be_added
            in [supervisor["username"] for supervisor in project_supervisors]
        )

    def test_remove_supervisor(self):
        supervisor_to_be_removed = "anotheruser"
        # setUp
        self.project.add_supervisor(supervisor_to_be_removed)
        # testing
        self.project.remove_supervisor(supervisor_to_be_removed)
        self.project = self.client.scope(pk=self.project.id)
        project_supervisors = self.project.members(is_supervisor=True)
        self.assertTrue(
            supervisor_to_be_removed
            not in [supervisor["username"] for supervisor in project_supervisors]
        )

class TestScopeEdit(TestBetamax):
    """
    Test modifications to a scope.
    """

    def setUp(self):
        super().setUp()
        testing_project = self.project
        self.project = None
        self.project_info = [{
                "id": 0,
                "name": "Project name",
                "value": "Bike project wannabe",
                "property_type": PropertyType.CHAR_VALUE,
            },
            {
                "id": 1,
                "name": "Project number",
                "value": 12,
                "property_type": PropertyType.INT_VALUE,
            }]
        self.scope = testing_project.clone()

    def tearDown(self):
        if self.scope:
            self.scope.delete()
        super().tearDown()

    # 2.2.0+
    # noinspection PyTypeChecker
    def test_edit_scope(self):
        # setUp
        new_scope_name = "Pykechain testing (bike project)"
        new_scope_description = (
            "Project used to build a Bike. Part-time job is to also test Pykechain."
        )
        new_start_date = datetime.datetime(2018, 12, 5, tzinfo=None)
        new_due_date = datetime.datetime(2018, 12, 8, tzinfo=None)
        new_tags = ["tag_one", "tag_two"]

        self.scope.edit(
            name=new_scope_name,
            description=new_scope_description,
            tags=new_tags,
            start_date=new_start_date,
            due_date=new_due_date,
            status=ScopeStatus.CLOSED,
            category=ScopeCategory.TEMPLATE_SCOPE,
        )

        retrieved_project = self.client.scope(id=self.scope.id, status=ScopeStatus.CLOSED)

        # testing
        self.assertEqual(new_scope_name, retrieved_project.name)
        self.assertEqual(new_scope_description, retrieved_project.description)
        self.assertIn(
            retrieved_project._json_data["start_date"],
            ("2018-12-05T00:00:00Z", "2018-12-05T00:00:00+00:00"),
        )
        self.assertIn(
            retrieved_project._json_data["due_date"],
            ("2018-12-08T00:00:00Z", "2018-12-08T00:00:00+00:00"),
        )
        self.assertEqual(ScopeStatus.CLOSED, retrieved_project.status)
        self.assertEqual(ScopeCategory.TEMPLATE_SCOPE, retrieved_project.category)
        self.assertEqual(new_tags, retrieved_project.tags)

        with self.assertRaises(IllegalArgumentError):
            self.scope.edit(name=True)

        with self.assertRaises(IllegalArgumentError):
            self.scope.edit(description=new_start_date)

        with self.assertRaises(IllegalArgumentError):
            self.scope.edit(start_date="Yes, man!")

        with self.assertRaises(IllegalArgumentError):
            self.scope.edit(due_date="Wrong")

        with self.assertRaises(IllegalArgumentError):
            self.scope.edit(status="ILLEGAL_STATUS_WILL_CAUSE_ERR")

        with self.assertRaises(IllegalArgumentError):
            self.scope.edit(category="Ice scoop")

        with self.assertRaises(IllegalArgumentError):
            self.scope.edit(tags="tags must be a list of strings")

    # test added due to #847 - providing no inputs overwrites values
    def test_edit_scope_clearing_values(self):
        # setUp
        initial_name = "Pykechain testing (bike project)"
        initial_description = (
            "Project used to build a Bike. Part-time job is to also test Pykechain."
        )
        initial_start_date = datetime.datetime(2018, 12, 5, tzinfo=None)
        initial_due_date = datetime.datetime(2018, 12, 8, tzinfo=None)
        initial_tags = ["tag_one", "tag_two"]
        team_one, team_two = self.client.teams()[:2]

        self.scope.edit(
            name=initial_name,
            description=initial_description,
            tags=initial_tags,
            start_date=initial_start_date,
            due_date=initial_due_date,
            team=team_two,
        )

        # Edit without mentioning values, everything should stay the same
        new_name = "Just Pykechain testing (bike project)"
        self.scope.edit(name=new_name)

        # testing
        self.assertEqual(self.scope.name, new_name)
        self.assertEqual(self.scope.description, initial_description)
        self.assertEqual(
            self.scope.start_date.strftime("%Y/%m/%d, %H:%M:%S"),
            initial_start_date.strftime("%Y/%m/%d, %H:%M:%S"),
        )
        self.assertEqual(
            self.scope.due_date.strftime("%Y/%m/%d, %H:%M:%S"),
            initial_due_date.strftime("%Y/%m/%d, %H:%M:%S"),
        )
        self.assertEqual(self.scope.tags, initial_tags)

        # Edit with clearing the values, name and status cannot be cleared
        self.scope.edit(
            name=None, description=None, tags=None, start_date=None, due_date=None, status=None
        )
        self.scope.refresh()
        self.assertEqual(self.scope.name, new_name)
        self.assertEqual(self.scope.description, "")
        self.assertEqual(self.scope.start_date, None)
        self.assertEqual(self.scope.due_date, None)
        self.assertEqual(self.scope.tags, list())

    # v2.3.3
    def test_edit_scope_team(self):
        """Test capabilities of changing team scope"""

        team_one, team_two = self.client.teams()[:2]

        self.scope.edit(team=team_one)
        self.assertEqual(self.scope.team, team_one)

        self.scope.edit(team=team_two)
        self.assertEqual(self.scope.team, team_two)

    def test_edit_project_info(self):
        self.scope.edit(project_info=self.project_info)

        retrieved_project_info = self.scope.get_project_info()

        self.assertIsInstance(retrieved_project_info, list)
        self.assertListEqual(retrieved_project_info, self.project_info)

    def test_clear_project_info_edit_project(self):
        self.scope.set_project_info(project_info=self.project_info)

        retrieved_project_info = self.scope.get_project_info()

        self.assertIsInstance(retrieved_project_info, list)
        self.assertListEqual(retrieved_project_info, self.project_info)

        # clean up the project info
        self.scope.edit(project_info=list())

        retrieved_project_info = self.scope.get_project_info()

        self.assertIsInstance(retrieved_project_info, list)
        self.assertListEqual(retrieved_project_info, [])

    def test_set_landing_page(self):
        tasks = [
            self.scope.activities()[0],
            KEChainPages.DATA_MODEL,
        ]

        for task in tasks:
            with self.subTest(msg=task):
                self.scope.set_landing_page(activity=task)

    def test_get_landing_page(self):
        landing_page = self.scope.get_landing_page_url()

        self.assertIsNone(landing_page)

        self.scope.set_landing_page(activity=self.scope.activities()[0])
        landing_page = self.scope.get_landing_page_url()

        self.assertIsInstance(landing_page, str)
        self.assertTrue(is_url(self.client.api_root + landing_page))

    def test_set_project_info(self):
        self.scope.set_project_info(project_info=self.project_info)

        retrieved_project_info = self.scope.get_project_info()

        self.assertIsInstance(retrieved_project_info, list)
        self.assertListEqual(retrieved_project_info, self.project_info)

    def test_get_project_info(self):
        retrieved_project_info = self.scope.get_project_info()

        self.assertListEqual(retrieved_project_info, [])

        self.scope.set_project_info(project_info=self.project_info)

        retrieved_project_info = self.scope.get_project_info()
        self.assertListEqual(retrieved_project_info, self.project_info)

    def test_set_project_info_with_wrong_attributes(self):
        with self.assertRaises(ValidationError):
            self.scope.set_project_info(project_info={})
        with self.assertRaises(ValidationError):
            project_info_too_many_attributes = self.project_info
            for prop_dict in project_info_too_many_attributes:
                prop_dict['some_key'] = "some value"
            self.scope.set_project_info(project_info=project_info_too_many_attributes)
        with self.assertRaises(ValidationError):
            for prop in self.project_info:
                prop.pop('id')
            self.scope.set_project_info(project_info=self.project_info)

    def test_empty_project_info(self):
        self.scope.set_project_info(project_info=self.project_info)

        retrieved_project_info = self.scope.get_project_info()

        self.assertIsInstance(retrieved_project_info, list)
        self.assertListEqual(retrieved_project_info, self.project_info)

        # clean up the project info
        self.scope.set_project_info(project_info=list())

        retrieved_project_info = self.scope.get_project_info()

        self.assertIsInstance(retrieved_project_info, list)
        self.assertListEqual(retrieved_project_info, [])


import itertools

n,m = map(int,input().split())
arr = []
num1 = [] # 집
num2 = [] # 치킨

for i in range(n):
  arr.append(list(map(int,input().split())))

for i in range(n):
  for j in range(n):
    if arr[i][j] == 1:
      num1.append(i+1)
      num1.append(j+1)
    elif arr[i][j] == 2:
      num2.append(i+1)
      num2.append(j+1)

num1_index = [num1[i*2:(i+1)*2] for i in range((len(num1)+1)//2)] #집 좌표
num2_index = [num2[i*2:(i+1)*2] for i in range((len(num2)+1)//2)] #치킨 좌표

com = list(itertools.combinations((num2_index),m)) #치킨집 m개 조합

num = 0
for i in range(len(num1_index)):
  minimal = []
  for j in range(0,m):
    list =[]
    temp = abs(num1_index[i][0] - com[i][j][0]) + abs(num1_index[i][1] - com[i][j][1])
    list.append(temp)
  res = min(list) #집x와 치킨집 사이의 치킨거리.
  num += res #도시의 치킨거리
  minimal.append(num)
print(min(minimal))


def grep(ruta, cadena):
    #Recibe una cadena y un archivo. Imprime
    #aquellas lineas del archivo que contienen a la cadena.
    resultado =[]
    linea ='x'
    with open(ruta) as archivo:
        while linea:
            linea = archivo.readline().rstrip()
            if linea == '':
                break
            resultado.append(linea)

        for item in resultado:
            if cadena in item:
                print(item)


# -*- coding: utf-8 -*-
import urllib
import subprocess as s
import os
import argparse
import threading
import sys
import time
import re
import logging
import atexit
from urllib.request import Request, urlopen
import urllib.error
from xml.dom.minidom import parse

class CookieList:
	time = 0
	value = ""

path = os.path.expanduser("~/festeloApp/")

def exit_handler():
	logging.info('Script closing')

def createParser(): #Настройка аргументов
	parser = argparse.ArgumentParser()
	parser.add_argument('-n', '--new', nargs='+', help="Добавляет новый Cookie в базу данных")
	parser.add_argument('-r', '--run', nargs=1, help="Запускает вручную скрипт для выбранного Cookie")
	parser.add_argument('-i', '--info', nargs  ='+', help="Получает информацию об аккаунте из выбранного Cookie")
	parser.add_argument('-rm', '--remove', nargs=1, help="Удаляет Cookie из базы данных")
	parser.add_argument('-ls', '--list', default=False, action='store_true', help="Выводит список Cookie")

	return parser

def checkAkk(cookie): #Проверка Cookie аккаунта / получение данных об аккаунте
	try:
		#Открытие CSGO500 для получения данных об аккаунте
		f = urlopen(Request('https://csgo500.com/', headers={'User-Agent': 'Mozilla/5.0', 'Cookie': 'express.sid=' + cookie }))
	except urllib.error.HTTPError:
		print("Ошибка соединения")
		return 1
	result = f.read().decode('utf-8') # Записывание кода HTML страницы в переменную
	try:
		# Ищет на странице данные и записывает в переменные
		rewDate = re.findall('rewardDate = "(.*?) GMT', result)[0]
		nick = re.findall('
\n(.*?)\n
', result)[0]
		balance = re.findall('value = (.*?);', result)[0]
		return [nick, balance, rewDate] # Возвращает массив с полученными данными
	except IndexError:
		#Происходит если какие-то данные на странице не обнаружены.
		print("Ошибка авторизации, данные указаны верно?")
		return 2

def test(cookie, i):
	informing("Send request to CSGO500. Cookie#" + str(i), cookie, False)
	headers = {'User-agent': 'Mozilla/5.0', 'Cookie': 'express.sid=' + cookie}
	try:
		f = urlopen(Request('https://csgo500.com/', headers=headers)) #Открывает страницу для получения HTML
		res = f.read().decode("UTF-8") #Записывает данные в переменную
	except urllib.error.HTTPError:
		informing("Error with access to site! Check internet connection!", True)
		return 0
	token = re.findall('csrfToken = "(.*?)";', res) #Ищет CSRF токен на странице и записывает в переменную
	app_xml = parse(path + "/data.xml") #Открывает XML документ для чтения
	element = app_xml.childNodes[0].getElementsByTagName('Cookie')[i] #Находит нужный элемент Cookie по индексу i

	if '
' in res: #Происходит если на странице есть кнопка входа
		informing("Login error! Cookie #" + str(i), cookie, True)
		element.tagName = "OUTDATE"
	else:
		requestdata = {'_csrf' : token[0]} #Формирует csrf данные для POST запроса
		params_auth = urllib.parse.urlencode(requestdata)
		try:
			#Отправляет POST запрос для получения ежедневного бонуса
			data = urlopen(Request('https://csgo500.com/reward', data=params_auth.encode("UTF-8"), headers=headers))

		except urllib.HTTPError: #Происходит когда 1) Нет соединения. 2) Сервер отвечает кодом ошибки
			informing("The daily bonus has not yet come. Cookie #" + str(i), cookie, True)
			return 0
		element.removeAttribute("time") #Обновляет данные времени ежедневного бонуса в XML документе
		element.setAttribute("time", str(time.time()))
		informing("Task complete succesful! Cookie # " + str(i), cookie, False)
	res = open(path + "/data.xml", "w") #Открывает XML документ для записи
	app_xml.childNodes[0].writexml(res) #Записывает в него обновленные данные
	res.close() #Закрывает XML документ

def refrCookieList(mode = 0):
	try:
		dom = parse(path + "/data.xml") #Открывает для чтения XML документ
		custom = []
		i = 0
		if mode == 0: ElementName = 'Cookie'
		else: ElementName = 'OUTDATE'
		# Цикл для каждого элемента в XML документе с именем Cookie или OUTDATE
		for node in dom.childNodes[0].getElementsByTagName(ElementName):
			custom.append(CookieList()) #Добавляет к массиву новый объект CookieList и заполняет его
			custom[i].time = node.getAttribute("time")
			custom[i].value = node.firstChild.nodeValue
			i = i + 1 #Счетчик
		return custom
	except IOError:
		DataMake()

def DataMake():
	print("Первый запуск. Подготовка файлов...")
	try:
		os.makedirs(path) #Создает рабочую директорию
		f = open(path + "/data.xml", 'w') #Создает и открывает документ XML
		f.write("<data/>") #Записывает в него XML тег и закрывает его и файл
		f.close
		print("Файлы созданы, добавьте cookie командой 'febot -n COOKIE''")
		exit(0)
	except OSError:
		print("Ошибка при создании файлов, путь: " + path)
		exit(0)

def go():  #Таймер проверки надобности отправления запроса на ежедневный бонус
	custom = refrCookieList() #Обновляет данные с XML документа
	i = 0 #Счетчик
	for s in custom: #Проверка каждого элемента
		if float(s.time) > 0 and time.time() >= float(s.time) + 86400:
			test(s.value, i)
		i = i + 1
	threading.Timer(60.0, go).start() #Новый старт таймера

def informing(msg , addition = "", error = False):
	if not error:
		logging.info(msg + addition)
	else:
		logging.error(msg + addition)
	if(sys.platform == 'linux'):
		s.call(['notify-send', msg,'FesteloBot'])
	print(msg + addition)

#������ ���������: ������ ����������
atexit.register(exit_handler)
namespace = createParser().parse_args(sys.argv[1:]) #Парсер аргументов
checkArgs = False
logging.basicConfig(format = u'%(filename)s# %(levelname)-8s [%(asctime)s]  %(message)s', level = logging.DEBUG, filename = path+ "/logfile.log")
arguments = ""
for i in sys.argv[1:]:
	arguments += i + " "
logging.info( 'Script was launched. Args: ' + arguments)

if namespace.new != None:
	checkArgs = True
	try:
		print("\nПроцесс может занять некоторое время, в зависимости от скорости вашего интернет-соединения\n")
		okda = True
		data = []
		for s in namespace.new:
			a = checkAkk(s)
			if a != 1 and a != 2:
				data.append(a)
			else:
				print("Произошли ошибки в процессе добавления Cookie, измените запрос и/или повторите попытку позже.\nCookie: " + s)
				okda = False
				break
		if okda:
			app_xml = parse(path + "/data.xml")
			i = 0
			for s in namespace.new:
				newCo = app_xml.createElement("Cookie")
				a = time.strptime(data[i][2], "%a %b %d %Y %H:%M:%S")
				b = time.mktime(a)
				c = b - time.altzone + 86400
				newCo.setAttribute("time", str(c))
				newCo.appendChild(app_xml.createTextNode(s))
				app_xml.childNodes[0].appendChild(newCo)
				print("Добавлен COOKIE: Nick: {} | Balance: {} | Reward Date: {} UTC".format(data[i][0], data[i][1], data[i][2]))
				logging.info( u'Cookie ' +  s + 'was added #' + i)
				i = i + 1
			res = open(path + "/data.xml", "w")
			app_xml.childNodes[0].writexml(res)
			res.close()
			#if len(namespace.new) == 1:
			#	print("\nДобавлен Cookie:: " + namespace.new[0])
			#else:
			#	print("\nДобавлены Cookie:s: " + format(len(namespace.new)))
	except IOError:
		DataMake()

if namespace.run != None:
	checkArgs = True
	custom = refrCookieList()
	if int(namespace.run[0]) >= len(custom) or int(namespace.run[0]) < 0:
		print("Ашибка")
	else:
		test(custom[int(namespace.run[0])].value, int(namespace.run[0]))
		logging.info( u'Cookie ' +  int(namespace.run[0]) + 'run manually')

if namespace.info != None:
	checkArgs = True
	custom = refrCookieList()
	i = int(namespace.info[0])
	if i >= len(custom) or i < 0:
		print("Ашибка")
	else:
		a = checkAkk(custom[int(namespace.info[0])].value)
		if a != 1 and a != 2:
			print(namespace.info[0] + ": Nick: {} | Balance: {} | Reward Date: {} UTC".format(a[0], a[1], a[2]))

if namespace.remove != None:
	checkArgs = True
	dom = parse(path + "/data.xml")
	custom = refrCookieList()
	outdate = refrCookieList(1)
	if int(namespace.remove[0]) >= len(custom) + len(outdate) or int(namespace.remove[0]) < 0:
		print("Ашибка")
		exit(0)
	else:
		if(int(namespace.remove[0]) >= len(custom)):
			dom.childNodes[0].removeChild(dom.childNodes[0].getElementsByTagName('OUTDATE')[int(namespace.remove[0]) - len(custom)])
		else:
			dom.childNodes[0].removeChild(dom.childNodes[0].getElementsByTagName('Cookie')[int(namespace.remove[0])])
		logging.info( u'Cookie ' +  int(namespace.remove[0]) + 'was removed')
		res = open(path + "/data.xml", "w")
		dom.childNodes[0].writexml(res)
		res.close()

if namespace.list:
	checkArgs = True
	custom = refrCookieList()
	i = 0
	for s in custom:
		date = time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime(float(custom[i].time)))
		print("\n{}: Recent action: {} UTC\nValue: {}".format(i, date, custom[i].value))
		i = i + 1
	outdate = refrCookieList(1)
	for s in outdate:
		date = time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime(float(outdate[i - len(custom)].time)))
		print("\n{}: OUTDATE!! Recent action: {}(sste)\nValue: {}".format(i, date, outdate[i - len(custom)].value))
		i = i + 1
#�����
#path = "/home/" + os.getlogin() + "/festeloApp/"
#test()
if not checkArgs:
	logging.info( u'Script starting')
	go()


## 最大自序和
## 动态规划：计算前i项和，与0比较，若小于0，则从第i项开始重新计算自序，否则继续

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        i = 1
        for i in range(1, len(nums)):
            nums[i] = max(nums[i-1], 0) + nums[i]
        return max(nums)


import torch
import torchaudio
import matplotlib.pyplot as plt
from function.play_signal import play_signal
from function.get_noise import get_noise
from dataset import AudioDataset
import numpy as np
from model_demo import Denoiser
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader

#IMPORT SIGNAL

file_path = "examples\data_dir\MIDI-Unprocessed_01_R1_2006_01-09_ORIG_MID--AUDIO_01_R1_2006_02_Track02_wav.wav"
signal, sample_rate = torchaudio.load(file_path)

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

#ADD NOISE

SNR = 20
noise = get_noise(signal,SNR)

for i in range(1):
    if(i ==0):
        signal_noise = signal + noise

    signal_noise = signal_noise + noise

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

#DENOISER

denoiser_model = Denoiser()

#denoiser_model = torch.load("trained_model/trained_model.pht")
#denoiser_model.eval()

n_fft = 512

spectrogram = torchaudio.transforms.Spectrogram(n_fft=n_fft)(signal)

noisy_spectrogram = torchaudio.transforms.Spectrogram(n_fft=n_fft)(signal_noise)

# Trénovanie autoencodéra pre úpravu spektrogramov
criterion = nn.MSELoss()
optimizer = optim.Adam(denoiser_model.parameters(), lr=0.001)

# Uchováva stratu počas trénovania
losses = []

num_epochs = 10

for epoch in range(num_epochs):
    # Predikcia a výpočet chyby
    output_spectrogram = denoiser_model(noisy_spectrogram)
    loss = criterion(output_spectrogram, spectrogram)

    # Spätná propagácia a aktualizácia váh
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    losses.append(loss.item())

    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

# Predikcia denoised spektrogramu pomocou natrénovaného denoisera
with torch.no_grad():
    denoised_spectrogram = denoiser_model(noisy_spectrogram)

# Vizualizácia pôvodného, zašumeného a denoised spektrogramu
plt.figure(figsize=(18, 12))

plt.subplot(3, 1, 1)
plt.imshow(torch.log(spectrogram[0] + 1e-9).numpy(), aspect='auto', origin='lower')
plt.title('Original Spectrogram')

plt.subplot(3, 1, 2)
plt.imshow(torch.log(noisy_spectrogram[0] + 1e-9).numpy(), aspect='auto', origin='lower')
plt.title('Noisy Spectrogram')

plt.subplot(3, 1, 3)
plt.imshow(torch.log(denoised_spectrogram[0] + 1e-9).numpy(), aspect='auto', origin='lower')
plt.title('Denoised Spectrogram')

plt.show()

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

#rekonštruovanie signálu - in progress problém že do modelu hádžem realne čísla a výstup su tiež realne čísla, takže to neviem transformovať späť

""""
reconstructed_signal = torch.istft(denoised_spectrogram,n_fft)

signal = signal.numpy()
plt.subplot(2,1,1)
plt.plot(signal[0])
plt.title('Original signal')

reconstructed_signal =reconstructed_signal.numpy()
plt.subplot(2,1,2)
plt.plot(reconstructed_signal[0])
plt.title('Reconstructed signal')

plt.show()
"""

#rekonštrukcia signálu s použitím funkcie torchaudio.transforms

reconstructed_signal = torchaudio.transforms.GriffinLim(n_fft=n_fft)(denoised_spectrogram)
signal_1 = signal.numpy()
plt.subplot(2,1,1)
plt.plot(signal_1[0])
plt.title('Original signal')

signal_new_1 = reconstructed_signal.numpy()
plt.subplot(2,1,2)
plt.plot(signal_new_1[0])
plt.title('transformed signal')

plt.show()


"""Buildbot module that handles communications between the Buildbot and
GitHub."""

from config import cfg

import events
import utils

import collections
import json
import logging
import os
import os.path
import queue
import re
import requests
import uuid

def make_netstring(s):
    """Creates a netstring from a blob of bytes."""
    return str(len(s)).encode('ascii') + b':' + s + b','

def make_build_request(repo, pr_id, job_id, baserev, headrev, patch, who,
                       comment):
    """Creates a build request binary blob in the format expected by the
    buildbot."""

    request_dict = {
        'branch': '',
        'builderNames': cfg.buildbot.pr_builders,
        'jobid': job_id,
        'baserev': baserev,
        'patch_level': 1,
        'patch_body': patch,
        'who': who,
        'comment': comment,
        'properties': {
            'branchname': 'pr-%d' % pr_id,
            'headrev': headrev,
            'shortrev': headrev[:6],
            'pr_id': pr_id,
            'repo': repo,
        },
    }
    encoded = json.dumps(request_dict, ensure_ascii=True).encode('ascii')
    version = make_netstring(b'5')
    return version + make_netstring(encoded)

def send_build_request(build_request):
    """Stores the build request (atomically) in the buildbot jobdir."""

    path = os.path.join(cfg.buildbot.jobdir, 'tmp', str(uuid.uuid4()))
    open(path, 'wb').write(build_request)
    final_path = os.path.join(cfg.buildbot.jobdir, 'new', str(uuid.uuid4()))
    os.rename(path, final_path)
    logging.info('Sent build request: %r', final_path)

class PullRequestBuilder:
    def __init__(self):
        self.queue = queue.Queue()

    def push(self, in_behalf_of, trusted, repo, pr_id):
        self.queue.put((in_behalf_of, trusted, repo, pr_id))

    def run(self):
        while True:
            in_behalf_of, trusted, repo, pr_id = self.queue.get()

            # To check if a PR is mergeable, we need to request it directly.
            pr = requests.get('https://api.github.com/repos/%s/pulls/%d'
                    % (repo, pr_id)).json()
            logging.info('PR %s mergeable: %s (%s)', pr_id, pr['mergeable'],
                    pr['mergeable_state'])

            base_sha = pr['base']['sha']
            head_sha = pr['head']['sha']

            if not trusted:
                status_evt = events.PullRequestBuildStatus(repo, head_sha,
                        'default', 'failure', '',
                        'PR not built because %s is not auto-trusted.'
                            % in_behalf_of)
                events.dispatcher.dispatch('prbuilder', status_evt)
                continue

            # mergeable can be None!
            if pr['mergeable'] is False:
                status_evt = events.PullRequestBuildStatus(repo, head_sha,
                        'default', 'failure', '',
                        'PR cannot be merged, please rebase.')
                events.dispatcher.dispatch('prbuilder', status_evt)
                continue

            status_evt = events.PullRequestBuildStatus(repo, head_sha,
                        'default', 'success', '',
                        'Very basic checks passed, handed off to Buildbot.')
            events.dispatcher.dispatch('prbuilder', status_evt)

            for builder in cfg.buildbot.pr_builders:
                status_evt = events.PullRequestBuildStatus(repo, head_sha,
                        builder, 'pending', cfg.buildbot.url + '/waterfall',
                        'Auto build in progress')
                events.dispatcher.dispatch('prbuilder', status_evt)

            patch = requests.get('https://github.com/%s/pull/%d.patch'
                                 % (repo, pr_id)).text
            req = make_build_request(repo, pr_id,
                    '%d-%s' % (pr_id, head_sha[:6]), base_sha,
                    head_sha, patch,
                    'Central (on behalf of: %s)' % in_behalf_of,
                    'Auto build for PR #%d (%s).' % (pr_id, head_sha))
            send_build_request(req)

class PullRequestListener(events.EventTarget):
    """Listens for new or synchronized pull requests and starts a new build."""

    def __init__(self, builder):
        super(PullRequestListener, self).__init__()
        self.builder = builder

    def accept_event(self, evt):
        return evt.type == events.GHPullRequest.TYPE

    def push_event(self, evt):
        if evt.action == 'opened' or evt.action == 'synchronize':
            if evt.repo in cfg.github.maintain:
                self.builder.push(evt.author, evt.safe_author, evt.repo,
                                  evt.id)

class ManualPullRequestListener(events.EventTarget):
    """Listens for comments from trusted users on PRs for a keyword to build
    a PR from an untrusted user."""

    def __init__(self, builder):
        super(ManualPullRequestListener, self).__init__()
        self.builder = builder

    def accept_event(self, evt):
        return evt.type == events.GHIssueComment.TYPE

    def push_event(self, evt):
        if not evt.safe_author:
            return
        if cfg.github.rebuild_command.lower() not in evt.body.lower():
            return
        if evt.repo not in cfg.github.maintain:
            return
        self.builder.push(evt.author, evt.safe_author, evt.repo, evt.id)

class IRCRebuildListener(events.EventTarget):
    """Listen for rebuild commands on IRC."""

    def __init__(self, builder):
        super(IRCRebuildListener, self).__init__()
        self.builder = builder

    def accept_event(self, evt):
        return evt.type == events.IRCMessage.TYPE

    def push_event(self, evt):
        trusted = 'o' in evt.modes
        if not evt.direct or not trusted:
            return
        matches = re.search(r'\brebuild (pr ?)?(?P<pr_id>\d+)\b', evt.what, re.I)
        if not matches:
            return
        pr_id = matches.group('pr_id')
        try:
            pr_id = int(pr_id)
        except ValueError:
            return
        self.builder.push(evt.who, trusted, cfg.irc.rebuild_repo, pr_id)

class BuildStatusCollector:
    def __init__(self):
        self.queue = queue.Queue()

    def push(self, evt):
        self.queue.put(evt)

    def run(self):
        while True:
            evt = self.queue.get()
            builder = evt.payload.build.builderName
            props = { a: b for (a, b, _) in evt.payload.build.properties }
            has_all_required = True
            for required in ('headrev', 'repo', 'buildnumber', 'pr_id'):
                if required not in props:
                    has_all_required = False
                    break  # Not PR build.
            if not has_all_required:
                continue
            headrev = props['headrev']
            repo = props['repo']
            buildnumber = props['buildnumber']
            pr_id = props['pr_id']
            success = evt.payload.results in (0, 1)  # SUCCESS/WARNING

            if builder in cfg.buildbot.pr_builders:
                url = cfg.buildbot.url + '/builders/%s/builds/%s' % (
                        builder, buildnumber)

                if not success:
                    evt = events.PullRequestBuildStatus(repo, headrev, builder,
                            'failure', url,
                            'Build failed on builder %s' % builder)
                    events.dispatcher.dispatch('buildbot', evt)
                else:
                    evt = events.PullRequestBuildStatus(repo, headrev, builder,
                            'success', url, 'Build succeeded on the Buildbot.')
                    events.dispatcher.dispatch('buildbot', evt)
            elif builder in cfg.buildbot.fifoci_builders and success:
                evt = events.PullRequestFifoCIStatus(
                        repo, headrev, builder, pr_id)
                events.dispatcher.dispatch('buildbot', evt)

class BBHookListener(events.EventTarget):
    def __init__(self, collector):
        super(BBHookListener, self).__init__()
        self.collector = collector

    def accept_event(self, evt):
        return evt.type == events.RawBBHook.TYPE

    def push_event(self, evt):
        if evt.bb_type == 'buildFinished':
            self.collector.push(evt.raw)

def start():
    """Starts all the Buildbot related services."""

    pr_builder = PullRequestBuilder()
    events.dispatcher.register_target(PullRequestListener(pr_builder))
    events.dispatcher.register_target(ManualPullRequestListener(pr_builder))
    events.dispatcher.register_target(IRCRebuildListener(pr_builder))
    utils.DaemonThread(target=pr_builder.run).start()

    collector = BuildStatusCollector()
    events.dispatcher.register_target(BBHookListener(collector))
    utils.DaemonThread(target=collector.run).start()


import io, os, sys

if 'PyPy' in sys.version:
    input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
    def strput():
        return input().decode()
else:
    input = sys.stdin.readline
    def strput():
        return input()

# code starts here

class Fenwick:
    size = 0
    bit = []

    def __init__(self, n):
        for i in range(n + 1):
            self.bit.append(0)
        self.size = n

    def update(self, pos, val):
        u = pos
        while u <= self.size:
            self.bit[u] += val
            u += u & (-u)

    def get(self, pos):
        res, u = 0, pos
        while u > 0:
            res += self.bit[u]
            u -= u & (-u)
        return res

def main():
    n = int(input())
    pos = [-1]
    hgt = [-1]
    for i in range(1, n + 1):
        p, h = [int(x) for x in input().split()]
        pos.append(p)
        hgt.append(h)

    q = int(input())
    ans = [0 for x in range(q)]
    query = [[] for x in range(n + 1)]
    for i in range(1, q + 1):
        l, r = [int(x) for x in input().split()]
        query[l].append((r, i))

    stack = []
    tree = Fenwick(n)
    for i in range(n, 0, -1):
        while len(stack) > 0:
            top = stack[-1]
            if pos[top] > pos[i] + hgt[i]:
                need = pos[top] - pos[i] - hgt[i]
                tree.update(top, min(0, need - tree.get(top) + tree.get(top - 1)))
                break
            tree.update(top, - tree.get(top) + tree.get(top - 1))
            stack.pop()

        stack.append(i)
        for j in query[i]:
            ans[j[1] - 1] = tree.get(j[0])
        tree.update(i, pos[i] - pos[i - 1])

    print('\n'.join(map(str, ans)))

if __name__ == "__main__":
    main()


import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVR
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error, median_absolute_error, precision_score, recall_score, f1_score
from time import time
import numpy as np
from sklearn.preprocessing import LabelEncoder

df = pd.read_csv('Final Data.csv')

df_melt = df.melt(id_vars='Name Of District', var_name='Year-Gender-Class', value_name='Value')

df_melt[['Year', 'Gender', 'Class']] = df_melt['Year-Gender-Class'].str.split('-', expand=True)

df_melt['Year'] = df_melt['Year'].astype(int)

X = df_melt[['Year', 'Gender', 'Class', 'Name Of District']]
y = df_melt['Value']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

le_gender = LabelEncoder()
le_district = LabelEncoder()

X_train['Gender'] = le_gender.fit_transform(X_train['Gender'])

X_train['Name Of District'] = le_district.fit_transform(X_train['Name Of District'])

X_test['Gender'] = le_gender.transform(X_test['Gender'])

X_test['Name Of District'] = le_district.transform(X_test['Name Of District'])

models = [

    ("Random Forest", RandomForestRegressor(), 33),
]

results = []

for name, model, params in models:
    start_time = time()
    model.fit(X_train, y_train)
    training_time = round(time() - start_time, 2)
    y_pred = model.predict(X_test)
    y_train_pred = model.predict(X_train)
    results.append({
        "Model": name,
        "Accuracy": model.score(X_test, y_test),
        "MAE": mean_absolute_error(y_test, y_pred),
        "MSE": mean_squared_error(y_test, y_pred),
        "RMSE": np.sqrt(mean_squared_error(y_test, y_pred)),
        "R-SQ": r2_score(y_test, y_pred),
        "MedAE": median_absolute_error(y_test, y_pred),
        "Number of Parameters": params
    })

results_df = pd.DataFrame(results)
print(results_df)

new_data = pd.DataFrame({
    'Year': [2026],
    'Gender': ['Boys'],
    'Class': ['9'],
    'Name Of District': ['Ahmadabad']
})

new_data['Gender'] = le_gender.transform(new_data['Gender'])
new_data['Name Of District'] = le_district.transform(new_data['Name Of District'])

for name, model, params in models:
    prediction = model.predict(new_data)
    print(f"The prediction for 2020 Boys class 9 in Ahmedabad using {name} is {prediction}")

Student Dropout Analysis For School Education Model.py


'''
Whenever George asks Lily to hang out, she's busy doing homework. George wants to help her finish it faster, but he's in over his head! Can you help George understand Lily's homework so she can hang out with him?

Consider an array of
distinct integers, . George can swap any two elements of the array any number of times. An array is beautiful if the sum of among

is minimal.

Given the array

, determine and return the minimum number of swaps that should be performed in order to make the array beautiful.

For example,
. One minimal array is

. To get there, George performed the following swaps:

Swap      Result
      [7, 15, 12, 3]
3 7   [3, 15, 12, 7]
7 15  [3, 7, 12, 15]

It took

swaps to make the array beautiful. This is minimal among the choice of beautiful arrays possible.

Function Description

Complete the lilysHomework function in the editor below. It should return an integer that represents the minimum number of swaps required.

lilysHomework has the following parameter(s):

    arr: an integer array

Input Format

The first line contains a single integer,
, the number of elements in . The second line contains space-separated integers

.

Constraints

Output Format

Return the minimum number of swaps needed to make the array beautiful.

Sample Input

4
2 5 3 1

Sample Output

2

Explanation

Let's define array
to be the beautiful reordering of . The sum of the absolute values of differences between its adjacent elements is minimal among all permutations and only two swaps ( with and then with ) were performed.

'''

# Complete the lilysHomework function below.
def lilysHomework(arr):
    arrD = arr.copy()
    ascend = arr.copy()
    descend = arr.copy()
    ascend.sort()
    descend.sort(reverse = True)

    dicA, dicD = {},{}
    swapsA, swapsD = 0,0
    for i in range(len(arr)):
        dicA[arr[i]] = i
        dicD[arr[i]] = i
    for i in range(len(arr)):
        if(arr[i] != ascend[i]):
            index = dicA[ascend[i]]#get index of swap location
            dicA[ascend[i]] = i #swap the indexes of the two keys
            dicA[arr[i]] = index
            temp = arr[i]
            arr[i] = arr[index]
            arr[index] = temp
            swapsA += 1
        if(arrD[i] != descend[i]):
            index = dicD[descend[i]]#get index of swap location
            dicD[descend[i]] = i #swap the indexes of the two keys
            dicD[arrD[i]] = index
            temp = arrD[i]
            arrD[i] = arrD[index]
            arrD[index] = temp
            swapsD += 1
    if(swapsA > swapsD):
        return swapsD
    else:
        return swapsA

print(lilysHomework([3,4,2,5,1]))

'''
Original Attempt

swaps: int = 0
    abs_min = 0
    new_abs_min = -1
    index = 0 # right index of the differnce pair
    diff = 0
    while(new_abs_min < abs_min):
        big_diff = -1
        new_abs_min = 0
        abs_min = 0
        for i in range(len(arr)-1):
            diff = abs(arr[i]-arr[i+1])
            abs_min += diff
            if(diff > big_diff):
                index = i+1
                big_diff = diff
        swap_index = index
        min_diff = big_diff

        diff = abs(arr[index]-arr[1])
        if(diff < min_diff):
            min_diff = diff
            swap_index = i
        for i in range(1,len(arr)-1):
            if(i != index):
                diff = abs(arr[index]-arr[i+1])
                if(diff < min_diff):
                    min_diff = diff
                    swap_index = i
        if(swap_index != index):
            temp = arr[swap_index]
            arr[swap_index] = arr[index]
            arr[index] = temp
            swaps += 1

        for i in range(len(arr)-1):
            diff = abs(arr[i]-arr[i+1])
            new_abs_min += diff
    return (swaps-1)

Second Attempt

    ascend = arr.copy()
    swapsA, swapsD = 0,0
    indexA, indexD = 0, len(arr)-1
    for i in range(len(arr)):
        minA, maxD = ascend[i], arr[len(arr)-i-1]
        for j in range(i,len(arr)):
            if(ascend[j] < minA):#small to big
                minA = ascend[j]
                indexA = j
            if(arr[len(arr)-j-1] > maxD):#big to small
                maxD = arr[len(arr)-j-1]
                indexD = len(arr)-j-1
        if(minA != ascend[i]):
            temp = ascend[i]
            ascend[i] = ascend[indexA]
            ascend[indexA] = temp
            swapsA += 1
        if(maxD != arr[len(arr)-i-1]):
            temp = arr[i]
            arr[i] = arr[len(arr)-i-1]
            arr[len(arr)-i-1] = temp
            swapsD += 1
    if(swapsA > swapsD):
        return swapsD
    else:
        return swapsA
'''


import pandas as pd
import numpy as np
import os
from datetime import datetime, date
from tqdm import tqdm

tqdm.pandas()

if os.name =='nt':
    df_path = r"D:\Coding_pratice\_Data\GalaxyEducation\ICK"
else:
    df_path = '/Users/admin/_Work/Data/icanKID'

# df_User = pd.read_csv(
#     os.path.join(df_path,'df_User.csv')
#     )
df_User = pd.read_csv(
    os.path.join(df_path,'df_User_Child_DeviceBrand.csv')
    )
df_Engagement = pd.read_csv(
    os.path.join(df_path, 'df_Engagement.csv')
    )
df_Engagement_updated = pd.read_csv(
os.path.join(df_path, 'df_Engagement_updated.csv')
    )
df_Payment = pd.read_csv(
    os.path.join(df_path, 'df_Payment.csv')
    )
df_fake_user = pd.read_csv(
    os.path.join(df_path, 'df_fake_paid_users.csv')
    )

# Discard fake user
df_User = df_User[~df_User['UserID'].isin(df_fake_user['UserID'])]
df_Engagement = df_Engagement[~df_Engagement['UserID'].isin(df_fake_user['UserID'])]
df_Payment = df_Payment[~df_Payment['UserID'].isin(df_fake_user['UserID'])]

# Get user's Age
df_User['monthBday'] = pd.to_datetime(df_User.ChildBday).dt.month
df_User['Age'] = (pd.to_datetime(date.today()) - pd.to_datetime(df_User.ChildBday)).astype('<m8[Y]').astype('int')

def day_of_week_func(x):
    """
        Input: Normal date

        Return: Day in week
    """
    # Why don't need .dt if apply to Series
    # https://stackoverflow.com/questions/62803633/timestamp-object-has-no-attribute-dt#_=_
    x = pd.to_datetime(x).dayofweek
    day_of_week = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    dict_dayofweek = {i:v for i,v in enumerate(day_of_week)}

    return dict_dayofweek[x]

def slope_function(x, y):
    # x: Timeseries
    # y: Datapoint
    n = len(x)
    x_sum = np.sum(x)
    y_sum = np.sum(y)
    xy_sum = np.sum(x*y)
    x2_sum = np.sum(x**2)

    denominator = n * x2_sum - x_sum**2
    if denominator == 0:
        return 0

    else:
        return (n * xy_sum - x_sum * y_sum) / (n * x2_sum - x_sum**2)

def slope_function_2(x, y):
    x_mean = np.mean(x)
    y_mean = np.mean(y)
    sx = np.std(x, ddof=1)
    sy = np.std(y, ddof=1)
    denominator = (len(x) * sx * sy)

    if denominator == 0:
        return 0
    else:
        r = np.sum((x - x_mean) * (y - y_mean)) / (len(x) * sx * sy)
        m = r * (sy / sx)
        return m

def accumulate_func(Series_values:pd.Series, take_abs:int):
    if take_abs:
        accumulate = lambda x,y: np.abs(x-y)
    else:
        accumulate = lambda x,y: x-y

    return ([
        accumulate(Series_values.iloc[i], Series_values.iloc[i-1]) for i in range(1, len(Series_values))
        ] if len(Series_values) > 1 else [0])

def interest_rate(Engagement, userID):
    usedDay_column = 'usedDays'
    if usedDay_column in Engagement.columns:
        pass
    else:
        usedDay_column = 'nth_day_from_registration'

    temp = Engagement[Engagement.UserID == userID].sort_values(by=usedDay_column)
    UserID_df = temp[['UserID']].head(1).reset_index(drop=True)
    temp['interest'] = temp['UsageTime'] * temp['Records']

    temp_check = temp.groupby('ActionType')['interest'].agg(
        total_interest=lambda x: sum(x),
        average_interest=lambda x: np.mean(x),
        # accumulate_inc_avg=lambda x: np.mean([
        #     x.iloc[i] - x.iloc[i-1] if (i != 0) and (x.iloc[i] - x.iloc[i-1]) > 0 else 0 for i in range(1, len(x))]),
        # accumulate_dec=lambda x: sum([
        #     x.iloc[i] - x.iloc[i-1] if (i != 0) and (x.iloc[i] - x.iloc[i-1]) < 0 else 0 for i in range(len(x))]),
        # total_accumulate_avg=lambda x: np.mean(accumulate_func(x, True)),
        accumulate=lambda x: np.sum(accumulate_func(x, False)),

    ).reset_index()

    grouped = temp.groupby('ActionType')
    # temp_check_2 = grouped.agg(
    #     Slope=pd.NamedAgg(
    #         column='interest',
    #         aggfunc=lambda x: slope_function(
    #             grouped[usedDay_column].get_group(x.name),
    #             x
    # ))).reset_index()

    temp_check_3 = grouped.agg(
        Slope_2=pd.NamedAgg(
            column='interest',
            aggfunc=lambda x: slope_function_2(
                grouped[usedDay_column].get_group(x.name),
                x
    ))).reset_index()

    # temp_check = pd.merge(temp_check, temp_check_2, on='ActionType')
    temp_check = pd.merge(temp_check, temp_check_3, on='ActionType')

    # To tell if the recent activity increase or decrease throughout the span of 't' days
    # Value range between [-1,1], with 0 as no trend (only 1 day of active)
    temp_check.reset_index(inplace=True, drop=True)
    temp_check['Slope_norm'] = temp_check['Slope_2'] / temp_check['average_interest']
    # display(temp_check)

    temp_check.drop(
        columns=['Slope_2'],
        inplace=True)

    most_active = temp_check.iloc[[temp_check['total_interest'].idxmax()]].reset_index(drop=True)
    most_accumulate = temp_check.iloc[[temp_check['accumulate'].idxmax()]].reset_index(drop=True)

    most_active.fillna(0, inplace=True)
    most_active.drop(columns=['accumulate','average_interest'], inplace=True)
    most_accumulate.fillna(0, inplace=True)
    most_accumulate.drop(columns=['total_interest', 'average_interest'], inplace=True)

    most_active.rename(columns={
        "ActionType": "MostInterest",
        "total_interest": "TotalInterestRatio",
        "Slope_norm": "InterestTrend"
    },inplace=True)

    most_accumulate.rename(columns={
        "ActionType": "MostAccumulate",
        "accumulate": "TotalAccuRatio",
        "Slope_norm": "AccuTrend"
    }, inplace=True)
    total_interest = temp_check['total_interest'].sum()
    total_accumulate = np.sum(np.abs(temp_check['accumulate']))

    if total_interest == 0:
        most_active['TotalInterestRatio'] = 0
    else:
        most_active['TotalInterestRatio'] = most_active['TotalInterestRatio'] / total_interest

    if total_accumulate == 0:
        most_accumulate['TotalAccuRatio'] = 0
    else:
        most_accumulate['TotalAccuRatio'] = most_accumulate['TotalAccuRatio'] / total_accumulate

    return pd.concat([UserID_df, most_active, most_accumulate], axis=1)

def create_dataframe(dataframes):
    df_User, df_Engagement, df_Payment = dataframes

    # Rebrand rarely used brand
    rep_brand = df_User['DeviceBrand'].value_counts()[
    df_User['DeviceBrand'].value_counts() < df_User['DeviceBrand'].value_counts().mean()].index.values
    df_User['DeviceBrand'] = df_User['DeviceBrand'].apply(lambda x: 'Other brand' if x in rep_brand else x)

    device_brand_df = pd.get_dummies(
            df_User[['UserID', 'DeviceBrand']],
            columns=['DeviceBrand'], prefix= '', prefix_sep=''
        )

    # Get total child
    print("Counting total children")
    total_child = df_User.groupby(by='UserID')[['ChildID']].nunique().reset_index()
    total_child.rename(
        columns={
            'ChildID':'TotalChild'
        }, inplace=True
    )

    # Get number of female and male children for each user
    print("Counting number of boy and girl seperate")
    no_fe_n_ma = df_User.pivot_table(index='UserID', columns='ChildGender', values='ChildID', aggfunc='count').reset_index()
    no_fe_n_ma.rename(
        columns={
            'female':'No.Female',
            'male': 'No.Male'
        }, inplace=True
    )
    no_fe_n_ma.fillna(0, inplace=True)

    # Get median age children
    print("Get median children age")
    age_child = df_User.groupby(by='UserID')[['Age']].median().reset_index()
    age_child.rename(
        columns={
            'Age':'MedianChildAge'
        }
    )

    # Rename certain columns to match with general database
    # df_Engagement['lastuse_byhour'] = df_Engagement['lastuse'].apply(lambda x: pd.to_datetime(x).strftime("%H:%M:%S"))
    df_Engagement.rename(
        columns={
            'open_time': 'Opentime',
            'payment_screen_time': 'PaymentScreenTime'
        }, inplace=True
    )

    # Acquire dataframe Engagement by condition
    # df_Engagement = df_Engagement[df_Engagement.nth_day_from_registration <=7]
    # df_Engagement = df_Engagement[condition]

    """
        Idea fromm: https://stackoverflow.com/questions/47360510/pandas-groupby-and-aggregation-output-should-include-all-the-original-columns-i
    """
    print("Obtain Users event base on condition")
    df_merge = df_Engagement.groupby(by=['UserID', 'EventDate', 'ActionType'], as_index=False).progress_apply(
        lambda x : x.sum() if ((x.dtypes=='int64') | (x.dtypes=='float64')).any() else x.head(1)
        )
    print('df_merge: \n',df_merge)
    # Retain labels and important features

    labels_df = df_merge[['UserID', 'cutoffDay', 'lateUser', 'Label']]

    # Create base df for merge
    print("Create base column for merge")
    based_df = df_Engagement.groupby('UserID', as_index=False).progress_apply(
        lambda x: x.head(1))[['UserID', 'UserJoinedDate']].reset_index(drop=True)
    print("Unique user: ", based_df.shape[0])

    # Total of Action/Events
    print("Get total Open time/Usage Time/Record/Payment screen time")
    total_merge = df_merge.groupby(by='UserID')[['Opentime', 'UsageTime', 'Records', 'PaymentScreenTime']].progress_apply(sum).reset_index()
    total_merge.rename(
        columns={'Opentime':'TotalOpentime', 'UsageTime':'TotalUsageTime',
                'Records':'TotalRecords', 'PaymentScreenTime': 'TotalPayscreentime'}, inplace=True
    )

    # Sum activity merge
    print('Get Open time/Usage Time/Record/Payment screen time base on Action type')
    activity_merge = pd.pivot_table(df_merge,
                                index='UserID',
                                columns='ActionType',
                                values=['Opentime', 'UsageTime', 'Records','PaymentScreenTime'],
                                aggfunc=np.sum)

    activity_merge.columns = ["".join((i,j.title())) for i,j in activity_merge.columns]
    activity_merge.reset_index(inplace=True)
    activity_merge.fillna(0, inplace=True)

    print("Get interest...")
    # map_func = np.vectorize(lambda x: interest_rate(df_Engagement, x))
    # interest_df = map_func(based_df['UserID'])
    interest_df = [interest_rate(df_Engagement, n) for n in tqdm(based_df['UserID'])]
    interest_df = pd.concat(interest_df, axis=0, ignore_index=True)

    print(interest_df)
    merge_dfs = [
        total_child, no_fe_n_ma, age_child, total_merge, activity_merge, interest_df, device_brand_df, labels_df
        ]

    print("Star merging....")
    for df in merge_dfs:
        df.reset_index(inplace=True, drop=True)
        based_df = based_df.merge(df, on='UserID', how='left')
        based_df.drop_duplicates(subset=['UserID'], keep='first', inplace=True, ignore_index=True)

    print("Total user with compress events: ", based_df.shape)
    return based_df

def getEvent_before_cutoff(df_events, cutOffDay=3):
    days_from_regis = df_events.groupby('UserID')[['nth_day_from_registration']].min().reset_index()
    days_from_regis.rename(
        columns={
            "nth_day_from_registration": "MinFirstDay"
        },inplace=True
    )
    days_from_regis['cutoffDay'] = days_from_regis.MinFirstDay + cutOffDay
    days_from_regis['lateUser'] = (days_from_regis['MinFirstDay'] > 0).astype(int)

    Engagement = df_events.merge(days_from_regis, on='UserID',how='left')
    Engagement = Engagement[
        (Engagement['cutoffDay'] - Engagement['nth_day_from_registration']) > 0
        ].reset_index(drop=True)
    Engagement['usedDays'] = Engagement['nth_day_from_registration'] - Engagement['MinFirstDay']
    return Engagement

def setLabel(df_events, df_Payment, markDay=30):
    df_events = df_events.merge(df_Payment[['UserID','gapday']], how='left', on='UserID')
    """
        If label = True -> User paid before markDay
        else -> Free user
    """
    df_events['Label'] = ((df_events['gapday'] - df_events['MinFirstDay']) <= markDay).astype(int)
    print("Total events with labels: ", df_events.shape)
    return df_events

Engagements = getEvent_before_cutoff(df_Engagement, cutOffDay=3)
Engagements = setLabel(Engagements, df_Payment, markDay=30)
list_dataframes = [
    df_User,
    Engagements,
    df_Payment
]
condition_df = create_dataframe(list_dataframes)
condition_df
print(condition_df)

save_path = os.path.join(
    df_path, "Dataset"
    )
os.makedirs(
    save_path, exist_ok=True
)
condition_df.to_csv(
    os.path.join(save_path, "3days_cutoff.csv"), index=False
)


# Naming convention
# Component ID = 'component-name-example'

import dash
import plotly
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table
from dash.exceptions import PreventUpdate
from dash_extensions import Download
import pandas as pd
from dash.dependencies import Input, Output, State
from app import app
from layouts import plots, cards, filters, tabs
from database import transforms as tf
import plotly.graph_objects as go

import io # Used for downloading csv file

from app import app

white_btn_style = {
    'background-color': '#e6e6e6'
    ,'color': 'black'
    ,'border-radius':'4px'
    ,'border': '1px solid #bbb'
    ,'height': '38px'
    ,'padding': '0 30px'
    #,'font-size': '11px'
}
blue_btn_style = {
    'background-color': '#007ace'
    ,'color': 'white'
    ,'border-radius':'4px'
    ,'border': '1px solid white'
    ,'height': '38px'
    ,'padding': '0 30px'
    #,'font-size': '11px'
}

#####################################################################################################################
####################################### Gauge App - Main Layout #####################################################
#####################################################################################################################

layout = html.Div([

    #######################################
    ########## Navigation Bar #############
    #######################################

    dbc.Row(
            [
            dbc.Col(
                [
                    filters.common_filters
                    ,filters.gauge_filters
                ]
                , width=2
                , style={
                    'margin-top':165
                    ,'margin-bottom':2200
                    #,'backgroundColor':'gray'
                }
            )
            #######################################
            ########## Current App Header #########
            #######################################
            ,dbc.Col(
                dbc.Row(
                    dbc.Col([
                        html.Div(
                            [html.H1('Food NA - Gauge Tracking System')]
                            ,style={'text-align':'center','margin-bottom':80}
                        )
                        #############################
                        ####### Gauges TABS ################
                        ,dbc.Row(html.Div(
                            [
                                dbc.Tabs(
                                    id='tabs-gauge'
                                    ,active_tab='tab-gauge-records'
                                    ,children=[
                                        dbc.Tab(label='Gauge Records', tab_id='tab-gauge-records')
                                        #,dbc.Tab(label='Add Gauge', tab_id='tab-add-gauge')
                                        ,dbc.Tab(label='Gauge Studies', tab_id='tab-gauge-studies')
                                        ,dbc.Tab(label='Gauge Capabilities', tab_id='tab-gauge-capabilities')
                                    ]
                                )
                                ,html.Div(
                                    id='tabs-gauge-content'
                                    ,style={'padding': '5px 5px 0px 5px'} # padding: Top,Right,Bottom,Left
                                )
                                ,html.Br()
                                # ,html.Div(
                                #     id='gauge-save-button-div'
                                #     ,children = html.Button(
                                #         'Save'
                                #         ,id='gauge-save-button'
                                #         #, style={'display', 'none'}
                                #         )
                                # )

                            ] )
                        ,style={
                            'margin-right':-5
                            ,'margin-left':10
                        }
                        )
                    ]
                    )
                )#, style={'backgroundColor':'gray'}
            )
    ], style={'margin-right':10,'margin-left':10, 'margin-top':0})
]
)

#####################################################################################################################
####################################### Callbacks ###################################################################
#####################################################################################################################

# Tabs callback
@app.callback(
    [
        Output('tabs-gauge-content', 'children')
        ,Output('tb-download-btn', 'children')
    ]
    ,[
        Input('tabs-gauge', 'active_tab') # dcc.Tabs
    ]
)
def tab_gauge_content(active_tab):
    if active_tab=='tab-gauge-records':
        download_btn = html.Div([html.Button("Download records", id="download-btn", style=white_btn_style), Download(id="download")])
        #print('tab_gauge_content')
        return tabs.gauge_table, download_btn
    # elif active_tab=='tab-add-gauge':
    #     return tabs.add_gauge_layout, html.Br()
    elif active_tab=='tab-gauge-studies':
        return html.H2('Gauge studies placeholder'), html.Br()
    elif active_tab=='tab-gauge-capabilities':
        return html.H2('Gauge capabilities placeholder'), html.Br()

# #Make table editable
# @app.callback(
#     [Output('gauge-table', 'editable')
#     ,Output('gauge-save-button', 'style')]
#     ,[Input('make-gauge-table-editable', 'value')]

# )
# def make_gauge_tbl_editable(value):
#     #print('make table editable')
#     if value == []:
#         style = {'display':'none'}
#         return False, style
#     elif value == ['Y']:
#         style = blue_btn_style
#         return True, style

# Gauge records filters
@app.callback(Output('gauge-table', 'data')
    ,[
        Input('plant', 'value')
        ,Input('gauge-manufacturer', 'value')
        ,Input('gauge-type', 'value')
        ,Input('gauge-due-soon', 'value')
    ]
)

def tb_gauge_filters(plant, mfg, g_type, due):
    filters_input = {'Plant': plant, 'Manufacturer':mfg, 'Type':g_type, 'Due Soon': due}
    filtered_dict = {k:v for k,v in filters_input.items() if len(v)!=0}
    #print('tb gauge filters')
    if len(filtered_dict)==0:
        return tf.df.to_dict('rows')
    else:
        filtered_table = tf.df.copy()
        for k,v in filtered_dict.items():
            filtered_table = filtered_table.loc[filtered_table[k].isin(v)]
        return filtered_table.to_dict('rows')

# Dynamic dropdown list (gauge filters)
@app.callback(
    [
        Output('gauge-manufacturer', 'options')
        ,Output('gauge-type', 'options')
    ]
    ,[
        Input('plant', 'value')
        ,Input('gauge-type', 'value')
    ]
)

def set_gauge_mfg_options(plant, gauge_type):
    #print('set gauge mfg options')
    if len(plant) == 0:

        mfg_options = tf.drop_options(tf.gauge_manufacturer)
        type_options = tf.drop_options(tf.gauge_types)
        return mfg_options, type_options
    else:
        # Gauge manufacturer dropdown options
        df_ = tf.df.loc[tf.df['Plant'].isin(plant)==True, ['Manufacturer', 'Type']]
        df_mfg = df_['Manufacturer'].dropna().unique()
        mfg_options = tf.drop_options(df_mfg)

        # Gauge type dropdown options
        df_type = df_['Type'].dropna().unique()
        type_options = tf.drop_options(df_type)

        return  mfg_options, type_options

# Download table (csv)
@app.callback(
    Output('download', 'data'),
    [
        Input('download-btn', 'n_clicks')
        ,Input('gauge-table', 'data')
    ]
)
def generate_csv(n_clicks, data):
    #print('generate csv')
    if n_clicks is not None and tf.current_clicks != n_clicks:
        s = io.StringIO()
        pd.DataFrame.from_dict(data).to_csv(s, index=False)
        content=s.getvalue()
        tf.current_clicks = n_clicks
        return dict(filename='data.csv', content=content, type='text/csv')

# #Update gauge records table with user edits
# @app.callback(
#     [
#         Output('table-updated', 'children')
#     ]
#     ,[

#         Input('gauge-table', 'active_cell')
#         ,Input('gauge-table', 'data')
#         ,Input('gauge-table', 'data_previous')
#         ,Input('make-gauge-table-editable', 'value')
#         ,Input('gauge-save-button', 'n_clicks')

#     ]
# )
# def update_gauge_table(active_cell, data, data_previous, editable, clicks):
#     #print('update gauge table') # - using this to troubleshoot missing output id warnings
#     if editable == ['Y']:
#         if active_cell is not None:
#             tf.changed_cells['row_id'].append(active_cell['row_id'])
#             tf.changed_cells['column_id'].append(active_cell['column_id'])
#             print(tf.changed_cells)
#         return ['tracking']
#     else:
#         return ['nothing tracked']

    # if clicks is None:
    #     updated_table = ['Not updated yet']
    #     return updated_table
    # else:


import os
import requests
from dotenv import load_dotenv

load_dotenv()
DISCORD_KEY = os.getenv('DISCORD_KEY')
RIOT_API_KEY = os.getenv('RIOT_API_KEY')

WORKING_DIR = os.getcwd()

PATHS = {
     'cwd':WORKING_DIR
    ,'help':os.path.join(WORKING_DIR,'helptext.txt')
    ,'version':os.path.join(WORKING_DIR, 'version.txt')
}

REQUEST_COUNT = 0

SEASONS = requests.get('http://static.developer.riotgames.com/docs/lol/seasons.json').json()
CURR_SEASON = SEASONS[-1]['id']

VERSION = {
     'summoner':'4'
    ,'match':'4'
    ,'clash':'1'
    ,'league':'4'
}

REGION = {
    'north_america':'NA1'
}

QUEUE_ID = {
    'clash':'700'
}

TEAM = {
    'sloppy_toppy':'926281'
}

URL = {
     'base':'https://{REGION}.api.riotgames.com/lol'
    ,'summoner_by_name':'/summoner/v{VER}/summoners/by-name/{queryval}' #summonername
    ,'summoner_by_id':'/summoner/v{VER}/summoners/{queryval}' #SummonerId
    ,'clash_match_by_account':'/match/v{VER}/matchlists/by-account/{queryval}'+'?queue={queue}'.format(queue=QUEUE_ID['clash']) #accountid
    ,'match_by_account':'/match/v{VER}/matchlists/by-account/{queryval}'+'?endIndex=50' #accountid
    ,'match_by_match':'/match/v{VER}/matches/{queryval}' #matchId
    ,'clash_by_team':'/clash/v{VER}/teams/{queryval}' #teamId
    ,'clash_by_summoner':'/clash/v{VER}/players/by-summoner/{queryval}' #summonerId
    ,'clash_tourn_by_team':'/clash/v{VER}/tournaments/by-team/{queryval}' #teamId
    ,'league_by_summoner':'/league/v{VER}/entries/by-summoner/{queryval}' #summonerId
    ,'dd_champion':'http://ddragon.leagueoflegends.com/cdn/10.9.1/data/en_US/champion.json'
}

CHAMP_JSON = requests.get(URL['dd_champion']).json()
CHAMP_DATA = CHAMP_JSON['data']
CHAMP_NAME_LOOKUP = {}
for champ in CHAMP_DATA:
    champ_id = int(CHAMP_DATA[champ]['key'])
    champ_name = CHAMP_DATA[champ]['name']
    CHAMP_NAME_LOOKUP.update({champ_id:champ_name})

#for item in CHAMP_NAME_LOOKUP:
    #print(item + ' ' + CHAMP_NAME_LOOKUP[item])


duration = int(input('Введите число в секундах: '))

day = duration // (60 * 60 * 24)
hour = duration // (60 * 60) - day * 24
minute = duration // 60 - hour * 60 - day * 24 * 60
second = duration % 60

if day:
    print(f'{day} дн, {hour} час, {minute} мин, {second} сек')

elif hour:
    print(f'{hour} час, {minute} мин, {second} секунд')
elif minute:
    print(f'{minute} мин, {second} секунд')
elif second:
    print(f'{second} секунд')


import streamlit as st
import pandas as pd
import numpy as np
import plotly_express as px
from PIL import Image
import seaborn as sns
st.set_option('deprecation.showPyplotGlobalUse', False)
# load model
import joblib

st.set_page_config(layout="wide")
st.title('ALONA: Allocation - Outcome - Anomali')
# pages = ['Home','Anomali','Allocation','Outcome']
# jump = st.sidebar.selectbox('Select Pages', pages)

menu = ['Anomali','Allocation & Outcome']
alona= Image.open('logo_alona.png')
st.sidebar.image(alona)
choice = st.sidebar.selectbox('Select Menu', menu)

if choice == "Allocation & Outcome":
    st.subheader("Budget Allocations and Prediction of Indexes")
    df = pd.read_excel('belanja_apbd_full.xlsx')
    new = df["nama_pemda"].str.split(" ", n = 1, expand = True)
    df["jenispemda"]= new[0]
    df["namapemda"]= new[1]
    # df.drop(columns =["nama_pemda"], inplace = True)
    df['wilayah'] = np.where(df['jenispemda'].str.contains("Provinsi"), "Provinsi", "Kab_Kota")
    p1, p2, p3 = st.beta_columns((4,0.5,4))
    with p1:
        wilayah = st.selectbox('Choose Region',['Provinsi','Kab_Kota'])
        if wilayah == 'Provinsi':
            df = df[df['wilayah'].isin(['Provinsi'])]
        else:
            df = df[df['wilayah'].isin(['Kab_Kota'])]
        lokasi = df['nama_pemda'].unique()
        kota = st.selectbox('Choose Local Government',lokasi)
        df = df[df['nama_pemda'].isin([kota])]
        df = df[df['Tahun'].isin([2019])]
        lybudget = df.sum(axis=1)
        pop = df['Populasi'].sum()
        base_ipm = df['Base_IPM'].sum()
        base_ahh = df['Base_AHH'].sum()
        base_hls = df['Base_HLS'].sum()
        base_rls = df['Base_RLS'].sum()
        base_ppk = df['Base_PPK'].sum()
        df['Total_Anggaran'] = df.sum(axis=1)
        ekvalue=df['Ekonomi']/df["Total_Anggaran"]
        ksvalue=df['Kesehatan']/df["Total_Anggaran"]
        ktvalue=df['Ketertiban']/df["Total_Anggaran"]
        lkvalue=df['Lingkungan']/df["Total_Anggaran"]
        pbvalue=df['ParBud']/df["Total_Anggaran"]
        plvalue=df['Pelayanan']/df["Total_Anggaran"]
        pdvalue=df['Pendidikan']/df["Total_Anggaran"]
        sovalue=df['Sosial']/df["Total_Anggaran"]
        fsvalue=df['Rumah_Fasum']/df["Total_Anggaran"]
    with p2:
        st.write("")
    with p3:
        # st.write(f"Total Populasi: {pop:.0f} (2019)")
        lytotal = st.text_input(label="Last Year Budget",value="Rp {:,.0f}".format(int(lybudget.values)))
        lypkp = st.text_input(label="Per Capita Budget",value="Rp {:,.0f}".format(int(lybudget.values/pop)))
        # perkapita = st.write(f"Anggaran Perkapita Akan Dialokasikan: {base/pop:.2f}")
    # with p3:
    #     st.write(" ")
    t1, t2 ,t3,t4= st.beta_columns((4,0.5,2,2))
    with t1:
        st.text_input(label="Total Population",value=int(pop))
        # st.write('(Populasi Penduduk Tahun 2019)')
    with t2:
        st.write(" ")
    with t3:
        # st.text_input(label="% Perubahan Anggaran: ",value=str(int(100*((base-lybudget.values)/lybudget.values)))+" %")
        # st.text_input(label="% Perubahan Perkapita: ",value=str(int(100*((base/pop-lybudget.values/pop)/lybudget.values/pop)))+" %")
        basechange = st.number_input(label="% Budget Adjustment",value=0,min_value=-100, max_value=100, step=5)
        allbase = int((basechange/100)*int(lybudget.values)+int(lybudget.values))
    with t4:
        # allbase = lybudget.values
        # alcpkp = lybudget.values/pop
        # base = st.number_input(label="Total Anggaran Akan Dialokasikan",value=allbase,min_value=0, max_value=1000000000000000)
#         base = st.number_input(label="Total Anggaran Akan Dialokasikan",value=allbase,min_value=0, max_value=1000000000000000,step=10000000000)
        base = int(allbase)
        st.text_input(label="Planned Budget",value="Rp {:,.0f}".format(base))
        # pkp = st.text_input(label="Anggaran Perkapita Akan Dialokasikan",value=alpkp)
    # perkapita = st.write(f"Anggaran Perkapita Akan Dialokasikan: {base/pop:.2f}")

    k1,k2,k3= st.beta_columns((4,0.5,4))
    with k1:
        st.write('(Population in 2019)')
    with k2:
        st.write(" ")
    with k3:
        perkapita = st.write("Planned Per Capita Budget: Rp {:,.0f}".format(int(base/pop)))

    c1, c2 ,c3, c4, c5= st.beta_columns((1,1,1,0.5,2))
    with c1:
        st.subheader("Last Year Budget Allocation")
        st.text_input(label="Ekonomi",value="Rp {:,.0f}".format(df['Ekonomi'].sum()))
        st.text_input(label="Kesehatan",value="Rp {:,.0f}".format(df['Kesehatan'].sum()))
        st.text_input(label="Ketertiban",value="Rp {:,.0f}".format(df['Ketertiban'].sum()))
        st.text_input(label="Lingkungan",value="Rp {:,.0f}".format(df['Lingkungan'].sum()))
        st.text_input(label="Pariwisata Budaya",value="Rp {:,.0f}".format(df['ParBud'].sum()))
        st.text_input(label="Pelayanan",value="Rp {:,.0f}".format(df['Pelayanan'].sum()))
        st.text_input(label="Pendidikan",value="Rp {:,.0f}".format(df['Pendidikan'].sum()))
        st.text_input(label="Sosial",value="Rp {:,.0f}".format(df['Sosial'].sum()))
        st.text_input(label="Rumah_Fasum",value="Rp {:,.0f}".format(df['Rumah_Fasum'].sum()))
    with c2:
        st.subheader("Allocated Budget Distribution (%)")
        a = st.number_input(label="Ekonomi",value=100*float(ekvalue.values),min_value=0.0, max_value=100.0, step=1.0)
        b = st.number_input(label="Kesehatan",value=100*float(ksvalue.values),min_value=0.0, max_value=100.0, step=1.0)
        c = st.number_input(label="Ketertiban",value=100*float(ktvalue.values),min_value=0.0, max_value=100.0, step=1.0)
        d = st.number_input(label="Lingkungan",value=100*float(lkvalue.values),min_value=0.0, max_value=100.0, step=1.0)
        e = st.number_input(label="Pariwisata Budaya",value=100*float(pbvalue.values),min_value=0.0, max_value=100.0, step=1.0)
        f = st.number_input(label="Pelayanan",value=100*float(plvalue.values),min_value=0.0, max_value=100.0, step=1.0)
        g = st.number_input(label="Pendidikan",value=100*float(pdvalue.values),min_value=0.0, max_value=100.0, step=1.0)
        h = st.number_input(label="Sosial",value=100*float(sovalue.values),min_value=0.0, max_value=100.0, step=1.0)
        i = st.number_input(label="Rumah_Fasum",value=100*float(fsvalue.values),min_value=0.0, max_value=100.0, step=1.0)

    with c3:
        st.subheader("Budget Allocated for Simulation")
        st.text_input(label="Ekonomi",value="Rp {:,.0f}".format(int(base*a/100)))
        st.text_input(label="Kesehatan",value="Rp {:,.0f}".format(int(base*b/100)))
        st.text_input(label="Ketertiban",value="Rp {:,.0f}".format(int(base*c/100)))
        st.text_input(label="Lingkungan",value="Rp {:,.0f}".format(int(base*d/100)))
        st.text_input(label="Pariwisata_Budaya",value="Rp {:,.0f}".format(int(base*e/100)))
        st.text_input(label="Pelayanan",value="Rp {:,.0f}".format(int(base*f/100)))
        st.text_input(label="Pendidikan",value="Rp {:,.0f}".format(int(base*g/100)))
        st.text_input(label="Sosial",value="Rp {:,.0f}".format(int(base*h/100)))
        st.text_input(label="Rumah_Fasum",value="Rp {:,.0f}".format(int(base*i/100)))

    with c4:
        st.write("")
    with c5:
        st.subheader("Index Change Prediction  \nBased on Machine-Learning Models")
        index = st.selectbox('Pilih Index',['IPM','AHH','HLS','RLS','PPK'])
        if index == "IPM":
            st.subheader("Base IPM Index")
            j = st.number_input(label="Base_IPM",value=base_ipm,min_value=0.0, max_value=100.0, step=1.0)
        elif index == "AHH":
            st.subheader("Base AHH Index")
            j = st.number_input(label="Base_AHH",value=base_ahh,min_value=0.0, max_value=100.0, step=1.0)
        elif index == "HLS":
            st.subheader("Base HLS Index")
            j = st.number_input(label="Base_HLS",value=base_hls,min_value=0.0, max_value=100.0, step=1.0)
        elif index == "RLS":
            st.subheader("Base RLS Index")
            j = st.number_input(label="Base_RLS",value=base_rls,min_value=0.0, max_value=100.0, step=1.0)
        elif index == "PPK":
            st.subheader("Base PPK Index")
            j = st.number_input(label="Base_PPK",value=base_ppk,min_value=0, max_value=30000, step=100)

        total = a+b+c+d+e+f+g+h+i
        # st.subheader("Total Alokasi Anggaran: "+str(total)+"%")
        st.subheader(f"Total Distributed Budget: {total:.2f} %")

        if index == "IPM":
            model= open("ipm_gb.pkl", "rb")
        elif index == "AHH":
            model= open("ahh_stack.pkl", "rb")
        elif index == "HLS":
            model= open("hls_knn.pkl", "rb")
        elif index == "RLS":
            model= open("rls_ridge.pkl", "rb")
        elif index == "PPK":
            model= open("ppk_stack.pkl", "rb")

        pkl=joblib.load(model)
        if st.button("Click to run Prediction"):
            a = (base/pop)*(a/100)
            b = (base/pop)*(b/100)
            c = (base/pop)*(c/100)
            d = (base/pop)*(d/100)
            e = (base/pop)*(e/100)
            f = (base/pop)*(f/100)
            g = (base/pop)*(g/100)
            h = (base/pop)*(h/100)
            i = (base/pop)*(i/100)
            dfvalues = pd.DataFrame(list(zip([a],[b],[c],[d],[e],[f],[g],[h],[i],[j])),columns =[
                    'Ekonomip',
                    'Kesehatanp',
                    'Ketertibanp',
                    'Lingkunganp',
                    'ParBudp',
                    'Pelayananp',
                    'Pendidikanp',
                    'Sosialp',
                    'Rumah_Fasump',
                    'Base_PPK',])
            input_variables = np.array(dfvalues[[
                    'Ekonomip',
                    'Kesehatanp',
                    'Ketertibanp',
                    'Lingkunganp',
                    'ParBudp',
                    'Pelayananp',
                    'Pendidikanp',
                    'Sosialp',
                    'Rumah_Fasump',
                    'Base_PPK']])
            prediction = pkl.predict(input_variables)
            nilai = j+float(prediction)
            st.title(f"Index Prediction: {nilai:.2f}")
            st.subheader(f"Index Change: {(nilai-j):.2f}")

elif choice == 'Anomali':
    st.subheader('Anomali Analysis in Budget Allocations')
    if st.checkbox("Exploratory Data Analysis"):
        # df = pd.read_csv('belanja_apbd.csv',sep=";",usecols=["nama_pemda","Tahun","Ekonomi","Kesehatan","Ketertiban","Lingkungan","ParBud","Pelayanan","Pendidikan","Sosial","Rumah_Fasum","Populasi"])
        # st.subheader('Automated Exploratory Data Analysis')
        df = pd.read_excel('belanja_apbd_full.xlsx')
        df.loc[:,'Total'] = df.sum(numeric_only=True, axis=1)
#         df = df.style.format("{:,.0f}")
        st.dataframe(df.style.format(subset=["Total","Ekonomi","Kesehatan","Ketertiban","Lingkungan","ParBud","Pelayanan","Pendidikan","Sosial","Rumah_Fasum","Populasi"],formatter="Rp {:,.0f}"))
        if st.checkbox('Show Shape'):
            st.write(df.shape)
        if st.checkbox('Show Summary'):
            st.write(df.describe())
        if st.checkbox('Correlation Matrix'):
            dfcor2 = df[['Base_IPM','Base_AHH','Base_HLS','Base_RLS','Base_PPK']]
            dfcor1 = df[["Ekonomi","Kesehatan","Ketertiban","Lingkungan","ParBud","Pelayanan","Pendidikan","Sosial","Rumah_Fasum"]]
            dfall = df[['Base_IPM','Base_AHH','Base_HLS','Base_RLS','Base_PPK',"Ekonomi","Kesehatan","Ketertiban","Lingkungan","ParBud","Pelayanan","Pendidikan","Sosial","Rumah_Fasum"]]
            z0, z1, z2 = st.beta_columns((1,1,1))
            with z0:
                st.write("Correlation Matrix of All Variables")
                st.write(sns.heatmap(dfall.corr(),annot=True,annot_kws={"size": 6}))
                st.pyplot()
            with z1:
                st.write("Correlation Matrix of Budget Functions")
                st.write(sns.heatmap(dfcor1.corr(),annot=True,annot_kws={"size": 10}))
                st.pyplot()
            with z2:
                st.write("Correlation Matrix of Index")
                st.write(sns.heatmap(dfcor2.corr(),annot=True,annot_kws={"size": 12}))
                st.pyplot()
        plot_type = st.selectbox('Select Type of Plot',["bar","line","area","hist","box"])
        all_columns = ["Total","Ekonomi","Kesehatan","Ketertiban","Lingkungan","ParBud","Pelayanan","Pendidikan","Sosial","Rumah_Fasum","Populasi"]
        pemda = st.multiselect('Choose Local Government',df['nama_pemda'])
        df["Tahun"] = df["Tahun"].astype(str)
        # tahun = st.selectbox('Pilih Tahun',[2019,2018])
        # df = df[df['Tahun'].isin([tahun])]
        selected_columns = st.selectbox('Select Column To Visualize', all_columns)
        # dimension = st.selectbox('Add Dimension', all_columns)
        if pemda == None or pemda ==[]:
            dfp = df
            color_value = dfp['nama_pemda']
            mode = 'stack'
            xbox = None
        else:
            dfp = df[df['nama_pemda'].isin(pemda)]
            color_value = dfp['nama_pemda']
            mode = 'group'
            xbox = dfp['nama_pemda']

        if plot_type == "bar":
            fig = px.bar(dfp,x='Tahun',y=selected_columns,color=color_value,barmode=mode)
            st.plotly_chart(fig)
        elif plot_type == "line":
            fig = px.line(dfp,x='Tahun',y=selected_columns,color=color_value)
            st.plotly_chart(fig)
        elif plot_type == "area":
            fig = px.area(dfp,x='Tahun',y=selected_columns,color=color_value)
        elif plot_type == "hist":
            fig = px.histogram(dfp, x=selected_columns)
            st.plotly_chart(fig)
        elif plot_type == "box":
            fig = px.box(dfp, y=selected_columns, x=xbox)
            st.plotly_chart(fig)
        elif plot_type:
            cust_plot = dfp[selected_columns].plot(kind=plot_type)
            st.write(cust_plot)
            st.pyplot()

    if st.checkbox("Budget Allocation vs Index Change Analysis"):
        # df = pd.read_csv('belanja_apbd.csv',sep=";")
        df = pd.read_excel('belanja_apbd_full.xlsx')
        df.loc[:,'Total_anggaran'] = df.sum(numeric_only=True, axis=1)
        st.subheader('Anomali Detection from Trends and Outliers Analysis ')
        index = st.selectbox('Choose Index',['IPM','AHH','HLS','RLS','PPK'])
        anggaran = st.selectbox('Choose Budget Function',["All","Ekonomi","Kesehatan","Ketertiban","Lingkungan","ParBud","Pelayanan","Pendidikan","Sosial","Rumah_Fasum"])
        pemda = st.multiselect('Choose Local Government',df['nama_pemda'].unique())
        df['TotalPerkapita'] = df['Total_anggaran']/df['Populasi']
        df['ek'] = df['Ekonomi']/df['Populasi']
        df['ks'] = df['Kesehatan']/df['Populasi']
        df['kt'] = df['Ketertiban']/df['Populasi']
        df['lk'] = df['Lingkungan']/df['Populasi']
        df['pb'] = df['ParBud']/df['Populasi']
        df['pl'] = df['Pelayanan']/df['Populasi']
        df['pd'] = df['Pendidikan']/df['Populasi']
        df['so'] = df['Sosial']/df['Populasi']
        df['fs'] = df['Rumah_Fasum']/df['Populasi']

        c1, c2 = st.beta_columns((1, 1))
        df["Tahun"] = df["Tahun"].astype(str)
        # st.write(pemda)
        with c1:
            if pemda == None or pemda ==[]:
                dfp = df
                msize=10
            else:
                dfp = df[df['nama_pemda'].isin(pemda)]
                msize=25

            if anggaran == "All":
                fig1 = px.scatter(dfp, x='nama_pemda', y='TotalPerkapita',color='Tahun')
            elif anggaran == "Ekonomi":
                fig1 = px.scatter(dfp, x='nama_pemda', y="ek",color='Tahun')
            elif anggaran == "Kesehatan":
                fig1 = px.scatter(dfp, x='nama_pemda', y="ks",color='Tahun')
            elif anggaran == "Ketertiban":
                fig1 = px.scatter(dfp, x='nama_pemda', y="kt",color='Tahun')
            elif anggaran == "Lingkungan":
                fig1 = px.scatter(dfp, x='nama_pemda', y="lk",color='Tahun')
            elif anggaran == "ParBud":
                fig1 = px.scatter(dfp, x='nama_pemda', y="pb",color='Tahun')
            elif anggaran == "Pelayanan":
                fig1 = px.scatter(dfp, x='nama_pemda', y='pl',color='Tahun')
            elif anggaran == "Pendidikan":
                fig1 = px.scatter(dfp, x='nama_pemda', y="pd",color='Tahun')
            elif anggaran == "Sosial":
                fig1 = px.scatter(dfp, x='nama_pemda', y="so",color='Tahun')
            elif anggaran == "Rumah_Fasum":
                fig1 = px.scatter(dfp, x='nama_pemda', y="fs",color='Tahun')

            fig1.update_traces(marker_size=msize, selector=dict(type='scatter'))
            st.plotly_chart(fig1)

        with c2:
            if pemda == None or pemda ==[]:
                dfp = df
                msize=10
            else:
                dfp = df[df['nama_pemda'].isin(pemda)]
                msize=25

            if index == "IPM":
                fig2 = px.scatter(dfp, x='nama_pemda', y='Base_IPM',color='Tahun')
            elif index == "AHH":
                fig2 = px.scatter(dfp, x='nama_pemda', y='Base_AHH',color='Tahun')
            elif index == "HLS":
                fig2 = px.scatter(dfp, x='nama_pemda', y='Base_HLS',color='Tahun')
            elif index == "RLS":
                fig2 = px.scatter(dfp, x='nama_pemda', y='Base_RLS',color='Tahun')
            elif index == "PPK":
                fig2 = px.scatter(dfp, x='nama_pemda', y='Base_PPK',color='Tahun')
            # fig2.update_layout(yaxis={'categoryorder':'total descending'})
            fig2.update_traces(marker_size=msize, selector=dict(type='scatter'))
            st.plotly_chart(fig2)


import math

from control.shapes import ControlSquare, ControlRectangle, Shape
from no_division.shapes import NoDivisionTriangle
from utilities import ConstructorSet

CIRCLE_CONSTANT = math.pi * 0.5 * 0.5

class PrecomputedConstCircle(Shape):
    def __init__(self, width: float):
        self.width = width

    def area(self) -> float:
        return CIRCLE_CONSTANT * self.width * self.width

class PrecomputedClassAttrCircle(Shape):
    circle_const =  math.pi * 0.5 * 0.5
    def __init__(self, width: float):
        self.width = width

    def area(self) -> float:
        return self.circle_const * self.width * self.width

PRECOMPUTED_CONSTRUCTORS: ConstructorSet = {
    'square': ControlSquare,
    'rectangle': ControlRectangle,
    'triangle': NoDivisionTriangle,
    'circle': PrecomputedConstCircle
}

PRECOMPUTED_CLASS_ATTR_CONSTRUCTORS: ConstructorSet = {
    'square': ControlSquare,
    'rectangle': ControlRectangle,
    'triangle': NoDivisionTriangle,
    'circle': PrecomputedClassAttrCircle,
}


# Part 1
# totalYes = 0
# currentYes = set()
#
# while True:
#     line = input()
#     if line == "-1":
#         break
#     elif line == "":
#         totalYes += len(currentYes)
#         currentYes = set()
#     else:
#         currentYes = currentYes.union({s for s in line})
#
# print(totalYes)

# Part 2
totalYes = 0
currentYes = None

while True:
    line = input()
    if line == "-1":
        break
    elif line == "":
        totalYes += len(currentYes) if currentYes is not None else 0
        currentYes = None
    else:
        if currentYes is None:
            currentYes = {s for s in line}
        else:
            currentYes = currentYes.intersection({s for s in line})

print(totalYes)


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

TRAIN_CORPUS_SOURCE = 'corpus/corpus.train.source.txt'
TRAIN_CORPUS_TARGET = 'corpus/corpus.train.target.txt'
TEST_CORPUS_SOURCE = 'corpus/corpus.test.source.txt'
TEST_CORPUS_TARGET = 'corpus/corpus.test_target.txt'

EOS_SYMBOL = 'E#O#S'
UNK_SYMBOL = 'U#N#K'

W2V_WINDOW_SIZE = 4
W2V_TOKEN_MIN_FREQUENCY = 1
W2V_VECTOR_SIZE = 500
W2V_WORKER_NUM = 10
W2V_CORPUS_NAME = '2W'
W2V_MODEL_DIR = 'w2v_model'
W2V_REBUILD_MODEL = False

NN_SENTENCE_MAX_LENGTH_SOURCE = 30
NN_SENTENCE_MAX_LENGTH_TARGET = 30
NN_CORPUS_NAME = '2W'
NN_MODEL_DIR = 'nn_model'

NN_EPOCH_NUM = 20
NN_BATCH_SIZE = 2
NN_HIDDEN_DIM = 600
NN_DEPTH = 4


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

import socket
import sys
import time
import base64
import subprocess

HOST = '' #all available interfaces
PORT = 2222

#1. open Socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print ('Socket created')

#2. bind to a address and port
try:
    s.bind((HOST, PORT))
except socket.error as msg:
    print ('Bind Failed. Error code: ' + str(msg[0]) + ' Message: ' + msg[1])
    sys.exit()

print ('Socket bind complete')

#3. Listen for incoming connections
s.listen(10)
print ('Socket now listening')

it = 2
#keep talking with the client
while 1:
    #4. Accept connection
    conn, addr = s.accept()
    print ('Connected with ' + addr[0] + ':' + str(addr[1]))

    id = conn.recv(255).decode()
    print('id : *' + id+ '*')

    timestamp = conn.recv(26).decode()
    print('timestamp : *' + timestamp +'*')

    result = conn.recv(1).decode()
    print('result : ' + result)

    if(result == '1'):
        it = 4
    elif(result == '0'):
        it = 2
    for i in range(1, it):
        #5. Read/Send
        img = ""
        len_data = conn.recv(1024).decode()
        len_data = int(len_data)
        size = 0

        print("Data Reading")

        while 1:
            data = conn.recv(65536)
            str_data = data.decode()
            img += data.decode()
            size += len(str_data)
            if size == len_data:
                print("Finished Data Reading")
                break

        with open('/root/openface/temp/test_'+str(i)+'.jpeg', 'wb') as f:
            f.write(base64.b64decode(img))
        time.sleep(0.1)
    break

res_list = {}

for j in range(1,it):
    # start face recognigionc
    res=subprocess.check_output(['/root/openface/demos/classifier_test.py infer /root/openface/embedding/us/classifier.pkl /root/openface/temp/test_'+str(j)+'.jpeg'], universal_newlines=True,shell=True)
    print("res: {}".format(res))

    # store recognition result
    name, accuracy = res.split(':')
    accuracy = float(accuracy)

    if accuracy > 0.5:
        if name in res_list.keys():
            res_list[name][1] += 1
            if res_list[name][0] < accuracy:
            	res_list[name][0] = accuracy
        else:
            res_list[name] = [accuracy, 1]

    print("res_list: {}".format(res_list))

if not res_list:
    print("*stranger*")
else:
    res_list = sorted(res_list.items(), key = lambda x: (x[1][1], x[1][0]), reverse = True)
    print("final res: *{}*".format(res_list[0][0]))

conn.close()
s.close()


import torch
import torch.nn as nn
from torch.autograd import Variable
# 导入torch.nn模块。实际上，“nn”是neural networks（神经网络）的缩写
#  nn.RNN的参数设置
#  input_size   输入x的特征大小(以mnist图像为例，特征大小为28*28 = 784)
#  hidden_size   隐藏层h的特征大小 即隐藏层节点的个数
#  num_layers    循环层的数量（RNN中重复的部分） 层数
#  nonlinearity   激活函数 默认为tanh，可以设置为relu
#  bias   是否设置偏置，默认为True
#  batch_first   默认为false, 设置为True之后，输入输出为(batch_size, seq_len, input_size)
#  dropout   默认为0
#  bidirectional   默认为False，True设置为RNN为双向

class DKT(nn.Module):
    def __init__(self, input_dim, hidden_dim, layer_dim, output_dim):
        super(DKT, self).__init__()
        self.hidden_dim = hidden_dim
        self.layer_dim = layer_dim
        self.output_dim = output_dim
        self.rnn = nn.RNN(input_dim, hidden_dim, layer_dim, batch_first=True,nonlinearity='tanh')
        self.fc = nn.Linear(self.hidden_dim, self.output_dim)

    def forward(self, x):
        device = x.device
        # torch.zeros 返回一个形状为为size,类型为torch.dtype，里面的每一个值都是0的tensor
        h0 = Variable(torch.zeros(self.layer_dim, x.size(0), self.hidden_dim)).to(device)
        out,hn = self.rnn(x, h0)
        res = self.fc(out)
        return res

# 输出形状
# DKT(
#   (rnn): RNN(246, 100, dropout=0.02)
#   (dense): Linear(in_features=100, out_features=123, bias=True)
#   (sig): Sigmoid()
#  )