"""
This file defines actions, i.e. functions the URLs are mapped into
The @action(path) decorator exposed the function at URL:

    http://127.0.0.1:8000/{app_name}/{path}

If app_name == '_default' then simply

    http://127.0.0.1:8000/{path}

If path == 'index' it can be omitted:

    http://127.0.0.1:8000/

The path follows the bottlepy syntax.

@action.uses('generic.html')  indicates that the action uses the generic.html template
@action.uses(session)         indicates that the action uses the session
@action.uses(db)              indicates that the action uses the db
@action.uses(T)               indicates that the action uses the i18n & pluralization
@action.uses(auth.user)       indicates that the action requires a logged in user
@action.uses(auth)            indicates that the action requires the auth object

session, db, T, auth, and tempates are examples of Fixtures.
Warning: Fixtures MUST be declared with @action.uses({fixtures}) else your app will result in undefined behavior
"""

from py4web import action, request, abort, redirect, URL
from yatl.helpers import A
from .common import db, session, T, cache, auth, logger, authenticated, unauthenticated, flash
from py4web.utils.url_signer import URLSigner
from .models import get_user_email

from py4web.utils.form import Form, FormStyleBulma
from .common import Field

url_signer = URLSigner(session)

@action('index')
@action.uses(db, auth, 'index.html')
def index():
    print("User:", get_user_email())
    rows = db(db.contact.user_email == get_user_email()).select()
    return dict(rows=rows, url_signer=url_signer)

@action('add_contact', method=["GET", "POST"]) # the :int means: please convert this to an int.
@action.uses(db, session, auth.user, 'add_contact.html')
def add():
    form = Form(db.contact, csrf_session=session, formstyle=FormStyleBulma)
    if form.accepted:
        redirect(URL('index'))
    return dict(form=form)

@action('edit_contact/<contact_id:int>', method=["GET", "POST"])
@action.uses(db, session, auth.user, 'edit_contact.html')
def edit(contact_id=None):
    assert contact_id is not None
    assert get_user_email() is not None
    p = db.contact[contact_id]
    print(p)
    if p is None:
        redirect(URL('index'))
    form = Form(db.contact, record=p, deletable=False, csrf_session=session, formstyle=FormStyleBulma)
    if form.accepted:
        redirect(URL('index'))
    return dict(form=form)

@action('delete_contact/<contact_id:int>')
@action.uses(db, session, auth.user)
def delete(contact_id=None):
    assert contact_id is not None
    assert get_user_email() is not None
    p = db.contact[contact_id]
    # print(db.bird[bird_id]['bird'])
    # print(db.bird[bird_id]['n_sightings'])
    # db.bird.update_or_insert(
    #     db.bird.bird==db.bird[bird_id]['bird'],
    #     bird=db.bird[bird_id]['bird'],
    #     n_sightings=db.bird[bird_id]['n_sightings'] + 1
    # )
    p.delete_record()
    redirect(URL('index'))

@action('edit_phones/<contact_id:int>')
@action.uses(db, auth.user, 'edit_phones.html')
def editphones(contact_id=None):
    assert contact_id is not None
    assert get_user_email() is not None
    #print("User:", get_user_email())
    rows = db(db.phone.contact_id == contact_id).select()
    return dict(rows=rows, contact_id=contact_id, url_signer=url_signer)

@action('add_phone/<contact_id:int>', method=["GET", "POST"])
@action.uses(db, auth.user, session, 'add_phone.html')
def addphone(contact_id=None):
    assert contact_id is not None
    assert get_user_email() is not None
    #print("User:", get_user_email())
    form = Form([Field('phone_number'), Field('phone_name')], csrf_session=session,
                formstyle=FormStyleBulma)
    if form.accepted:
        db.phone.insert(
            contact_id=contact_id,
            phone_number=form.vars["phone_number"],
            phone_name=form.vars["phone_name"]
        )
        redirect(URL('index'))
    return dict(form=form)


import PySimpleGUIWeb as sg
import pyautogui

input_file = open('input.txt', 'w')
input = ""

sg.theme('Material1')

gender_choices = ('Bitte auswählen', 'männlich', 'weiblich', 'divers')
day_choices = ('Bitte auswählen', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31)
month_choices = ('Bitte auswählen', 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember')
year_choices = ('Bitte auswählen', 2015, 2014, 2013, 2012, 2011, 2010, 2009, 2008, 2007, 2006, 2005, 2004)

layout = [
    [sg.Text('Anmeldung am Dietrich-Bonhoeffer-Gymnasium Eppelheim:', font='Helvetica 24')],
    [sg.Text('')],
    [sg.Text('Schüler/in:', font='Helvetica 18')],
    [sg.Text('Name', size=(30, 1)), sg.InputText()],
    [sg.Text('Vorname', size=(30, 1)), sg.InputText()],
    [sg.Text('Geschlecht', size=(30, 1)), sg.Combo(gender_choices, default_value='')],
    [sg.Text('Geburtsdatum', size=(30, 1)), sg.Combo(day_choices, default_value='', size=(5, 1)), sg.Combo(month_choices, default_value='', size=(11, 1)), sg.Combo(year_choices, default_value='', size=(7, 1))],
    [sg.Text('Geburtsort', size=(30, 1)), sg.InputText()],
    [sg.Text('Straße und Hausnummer', size=(30, 1)), sg.InputText()],
    [sg.Text('Postleitzahl', size=(30, 1)), sg.InputText()],
    [sg.Text('Wohnort', size=(30, 1)), sg.InputText()],
    [sg.Text('Land / Bundesland', size=(30, 1)), sg.InputText()],
    [sg.Text('Antragsdatum', size=(30, 1)), sg.InputText()],
    [sg.Text('Telefonnummern (Festnetz, Mobiltelefon)', size=(30, 1)), sg.InputText()],
    [sg.Text('E-Mail', size=(30, 1)), sg.InputText()],
    [sg.Text('')],
    [sg.Text('Erziehungsberechtigte/r:', font='Helvetica 18')],
    [sg.Text('Name', size=(30, 1)), sg.InputText()],
    [sg.Text('Vorname', size=(30, 1)), sg.InputText()],
    [sg.Text('Straße und Hausnummer', size=(30, 1)), sg.InputText()],
    [sg.Text('Postleitzahl', size=(30, 1)), sg.InputText()],
    [sg.Text('Wohnort', size=(30, 1)), sg.InputText()],
    [sg.Text('Land', size=(30, 1)), sg.InputText()],
    [sg.Text('Telefonnummern (Festnetz, Mobiltelefon)', size=(30, 1)), sg.InputText()],
    [sg.Text('E-Mail', size=(30, 1)), sg.InputText()],
    [sg.Text('')],
    [sg.Text('Angaben zur zuletzt besuchten Schule:', font='Helvetica 18')],
    [sg.Text('Schulart', size=(30, 1)), sg.InputText()],
    [sg.Text('Schulname', size=(30, 1)), sg.InputText()],
    [sg.Text('Ort', size=(30, 1)), sg.InputText()],
    [sg.Text('')],
    [sg.Text('Fächer und Noten:', font='Helvetica 18')],
    [sg.Text('Deutsch', size=(30, 1)), sg.InputText()],
    [sg.Text('Englisch', size=(30, 1)), sg.InputText()],
    [sg.Text('Mathematik', size=(30, 1)), sg.InputText()],
    [sg.Text('')],
    [sg.Submit('Einreichen'), sg.Cancel('Abbrechen')],
    [sg.Text('')],
]

window = sg.Window('Anmeldung am Dietrich-Bonhoeffer-Gymnasium Eppelheim', layout, web_port=3141, web_start_browser=True)
event, values = window.read()
window.close()
pyautogui.keyDown('ctrl')
pyautogui.press('w')
pyautogui.keyUp('ctrl')
print(event, values)
for value in range(0, len(values)):
    input += str(values.get(value))+"\n"
new_input = ""
for letter in input:
    if letter == "ä":
        new_input += "ae"
    elif letter == "Ä":
        new_input += "Ae"
    elif letter == "ö":
        new_input += "oe"
    elif letter == "Ö":
        new_input += "Oe"
    elif letter == "ü":
        new_input += "ue"
    elif letter == "Ü":
        new_input += "Ue"
    else:
        new_input += letter
if event == "Einreichen":
    input_file.writelines(new_input)
input_file.close()


'''
Section 3
Concurrency, CPU Bound vs I/O Bound(3) - threading vs asyncio vs multiprocessing
Keyword - I/O Bound, requests, multiprocessing, asyncio
'''
import time
import asyncio
import aiohttp

# IO bound Asyncio 예제
# threading 보다 높은 코드 복잡도 -> async , await 적절하게 코딩

# 실행함수1(다운로드)
async def request_site(session, url):
    # 세셕 획득
    #

    #세션확인
    print(session)

    async with session.get(url) as response:
        print(f'Read Contents {0}, from {1}'.format(response.status_code, url))

# 실행함수2(요청)
async def request_all_sites(urls):
    async with aiohttp.ClientSession() as session:
        # 작업 목록
        tasks = []
        for url in urls:
            #태스크 목록 생성
            task = asyncio.ensure_future(request_site(session, url))
            tasks.append(task)

        # task 확인
        print(*tasks)
        print(tasks)

        await asyncio.gather(*tasks, return_exceptions=True)
def main():
    # 테스트 URLS
    urls = [
        "https://www.jython.org",
        "https://www.naver.com",
        "https://yahoo.com"
    ]*3

    # 실행시간 측정
    start_time = time.time()

    # 실행
    asyncio.run(request_all_sites(urls))

    # 실행 시간 종료
    duration = time.time() - start_time

    print()

    # 결과
    print(f'Downloaded {len(urls)} sites in {duration} seconds')

if __name__ == "__main__":
    main()


import json
import requests
from easygui import choicebox, enterbox

from helper import project_api_id, access_token, base_url

title = "JamaScript"
display = ""
artifact_result = ""
main_components_result = ""
component_ids = []
test_management_ids = []
target_item_id = 0
user_choice = 0
main_selection = 0
main2_selection = 0
total_items_imported = 0
original_count = 0
choices = ["Architecture", "Business Request", "Component", "Data Dictionary",
           "Data Requirement", "Defect", "Epic", "Functional Requirement",
           "Meeting Note", "Non-Functional Requirement", "Persona", "Requirement",
           "Style Guide", "Test Case", "Text", "Use Case", "User Storie", "Wireframe"]
headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}

def add_components_to_root_level(root_cmp_names1):
    global original_count, main_components_result
    original_count = 9 * len(root_cmp_names1)
    url = base_url + "/rest/latest/items?setGlobalIdManually=false"
    for name in root_cmp_names1:
        data = {"project": project_api_id, "itemType": 30,
                "childItemType": 30, "fields": {"name": name}}

        response = requests.request("POST", url, headers=headers, data=json.dumps(data))
        global component_ids
        component_ids.append(response.json()["meta"]["id"])
    main_components_result += ("[" + str(len(component_ids)) + "/" + str(len(root_cmp_names1)) + "] Components "
                                                                                "created\n")
    global total_items_imported
    total_items_imported += len(component_ids)

def add_sets_to_components():
    count = []
    child_item_types = ["25", "87", "87", "87", "116"]
    set_names = ["Use Cases", "Functional Requirements", "Non-Functional Requirements", "Technical Requirements",
                 "Wireframes"]
    set_keys = ["UC", "FR", "NFR", "TR", "WF"]
    url = base_url + "/rest/latest/items?setGlobalIdManually=false"
    i = 0
    while 5 > i > -1:
        for item in component_ids:
            data = {"project": project_api_id, "itemType": 31,
                    "childItemType": child_item_types[i], "location":
                        {
                            "parent":
                                {
                                    "item": item
                                }
                        }, "fields": {"setKey": set_keys[i], "name": set_names[i]}
                    }
            response = requests.request("POST", url, headers=headers, data=json.dumps(data))
            count.append(response.json()["meta"]["id"])
        i += 1
    global main_components_result
    main_components_result += ("[" + str(5 * len(component_ids)) + "/" + str(len(count)) + "] Sets of Use Cases, "
                                                                                "Functional "
                                                                                "Requirements, "
                                                                                "Non-Functional "
                                                                                "Requirements, Technical "
                                                                                "Requirements, "
                                                                                "and Wireframes created\n")
    global total_items_imported
    total_items_imported += (5 * len(component_ids))

def add_test_management():
    url = base_url + "/rest/latest/items?setGlobalIdManually=false"
    for item in component_ids:
        data = {"project": project_api_id, "itemType": 30,
                "childItemType": 30, "location": {"parent": {"item": item}}, "fields": {"name": "Test Management"}}
        response = requests.request("POST", url, headers=headers, data=json.dumps(data))
        global test_management_ids
        test_management_ids.append(response.json()["meta"]["id"])
    global main_components_result
    main_components_result += ("[" + str(len(component_ids)) + "/" + str(len(test_management_ids)) + "] Test "
                                                                                "Management Sub "
                                                                                "Components "
                                                                                "created\n")
    global total_items_imported
    total_items_imported += len(component_ids)

def add_test_cases_and_defects():
    count = []
    child_item_types = ["26", "27"]
    set_names = ["Test Cases", "Defects"]
    set_keys = ["TC", "DEF"]
    url = base_url + "/rest/latest/items?setGlobalIdManually=false"
    i = 0
    while 2 > i > -1:
        for item in test_management_ids:
            data = {"project": project_api_id,
                    "itemType": 31,
                    "childItemType": child_item_types[i],
                    "location": {
                        "parent": {
                            "item": item}
                    }, "fields": {"setKey": set_keys[i], "name": set_names[i]}
                    }
            response = requests.request("POST", url, headers=headers, data=json.dumps(data))
            count.append(response.json()["meta"]["id"])
        i += 1
    global main_components_result, total_items_imported
    main_components_result += ("[" + str(len(count)) + "/" + str(2 * len(component_ids)) + "] Sets of Test Cases and "
                                                                                "Defects created\n")
    total_items_imported += (2 * len(component_ids))
    if original_count == total_items_imported:
        main_components_result += ("\nSuccess, imported [" + str(total_items_imported) + "] items!")
    else:
        main_components_result += ("Failed, only [" + str(total_items_imported) + "] items were imported.")

def get_user_choices():
    global user_choice
    user_choice = choicebox("What artifact type would you like to add?", choices=choices)
    if user_choice == "Go back":
        main()
    else:
        msg = "Please enter the target item's ID"
        document_key = enterbox(msg, title)
        url = base_url + "/rest/latest/abstractitems?project=" + str(project_api_id) + "&documentKey=" + document_key
        response = requests.request("GET", url, headers=headers)
        global target_item_id
        target_item_id = response.json()["data"][0]['id']

def add_uc(uc_data1):
    count = []
    url = base_url + "/rest/latest/items?setGlobalIdManually=false"
    for name, pre, main_flow, post, alt, blueprint_id in zip(uc_data1["Name"], uc_data1["PreCondition"],
                                                             uc_data1["MainFlow"],
                                                             uc_data1["PostCondition"], uc_data1["AlternateFlows"],
                                                             uc_data1["Blueprint_ID"]):
        data = {"project": project_api_id, "itemType": 25,
                "childItemType": 25, "location":
                    {
                        "parent":
                            {
                                "item": target_item_id
                            }
                    }, "fields": {"name": name, "precondition": pre,
                                  "mainflow": main_flow, "postcondition": post, "alternateflows": alt,
                                  "blueprint_id": blueprint_id}
                }
        response = requests.request("POST", url, headers=headers, data=json.dumps(data))
        count.append(response.json()["meta"]["id"])
    global artifact_result
    if len(uc_data1["Name"]) == len(count):
        artifact_result = "Success, imported " + str(len(count)) + " Use Cases!"
    else:
        artifact_result = "Failed, only " + str(len(count)) + " Use Cases imported"

def add_cmp(cmp_name1):
    count = []
    url = base_url + "/rest/latest/items?setGlobalIdManually=false"
    for name in cmp_name1:
        data = {"project": project_api_id, "itemType": 30,
                "childItemType": 30, "location":
                    {
                        "parent":
                            {
                                "item": target_item_id
                            }
                    }, "fields": {"name": name}
                }
        response = requests.request("POST", url, headers=headers, data=json.dumps(data))
        count.append(response.json()["meta"]["id"])
    global artifact_result
    if len(cmp_name1) == len(count):
        artifact_result = "Success, imported [" + str(len(count)) + "] Components!"
    else:
        artifact_result = "Failed, only [" + str(len(count)) + "] Components imported."

def add_rq(rq_data1):
    count = []
    url = base_url + "/rest/latest/items?setGlobalIdManually=false"
    for name, description, blueprint_id in zip(rq_data1["Name"], rq_data1["Description"], rq_data1["Blueprint_ID"]):
        data = {"project": project_api_id, "itemType": 87,
                "childItemType": 87, "location":
                    {
                        "parent":
                            {
                                "item": target_item_id
                            }
                    }, "fields": {"name": name, "description": description, "blueprint_id": blueprint_id}
                }
        response = requests.request("POST", url, headers=headers, data=json.dumps(data))
        count.append(response.json()["meta"]["id"])
    global artifact_result
    if len(rq_data1["Name"]) == len(count):
        artifact_result = "Success, imported [" + str(len(count)) + "] Requirements!"
    else:
        artifact_result = "Failed, only [" + str(len(count)) + "] Requirements were imported."

def add_wf(wf_data1):
    count = []
    url = base_url + "/rest/latest/items?setGlobalIdManually=false"
    for name, blueprint_id in zip(wf_data1["Name"], wf_data1["Blueprint_ID"]):
        data = {"project": project_api_id, "itemType": 116,
                "childItemType": 116, "location":
                    {
                        "parent":
                            {
                                "item": target_item_id
                            }
                    }, "fields": {"name": name, "blueprint_id": blueprint_id}
                }
        response = requests.request("POST", url, headers=headers, data=json.dumps(data))
        count.append(response.json()["meta"]["id"])
    global artifact_result
    if len(wf_data1["Name"]) == len(count):
        artifact_result = "Success, imported [" + str(len(count)) + "] Wireframes!"
    else:
        artifact_result = "Failed, only [" + str(len(count)) + "] Wireframes imported."

def add_requirements():
    global display
    if user_choice == choices[0]:
        display = "Architecture in development."
        main2()
    elif user_choice == choices[1]:
        display = "Business Request in development."
        main2()
    elif user_choice == choices[2]:
        from file_handler import components_file
        add_cmp(components_file())
        display = artifact_result
        main2()
    elif user_choice == choices[3]:
        display = "Data Dictionary in development."
        main2()
    elif user_choice == choices[4]:
        display = "Data Requirement in development."
        main2()
    elif user_choice == choices[5]:
        display = "Defect in development."
        main2()
    elif user_choice == choices[6]:
        display = "Epic in development."
        main2()
    elif user_choice == choices[7]:
        display = "Functional Requirement in development."
        main2()
    elif user_choice == choices[8]:
        display = "Meeting Note in development."
        main2()
    elif user_choice == choices[9]:
        display = "Non-Functional Requirement in development."
        main2()
    elif user_choice == choices[10]:
        display = "Persona in development."
        main2()
    elif user_choice == choices[11]:
        from file_handler import requirements_file
        add_rq(requirements_file())
        display = artifact_result
        main2()
    elif user_choice == choices[12]:
        display = "Style Guide in development."
        main2()
    elif user_choice == choices[13]:
        display = "Test Case in development."
        main2()
    elif user_choice == choices[14]:
        display = "Text in development."
        main2()
    elif user_choice == choices[15]:
        from file_handler import use_cases_file
        add_uc(use_cases_file())
        display = artifact_result
        main2()
    elif user_choice == choices[16]:
        display = "User Story in development."
        main2()
    elif user_choice == choices[17]:
        from file_handler import wireframes_file
        add_wf(wireframes_file())
        display = artifact_result
        main2()
    else:
        print("Error")
        get_user_choices()

def main2():
    choices = ["Add artifacts", "Change project"]
    global main2_selection
    main2_selection = choicebox(display + "\n\n What else would you like to do?", choices=choices, title=title)
    if main2_selection == "Add artifacts":
        get_user_choices()
        add_requirements()
    elif main2_selection == "Change project":
        from helper import get_project_name
        get_project_name()
        main()
    else:
        exit()

def main():
    choices = ["Add main components with their sets", "Add artifacts", "Change project"]
    global main_selection, display
    main_selection = choicebox("What would you like to do?", choices=choices, title=title)
    if main_selection == "Add main components with their sets":
        from file_handler import components_file
        add_components_to_root_level(components_file())
        add_sets_to_components()
        add_test_management()
        add_test_cases_and_defects()
        display = main_components_result
        main2()
    elif main_selection == "Add artifacts":
        get_user_choices()
        add_requirements()
        display = artifact_result
    elif main_selection == "Change project":
        from helper import get_project_name
        get_project_name()
        main()
    else:
        exit()

if __name__ == '__main__':
    main()


# this is the hook for the trainer.
import typing as t
from contextlib import contextmanager

from loguru import logger
from torch import nn

# _Base = Trainer
# else:
#     _Base = object
from contrastyou.hooks import TrainerHook

if t.TYPE_CHECKING:
    from contrastyou.trainer.base import Trainer

    _Base = Trainer
else:
    _Base = object

class HookMixin(_Base):
    def __init__(self, **kwargs) -> None:
        super().__init__(**kwargs)
        self._hooks = nn.ModuleList()

    @contextmanager
    def register_hook(self, *hook: "TrainerHook"):
        if self._initialized:
            raise RuntimeError("`register_hook must be called before `init()``")
        for h in hook:
            self._hooks.append(h)
            h.to(self.device)  # put the hook into device.
            h.register_trainer(self)

        logger.trace("bind TrainerHooks")

        for h in self._hooks:
            h.after_initialize()
        yield
        for h in hook:
            h.close()
        logger.trace("close TrainerHooks")


from threading import Thread

from flask import current_app, render_template
from flask_mail import Message

from . import mail

# 在实际项目中如果哟啊发送大量电子邮件时 使用专门发送电子邮件的作业比给每份邮件创建一个线程合适
# 例如把直线send_async_email()函数的操作发给Celery(http://www.celeryproject.org/)任务队列
# 异步发送电子邮件
def send_async_email(app, msg):
    with app.app_context():
        mail.send(msg)

# 发送邮件 参数: [收件人地址], '主题', 渲染正文模板, {关键字参数列表}
# 指定模板时不佳扩展名 这样才能使用两个模板分别渲染纯文本正文和富文本正文
# 调用者将关键字参数传给render_template()函数 以便在模板中使用 进而生成电子邮件正文
def send_email(to, subject, template, **kwargs):
    app = current_app._get_current_object()
    msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX']+subject,
                sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
    msg.body = render_template(template + '.txt', **kwargs)
    msg.html = render_template(template + '.html', **kwargs)
    # 原:同步发送 在发送邮件时会停滞几秒钟 为避免处理请求过程中不必要的延迟 采用异步发送
    # 将发送电子邮件的函数移到后台线程中
    #mail.send(msg)
    thr = Thread(target=send_async_email, args=[app, msg])
    thr.start()
    return thr


import random
import numpy as np
import scipy

class BaseCEE(object):
    def __init__(self, params):
        self.senders = []
        self.receivers = []
        self.agents = []  # case where single pool of agents
        self.params = params
        self.generation = 0
        self.iteration = 0
        self.initialize_population(params)

    def initialize_population(self, params: dict):
        raise NotImplementedError("Initialize population needs to be implemented")

    def train_population(self, batch):
        raise NotImplementedError("Train population needs to be implemented")

    def evaluate_population(self):
        raise NotImplementedError("Evaluate population needs to be implemented")

    def sample_population(self, receiver=False, mode: str = "random"):
        """
        population (dict): population dictionary containing a single population.
                            keys should be filenames and values attribute to do
                            selection on
        mode: pick from {'random'}
            - random: uniformly sample from population to cull ()
        """
        if self.params.single_pool:
            att = "agents"
        else:
            att = "receivers" if receiver else "senders"

        pop_size = len(getattr(self, att))

        if mode == "random":
            r = random.randrange(0, pop_size)
        else:
            raise ValueError("mode={} undefined for sampling population".format(mode))

        return getattr(self, att)[r]

    def sample_agents_pair(self, mode: str = "random"):
        """
        samples two agents from agent pool with no replacement
        mode: pick from {'random'}
            - random: uniformly sample from population to cull ()
        """
        pop_size = len(self.agents)
        if mode == "random":
            rnd = np.random.choice(pop_size, 2, replace=False)
            s1, s2 = rnd[0], rnd[1]
        else:
            raise ValueError("mode={} undefined for sampling population".format(mode))
        return (self.agents[s1], self.agents[s2])

    def sort_agents(self, receiver=False):
        raise NotImplementedError("sort_agents not implemented")

    def cull_population(self, receiver=False, culling_rate=0.2, mode="random"):
        """
        Culls Population according to culling rate and mode
        Args:
            culling_rate (float, optional): percentage of the population to cull
                                            default: 0.2
            mode (string, optional): argument for sampling
        """
        self.generation += 1

        if self.params.single_pool:
            att = "agents"
        else:
            att = "receivers" if receiver else "senders"

        pop_size = len(getattr(self, att))
        c = max(1, int(culling_rate * pop_size))

        if mode == "random":
            for _ in range(c):
                sampled_model = self.sample_population(receiver=receiver, mode=mode)
                sampled_model.cull()

        # sort by best converging
        if mode == "best":
            agents, _ = self.sort_agents(receiver=receiver)
            # cull worst c models
            agents.reverse()  # resort from worst to best
            for w in agents[:c]:
                worst_agent = getattr(self, att)[w]
                worst_agent.cull()

        if mode == "greedy":
            agents, values = self.sort_agents(receiver=receiver)
            p = scipy.special.softmax(np.array(values))
            selected_agents = np.random.choice(agents, c, p=p, replace=False)
            for w in selected_agents:
                worst_agent = getattr(self, att)[w]
                worst_agent.cull()

        # order by age
        if mode == "age":
            agents = []
            ages = []
            for a in range(pop_size):
                ages.append(getattr(self, att)[a].age)
                agents.append(a)
            # sort from oldest to newest
            ages, agents = zip(*sorted(zip(ages, agents), reverse=True))
            agents = list(agents)
            for w in agents[:c]:
                worst_agent = getattr(self, att)[w]
                worst_agent.cull()


import os
import sys
import json
import logging
from datetime import datetime
from typing import Optional
from dataclasses import dataclass, field

from transformers import (
    HfArgumentParser,
    set_seed,
)
from chemdataextractor.doc import Paragraph

from seqlbtoolkit.io import set_logging, logging_args, save_json
from seqlbtoolkit.data import (
    respan,
    span_dict_to_list,
    merge_list_of_lists,
    label_to_span
)

logger = logging.getLogger(__name__)

@dataclass
class Arguments:
    """
    Arguments regarding the training of Neural hidden Markov Model
    """

    # --- manage directories and IO ---
    data_dir: Optional[str] = field(
        default='', metadata={'help': 'Directory to datasets'}
    )
    output_dir: Optional[str] = field(
        default='.',
        metadata={"help": "The folder where the models and outputs will be written."},
    )
    log_dir: Optional[str] = field(
        default=None,
        metadata={"help": "the directory of the log file. Set to '' to disable logging"}
    )

def process(args: Arguments):
    ents = set()
    for partition in ('train', 'valid', 'test'):
        with open(os.path.join(args.data_dir, f"{partition}.txt"), 'r', encoding='utf-8') as f:
            instances = json.load(f)

        text_list = merge_list_of_lists(instances['text'])
        lbs_list = merge_list_of_lists(instances['label'])

        output_dict = dict()
        for idx, (text, lbs) in enumerate(zip(text_list, lbs_list)):
            raw_tks = Paragraph(' '.join(text)).raw_tokens
            cde_tks = merge_list_of_lists(raw_tks)
            ori_spans = label_to_span(lbs)
            ent_spans = {k: v for k, v in ori_spans.items() if v != 'ES'}
            cde_ent_spans = span_dict_to_list(respan(text, cde_tks, ent_spans))
            sent_lengths = [len(tk_seq) for tk_seq in raw_tks]

            output_dict[f"{idx}"] = {"label": cde_ent_spans, "data": {"text": cde_tks, 'sent_lengths': sent_lengths}}

            ents.update(ent_spans.values())

        save_json(output_dict, os.path.join(args.output_dir, f"{partition}.json"), collapse_level=4)

    save_json({'entity_types': list(ents)}, os.path.join(args.output_dir, "meta.json"))

if __name__ == '__main__':

    _time = datetime.now().strftime("%m.%d.%y-%H.%M")
    _current_file_name = os.path.basename(__file__)
    if _current_file_name.endswith('.py'):
        _current_file_name = _current_file_name[:-3]

    # --- set up arguments ---
    parser = HfArgumentParser(Arguments)
    if len(sys.argv) == 2 and sys.argv[1].endswith(".json"):
        # If we pass only one argument to the script, and it's the path to a json file,
        # let's parse it to get our arguments.
        arguments, = parser.parse_json_file(
            json_file=os.path.abspath(sys.argv[1])
        )
    else:
        arguments, = parser.parse_args_into_dataclasses()

    if getattr(arguments, "log_dir", None) is None:
        arguments.log_dir = os.path.join('logs', f'{_current_file_name}', f'{_time}.log')

    set_logging(log_dir=arguments.log_dir)
    logging_args(arguments)

    set_seed(getattr(arguments, 'seed', 42))

    try:
        process(args=arguments)
    except Exception as e:
        logger.exception(e)
        raise e


import logging
from typing import Union, List, Optional, Dict, Tuple

from custom_types.openstack_query.aliases import OpenstackResourceObj, PropValue
from enums.cloud_domains import CloudDomains
from enums.query.props.prop_enum import PropEnum
from enums.query.sort_order import SortOrder
from enums.query.query_presets import QueryPresets
from enums.query.query_types import QueryTypes
from exceptions.parse_query_error import ParseQueryError
from structs.query.query_components import QueryComponents

logger = logging.getLogger(__name__)

class QueryAPI:
    """
    Interface for Query Classes. This class exposes all public methods for query api.
    """

    def __init__(self, query_components: QueryComponents):
        self.builder = query_components.builder
        self.executer = query_components.executer
        self.parser = query_components.parser
        self.output = query_components.output
        self.chainer = query_components.chainer
        self._query_run = False

    def select(self, *props: PropEnum):
        """
        Public method used to 'select' properties that the query will return the value of.
        Mutually exclusive to returning objects using select_all()
        :param props: one or more properties to collect described as enum
        """

        # is an idempotent function
        # an be called multiple times with should aggregate properties to select
        logger.debug("select() called, with props: %s", [prop.name for prop in props])
        if not props:
            raise ParseQueryError("provide at least one property to select")

        self.output.parse_select(*props, select_all=False)
        logger.debug(
            "selected props are now: %s",
            [prop.name for prop in self.output.selected_props],
        )
        return self

    def select_all(self):
        """
        Public method used to 'select' all properties that are available to be returned
        Mutually exclusive to returning objects using select_all()

        Overrides all currently selected properties
        returns list of properties currently selected
        """
        logger.debug("select_all() called - getting all properties")
        self.output.parse_select(select_all=True)
        logger.debug(
            "selected props are now: %s",
            [prop.name for prop in self.output.selected_props],
        )
        return self

    def where(self, preset: QueryPresets, prop: PropEnum, **kwargs):
        """
        Public method used to set the conditions for the query.
        :param preset: QueryPreset Enum to use
        :param prop: Property Enum that the query preset will be used on
        :param kwargs: a set of optional arguments to pass along with the preset - property pair
            - these kwargs are dependent on the preset given
        """
        kwargs_log_str = "<none>"
        if kwargs:
            kwargs_log_str = "\n\t\t".join(
                [f"{key}: '{arg}'" for key, arg in kwargs.items()]
            )

        logger.debug(
            "where() called, with args:"
            "\n\t preset: %s"
            "\n\t prop: %s"
            "\n\t preset-args:\n\t\t%s",
            preset.name,
            prop.name,
            kwargs_log_str,
        )

        self.builder.parse_where(preset, prop, kwargs)
        return self

    def sort_by(self, *sort_by: Tuple[PropEnum, SortOrder]):
        """
        Public method used to configure sorting results
        :param sort_by: Tuple of property enum to sort by and enum representing sorting order
            - SortOrder.ASC (ascending) or SortOrder.DESC (descending)
        """
        self.parser.parse_sort_by(*sort_by)
        return self

    def group_by(
        self,
        group_by: PropEnum,
        group_ranges: Optional[Dict[str, List[PropValue]]] = None,
        include_ungrouped_results: bool = False,
    ):
        """
        Public method used to configure how to group results.
        :param group_by: name of the property to group by
        :param group_ranges: a set of optional group mappings - group name to list of values of
        selected group by property to be included in each group
        :param include_ungrouped_results: an optional flag to include a "ungrouped" group to the
        output of values found that were
        not specified in group mappings - ignored if group ranges not given
        """
        self.parser.parse_group_by(group_by, group_ranges, include_ungrouped_results)
        return self

    def run(
        self,
        cloud_account: Union[str, CloudDomains],
        from_subset: Optional[List[OpenstackResourceObj]] = None,
        **kwargs,
    ):
        """
        Public method that runs the query provided and outputs
        :param cloud_account: A String or a CloudDomains Enum for the clouds configuration to use
        :param from_subset: A subset of openstack resources to run query on instead of querying openstacksdk
        :param kwargs: keyword args that can be used to configure details of how query is run
            - valid kwargs specific to resource
        """

        if from_subset:
            logger.debug(
                "'from_subset' optional param given - will run client-side filters only"
            )
            self.executer.client_side_filters = (
                self.builder.client_side_filters + self.builder.server_filter_fallback
            )
            self.executer.server_side_filters = None
        else:
            self.executer.client_side_filters = self.builder.client_side_filters
            self.executer.server_side_filters = self.builder.server_side_filters

        self.executer.run_query(
            cloud_account=cloud_account,
            from_subset=from_subset,
            **kwargs,
        )
        self._query_run = True
        return self

    def to_list(
        self, as_objects=False, flatten=False, groups: Optional[List[str]] = None
    ) -> Union[Dict[str, List], List[Dict[str, str]]]:
        """
        Public method to return results as a list (ungrouped) or dict (if grouped/flattened)
        :param as_objects: if true return result as openstack objects
        :param flatten: boolean which will flatten results if true
        :param groups: a list group to limit output by
        """
        result_as_objects, selected_results = self.executer.parse_results(
            parse_func=self.parser.run_parser, output_func=self.output.generate_output
        )
        results = result_as_objects if as_objects else selected_results

        if groups:
            if not isinstance(results, dict):
                raise ParseQueryError(
                    f"Result is not grouped - cannot filter by given group(s) {groups}"
                )
            if not all(group in results.keys() for group in groups):
                raise ParseQueryError(
                    f"Group(s) given are invalid - valid groups {list(results.keys())}"
                )
            return {group_key: results[group_key] for group_key in groups}

        if flatten:
            return self.output.flatten(results)
        return results

    def to_string(
        self, title: Optional[str] = None, groups: Optional[List[str]] = None, **kwargs
    ) -> str:
        """
        Public method to return results as table(s)
        :param title: an optional title for the table(s)
        :param groups: a list group to limit output by
        :param kwargs: kwargs to pass to generate table
        """
        _, selected_results = self.executer.parse_results(
            parse_func=self.parser.run_parser, output_func=self.output.generate_output
        )

        return self.output.to_string(selected_results, title, groups, **kwargs)

    def to_html(
        self, title: Optional[str] = None, groups: Optional[List[str]] = None, **kwargs
    ) -> str:
        """
        Public method to return results as html table
        :param title: an optional title for the table(s) - will be converted to html automatically
        :param groups: a list group to limit output by
        :param kwargs: kwargs to pass to generate table
        """
        _, selected_results = self.executer.parse_results(
            parse_func=self.parser.run_parser, output_func=self.output.generate_output
        )
        return self.output.to_html(selected_results, title, groups, **kwargs)

    def then(
        self, query_type: Union[str, QueryTypes], keep_previous_results: bool = True
    ):
        """
        Public method to chain current query into another query of a different type
        and return the new query so that it will work only on the results of the original query.
        NOTE - query must be run first for this to work
        NOTE - a shared common property must exist between this query and the new query
            - i.e. both ServerQuery and UserQuery share the 'USER_ID' property so chaining is possible
                - see Mappings for more chaining options

        :param query_type: an enum representing the new query to chain into
        :param keep_previous_results:
            - If True - will forward outputs from this query (and previous chained queries) onto new query.
            - If False - runs the query based on the previous results as a filter without adding additional fields
            NOTE: You will NOT be able to group/sort by these properties in the new query
        """
        return self.chainer.parse_then(self, query_type, keep_previous_results)

    def append_from(
        self,
        query_type: Union[str, QueryTypes],
        cloud_account: Union[str, CloudDomains],
        *props: PropEnum,
    ):
        """
        Public method to append specific properties from other queries to the output
        of this query. This method will run a secondary query on top of this one to get required properties
        and append the properties to the results of this query
        NOTE - query must be run first for this to work
        NOTE - a shared common property must exist between this query and the new query
            - i.e. both ServerQuery and UserQuery share the 'USER_ID' property so chaining is possible
                - see Mappings for more chaining options

        :param query_type: an enum representing the new query to chain into
        :param cloud_account: A String or a CloudDomains Enum for the clouds configuration to use
        :param props: list of props from new queries to get
        """
        if isinstance(query_type, str):
            query_type = QueryTypes.from_string(query_type)

        new_query = self.then(query_type, keep_previous_results=False)
        new_query.select(*props)
        new_query.run(cloud_account)

        link_props = self.chainer.get_link_props(query_type)
        new_query.group_by(link_props[1])

        self.output.update_forwarded_outputs(link_props[0], new_query.to_list())
        return self


from urllib.request import urlopen
from bs4 import BeautifulSoup

class StackoverflowScrapper:

    def __init__(self, name):
        main_url = "http://stackoverflow.com/tags/%s/info" %(name)
        html = urlopen(main_url)
        self.bsObj = BeautifulSoup(html, "lxml")

    def check_wiki_extract_same_paragraph(self, tagInfo):
        wiki_extract = tagInfo.find('div', {'id': 'wiki-excerpt'})
        children = tagInfo.children
        childs = []
        for child in children:
            if child.name == 'p':
                childs.append(child.get_text())
        if childs[0] == wiki_extract.get_text().strip(): return True

    def get_tag_description(self):
        try:
            tagInfo = self.bsObj.find('div', {'class': 'post-text'})
            paragraphs = tagInfo.findAll("p")
            description = ""
            idx = 0
            if self.check_wiki_extract_same_paragraph(tagInfo): idx = 1
            for paragraph in paragraphs[idx:]:
                link = paragraph.find("a")
                if link is not None:
                    if link.get_text() != paragraph.get_text():
                        description += paragraph.get_text().strip(" ")
                else:
                    description += paragraph.get_text().strip(" ")
            for tag in self.bsObj.findAll("li"):
                if tag.find("a") is None:
                    description += tag.get_text()
            return description
        except Exception as e:
            print(str(e))
            return None

    def get_links(self):
        result_links = []
        try:
            tag_info = self.bsObj.find('div', {'class': 'post-text'})
            links = tag_info.findAll("a")
            for link in links:
                url = link.attrs['href']
                if '/questions/tagged' not in url:
                    title = link.get_text()
                    result_links.append({'title': title, 'url': url})
            return result_links
        except Exception as e:
            print(str(e))
            return None

    def get_stats(self):
        try:
            table = self.bsObj.find("table", {"id": "qinfo"})
            rows = table.findAll("tr")
            stats = ""
            for row in rows:
                for cell in row.findAll(['td']):
                    stats += cell.find("p").get_text().strip() + ' '
                stats += '\n'
            return stats
        except:
            return None

def get_followers(name):
    import selenium
    from selenium import webdriver
    from selenium.webdriver import ActionChains
    from selenium.webdriver.common.keys import Keys
    import time
    driver = webdriver.PhantomJS()
    driver.get('http://stackoverflow.com/tags')
    search_input = driver.find_element_by_id('tagfilter')
    search_input.send_keys(name)
    search_input.send_keys(Keys.RETURN)
    time.sleep(20)
    element = driver.find_element_by_link_text(name)
    hover = ActionChains(driver).move_to_element(element)
    hover.perform()
    time.sleep(10)
    info = driver.find_element_by_class_name('tm-sub-info')
    text = info.text
    print("Original: %s" %(text))
    followers, questions = text.split(',')
    followers = followers.replace('followers', '')
    followers = followers.replace('follower', '')

    if 'k' in followers:
        followers = followers.replace('k', '')
        followers = float(followers.strip(' '))
        followers = followers * 1000
    else:
        followers = int(followers.strip())

    questions = questions.replace('questions', '')
    questions = questions.replace('\nrss', '')
    if 'k' in questions:
        index = questions.index('k')
        questions = questions[:index]
        questions = questions.replace('k', '')
        questions = float(questions.strip(' '))
        questions = questions * 1000
    else:
        questions = int(questions)
    return followers, questions


import sys
_module = sys.modules[__name__]
del sys
models = _module
models = _module
snres_discriminator = _module
snres_generator = _module
src = _module
functions = _module
max_sv = _module
snlayers = _module
snconv2d = _module
snlinear = _module
test = _module
train = _module

from _paritybench_helpers import _mock_config, patch_functional
from unittest.mock import mock_open, MagicMock
from torch.autograd import Function
from torch.nn import Module
import abc, collections, copy, enum, functools, inspect, itertools, logging, math, matplotlib, numbers, numpy, pandas, queue, random, re, scipy, sklearn, string, tensorflow, time, torch, torchaudio, torchtext, torchvision, types, typing, uuid, warnings
import numpy as np
from torch import Tensor
patch_functional()
open = mock_open()
yaml = logging = sys = argparse = MagicMock()
ArgumentParser = argparse.ArgumentParser
_global_config = args = argv = cfg = config = params = _mock_config()
argparse.ArgumentParser.return_value.parse_args.return_value = _global_config
yaml.load.return_value = _global_config
sys.argv = _global_config
__version__ = '1.0.0'
xrange = range
wraps = functools.wraps

import torch.nn as nn

import torch

from torch.nn.modules import conv

from torch.nn.modules import Linear

import torch.nn.functional as F

from torch.nn.modules.utils import _pair

import torch.optim as optim

from torchvision import datasets

from torchvision import transforms

import torchvision.utils as vutils

from torch.autograd import Variable

import torch.utils.data

from torch.nn.modules.utils import _triple

import torch.backends.cudnn as cudnn

import random

import numpy as np

import matplotlib.pyplot as plt

class _netG(nn.Module):

    def __init__(self, nz, nc, ngf):
        super(_netG, self).__init__()
        self.convT1 = nn.Sequential(nn.ConvTranspose2d(nz, ngf * 4, 4, 1, 0, bias=False), nn.BatchNorm2d(ngf * 4), nn.ReLU(True))
        self.convT2 = nn.Sequential(nn.ConvTranspose2d(10, ngf * 4, 4, 1, 0, bias=False), nn.BatchNorm2d(ngf * 4), nn.ReLU(True))
        self.main = nn.Sequential(nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False), nn.BatchNorm2d(ngf * 4), nn.ReLU(True), nn.ConvTranspose2d(ngf * 4, ngf * 2, 4, 2, 1, bias=False), nn.BatchNorm2d(ngf * 2), nn.ReLU(True), nn.ConvTranspose2d(ngf * 2, ngf, 4, 2, 1, bias=False), nn.BatchNorm2d(ngf), nn.ReLU(True), nn.ConvTranspose2d(ngf, nc, 4, 2, 1, bias=False), nn.Tanh())

    def forward(self, input, input_c):
        out1 = self.convT1(input)
        out2 = self.convT2(input_c)
        output = torch.cat([out1, out2], 1)
        output = self.main(output)
        return output

def _l2normalize(v, eps=1e-12):
    return v / ((v ** 2).sum() ** 0.5 + eps)

def max_singular_value(W, u=None, Ip=1):
    """
    power iteration for weight parameter
    """
    if u is None:
        u = torch.FloatTensor(1, W.size(0)).normal_(0, 1)
    _u = u
    for _ in range(Ip):
        _v = _l2normalize(torch.matmul(_u, W.data), eps=1e-12)
        _u = _l2normalize(torch.matmul(_v, torch.transpose(W.data, 0, 1)), eps=1e-12)
    sigma = torch.matmul(torch.matmul(_v, torch.transpose(W.data, 0, 1)), torch.transpose(_u, 0, 1))
    return sigma, _v

class SNConv2d(conv._ConvNd):

    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True):
        kernel_size = _pair(kernel_size)
        stride = _pair(stride)
        padding = _pair(padding)
        dilation = _pair(dilation)
        super(SNConv2d, self).__init__(in_channels, out_channels, kernel_size, stride, padding, dilation, False, _pair(0), groups, bias)

    def forward(self, input):
        w_mat = self.weight.view(self.weight.size(0), -1)
        sigma, _ = max_singular_value(w_mat)
        self.weight.data = self.weight.data / sigma
        return F.conv2d(input, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups)

class _netD(nn.Module):

    def __init__(self, nc, ndf):
        super(_netD, self).__init__()
        self.conv1_1 = SNConv2d(nc, ndf / 2, 3, 1, 1, bias=False)
        self.conv1_2 = SNConv2d(10, ndf / 2, 3, 1, 1, bias=False)
        self.lrelu = nn.LeakyReLU(0.2, inplace=True)
        self.main = nn.Sequential(SNConv2d(ndf, ndf, 4, 2, 1, bias=False), nn.LeakyReLU(0.2, inplace=True), SNConv2d(ndf, ndf * 2, 3, 1, 1, bias=False), nn.LeakyReLU(0.2, inplace=True), SNConv2d(ndf * 2, ndf * 2, 4, 2, 1, bias=False), nn.LeakyReLU(0.2, inplace=True), SNConv2d(ndf * 2, ndf * 4, 3, 1, 1, bias=False), nn.LeakyReLU(0.2, inplace=True), SNConv2d(ndf * 4, ndf * 4, 4, 2, 1, bias=False), nn.LeakyReLU(0.2, inplace=True), SNConv2d(ndf * 4, ndf * 8, 3, 1, 1, bias=False), nn.LeakyReLU(0.2, inplace=True), SNConv2d(ndf * 8, ndf * 8, 4, 2, 1, bias=False), nn.LeakyReLU(0.2, inplace=True), SNConv2d(ndf * 8, 1, 4, 1, 0, bias=False))

    def forward(self, input, input_c):
        out1 = self.lrelu(self.conv1_1(input))
        out2 = self.lrelu(self.conv1_2(input_c))
        output = torch.cat([out1, out2], 1)
        output = self.main(output)
        return output.view(-1, 1).squeeze(1)

class ResBlock(nn.Module):

    def __init__(self, in_channels, out_channels, hidden_channels=None, upsample=False):
        super(ResBlock, self).__init__()
        hidden_channels = in_channels
        self.upsample = upsample
        self.conv1 = nn.Conv2d(in_channels, hidden_channels, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(hidden_channels, out_channels, kernel_size=3, padding=1)
        self.conv_sc = nn.Conv2d(in_channels, out_channels, kernel_size=1, padding=0)
        self.upsampling = nn.UpsamplingBilinear2d(scale_factor=2)
        self.bn1 = nn.BatchNorm2d(in_channels)
        self.bn2 = nn.BatchNorm2d(hidden_channels)
        self.relu = nn.ReLU()

    def forward_residual_connect(self, input):
        out = self.conv_sc(input)
        if self.upsample:
            out = self.upsampling(out)
        return out

    def forward(self, input):
        out = self.relu(self.bn1(input))
        out = self.conv1(out)
        if self.upsample:
            out = self.upsampling(out)
        out = self.relu(self.bn2(out))
        out = self.conv2(out)
        out_res = self.forward_residual_connect(input)
        return out + out_res

class OptimizedBlock(nn.Module):

    def __init__(self, in_channels, out_channels):
        super(OptimizedBlock, self).__init__()
        self.res_block = self.make_res_block(in_channels, out_channels)
        self.residual_connect = self.make_residual_connect(in_channels, out_channels)

    def make_res_block(self, in_channels, out_channels):
        model = []
        model += [SNConv2d(in_channels, out_channels, kernel_size=3, padding=1)]
        model += [nn.ReLU()]
        model += [SNConv2d(out_channels, out_channels, kernel_size=3, padding=1)]
        model += [nn.AvgPool2d(2)]
        return nn.Sequential(*model)

    def make_residual_connect(self, in_channels, out_channels):
        model = []
        model += [SNConv2d(in_channels, out_channels, kernel_size=1, padding=0)]
        model += [nn.AvgPool2d(2)]
        return nn.Sequential(*model)

    def forward(self, input):
        return self.res_block(input) + self.residual_connect(input)

class SNLinear(Linear):
    """Applies a linear transformation to the incoming data: :math:`y = Ax + b`
       Args:
           in_features: size of each input sample
           out_features: size of each output sample
           bias: If set to False, the layer will not learn an additive bias.
               Default: ``True``
       Shape:
           - Input: :math:`(N, *, in\\_features)` where :math:`*` means any number of
             additional dimensions
           - Output: :math:`(N, *, out\\_features)` where all but the last dimension
             are the same shape as the input.
       Attributes:
           weight: the learnable weights of the module of shape
               `(out_features x in_features)`
           bias:   the learnable bias of the module of shape `(out_features)`

           W(Tensor): Spectrally normalized weight

           u (Tensor): the right largest singular value of W.
       """

    def __init__(self, in_features, out_features, bias=True):
        super(SNLinear, self).__init__(in_features, out_features, bias)
        self.register_buffer('u', torch.Tensor(1, out_features).normal_())

    @property
    def W_(self):
        w_mat = self.weight.view(self.weight.size(0), -1)
        sigma, _u = max_singular_value(w_mat, self.u)
        self.u.copy_(_u)
        return self.weight / sigma

    def forward(self, input):
        return F.linear(input, self.W_, self.bias)

class SNResDiscriminator(nn.Module):

    def __init__(self, ndf=64, ndlayers=4):
        super(SNResDiscriminator, self).__init__()
        self.res_d = self.make_model(ndf, ndlayers)
        self.fc = nn.Sequential(SNLinear(ndf * 16, 1), nn.Sigmoid())

    def make_model(self, ndf, ndlayers):
        model = []
        model += [OptimizedBlock(3, ndf)]
        tndf = ndf
        for i in range(ndlayers):
            model += [ResBlock(tndf, tndf * 2, downsample=True)]
            tndf *= 2
        model += [nn.ReLU()]
        return nn.Sequential(*model)

    def forward(self, input):
        out = self.res_d(input)
        out = F.avg_pool2d(out, out.size(3), stride=1)
        out = out.view(-1, 1024)
        return self.fc(out)

class SNResGenerator(nn.Module):

    def __init__(self, ngf, z=128, nlayers=4):
        super(SNResGenerator, self).__init__()
        self.input_layer = nn.Linear(z, 4 ** 2 * ngf * 16)
        self.generator = self.make_model(ngf, nlayers)

    def make_model(self, ngf, nlayers):
        model = []
        tngf = ngf * 16
        for i in range(nlayers):
            model += [ResBlock(tngf, tngf / 2, upsample=True)]
            tngf /= 2
        model += [nn.BatchNorm2d(ngf)]
        model += [nn.ReLU()]
        model += [nn.Conv2d(ngf, 3, kernel_size=3, stride=1, padding=1)]
        model += [nn.Tanh()]
        return nn.Sequential(*model)

    def forward(self, z):
        out = self.input_layer(z)
        out = out.view(z.size(0), -1, 4, 4)
        out = self.generator(out)
        return out

import torch
from torch.nn import MSELoss, ReLU
from _paritybench_helpers import _mock_config, _mock_layer, _paritybench_base, _fails_compile

TESTCASES = [
    # (nn.Module, init_args, forward_args, jit_compiles)
    (ResBlock,
     lambda: ([], {'in_channels': 4, 'out_channels': 4}),
     lambda: ([torch.rand([4, 4, 4, 4])], {}),
     True),
    (SNLinear,
     lambda: ([], {'in_features': 4, 'out_features': 4}),
     lambda: ([torch.rand([4, 4, 4, 4])], {}),
     False),
    (_netG,
     lambda: ([], {'nz': 4, 'nc': 4, 'ngf': 4}),
     lambda: ([torch.rand([4, 4, 64, 64]), torch.rand([4, 10, 64, 64])], {}),
     True),
]

class Test_godisboy_SN_GAN(_paritybench_base):
    def test_000(self):
        self._check(*TESTCASES[0])

    def test_001(self):
        self._check(*TESTCASES[1])

    def test_002(self):
        self._check(*TESTCASES[2])


"""Vehicles Routing Problem (VRP) by google.

https://developers.google.com/optimization/routing/vrp"""

from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
import flora
import network_operations as net_ops
import input_output_operations as io_ops
import pandas as pd
import pdb
import optops

def create_data_model():
    data = {}
    data['distance_matrix'] = []
    data['num_vehicles'] = 4
    data['depot'] = 0
    return data

def convert_list_data_to_ints(a_list):
    """ Method to get a list of floats and to return them as ints.

    Args:
        a_list (list): list of floats
    return:
        list of ints
    """
    int_list = [[int(float(j)) for j in i] for i in a_list]
    return int_list

def print_results_to_map(or_result, data_csvfile):
    """Method to read VRP result and original data file and to print
    the result to map

    Args:
        or_result (str): text with VRP result
        data_csvfile (str): filepath of original data position in disk
    """
    # read data from disk
    supermarkets = pd.read_csv(data_csvfile, delimiter='\t')
    result = io_ops.get_route_node_ids_from_textfile(or_result)
    # update dataframes with results
    pdb.set_trace()
    add_route_to_df(supermarkets, result)

def add_route_to_df(df, routes, new_col='routes'):
    """Method to add a new column (route) to dataframe and
    the corresponding nodes of the route.

    Args:
        df (dataframe): Dataframe to work on (add new column)
        routes (dict): dictionary of <route_id: nodes_list> pairs
        new_col (str, optional): Name of the new column. Defaults to 'routes'.
    """
    # add new column to dataframe
    df[new_col] = -1
    # populate new column with data
    for route in routes:
        _populate_df_with_route(routes, route, df)

def _populate_df_with_route(routes_dict, route_id, df):
    """Method to populate a dataframe with routes

    Args:
        routes_dict ([type]): [description]
        route_id ([type]): [description]
        df ([type]): [description]
    """
    pass

def print_solution(data, manager, routing, solution):
    """Prints solution on console."""
    max_route_distance = 0
    written_result = ''
    for vehicle_id in range(data['num_vehicles']):
        index = routing.Start(vehicle_id)
        plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
        route_distance = 0
        while not routing.IsEnd(index):
            plan_output += ' {} -> '.format(manager.IndexToNode(index))
            previous_index = index
            index = solution.Value(routing.NextVar(index))
            route_distance += routing.GetArcCostForVehicle(
                previous_index, index, vehicle_id)
        written_result += plan_output
        plan_output += '{}\n'.format(manager.IndexToNode(index))
        plan_output += 'Distance of the route: {}m\n'.format(route_distance)
        print(plan_output)
        max_route_distance = max(route_distance, max_route_distance)
    print('Maximum of the route distances: {}m'.format(max_route_distance))
    return written_result

def main():
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    #data = flora.flora('results/graphs/attica-graph.graphml', 'data/supermarkets.csv', '') #create_data_model()
    data_csvfile = 'data/super_sample_tabs.csv'
    data = create_data_model()
    od_result = net_ops.compute_distance_matrix(data_csvfile)
    data['distance_matrix'] = od_result[0].values.tolist()
    data['distance_matrix'] = convert_list_data_to_ints(data['distance_matrix'])
    #pdb.set_trace()
    # following line is for kasselouris od matrix
    #io_ops.write_od_to_csv(data['distance_matrix'], 'data/kassel_results.csv')

    # Create the routing index manager.
    manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),
                                           data['num_vehicles'], data['depot'])

    # Create Routing Model.
    routing = pywrapcp.RoutingModel(manager)

    # Create and register a transit callback.
    def distance_callback(from_index, to_index):
        """Returns the distance between the two nodes."""
        # Convert from routing variable Index to distance matrix NodeIndex.
        from_node = manager.IndexToNode(from_index)
        to_node = manager.IndexToNode(to_index)
        return data['distance_matrix'][from_node][to_node]

    transit_callback_index = routing.RegisterTransitCallback(distance_callback)

    # Define cost of each arc.
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

    # Add Distance constraint.
    dimension_name = 'Distance'
    routing.AddDimension(
        transit_callback_index,
        0,  # no slack
        20000,  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100000)

    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

    # Solve the problem.
    solution = routing.SolveWithParameters(search_parameters)

    # Print solution on console.
    written_solution = ''
    or_result = 'results/or_results.txt'
    solution_paths = optops.get_all_routes(data, manager, routing, solution)
    if solution:
        written_solution = print_solution(data, manager, routing, solution)
        with open(or_result, 'w') as f:
            f.write(written_solution)
    pdb.set_trace()
    # process the results and print them to map
    print_results_to_map(or_result, data_csvfile)

if __name__ == '__main__':
    main()


import database.db as db
from flask import jsonify
from bson.objectid import ObjectId
from domain.domain import FeedDomain

class FeedService:
    def addNewContent(self,FeedDomain):
        try:
            response=db.Feeds().addPost(FeedDomain)
        except Exception as e:
            print("the value of error is",e)
            return {"message":"Error while Adding the post"}

        try:
            postID=str(response.inserted_id)
            db.UserFeed().addNewPost(FeedDomain,postID)
            return {"message":"Successfully Added The post"}
        except Exception as e:
            db.Feeds().deletePost(FeedDomain.userID,response.inserted_id)
            return {"message":"Error While Adding The Post2"},500

    def deleteContent(self,userID,postID):
        postIDKey=ObjectId(postID)
        try:
            response=db.Feeds().deletePost(userID,postIDKey)
            if response==None:
                return {"message":"Unable To Delete The post"},500
            db.UserFeed().deleteContent(userID,postID)
            return {"message":"Post Has Been Deleted Successfully"},200
        except Exception as e:
            print("The value of error is",e)
            return {"message":"Error while deleting the post"},500

    def modifyContent(self,userID,postID,FeedDomain):
        postIDKey=ObjectId(postID)
        savedDetaills=db.Feeds().getPost(postIDKey)
        if savedDetaills==None:
            return {"message":"Unable To Fetch The Details"},404
        if FeedDomain.company=="":
            FeedDomain.company=savedDetaills["company"]
        if FeedDomain.description=="":
            FeedDomain.description=savedDetaills["description"]
        if FeedDomain.experience=="":
            FeedDomain.experience=savedDetaills['experience']
        if FeedDomain.role=="":
            FeedDomain.role=savedDetaills["role"]
        try:
            response=db.Feeds().ModifyPost(postIDKey,FeedDomain)
            if response==None:
                return{"message":"Unable To Update The post"},500
            db.UserFeed().ModifyPost(postID,FeedDomain)
            return {"message":"Post Has Been Updated Successfully"},200
        except:
            return {"message":"Error While Updating The Details"},500

    def ViewContentOfUser(self,userID):
        try:
            response=db.UserFeed().ViewAllContent(userID)
        except:
            return {"message":"Unable To Fetch The Posts...."},500
        if response==None:
            return {"message":"No Data Found"}, 404
        else:
            for values in response["Content"]:
                values["postID"]=str(values["postID"])
            return response["Content"]

    def getPost(self,postID):
        postID=ObjectId(postID)
        try:
            response=db.Feeds().getPost(postID)
            if response==None:
                return {"message":"No Post Found"},404
            else:
                response["_id"]=str(response["_id"])
                return response
        except:
            return {"message":"Couldn't Fetch The post...Please Try again"},500

    def filterPost(self,experience,role,company):
        try:
            ans=[]
            results=None
            if experience!=None:
                results=db.Feeds().filterByExperience(experience)
            elif role!=None:
                results=db.Feeds().filterByRole(role)
            elif company!=None:
                results=db.Feeds().filterByCompany(company)
            for values in results:
                if experience!=None and values["experience"]!=experience:
                    continue
                elif role!=None and values["role"]!=role:
                    continue
                elif company!=None and values["company"]!=company:
                    continue
                else:
                    values["_id"]=str(values["_id"])
                    ans.append(values)
            return ans

        except Exception as e:
            print("the value of error is",e)
            return {"message":"Cannot Filter Values According to the result"}


import k5test
import pytest

import krb5

def test_parse_principal(realm: k5test.K5Realm) -> None:
    name = f"role/abc\\/def\\@test@{realm.realm}"
    ctx = krb5.init_context()

    principal = krb5.parse_name_flags(ctx, name.encode())
    assert isinstance(principal, krb5.Principal)
    assert str(principal) == name
    assert repr(principal) == f"Principal({name})"
    assert principal.name == name.encode()
    assert isinstance(principal.addr, int)

    no_flags = krb5.parse_name_flags(ctx, name.encode(), flags=krb5.PrincipalParseFlags.none)
    assert isinstance(principal, krb5.Principal)
    assert str(principal) == str(no_flags)

    no_realm = krb5.parse_name_flags(ctx, b"role/abc\\/def\\@test", flags=krb5.PrincipalParseFlags.no_realm)
    assert isinstance(no_realm, krb5.Principal)
    if realm.provider == "mit":
        # MIT seems to have a bug here
        assert str(no_realm) == "role/abc\\/def@test"
    else:
        assert str(no_realm) == "role/abc\\/def\\@test"

    require_realm = krb5.parse_name_flags(ctx, name.encode(), flags=krb5.PrincipalParseFlags.require_realm)
    assert isinstance(require_realm, krb5.Principal)
    assert str(require_realm) == name

    enterprise = krb5.parse_name_flags(ctx, name.encode(), flags=krb5.PrincipalParseFlags.enterprise)
    assert isinstance(enterprise, krb5.Principal)
    assert str(enterprise) == f"role\\/abc\\/def\\@test\\@{realm.realm}@{realm.realm}"

    ignore_realm = krb5.parse_name_flags(ctx, name.encode(), flags=krb5.PrincipalParseFlags.ignore_realm)
    assert isinstance(ignore_realm, krb5.Principal)
    if realm.provider == "mit":
        assert str(ignore_realm) == "role/abc\\/def@test"
    else:
        assert str(ignore_realm) == "role/abc\\/def\\@test"

def test_parse_principal_no_realm_failure(realm: k5test.K5Realm) -> None:
    ctx = krb5.init_context()

    expected = "has realm present" if realm.provider == "mit" else "realm found in"
    with pytest.raises(krb5.Krb5Error, match=expected):
        krb5.parse_name_flags(ctx, realm.user_princ.encode(), flags=krb5.PrincipalParseFlags.no_realm)

def test_unparse_principal(realm: k5test.K5Realm) -> None:
    name = f"role/abc\\/def\\@test@{realm.realm}"
    ctx = krb5.init_context()
    principal = krb5.parse_name_flags(ctx, name.encode())

    normal = krb5.unparse_name_flags(ctx, principal)
    assert normal == b"role/abc\\/def\\@test@" + realm.realm.encode()

    no_flags = krb5.unparse_name_flags(ctx, principal, flags=krb5.PrincipalUnparseFlags.none)
    assert no_flags == normal

    no_realm = krb5.unparse_name_flags(ctx, principal, flags=krb5.PrincipalUnparseFlags.no_realm)
    if realm.provider == "mit":
        # MIT seems to have a bug here
        assert no_realm == b"role/abc\\/def@test"
    else:
        assert no_realm == b"role/abc\\/def\\@test"

    display = krb5.unparse_name_flags(ctx, principal, flags=krb5.PrincipalUnparseFlags.display)
    assert display == b"role/abc/def@test@" + realm.realm.encode()

    short = krb5.unparse_name_flags(ctx, principal, flags=krb5.PrincipalUnparseFlags.short)
    assert short == b"role/abc\\/def\\@test"

    krb5.set_default_realm(ctx, b"NEW.REALM")
    short = krb5.unparse_name_flags(ctx, principal, flags=krb5.PrincipalUnparseFlags.short)
    assert short == b"role/abc\\/def\\@test@" + realm.realm.encode()

@pytest.mark.requires_api("principal_get_realm")
def test_principal_get_realm() -> None:
    ctx = krb5.init_context()
    principal = krb5.parse_name_flags(ctx, b"username@REALM.COM")

    realm = krb5.principal_get_realm(ctx, principal)
    assert realm == b"REALM.COM"


from typing import Tuple
import math
import latlon

# from geographiclib.geodesic import Geodesic
# geod = Geodesic.WGS84

EARTH_RADIUS = 60.0 * 360 / (2 * math.pi) # nm
NAUTICAL_MILE_IN_KM = 1.852

def cfbinomiale(n: float, i: float) -> float:
	return math.factorial(n)/(math.factorial(n-i)*math.factorial(i))

def ortodromic2 (lat1: float, lon1: float, lat2: float, lon2: float) -> Tuple[float, float]:
	p1 = math.radians (lat1)
	p2 = math.radians (lat2)
	dp = math.radians (lat2-lat1)
	dp2 = math.radians (lon2-lon1)

	a = math.sin (dp/2) * math.sin (dp2/2) + math.cos (p1) * math.cos (p2) * math.sin (dp2/2) * math.sin (dp2/2)
	c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
	return (EARTH_RADIUS * c, a)

def ortodromic (latA: float, lonA: float, latB: float, lonB: float) -> Tuple[float, float]:
	# g = geod.Inverse(latA, lonA, latB, lonB)
	# return (g['s12'] * 1e-3, math.radians (g['azi1']))

	p1 = latlon.LatLon(latlon.Latitude(latA), latlon.Longitude(lonA))
	p2 = latlon.LatLon(latlon.Latitude(latB), latlon.Longitude(lonB))
	return (p1.distance (p2), math.radians (p1.heading_initial(p2)))

def lossodromic (latA: float, lonA: float, latB: float, lonB: float) -> Tuple[float, float]:
	# g = geod.Inverse(latA, lonA, latB, lonB)
	# return (g['s12'] * 1e-3, math.radians (g['azi1']))

	p1 = latlon.LatLon(latlon.Latitude(latA), latlon.Longitude(lonA))
	p2 = latlon.LatLon(latlon.Latitude(latB), latlon.Longitude(lonB))
	return (p1.distance (p2, ellipse = 'sphere'), math.radians (p1.heading_initial(p2)))

def km2nm(d: float) -> float:
	return d * 0.539957

def nm2km(d: float) -> float:
	return d / 0.539957

def pointDistance (latA: float, lonA: float, latB: float, lonB: float, unit: str = 'nm') -> float:
	""" Returns the distance between two geo points """
	p1 = latlon.LatLon(latlon.Latitude(latA), latlon.Longitude(lonA))
	p2 = latlon.LatLon(latlon.Latitude(latB), latlon.Longitude(lonB))
	d = p1.distance (p2)

	# d = ortodromic(latA, lonA, latB, lonB)[0]

	if unit == 'nm':
		return km2nm(d)
	elif unit == 'km':
		return d

def routagePointDistance (latA: float, lonA: float, distance: float, hdg: float, unit: str='nm') -> Tuple[float, float]:
	""" Returns the point from (latA, lonA) to the given (distance, hdg) """
	if unit == 'nm':
		d = nm2km(distance)
	elif unit == 'km':
		d = distance

	# g = geod.Direct(latA, lonA, math.degrees(hdg), d * 1e3)
	# return (g['lat2'], g['lon2'])

	p = latlon.LatLon(latlon.Latitude(latA), latlon.Longitude(lonA))
	of = p.offset (math.degrees (hdg), d).to_string('D')
	return (float (of[0]), float (of[1]))

def maxReachDistance(p, speed: float, dt: float = (1. / 60. * 60.)) -> float:
	maxp = routagePointDistance (p[0], p[1], speed * dt, 1)
	return pointDistance(p[0], p[1], maxp[0], maxp[1])

def reduce360 (alfa: float) -> float:
	if math.isnan (alfa):
		return 0.0

	n=int(alfa*0.5/math.pi)
	n=math.copysign(n,1)
	if alfa>2.0*math.pi:
		alfa=alfa-n*2.0*math.pi
	if alfa<0:
		alfa=(n+1)*2.0*math.pi+alfa
	if alfa>2.0*math.pi or alfa<0:
		return 0.0
	return alfa

def reduce180 (alfa: float) -> float:
	if alfa>math.pi:
		alfa=alfa-2*math.pi
	if alfa<-math.pi:
		alfa=2*math.pi+alfa
	if alfa>math.pi or alfa<-math.pi:
		return 0.0
	return alfa

def pathAsGeojson(path) -> object:
	feats = []
	route = []

	for order, wayp in enumerate(path):
		feat = {
			"type": "Feature",
			"id": order,
			"geometry": {
				"type": "Point",
				"coordinates": [ # longitude, latitude
					wayp.pos[1],
					wayp.pos[0]
				]
			},
			"properties": {
				"timestamp": str(wayp.time),
				"twd": math.degrees(wayp.twd),
				"tws": wayp.tws,
				"knots": wayp.speed,
				"heading": wayp.brg
			}
		}
		feats.append(feat)
		route.append([wayp.pos[1], wayp.pos[0]]) # longitude, latitude

	feats.append({
		"type": "Feature",
		"id": 999,
		"geometry": {
			"type": "LineString",
			"coordinates": route
		},
		"properties": {
			"start-timestamp": str(path[0].time),
			"end-timestamp": str(path[-1].time)
		}
	})

	return {
		"type": "FeatureCollection",
		"features": feats
	}


from sklearn.datasets import load_iris
iris=load_iris()
'''
print (type(iris))
#print (iris.data)
print(iris.feature_names)
print(iris.target)
print(iris.target_names)
print(iris.data.shape)
print (iris.target.shape)
'''

X=iris.data
y=iris.target
#print(X.shape)
#print(y.shape)

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

from sklearn.neighbors import KNeighborsClassifier
knn=KNeighborsClassifier(n_neighbors=1)

knn.fit(X,y)

X_new=[[3,5,4,2],[5,4,3,2]]
Fl = knn.predict(X_new)
print ('Pridicted Flower type are :- ')
print (iris['target_names'][Fl])

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

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(iris['data'],iris['target'],test_size=0.3,random_state=0)

knn=KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train,y_train)
y_pred=knn.predict(X_test)

print (y_pred)
print (y_test)


import findspark
from pyspark.sql import SparkSession
import sys

# The entry point into all functionality in Spark is the SparkSession class.
spark = (SparkSession
        .builder
        .appName("my awesome Spark SQL program")
        .master("spark://172.31.93.203:7077")
        .getOrCreate())

# You can read the data from a file into DataFrames
# df = spark.read.json("")
input_path = "hdfs://172.31.93.203:9000/" + sys.argv[1]
df2 = spark.read.option("header","true").option("delimiter", ",").csv(input_path)

# sorting as required
answer = df2.sort(["cca2", "timestamp"])

answer.write.format("csv").mode("overwrite").save("hdfs://172.31.93.203:9000/" + sys.argv[2])


import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import tqdm
from transformers import BartTokenizer, BartModel, BartForConditionalGeneration
from bart_evaluate import combine_into_words
import pickle
from data import tokenizer
import bart_evaluate
import random

device = torch.device("cuda")
eval_batch_size = 32

def lm_loss(logits, labels, lable_masks, reduction = "mean"):

    bsz = logits.shape[0]
    out = logits[:, :-1, :].contiguous().reshape(-1,logits.shape[-1])
    out = F.log_softmax(out)
    target = labels[:, 1:].contiguous().reshape(-1)

    loss = F.nll_loss(out,target, reduction='none').view(bsz,-1)
    loss = (loss * lable_masks[:,1:].float()).sum(1)
    length = lable_masks[:,1:].float().sum(1)
    loss = loss / length

    if reduction == "mean":
        loss = loss.sum()/bsz

    return loss

class Architect():
    """ Compute gradients of alphas """
    def __init__(self, net, w_momentum, w_weight_decay):
        """
        Args:
            net
            w_momentum: weights momentum
        """
        self.net = net
        self.v_net = net
        self.w_momentum = w_momentum
        self.w_weight_decay = w_weight_decay

    def virtual_step(self, trn_X, trn_y, w_optim, Likelihood, step, batch_size):
        """
        Compute unrolled weight w' (virtual step)
        Step process:
        1) forward
        2) calc loss
        3) compute gradient (by backprop)
        4) update gradient
        Args:
            xi: learning rate for virtual gradient step (same as weights lr)
            w_optim: weights optimizer
        """
        # forward & calc loss
        dataIndex = len(trn_y)+step*batch_size

        input_id, input_mask = trn_X
        output_id, output_mask = trn_y

        # forward
        logits = self.v_net(input_ids = input_id, decoder_input_ids = output_id, labels = output_id)[1]

        # sigmoid loss
        first = torch.sigmoid(Likelihood[step*batch_size:dataIndex])
        second = lm_loss(logits, output_id, output_mask, reduction="none")
        # print(first.size())
        # print(second.size())
        lossup = torch.dot(first, second)
        lossdiv =(torch.sigmoid(Likelihood[step*batch_size:dataIndex]).sum())
        loss = lossup/lossdiv

#         loss = torch.dot(torch.sigmoid(Likelihood[step*batch_size:dataIndex]), ignore_crit(logits, trn_y))/(torch.sigmoid(Likelihood[step*batch_size:dataIndex]).sum())

        # compute gradient of train loss towards likelihhod
        loss.backward()

        # do virtual step (update gradient)
        # below operations do not need gradient tracking
        with torch.no_grad():
            # dict key is not the value, but the pointer. So original network weight have to
            # be iterated also.
            for w, vw in zip(self.net.parameters(), self.v_net.parameters()):
                m = w_optim.state[w].get('momentum_buffer', 0.) * self.w_momentum

                if w.grad is not None:
                    vw.copy_(w - args.lr * (m + w.grad + self.w_weight_decay*w))

    def unrolled_backward(self, trn_X, trn_y, val_X, val_y, w_optim, Likelihood, Likelihood_optim, step, batch_size):
        """ Compute unrolled loss and backward its gradients
        Args:
            xi: learning rate for virtual gradient step (same as net lr)
            w_optim: weights optimizer - for virtual step
        """
        # crit = nn.CrossEntropyLoss().cuda()

        xi = 0.01
        # do virtual step (calc w`)
        self.virtual_step(trn_X, trn_y, w_optim, Likelihood, step, batch_size)

        vinput_id, vinput_mask = val_X
        voutput_id, voutput_mask = val_y
        # calc val prediction
        logits = self.v_net(input_ids = vinput_id, decoder_input_ids = voutput_id, labels = voutput_id)[1]
        # calc unrolled validation loss
        loss = lm_loss(logits, voutput_id, voutput_mask, reduction='mean')# L_val(w`)

        # compute gradient of validation loss towards weights
        v_weights = tuple(self.v_net.parameters())
        # some weights not used return none

        dw = []
        for w in v_weights:
            if w.requires_grad:
                dw.append(torch.autograd.grad(loss, w, allow_unused=True, retain_graph=True))
            else:
                dw.append(None)
        hessian = self.compute_hessian(dw, trn_X, trn_y, Likelihood, batch_size, step)

        Likelihood_optim.zero_grad()
        # update final gradient = - xi*hessian
#         with torch.no_grad():
#             for likelihood, h in zip(Likelihood, hessian):
#                 print(len(hessian))
#                 likelihood.grad = - xi*h
        with torch.no_grad():
            Likelihood.grad = - xi*hessian[0]
        Likelihood_optim.step()
        return Likelihood, Likelihood_optim, loss

    def compute_hessian(self, dw, trn_X, trn_y, Likelihood, batch_size, step):
        """
        dw = dw` { L_val(w`, alpha) }
        w+ = w + eps * dw
        w- = w - eps * dw
        hessian = (dalpha { L_trn(w+, alpha) } - dalpha { L_trn(w-, alpha) }) / (2*eps)
        eps = 0.01 / ||dw||
        """

        norm = torch.cat([w[0].view(-1) for w in dw if ((w != None) and (w[0] != None))]).norm()

        eps = 0.01 / norm

        input_id, input_mask = trn_X
        output_id, output_mask = trn_y

        # w+ = w + eps*dw`
        with torch.no_grad():
            for p, d in zip(self.net.parameters(), dw):
                if d!= None and d[0] != None:
                    pp = eps * d[0]
                    p += eps * d[0]

        # forward & calc loss
        dataIndex = len(input_id)+step*batch_size
        # forward
        logits = self.net(input_ids = input_id, decoder_input_ids = output_id, labels = output_id)[1]
        # sigmoid loss
        first = torch.sigmoid(Likelihood[step*batch_size:dataIndex])
        second = lm_loss(logits, output_id, output_mask, reduction="none")
        lossup = torch.dot(first, second)
        lossdiv =(torch.sigmoid(Likelihood[step*batch_size:dataIndex]).sum())
        loss = lossup/lossdiv

        dalpha_pos = torch.autograd.grad(loss, Likelihood) # dalpha { L_trn(w+) }

        # w- = w - eps*dw`
        with torch.no_grad():
            for p, d in zip(self.net.parameters(), dw):
                if d != None and d[0] != None:
                    p -= 2. * eps * d[0]
        # forward
        logits = self.net(input_ids = input_id, decoder_input_ids = output_id, labels = output_id)[1]
        # sigmoid loss
        first = torch.sigmoid(Likelihood[step*batch_size:dataIndex])
        second = lm_loss(logits, output_id, output_mask, reduction="none")
        lossup = torch.dot(first, second)
        lossdiv =(torch.sigmoid(Likelihood[step*batch_size:dataIndex]).sum())
        loss = lossup/lossdiv

        dalpha_neg = torch.autograd.grad(loss, Likelihood) # dalpha { L_trn(w-) }

        # recover w
        with torch.no_grad():
            for p, d in zip(self.net.parameters(), dw):
                if d != None and d[0] != None:
                    p += eps * d[0]

        hessian = [(p-n) / (2.*eps) for p, n in zip(dalpha_pos, dalpha_neg)]
        return hessian

def train(model,dataset,test_data,train_data,optimizer,log_path,gen_path,best_model_pth,batch_size = 64, num_accumulation = 2, steps = 50000, epoch_num = 10):
    train_dataset = dataset["train"]
    test_dataset = dataset["test"]
    dev_dataset = dataset["dev"]
    iter_num = len(train_dataset) // batch_size
    best_ppl = 10000000
    best_score = 0
    step_count = 0
    total_loss = []

    architect = Architect(model,w_momentum=0.9,w_weight_decay = 3e-4)
    Likelihood = torch.nn.Parameter(torch.ones(len(train_dataset)).cuda(),requires_grad=True).cuda()
    Likelihood_optim = torch.optim.Adam({Likelihood}, 0.1, betas=(0.5, 0.999))

    bar = tqdm.tqdm(total=steps)
    bar.update(0)

    logs = {}
    begin_eval = False
    dev_iter = 0
    total_dev_iter = len(dev_dataset) // batch_size

    while step_count < steps:
      model.train()
      epoch_loss = 0
      optimizer.zero_grad()
      random.shuffle(train_dataset)
      for iter in range(iter_num):
        input_id, input_mask, output_id, output_mask = gen_batched_data(batch_size, iter, train_dataset)
        vinput_id, vinput_mask, voutput_id, voutput_mask = gen_batched_data(batch_size, dev_iter, dev_dataset)

        trn_x = (input_id,input_mask)
        trn_y = (output_id,output_mask)
        val_x = (vinput_id,vinput_mask)
        val_y = (voutput_id,voutput_mask)

        bsz = input_id.shape[0]

        architect.unrolled_backward(trn_x,trn_y,val_x,val_y,optimizer,Likelihood,Likelihood_optim,iter,bsz)

        logits = model(input_ids = input_id, decoder_input_ids = output_id, labels = output_id)[1]

        loss = lm_loss(logits,output_id,output_mask,reduction="mean")

        loss.backward()

        epoch_loss += loss.item()
        total_loss.append(loss.item())

        if (iter + 1) % num_accumulation == 0:
          optimizer.step()
          optimizer.zero_grad()
          step_count += 1
          if step_count >= steps:
            break

          if (step_count % 500) == 0:
            begin_eval = True
          bar.update(1)

        if begin_eval:
          test_perplexity, log = do_eval(model, dev_dataset, test_dataset, test_data, train_data, gen_path, step_count, steps)
          log["macro loss"] = sum(total_loss) / len(total_loss)
          logs[str(step_count)] = log
          torch.save(logs, log_path + "/{}-{}.pkl".format(step_count, steps))
          begin_eval = False
          if test_perplexity < best_ppl:
            best_ppl = test_perplexity
            #save model
            torch.save({"model":model.state_dict(), "opt":optimizer}, open(best_model_pth,"wb"))
            print("best ppl model saved")

        dev_iter = (dev_iter + 1) % total_dev_iter

def do_eval(model, dev_dataset, test_dataset, test_data, train_data, gen_path, step_count, steps):
#   eval_perplexity = eval_model(model,dev_dataset)
  test_perplexity = eval_model(model,test_dataset)

  gen_name = gen_path + "/iter{}-{}.txt".format(step_count, steps)
  log_info = bart_evaluate.evaluate_generation_dataset(test_dataset,test_data,train_data,model,gen_name=gen_name)
  log_info["Test Perplexity"] = test_perplexity
#   log_info["Eval Perplexity"] = eval_perplexity
  log_info["step"] = step_count

  print("================Step %d===================="%(step_count))
  print("Saving gens to {}".format(gen_name))
#   print("Eval Perplexity: %f"%(eval_perplexity))
  print("Test Perplexity: %f"%(test_perplexity))

  return test_perplexity, log_info

  # break

def gen_batched_data(batch_size, iter, dataset, PAD_IDX = 1):
  st = iter * batch_size
  ed = min([(iter+1) * batch_size, len(dataset)])
  batched_data = dataset[st:ed]

  max_input_len = max([len(data[0]) for data in batched_data])
  max_output_len = max([len(data[1]) for data in batched_data])

  batched_input_id = []
  batched_output_id = []

  for input_id, output_id in batched_data:
    input_id += [PAD_IDX] * (max_input_len - len(input_id))
    output_id += [PAD_IDX] * (max_output_len - len(output_id))
    batched_input_id.append(input_id)
    batched_output_id.append(output_id)

  batched_input_id = torch.LongTensor(batched_input_id).to(device)
  batched_output_id = torch.LongTensor(batched_output_id).to(device)
  batched_input_mask = batched_input_id != PAD_IDX
  batched_output_mask = batched_output_id != PAD_IDX

  return batched_input_id, batched_input_mask, batched_output_id, batched_output_mask

def log_to_file(file_name, log_info):
  with open(file_name,"a") as fout:
    fout.write("==============Epoch {}=======================\n".format(log_info["Epoch"]))
    fout.write("Training Steps: {}\n".format(log_info["step"]))
    fout.write("Trainning Loss: {}\n".format(log_info["Trainning Loss"]))
    fout.write("Eval Perplexity: {}\n".format(log_info["Eval Perplexity"]))
    fout.write("Test Perplexity: {}\n".format(log_info["Test Perplexity"]))
    fout.write("N/T_sro: {}\n".format(log_info["N_sro"]))
    fout.write("N/T_o: {}\n".format(log_info["N_o"]))
    fout.write("Score: {}\n".format(log_info["score"]))

def sample(model, test_dataset,sample_num = 5):
  input_ids = gen_batched_data(sample_num, 0, test_dataset)[0]
  output_ids = model.generate(input_ids=input_ids, max_length=20,do_sample=False)
  for i in range(output_ids.shape[0]): #  3 output sequences were generated
    print('Generated {}: {} {}'.format(i, tokenizer.decode(input_ids[i], skip_special_tokens=True), tokenizer.decode(output_ids[i], skip_special_tokens=True)))

def eval_model(model, eval_dataset):
  eval_iter_num = len(eval_dataset) // eval_batch_size
  model.eval()
  perplexity = 0
  for iter in range(eval_iter_num):
    with torch.no_grad():
      input_id, input_mask, output_id, output_mask = gen_batched_data(eval_batch_size, iter, eval_dataset)
      bsz = input_id.shape[0]
      logits = model(input_ids = input_id, decoder_input_ids = output_id, labels = output_id)[1]

      out = logits[:, :-1, :].contiguous().reshape(-1,logits.shape[-1])
      out = F.log_softmax(out)
      # print(out.shape)
      target = output_id[:, 1:].contiguous().reshape(-1)
      # print(target.shape)

      loss = F.nll_loss(out,target, reduction='none').view(bsz,-1)
      loss = (loss * output_mask[:,1:].float()).sum(1)
      length = output_mask[:,1:].float().sum(1)
      loss = (loss/length).sum()/bsz

      perplexity += loss.item()

  return np.exp(perplexity / eval_iter_num)


# Import the necessary libraries
import gym
import numpy as np

# Create the Frozen Lake environment using Gym
env = gym.make('FrozenLake-v0')

# Let's take a look at the Frozen Lake environment using the render function
env.render()

# FROM HERE WE WILL START COMPUTING THE OPTIMAL VALUE FUNCTION
# Define the value_iteration function, which takes the environment as a parameter
def value_iteration(env):
	# Set the number of iterations
	num_iterations = 1000

	# Set the threshold number for checking the convergence of the value function
	threshold = 1e-20

	# Set the discount factor 𝛾  to 1
	gamma = 1.0

	# We will initialize the value table by setting the value of all states to zero
	value_table = np.zeros(env.observation_space.n)

	# For every iteration
	for i in range(num_iterations):
		# Update the value table
		updated_value_table = np.copy(value_table)

		# for each state, we compute the Q values of all the actions
		# in the state and then we update the value of the state as
		# the one that has the maximum Q value
		for s in range(env.observation_space.n):
			# Compute the Q value of all the actions
			Q_values = [sum([prob*(r + gamma * updated_value_table[s_])
				for prob, s_, r, _ in env.P[s][a]])
					for a in range(env.action_space.n)]

			# Update the value of the state as a maximum Q value
			value_table[s] = max(Q_values)

		# After computing the value table, we check whether
		# the difference between the value table obtained in
		# the current iteration and the previous iteration
		# is less than or equal to a threshold value.
		# If the difference is less than the threshold,
		# then we break the loop and return the value table
		# as our optimal value function as the following code shows:
		if (np.sum(np.fabs(updated_value_table - value_table)) <= threshold):
			break
	return value_table

# FROM HERE WE WILL EXTRACT THE OPTIMAL POLICY FROM
# THE COMPUTED OPTIMAL VALUE FUNCTION

# We define a function called extract_policy
# which takes value_table as a parameter
def extract_policy(value_table):
	# Set the discount factor 𝛾  to 1
	gamma = 1.0
	# Let initialize the policy with zeros,
	# that is, we set the actions for all the states to be zero:
	policy = np.zeros(env.observation_space.n)

	# For each state, we compute the Q values for all the actions
	# in the state and then we extract the policy by selecting
	# the action that has the maximum Q value.
	for s in range(env.observation_space.n):
		# Compute the Q value of all the actions in the state, 𝑄(𝑠,a)
		Q_values = [sum([prob*(r + gamma * value_table[s_])
			for prob, s_, r, _ in env.P[s][a]])
				for a in range(env.action_space.n)]

		# Extract the policy by selecting the action that has the maximum Q value,
		policy[s] = np.argmax(np.array(Q_values))
	return policy

#	We learned that in the Frozen Lake environment,
#	our goal is to find the optimal policy that selects the correct action
#	in each state so that we can reach state G from state A without visiting the hole states.

# Firstly, we compute the optimal value function
# using our value_iteration function by passing our
# Frozen Lake environment as the parameter:
optimal_value_function = value_iteration(env)

# Next, we extract the optimal policy from the optimal value
# function using our extract_policy function:
optimal_policy = extract_policy(optimal_value_function)

# We can print the obtained optimal policy:
print(optimal_policy)

# The preceding code will print the following.
# As we can observe, our optimal policy tells us
# to perform the correct action in each state:

basic_rl_algorithm/2. Solving the Frozen Lake problem with value iteration.py