import numpy as np
from numpy import linalg as lin
import math
import filterpy
from filterpy.kalman import KalmanFilter
from munkres import Munkres

# Theorie GNN : https://www.youtube.com/watch?v=MDMNsQJl6-Q&list=PLadnyz93xCLiCBQq1105j5Jeqi1Q6wjoJ&index=21&t=0s
def gnn(data,p_d,lambda_c,F,H,n,R,Q,init_values):
    #data Messung aller Zeitschritten
    #p_d =detection rate
    #lambda_c Clutter Intensität
    #F, H  System bzw Ausgangsmatrux
    #n Anzahl Objekten
    #R,Q Kovarianz Matrizen
    #Algorithmus eignet sich nur für GNN mit einem linearen und gaußverteilten Modell
         #Initialisierung
        hungarian = Munkres() # Objekt, welches den Hungarian Algorithmus darstellt
        number_states = len(F) # Zuständezahl
        theta_k = np.zeros((1,n)) #Data Assossiation Vektor
        number_coordinates = int(number_states/2) # Zahl Koordinaten: 1 wenn z= x, 2 wenn z=[x;y]
        estimate = np.zeros((number_states,n)) # Zustände geschätz
        estimate[0:number_states,0:n] = init_values #Anfangswerte hinzufügen
        P = np.zeros((number_states,n*number_states)) #Kovarianzmatrix des Schätzfehlers
        #total_cost = 0 #Kosten Data Assossiation
        estimate_all =[]
        estimate_all.append(init_values.tolist()) #Liste mit  Erwartungswerten von allen Zuständen aller Objekten über alle Zeitschritten
        z_opt_assossiation= 0 # Messung der wahrscheinlichsten Hypothese

        ## Berechnung mit Messdaten/Testdaten
        while len(data)>0: #While: data nicht leer
            measurement_k = data.pop(0)  #Erste Messung aus Datensatz (wird danach aus Datenliste entfernt)
            m= len(measurement_k) #Anzahl Messungen pro Zeitschritt k
            L_detection = np.zeros((n,m)) #Kostfunktion detektiert
            L_missdetection = np.zeros((n,n)) #Kostfunktion nicht-detektiert
            L_missdetection[:,:] = np.inf # Alle Einträge gleich unendlich setzen
            L = np.zeros((n,m+n)) #Gesamte Kostenmatrix

            for i in range(n):
                estimate_i = np.transpose(estimate[0:number_states,i] )   #Zustandände pro Objekt aus der gesamten estimates Matrix extraieren. Muss Transponiert werden, da Python mit stehenden Vektoren nicht umgehen kann
                P_i= P[0:number_states,i*number_states:number_states*(i+1)] #Kovarianz pro Objekt aus der gesamten P matrix extraieren
            #Prädiktion mit Kalmanfilter
                estimate_i,P_i = kalman_filter_prediction(estimate_i, P_i,F,Q)

            #Kostenmatrix erzeugen
                S = R+ np.matmul(H,np.matmul(P_i,np.transpose(H))) #Inovation Kovarianz
                z_hat = np.matmul(H,estimate_i) #Predicted detection
                L_missdetection[i][i] = np.log(1-p_d)
                for j in range(m):
                    if number_coordinates == 1:

                        L_detection[i][j] =  np.log(p_d/lambda_c) - 0.5*np.log(2*math.pi*abs(S))-0.5*1/S*(measurement_k[j]-z_hat)*(measurement_k[j]-z_hat)

                    else:
                        L_detection[i][j] = np.log(p_d/lambda_c) - 0.5*np.log(np.linalg.det(2*math.pi*S))-0.5*(np.matmul(np.transpose((measurement_k[j]-z_dach)),np.matmul(np.linalg.inv(S),(z_dach-measurement_k[j]))))

            L= np.concatenate((L_detection,L_missdetection),axis=1) #L_detection und L_missdetection zusammensetzen

            #Berechnen assignment Matrix A mit Hungarian Algorithmus
            indexes_opt = hungarian.compute(L) #Assignment matrix indexes

            # Berechnung von Data Assossiation theta_k
            for i in range(n):

                #total_cost += L[i][indexes_opt[i][1]]
                #weight_opt = np.exp(-total_cost)
                #Fallunterscheidung: theta = index von Messung wenn die Detektion einem Objekt entspicht, theta = 0 wenn die Detektion einem Clutter entspricht
                if indexes_opt[i][1]< m :
                    theta_k[0][i] = indexes_opt[i][1] +1
                    if number_coordinates ==1 :
                       z_opt_assossiation = measurement_k[indexes_opt[i][1]] # Messung der wahrscheinlichsten Hypothese
                    else:
                       z_opt_assossiation = measurement_k[np.arange(0,number_coordinates,1)][indexes_opt[i][1]]

                else:
                    theta_k[0][i] = 0

                estimate_i,P_i = kalman_filter_update(estimate_i,P_i,H,z_opt_assossiation,theta_k[0][i],R,number_coordinates) #Update P und estimate_i mit Kalman-Korrekturschritt
                P[0:number_states,i*number_states:number_states*(i+1)] = P_i #P_i in die gesamte P Matrix wieder einfügen
                estimate[0:number_states,i] = estimate_i #estimates_i in die gesamte estimates Matrix wieder einfügen

            estimate_all.append(estimate.tolist())

        return estimate_all

def kalman_filter_prediction(estimates_i, P_i,F,Q):
    estimates_i, P_i = filterpy.kalman.predict(estimates_i, P_i,F,Q) #Kalman Prädiktion estimates und P
    return estimates_i, P_i

def kalman_filter_update(estimate_i,P_i,H,z_opt_assossiation,theta_i,R,number_coordinates):
    if theta_i != 0: #Wenn Objekt detektiert wurde => Kalmanprediktion durchführen
        estimate_i, P_i = filterpy.kalman.update(estimate_i, P_i,z_opt_assossiation,R, H) #Kalman Korrektur für estimates und P
    else: #Objekt nicht erkannt => Werte durchreichen
        P_i = P_i
        estimate_i = estimate_i
    return estimate_i,P_i


import pytest
import time, itertools, traceback
from colorama import init, Fore, Style
init()

from lib.logger import Logger, Level
from lib.config_loader import ConfigLoader
from lib.event import Event
from lib.message import Message
from lib.message_bus import MessageBus
from lib.message_factory import MessageFactory
from lib.clock import Clock
from lib.ifs import IntegratedFrontSensor
#from lib.indicator import Indicator

# ..............................................................................
class MockMessageQueue():
    '''
    This message queue just displays IFS events as they arrive.
    '''
    def __init__(self, level):
        super().__init__()
        self._count = 0
        self._counter = itertools.count()
        self._log = Logger("queue", Level.INFO)
        self._listeners = []
        self._triggered_ir_port_side = False
        self._triggered_ir_port      = False
        self._triggered_ir_cntr      = False
        self._triggered_ir_stbd      = False
        self._triggered_ir_stbd_side = False
        self._triggered_bmp_port     = False
        self._triggered_bmp_cntr     = False
        self._triggered_bmp_stbd     = False
        self._log.info('ready.')

    # ......................................................
    def add(self, message):
        self._log.debug(Fore.BLUE + 'add message {}'.format(message))
        self.add(message)

    # ......................................................
    def add(self, message):
        self._count = next(self._counter)
        message.number = self._count
        _event = message.event
        self._log.debug('added message #{}; priority {}: {}; event: {}'.format(message.number, message.priority, message.description, _event))
        _value = message.value

        if _event is Event.BUMPER_PORT and not self._triggered_bmp_port:
            self._log.info(Fore.RED + Style.BRIGHT + 'BUMPER_PORT: {}; value: {}'.format(_event.description, _value))
            self._triggered_bmp_port     = True
        elif _event is Event.BUMPER_CNTR and not self._triggered_bmp_cntr:
            self._log.info(Fore.BLUE + Style.BRIGHT + 'BUMPER_CNTR: {}; value: {}'.format(_event.description, _value))
            self._triggered_bmp_cntr     = True
        elif _event is Event.BUMPER_STBD and not self._triggered_bmp_stbd:
            self._log.info(Fore.GREEN + Style.BRIGHT + 'BUMPER_STBD: {}; value: {}'.format(_event.description, _value))
            self._triggered_bmp_stbd     = True

        elif _event is Event.INFRARED_PORT_SIDE and not self._triggered_ir_port_side:
            self._log.debug(Fore.RED  + '> INFRARED_PORT_SIDE: {}; value: {}'.format(_event.description, _value))
            self._triggered_ir_port_side = True
        elif _event is Event.INFRARED_PORT and not self._triggered_ir_port:
            self._log.debug(Fore.RED  + '> INFRARED_PORT: {}; value: {}'.format(_event.description, _value))
            self._triggered_ir_port      = True
        elif _event is Event.INFRARED_CNTR and not self._triggered_ir_cntr:
            self._log.debug(Fore.BLUE + '> INFRARED_CNTR:     distance: {:>5.2f}cm'.format(_value))
            self._triggered_ir_cntr      = True
        elif _event is Event.INFRARED_STBD and not self._triggered_ir_stbd:
            self._log.debug(Fore.GREEN + '> INFRARED_STBD: {}; value: {}'.format(_event.description, _value))
            self._triggered_ir_stbd      = True
        elif _event is Event.INFRARED_STBD_SIDE and not self._triggered_ir_stbd_side:
            self._log.debug(Fore.GREEN + '> INFRARED_STBD_SIDE: {}; value: {}'.format(_event.description, _value))
            self._triggered_ir_stbd_side = True

        else:
            self._log.debug(Fore.BLACK + Style.BRIGHT + 'other event: {}'.format(_event.description))

    # ..........................................................................
    def add_listener(self, listener):
        '''
        Add a listener to the optional list of message listeners.
        '''
        return self._listeners.append(listener)

    # ..........................................................................
    def remove_listener(self, listener):
        '''
        Remove the listener from the list of message listeners.
        '''
        try:
            self._listeners.remove(listener)
        except ValueError:
            self._log.warn('message listener was not in list.')

    # ......................................................
    @property
    def all_triggered(self):
        _all_ir_triggered  = self._triggered_ir_port_side and self._triggered_ir_port and self._triggered_ir_cntr and self._triggered_ir_stbd and self._triggered_ir_stbd_side
        _all_bmp_triggered = self._triggered_bmp_port and self._triggered_bmp_cntr and self._triggered_bmp_stbd
        return _all_ir_triggered and _all_bmp_triggered

    # ......................................................
    @property
    def count(self):
        return self._count

    # ..........................................................................
    def waiting_for_message(self):
        _fmt = '{0:>9}'
        self._log.info('waiting for: | ' \
                + Fore.RED   + _fmt.format( 'PORT_SIDE' if not self._triggered_ir_port_side else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.RED   + _fmt.format( 'PORT' if not self._triggered_ir_port else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.BLUE  + _fmt.format( 'CNTR' if not self._triggered_ir_cntr else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.GREEN + _fmt.format( 'STBD' if not self._triggered_ir_stbd else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.GREEN + _fmt.format( 'STBD_SIDE' if not self._triggered_ir_stbd_side else '' )
                + Fore.CYAN  + ' || ' \
                + Fore.RED   + _fmt.format( 'BMP_PORT' if not self._triggered_bmp_port else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.BLUE  + _fmt.format( 'BMP_CNTR' if not self._triggered_bmp_cntr else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.GREEN + _fmt.format( 'BMP_STBD' if not self._triggered_bmp_stbd else '' ) \
                + Fore.CYAN  + ' |' )

# ..............................................................................
@pytest.mark.unit
def test_ifs():
    '''
    Test the functionality of Integrated Front Sensor.
    '''
    _log = Logger("test-ifs", Level.INFO)

    # read YAML configuration
    _loader = ConfigLoader(Level.INFO)
    filename = 'config.yaml'
    _config = _loader.configure(filename)

    _message_factory = MessageFactory(Level.INFO)
    _message_bus = MessageBus(Level.INFO)

    _log.info('creating clock...')
    _clock = Clock(_config, _message_bus, _message_factory, Level.WARN)

    _ifs = IntegratedFrontSensor(_config, _clock, Level.INFO)

    # establish queue to receive messages
    _queue = MockMessageQueue(Level.INFO)
    _message_bus.add_handler(Message, _queue.add)

    _ifs.enable()
    _clock.enable()

    while not _queue.all_triggered:
        _queue.waiting_for_message()
        time.sleep(0.5)
    _ifs.disable()

    assert _queue.count > 0
    _log.info('test complete.' + Style.RESET_ALL)

# ..............................................................................
def main():

    try:
        test_ifs()
    except KeyboardInterrupt:
        print(Fore.RED + 'Ctrl-C caught; exiting...' + Style.RESET_ALL)
    except Exception as e:
        print(Fore.RED + Style.BRIGHT + 'error testing ifs: {}\n{}'.format(e, traceback.format_exc()) + Style.RESET_ALL)

if __name__== "__main__":
    main()

#EOF


#############################################
## - Author: Chunlai.hua                   ##
## - Date  : 2017-10-10                    ##
## - Lang  : Python                        ##
## - Func  : Downlaod the target page      ##
#############################################

## <1> 重试下载功能
## <2> 设置用户代理
## <3> 下载目标网页

from bs4 import BeautifulSoup
import urllib
import urllib.request
import re

def download(url, num_retries):
    head = {}
    head['User-agent'] = 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36'
    print ("Downloading the page", url)
    try:
        request = urllib.request.Request(url, headers=head)
        html    = urllib.request.urlopen(request).read()
    except urllib.request.URLError as e:
        print ("Download Error:", e.reason)
        html = None
        if num_retries > 0:
            if hasattr(e, 'code') and 500 <= e.code < 600:
                return download(url, num_retries-1)
    return html

## ---- belwo content just for test ##
f     = open("./html", "wb")
url1  = "http://www.baidu.com"
html  = download(url1,2)
f.write(html)
f.close

##---- 获取百度首页logo图片 ----##

## 正则抓取
html = html.decode('utf-8')
img = re.findall('<img.*?src="(.*?)".*?>',html)

def getImg(items):
    print (len(items))
    x = 1
    for imgurl in items:
        print (imgurl)
        print ("正在下载第%s张图片" %x)
        if 'https' in imgurl:
            try:
                urllib.request.urlretrieve(imgurl,'%s.jpg' % x)
                x+=1
            except urllib.request.URLError:
                print ("error", imgurl)
        else:
            imgurl = "https:"+ imgurl
            try:
                urllib.request.urlretrieve(imgurl,'%s.jpg' % x)
                x+=1
            except urllib.request.URLError:
                print ("error", imgurl)
getImg(img)


from typing import Literal, Optional, Union

from playwright.sync_api import (
    Browser,
    BrowserContext,
    ElementHandle,
    Locator,
    Page,
    Playwright,
)
from robocorp_ls_core.robotframework_log import get_logger

from ._browser_engines import BrowserEngine

__version__ = "2.1.0"
version_info = [int(x) for x in __version__.split(".")]

log = get_logger(__name__)

def configure(**kwargs) -> None:
    """
    May be called before any other method to configure the browser settings.

    Calling this method is optional (if not called a default configuration will
    be used -- note that calling this method after the browser is already
    initialized will have no effect).

    Args:
        browser_engine: Browser engine which should be used (default: Chromium)
        headless: If set to False the browser UI will be shown. If set to True
            the browser UI will be kept hidden. If unset or set to None it'll
            show the browser UI only if a debugger is detected.
        slowmo: Run interactions in slow motion.
        screenshot: Whether to automatically capture a screenshot after each task.
            Options are `on`, `off`, and `only-on-failure` (default).
        viewport_size: Size to be set for the viewport. Specified as tuple(width, height).

    Note:
        See also: `robocorp.browser.configure_context` to change other
        arguments related to the browser context creation.
    """  # noqa
    from ._browser_context import _browser_config

    config = _browser_config()

    for key, value in kwargs.items():
        if key == "viewport_size":
            width, height = value
            configure_context(viewport={"width": width, "height": height})
            continue

        if not hasattr(config, key):
            raise ValueError(f"Invalid configuration: {key}.")
        setattr(config, key, value)

def configure_context(**kwargs) -> None:
    """
    While the most common configurations may be configured through `configure`,
    not all arguments passed to `playwright.Browser.new_context` are covered.

    For cases where different context keyword arguments are needed it's possible
    to use this method to customize the keyword arguments passed to
    `playwright.Browser.new_context`.

    Example:
        ```python
        from robocorp import browser
        browser.configure_context(ignore_https_errors = True)
        ```

    Note:
        The changes done persist through the full session, so, new tasks which
        create a browser context will also get the configuration changes.
        If the change should not be used across tasks it's possible
        to call `robocorp.browser.context(...)` with the required arguments
        directly.
    """
    from . import _browser_context

    browser_context_kwargs = _browser_context.browser_context_kwargs()
    browser_context_kwargs.update(kwargs)

def page() -> Page:
    """
    Provides a managed instance of the browser page to interact with.

    Returns:
        The browser page to interact with.

        Note that after a page is created, the same page is returned until the
        current task finishes or the page is closed.

        If a new page is required without closing the current page use:

        ```python
        from robocorp import browser
        page = browser.context().new_page()
        ```
    """
    from . import _browser_context

    return _browser_context.page()

def browser() -> Browser:
    """
    Provides a managed instance of the browser to interact with.

    Returns:
        The browser which should be interacted with.

        If no browser is created yet one is created and the same one
        is returned on new invocations.

        To customize the browser use the `configure` method (prior
        to calling this method).

        Note that the returned browser must not be closed. It will be
        automatically closed when the task run session finishes.
    """
    from . import _browser_context

    return _browser_context.browser()

def playwright() -> Playwright:
    """
    Provides a managed instance of playwright to interact with.

    Returns:
        The playwright instance to interact with.

        If no playwright instance is created yet one is created and the same one
        is returned on new invocations.

        To customize it use the `configure` method (prior
        to calling this method).

        Note that the returned instance must not be closed. It will be
        automatically closed when the task run session finishes.
    """
    from . import _browser_context

    return _browser_context.playwright()

def context(**kwargs) -> BrowserContext:
    """
    Provides a managed instance of the browser context to interact with.

    Returns:
        The browser context instance to interact with.

        If no browser context instance is created yet one is created and the
        same one is returned on new invocations.

        Note that the returned instance must not be closed. It will be
        automatically closed when the task run session finishes.

    Note:
        If the context is not created it's possible to customize the context
        arguments through the kwargs provided, by using the `configure(...)`
        method or by editing the `configure_context(...)` returned dict.

        If the context was already previously created the **kwargs passed will
        be ignored.
    """
    from . import _browser_context

    return _browser_context.context(**kwargs)

def goto(url: str) -> Page:
    """
    Changes the url of the current page (creating a page if needed).

    Args:
        url: Navigates to the provided URL.

    Returns:
        The page instance managed by the robocorp.tasks framework
        (it will be automatically closed when the task finishes).
    """
    p = page()
    p.goto(url)
    return p

def screenshot(
    element: Optional[Union[Page, ElementHandle, Locator]] = None,
    timeout: int = 5000,
    image_type: Literal["png", "jpeg"] = "png",
) -> bytes:
    """
    Takes a screenshot of the given page/element/locator and saves it to the
    log. If no element is provided the screenshot will target the current page.

    Note: the element.screenshot can be used if the screenshot is not expected
    to be added to the log.

    Args:
        element: The page/element/locator which should have its screenshot taken. If not
        given the managed page instance will be used.

    Returns:
        The bytes from the screenshot.
    """
    import base64

    if element is None:
        from . import _browser_context

        element = _browser_context.page()

    in_bytes = element.screenshot(timeout=timeout, type=image_type)
    # in_base64 = base64.b64encode(in_bytes).decode("ascii")

    return in_bytes

def install(browser_engine: BrowserEngine):
    """
    Downloads and installs the given browser engine.

    Note: Google Chrome or Microsoft Edge installations will be installed
    at the default global location of your operating system overriding your
    current browser installation.

    Args:
        browser_engine: Browser engine which should be installed
    """
    from . import _browser_engines

    _browser_engines.install_browser(browser_engine, force=False)

__all__ = [
    "configure",
    "configure_context",
    "page",
    "browser",
    "playwright",
    "context",
    "goto",
    "screenshot",
    "install",
    "BrowserEngine",
]


import tensorflow as tf
import numpy as np

x = tf.sparse_placeholder(tf.float32)
y = tf.sparse_reduce_sum(x)

with tf.Session() as sess:
    indices = np.array([[3, 2, 0], [4, 5, 1]], dtype=np.int64)
    values = np.array([1.0, 2.0], dtype=np.float32)
    shape = np.array([7, 9, 2], dtype=np.int64)

    s1 = (indices, values, shape)
    s2 = (indices, values, shape)
    s3 = np.vstack((s1, s2))
    print(sess.run(y, feed_dict={
        x: tf.SparseTensorValue(indices, values, shape)}))  # Will succeed.
    print(sess.run(y, feed_dict={
        x: (indices, values, shape)}))  # Will succeed.
    print(sess.run(y, feed_dict={
        x: s3}))  # Will succeed.


from typing import Optional

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

# O(h + k) time | O(h) space, h --> height of the tree
class Solution:
    def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
        stack = []
        count = 0
        node = root
        while node or stack:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            count += 1
            if count == k:
                return node.val
            node = node.right


import math
from sympy import *
import scipy.integrate as spi
import numpy as np
def fxE(exp, a):
    x = symbols('x')
    res = sympify(exp).subs(x, a).evalf()
    return res

def trapecio(f, a, b, n=1000):
    h = (b-a)/float(n)
    s = 0.5*(fxE(f,a) + fxE(f,b))
    for i in range(1,n,1):
        s = s + fxE(f,a + i*h)
    return h*s

# Function for approximate integral
def simpson(f,a, b, n=100):
    h = (b - a) / n
    x = list()
    fx = list()
    i = 0
    while i <= n:
        x.append(a + i * h)
        fx.append(fxE(f,x[i]))
        i += 1

    res = 0
    i = 0
    while i <= n:
        if i == 0 or i == n:
            res += fx[i]
        elif i % 2 != 0:
            res += 4 * fx[i]
        else:
            res += 2 * fx[i]
        i += 1
    res = res * (h / 3)
    return res

def mean(a, b):
    meanValue = (a + b) / 2
    return meanValue

def puntomedio(f,a,b,n=100):
    deltaX = (b - a) / n

    xValue = [a]
    heightValue = []

    for i in range(0, n):
        xValue.append(a + deltaX)
        deltaX = deltaX + (b - a) / n

    for i in xValue:
        heightValue.append(fxE(f,mean(i, i + (b - a) / n)))
    del heightValue[-1]

    the_sum = sum(heightValue)
    definite_integral = the_sum * ((b - a) / n)

    return definite_integral

print(simpson("(250*x/(6+x**2))*E**(-x/10)",0,30))


"""
Name: zibin chen
User ID: zchen393
"""

import datetime as dt
import pandas as pd
import util as ut
import StrategyLearner as sl
import marketsimcode as msc
import ManualStrategy as ms
import matplotlib.pyplot as plt
from numpy import random

symbol = 'JPM'
sd=dt.datetime(2008,1,1)
ed=dt.datetime(2009,12,31)
sv = 100000

'''
strategy learner
'''

random.seed(12)
learner = sl.StrategyLearner(verbose = False, impact = 0.000) # constructor
learner.addEvidence(symbol = symbol, sd=sd, ed=ed, sv = sv) # training phase
df_trades = learner.testPolicy(symbol = symbol, sd=sd, ed=ed, sv = sv) # testing phase
daily_value_strategy = msc.compute_portvals(order = df_trades, symbol = symbol, start_val = sv, commission=0, impact=0.000)/sv

'''
benchmark
'''
date = pd.date_range(sd, ed)
stockvals = ut.get_data([symbol], date)
stockvals = stockvals.loc[:, [symbol]]
Benchmark = pd.DataFrame(0, index = stockvals.index[[0,-1]], columns = ['Order'])
Benchmark['Order'].iloc[0] = 1000
Benchmark['Order'].iloc[-1] = -1000
daily_value_benchmark = msc.compute_portvals(order = Benchmark, symbol = 'JPM', start_val = sv, commission=0, impact=0.000)/sv

'''
manuel strategy
'''
order = ms.testPolicy(symbol = 'JPM', sd = sd, ed = ed, sv = sv)
daily_value_manual = msc.compute_portvals(order = order, symbol = 'JPM', start_val = sv, commission=0, impact=0.000)/sv

cr_benchmark, adr_benchmark, sddr_benchmark = ms.portstats(daily_value_benchmark)
cr_manual, adr_manual, sddr_manual = ms.portstats(daily_value_manual)
cr_strategy, adr_strategy, sddr_strategy = ms.portstats(daily_value_strategy)

buy_m = order[order['Order'] > 0]
sell_m = order[order['Order'] < 0]

plt.figure(figsize=(20,5))
plt.plot(daily_value_benchmark.index, daily_value_benchmark, label = "Benchmark", color = "Blue")
plt.plot(daily_value_manual.index,daily_value_manual, label = "Manual Strategy", color = "Black")
buy_date = buy_m.shape[0]
for td in range(0,buy_date):
    plt.axvline(pd.to_datetime(buy_m.index[td]), color = "Green")
sell_date = sell_m.shape[0]
for td in range(0,sell_date):
    plt.axvline(pd.to_datetime(sell_m.index[td]), color = "Red")

plt.title("Manual Strategy vs Benchmark: In-Sample")
plt.legend()
plt.xlabel("Date")
plt.show()

buy_s = df_trades[df_trades['Order'] > 0]
sell_s = df_trades[df_trades['Order'] < 0]
plt.figure(figsize=(20,5))
plt.plot(daily_value_benchmark.index, daily_value_benchmark, label = "Benchmark", color = "Blue")

plt.plot(daily_value_manual.index,daily_value_strategy, label = "Strategy Learner", color = "Black")
buy_date = buy_s.shape[0]
for td in range(0,buy_date):
    plt.axvline(pd.to_datetime(buy_s.index[td]), color = "Green")
sell_date = sell_s.shape[0]
for td in range(0,sell_date):
    plt.axvline(pd.to_datetime(sell_s.index[td]), color = "Red")

plt.title("Strategy Learner vs Benchmark: In-Sample")
plt.legend()
plt.xlabel("Date")
plt.show()


# https://www.acmicpc.net/problem/10995

# 첫째 줄에 N을 입력합니다.
# 1 <= N <= 100
N = int(input())

# 별을 출력 중일 때 현재 줄이 홀수 번째 줄인지 아닌지를 판별하는 변수를 선언합니다.
is_odd_line = True

# 별의 패턴을 입력한 N만큼의 줄로 반복합니다.
for line in range(N):
    # 별을 출력할 줄이 홀수 번째 줄이라면
    if is_odd_line == True:
        # 별 패턴을 반복합니다.
        for i in range(N):
            # 홀수 번째 줄에서는 '* ' 형태로 반복합니다.
            print('* ', end='')
        # 현재 줄에서 별 패턴을 다 출력했으면 다음 줄은 짝수 번째 줄이므로 is_odd_line의 값을 바꿉니다.
        is_odd_line = False
    # 별을 출력할 줄이 짝수 번째 줄이라면
    else:
        # 별 패턴을 반복합니다.
        for i in range(N):
            # 짝수 번째 줄에서는 ' *' 형태로 반복합니다.
            print(' *', end='')
        # 현재 줄에서 별 패턴을 다 출력했으면 다음 줄은 홀수 번째 줄이므로 is_odd_line의 값을 바꿉니다.
        is_odd_line = True

    # 다음 줄로 넘어갑니다.
    print()

백준/Bronze/Bronze 2/10995번 ; 별 찍기 - 20.py


import torch
import torchvision
import torchvision.transforms as transforms
import PIL
import numpy as np
import os
from . import generative_model

base_params = {"size":[3,3,3], "poison_label":0, "random_pos":False, "dataset_name":"cifar10",
                "normalize_param" : None, "trigger" : None, "random_init" : None, "trigger_path" : None}

class PoisonTrainer:
    name = "base_attack"
    def __init__(self, model, dataloader, loss_func, optim, trigger, poison_prob, device,
                      trigger_params, scheduler = None, val_loader = None, test_loader = None):
        self.device = device
        self.model = model.to(self.device)
        self.dataloader = dataloader
        self.loss_func = loss_func
        self.trigger = trigger
        self.optim = optim
        self.scheduler = scheduler
        self.val_loader = val_loader
        self.test_loader = test_loader
        self.poison_prob = poison_prob
        self.trigger_params = trigger_params

    def train(self, epoch, valid_func):
        scaler = torch.cuda.amp.GradScaler(enabled=True)
        for epoch_ in range(1, epoch + 1):
            for data, label in self.dataloader:
                self.optim.zero_grad()
                data, label = data.to(self.device), label.to(self.device)
                poison_data, poison_label = self.trigger.paste(data, label, self.poison_prob)

                with torch.cuda.amp.autocast(enabled = True):
                    predict = self.model(data)
                    loss = self.loss_func(predict, label)
                    if poison_label != None:
                        loss = loss + self.poison_prob * self.loss_func(self.model(poison_data), poison_label)
                scaler.scale(loss).backward()
                scaler.step(self.optim)
                scaler.update()
            if self.scheduler:
                self.scheduler.step()
            clean_acc, poison_acc = self.validate()
            print("clean_acc = {:.2f}, poison_acc = {:.2f}\n".format(clean_acc, poison_acc))
        valid_func(self.model, self.trigger.trigger, clean_acc, poison_acc, self.device)

    @torch.no_grad()
    def validate(self):
        num, num2, poison_num, clean_num = 0, 0, 0, 0
        # accuracy and attack success rate
        for data, label in self.val_loader:
            data, label = data.to(self.device), label.to(self.device)
            clean_predict = self.model(data)
            clean_num += (clean_predict.max(dim = 1)[1] == label).sum().item()
            mask = (label != self.trigger.poison_label)
            poison_data, poison_label = self.trigger.paste(data[mask], label[mask], 1.)
            poison_predict = self.model(poison_data)
            poison_num += (poison_predict.max(dim = 1)[1] == self.trigger.poison_label).sum().item()
            num += label.size()[0]
            num2 += mask.sum().item()
        return clean_num / num * 100., poison_num / num2 * 100.

    def load(self, path):
        checkpoint = torch.load(path)
        self.model.load_state_dict(checkpoint["model"])
        self.trigger.trigger = checkpoint["trigger"]
        if self.name == "TrojanNNAttack":
            self.trigger.trigger = checkpoint["trigger"].trigger
        self.trigger.trigger = self.trigger.trigger.to(self.device)

class BadNet(PoisonTrainer):
    name = "BadNet"
    def __init__(self, model, dataloader, loss_func, optim, poison_prob, device,
                      trigger_params, scheduler = None, val_loader = None, test_loader = None):
        super(BadNet, self).__init__(model, dataloader, loss_func, optim, None, poison_prob, device,
                      trigger_params, scheduler, val_loader, test_loader)
        base_params.update(trigger_params)
        self.trigger = Trigger(size = base_params["size"], poison_label = base_params["poison_label"],
                                random_pos = False, device = device,
                                normalize_param = base_params["normalize_param"], trigger = base_params["trigger"],
                                random_init = base_params["random_init"], trigger_path = base_params["trigger_path"])

class BlendAttack(PoisonTrainer):
    name = "BlendAttack"
    def __init__(self, model, dataloader, loss_func, optim, poison_prob, device,
                      trigger_params, scheduler = None, val_loader = None, test_loader = None):
        super(BlendAttack, self).__init__(model, dataloader, loss_func, optim, None, poison_prob, device,
                      trigger_params, scheduler, val_loader, test_loader)
        base_params.update(trigger_params)
        self.trigger = BlendTrigger(size = base_params["size"], poison_label = base_params["poison_label"],
                                random_pos = base_params["random_pos"], device = device,
                                normalize_param = base_params["normalize_param"], trigger = base_params["trigger"],
                                random_init = base_params["random_init"], trigger_path = base_params["trigger_path"])

class EnhancedTriggerAttack(PoisonTrainer):
    name = "EnhancedTriggerAttack"
    def __init__(self, model, dataloader, loss_func, optim, poison_prob, device,
                      trigger_params, scheduler = None, val_loader = None, test_loader = None):
        super(EnhancedTriggerAttack, self).__init__(model, dataloader, loss_func, optim, None, poison_prob, device,
                      trigger_params, scheduler, val_loader, test_loader)
        base_params.update(trigger_params)
        self.trigger = EnhancedTrigger(size = base_params["size"], poison_label = base_params["poison_label"],
                                random_pos = base_params["random_pos"], device = device,
                                normalize_param = base_params["normalize_param"], trigger = base_params["trigger"],
                                random_init = base_params["random_init"], trigger_path = base_params["trigger_path"])
        self.trigger.data_shape = {"mnist":[1,28,28], "fashionmnist":[1,28,28], "SVHN":[3,32,32], "cifar10":[3,32,32], "cifar100":[3,32,32]}[base_params["dataset_name"]]


from pprint import pprint
from itertools import product
class Person:
    def __init__(self, name, surname,father_name, age, address):
        self.name,self.surname, self.father_name, self.age, self.address = name, surname, father_name, age, address
        self.key = (name, address)

    def __repr__(self):
        return "Person('%s', '%s', '%s', %s, '%s')" % (self.name,self.surname,self.father_name, self.age, self.address)

    def __eq__(self, obj):
        if type(obj) == Person:
            return (self.name, self.surname, self.father_name, self.age, self.address) == (obj.name, obj.surname,
                                                                                obj.father_name, obj.age,
                                                                                obj.address)
        elif type(obj) == str:
            return self.fuzzy_compare(obj)
        else:
            return self.__repr__() == obj.__repr__()

    ## реализация нечеткого запроса
    ADDRESS_WORDS = {'дом', 'улица', 'живет'}
    NAME_WORDS = {'имя', 'зовут'}
    AGE_WORDS = {'возраст', 'старше', 'младше'}
    SURNAME_WORDS ={'фамилия'}
    FATHERNAME_WORDS = {'отчество', 'по-батюшке'}

    def compare(self, s1, s2):
        s1, s2 = [s.lower() for s in [s1,s2]]
        ngrams = [s1[i:i+3] for i in range(len(s1))]
        count = 0
        for ngram in ngrams:
            count += s2.count(ngram)
        return count / max(len(s1),len(s2))

    def int_val(self,s):
        try:
            return int(s)
        except ValueError:
            return 0

    def fuzzy_compare(self, query):
        def by_address(Q):
            Q = Q - self.ADDRESS_WORDS
            W = set(self.address.split())
            rez = []
            for a, b in product(Q, W):
                rez += [(self.compare(a, b), a, b)]
            return max(rez)[0]

        def by_age(Q):
            q_age = max([self.int_val(q) for q in Q])
            if 'старше' in Q:
                return q_age < self.age
            if 'младше' in Q:
                return q_age > self.age
            return q_age + 5 >= self.age >= q_age - 5

        def by_name(Q):
            Q = Q - self.NAME_WORDS
            W = set(self.name.split())
            rez = []
            for a, b in product(Q, W):
                rez += [(self.compare(a, b), a, b)]
            return max(rez)[0]
        def by_surname(Q):
            Q = Q - self.SURNAME_WORDS
            W = set(self.surname.split())
            rez = []
            for a, b in product(Q, W):
                rez += [(self.compare(a, b), a, b)]
            return max(rez)[0]

        def by_fathername(Q):
            Q = Q - self.FATHERNAME_WORDS
            W = set(self.father_name.split())
            rez = []
            for a, b in product(Q, W):
                rez += [(self.compare(a, b), a, b)]
            return max(rez)[0]

        q_words = set(query.split())
        score = 0
        for m_words, method in zip([self.ADDRESS_WORDS, self.NAME_WORDS, self.AGE_WORDS, self.SURNAME_WORDS,
                                    self.FATHERNAME_WORDS],
                        [by_address, by_name, by_age, by_surname, by_fathername]):
            if m_words & q_words:
                score += method(q_words)
        return score > 0.49

lena = Person("Лена","Ленина", "Александровна", 19, "Пушкина, 14, 115")
oleg = Person("Олег", "Ленский", "Михайлович", 34, "Ленского, 10, 11")
olga = Person("Ольга","Хоритонова", "Константиновна",  28, "Онегина,  11,  12")
nata = Person("Наташа","Шемякина", "Александровна", 17, "Ростова,  16,  15")

people = {
    lena.key: lena,
    oleg.key: oleg,
    olga.key: olga,
    nata.key: nata,
}

##pprint(people)

queries = [
    'имя Ольга', 'возраст 30', 'старше 20', 'младше 20', 'живет на Пушкина', 'дом 10', 'фамилия ростова', 'зовут нташа',
    'женского пола', 'фамилия Ленна', 'по-батюшке Александровна',
]

for query, person in product(queries, people.values()):
    if person == query:
       pprint((query,person))

##Добавлены фамилия и отчество, разбитые в другие поля
##Ошибка в видео - self для функций не был указан


import os, sys, platform

__SUPPORT_ANSI__ = False

class style:
    RESET_ALL         = "\033[0m"

    # Style set
    BOLD              = "\033[1m"
    DIM               = "\033[2m"
    UNDERLINED        = "\033[4m"
    BLINK             = "\033[5m"
    REVERSE           = "\033[7m"
    HIDDEN            = "\033[8m"

    # Style reset
    RESET_BOLD        = "\033[21m"
    RESET_DIM         = "\033[22m"
    RESET_UNDERLINED  = "\033[24m"
    RESET_BLINK       = "\033[25m"
    RESET_REVERSE     = "\033[27m"
    RESET_HIDDEN      = "\033[28m"

    # Foreground color
    DEFAULT           = "\033[39m"
    BLACK             = "\033[30m"
    RED               = "\033[31m"
    GREEN             = "\033[32m"
    YELLOW            = "\033[33m"
    BLUE              = "\033[34m"
    MAGENTA           = "\033[35m"
    CYAN              = "\033[36m"
    LIGHT_GRAY        = "\033[37m"
    DARK_GRAY         = "\033[90m"
    LIGHT_RED         = "\033[91m"
    LIGHT_GREEN       = "\033[92m"
    LIGHT_YELLOW      = "\033[93m"
    LIGHT_BLUE        = "\033[94m"
    LIGHT_MAGENTA     = "\033[95m"
    LIGHT_CYAN        = "\033[96m"
    WHITE             = "\033[97m"

    # Background color
    BCK_DEFAULT       = "\033[49m"
    BCK_BLACK         = "\033[40m"
    BCK_RED           = "\033[41m"
    BCK_GREEN         = "\033[42m"
    BCK_YELLOW        = "\033[43m"
    BCK_BLUE          = "\033[44m"
    BCK_MAGENTA       = "\033[45m"
    BCK_CYAN          = "\033[46m"
    BCK_LIGHT_GRAY    = "\033[47m"
    BCK_DARK_GRAY     = "\033[100m"
    BCK_LIGHT_RED     = "\033[101m"
    BCK_LIGHT_GREEN   = "\033[102m"
    BCK_LIGHT_YELLOW  = "\033[103m"
    BCK_LIGHT_BLUE    = "\033[104m"
    BCK_LIGHT_MAGENTA = "\033[105m"
    BCK_LIGHT_CYAN    = "\033[106m"
    BCK_WHITE         = "\033[107m"

class flags:
    ENDC = style.DEFAULT
    WARN = style.YELLOW
    INFO = style.BLUE
    ERR  = style.RED

def checkANSI():
        if platform.system() == 'Windows' and not ('TERM' in os.environ and os.environ['TERM']=='ANSI'):
            __SUPPORT_ANSI__ = False
        else:
            __SUPPORT_ANSI__ = True

def warn(*args, **kwargs):
    if __SUPPORT_ANSI__:
        print(flags.WARN + "[WARN]:" + flags.ENDC + " ".join(map(str,args)), **kwargs)
    else:
        print("[WARN]:" + " ".join(map(str, args)), **kwargs)

def err(*args, **kwargs):
    if __SUPPORT_ANSI__:
        print(flags.ERR + "[ERR]:" + flags.ENDC + " ".join(map(str,args)), **kwargs)
    else:
        print("[ERR]:" + " ".join(map(str, args)), **kwargs)

def info(*args, **kwargs):
    if __SUPPORT_ANSI__:
        print(flags.INFO + "[INFO]:" + flags.ENDC+ " ".join(map(str,args)), **kwargs)
    else:
        print("[INFO]:" + " ".join(map(str, args)), **kwargs)


from django.contrib import admin

from mainapp import models

class MovieAdmin(admin.ModelAdmin):
    list_filter = ('release_date',)
    fieldsets = (
        (None, {
            'fields': ('title', 'release_date')
        }),
        ('Details', {
            'classes': ('collapse',),
            'fields': ('description',),
        }),
    )

admin.site.register(models.Movie, MovieAdmin)


from sklearn.neural_network.multilayer_perceptron import MLPClassifier
from sklearn import datasets

# Since the book came out, the cross_validation method has been moved to
# the model_selection library from the cross_validation library
#from sklearn.cross_validation import train_test_split
from sklearn.model_selection import train_test_split

from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score

import numpy
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt

#Apply standardization
standardised = True

M = {0:"sepal length", 1:"sepal width", 2:"petal length", 3:"petal width"}

#Choose two features
x=1 #1 corresponds to the sepal width
y=3 #3 corresponds to the petal width

iris = datasets.load_iris()
data = iris.data[:,[x,y]]

labels = iris.target

X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.5, random_state=1)

reg = StandardScaler()
reg.fit(data)
X_train_std = reg.transform(X_train)
X_test_std = reg.transform(X_test)

if (standardised == False):
  X_train_std = X_train
  X_test_std = X_test

# We add max_iter=1000 becaue the default is max_iter=200 and
# it is not enough for full convergence
mlp = MLPClassifier(random_state=1, max_iter=1000)
mlp.fit(X_train_std, y_train)

y_pred = mlp.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())

print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

def plot_decision_regions(data, labels, classifier, resolution=0.01):
    markers = ('s', '*', '^')
    colors = ('blue', 'green', 'red')
    cmap = ListedColormap(colors)
    # plot the decision surface
    x_min, x_max = data[:, 0].min() - 1, data[:, 0].max() + 1
    y_min, y_max = data[:, 1].min() - 1, data[:, 1].max() + 1

    x, y = numpy.meshgrid(numpy.arange(x_min, x_max, resolution), numpy.arange(y_min, y_max, resolution))
    Z = classifier.predict(numpy.array([x.ravel(), y.ravel()]).T)
    Z = Z.reshape(x.shape)

    plt.pcolormesh(x, y, Z, cmap=cmap)
    plt.xlim(x.min(), x.max())
    plt.ylim(y.min(), y.max())

    colors = ('yellow', 'white', 'black')
    #cmap = ListedColormap(colors)
    #plot the data
    classes = ["setosa", "versicolor", "verginica"]
    for index, cl in enumerate(numpy.unique(labels)):
        plt.scatter(data[labels == cl, 0], data[labels == cl, 1], c=cmap(index), marker=markers[index], edgecolor="black", alpha=1.0, s=50, label=classes[index])

X_combined_std = numpy.vstack((X_train_std, X_test_std))
y_combined = numpy.hstack((y_train, y_test))
plot_decision_regions(X_combined_std, y_combined, classifier=mlp)

if (standardised == False):
  xString = M[x] + " [not standardized]"
  yString = M[y] + " [not standardized]"
else:
  xString = M[x] + " [standardized]"
  yString = M[y] + " [standardized]"

plt.xlabel(xString)
plt.ylabel(yString)
plt.legend(loc='upper left')
plt.show()


import inspect
import logging
import numpy as np
from typing import Dict, List, Optional, Tuple
import torch
from torch import nn
from detectron2.data.detection_utils import convert_image_to_rgb
from detectron2.config import configurable
from detectron2.layers import ShapeSpec, nonzero_tuple
from detectron2.structures import Boxes, ImageList, Instances, pairwise_iou
from detectron2.utils.events import get_event_storage
from detectron2.modeling.backbone import Backbone, build_backbone
from detectron2.modeling.postprocessing import detector_postprocess
from detectron2.modeling.proposal_generator import build_proposal_generator
from detectron2.modeling.roi_heads import build_roi_heads, ROI_HEADS_REGISTRY, ROIHeads
from detectron2.modeling.meta_arch.build import META_ARCH_REGISTRY
from detectron2.modeling.poolers import ROIPooler
from detectron2.modeling.roi_heads.roi_heads import select_proposals_with_visible_keypoints, select_foreground_proposals
from detectron2.modeling.roi_heads.box_head import build_box_head
from detectron2.modeling.roi_heads.fast_rcnn import FastRCNNOutputLayers
from detectron2.modeling.roi_heads.keypoint_head import build_keypoint_head
from detectron2.modeling.roi_heads.mask_head import build_mask_head

logger = logging.getLogger(__name__)

__all__ = ["MyRCNN", "MyROIHeads"]

@META_ARCH_REGISTRY.register()
class MyRCNN(nn.Module):
    """
    Generalized R-CNN. Any models that contains the following three components:
    1. Per-image feature extraction (aka backbone)
    2. Region proposal generation
    3. Per-region feature extraction and prediction
    """

    @configurable
    def __init__(
        self,
        *,
        backbone: Backbone,
        proposal_generator: nn.Module,
        roi_heads: nn.Module,
        pixel_mean: Tuple[float],
        pixel_std: Tuple[float],
        input_format: Optional[str] = None,
        vis_period: int = 0,
    ):
        """
        NOTE: this interface is experimental.

        Args:
            backbone: a backbone module, must follow detectron2's backbone interface
            proposal_generator: a module that generates proposals using backbone features
            roi_heads: a ROI head that performs per-region computation
            pixel_mean, pixel_std: list or tuple with #channels element,
                representing the per-channel mean and std to be used to normalize
                the input image
            input_format: describe the meaning of channels of input. Needed by visualization
            vis_period: the period to run visualization. Set to 0 to disable.
        """
        super().__init__()
        self.backbone = backbone
        self.proposal_generator = proposal_generator
        self.roi_heads = roi_heads

        self.input_format = input_format
        self.vis_period = vis_period
        if vis_period > 0:
            assert input_format is not None, "input_format is required for visualization!"

        self.register_buffer("pixel_mean", torch.Tensor(pixel_mean).view(-1, 1, 1))
        self.register_buffer("pixel_std", torch.Tensor(pixel_std).view(-1, 1, 1))
        assert (
            self.pixel_mean.shape == self.pixel_std.shape
        ), f"{self.pixel_mean} and {self.pixel_std} have different shapes!"

    @classmethod
    def from_config(cls, cfg):
        backbone = build_backbone(cfg)
        return {
            "backbone": backbone,
            "proposal_generator": build_proposal_generator(cfg, backbone.output_shape()),
            "roi_heads": build_roi_heads(cfg, backbone.output_shape()),
            "input_format": cfg.INPUT.FORMAT,
            "vis_period": cfg.VIS_PERIOD,
            "pixel_mean": cfg.MODEL.PIXEL_MEAN,
            "pixel_std": cfg.MODEL.PIXEL_STD,
        }

    @property
    def device(self):
        return self.pixel_mean.device

    def visualize_training(self, batched_inputs, proposals):
        """
        A function used to visualize images and proposals. It shows ground truth
        bounding boxes on the original image and up to 20 top-scoring predicted
        object proposals on the original image. Users can implement different
        visualization functions for different models.

        Args:
            batched_inputs (list): a list that contains input to the model.
            proposals (list): a list that contains predicted proposals. Both
                batched_inputs and proposals should have the same length.
        """
        from detectron2.utils.visualizer import Visualizer

        storage = get_event_storage()
        max_vis_prop = 20

        for input, prop in zip(batched_inputs, proposals):
            img = input["image"]
            img = convert_image_to_rgb(img.permute(1, 2, 0), self.input_format)
            v_gt = Visualizer(img, None)
            v_gt = v_gt.overlay_instances(boxes=input["instances"].gt_boxes)
            anno_img = v_gt.get_image()
            box_size = min(len(prop.proposal_boxes), max_vis_prop)
            v_pred = Visualizer(img, None)
            v_pred = v_pred.overlay_instances(
                boxes=prop.proposal_boxes[0:box_size].tensor.cpu().numpy()
            )
            prop_img = v_pred.get_image()
            vis_img = np.concatenate((anno_img, prop_img), axis=1)
            vis_img = vis_img.transpose(2, 0, 1)
            vis_name = "Left: GT bounding boxes;  Right: Predicted proposals"
            storage.put_image(vis_name, vis_img)
            break  # only visualize one image in a batch

    def forward(self, batched_inputs, detected_instances=None):
        """
        Args:
            batched_inputs: a list, batched outputs of :class:`DatasetMapper` .
                Each item in the list contains the inputs for one image.
                For now, each item in the list is a dict that contains:

                * image: Tensor, image in (C, H, W) format.
                * instances (optional): groundtruth :class:`Instances`
                * proposals (optional): :class:`Instances`, precomputed proposals.

                Other information that's included in the original dicts, such as:

                * "height", "width" (int): the output resolution of the model, used in inference.
                  See :meth:`postprocess` for details.

        Returns:
            list[dict]:
                Each dict is the output for one input image.
                The dict contains one key "instances" whose value is a :class:`Instances`.
                The :class:`Instances` object has the following keys:
                "pred_boxes", "pred_classes", "scores", "pred_masks", "pred_keypoints"
        """
        if not self.training:
            return self.inference(batched_inputs, detected_instances)

        images = self.preprocess_image(batched_inputs)
        if "instances" in batched_inputs[0]:
            gt_instances = [x["instances"].to(self.device) for x in batched_inputs]
        else:
            gt_instances = None

        features = self.backbone(images.tensor)

        if self.proposal_generator:
            proposals, proposal_losses = self.proposal_generator(images, features, gt_instances)
        else:
            assert "proposals" in batched_inputs[0]
            proposals = [x["proposals"].to(self.device) for x in batched_inputs]
            proposal_losses = {}

        _, detector_losses = self.roi_heads(images, features, proposals, gt_instances)
        if self.vis_period > 0:
            storage = get_event_storage()
            if storage.iter % self.vis_period == 0:
                self.visualize_training(batched_inputs, proposals)

        losses = {}
        losses.update(detector_losses)
        losses.update(proposal_losses)
        return losses

    def inference(self, batched_inputs, detected_instances=None, do_postprocess=True):
        """
        Run inference on the given inputs.

        Args:
            batched_inputs (list[dict]): same as in :meth:`forward`
            detected_instances (None or list[Instances]): if not None, it
                contains an `Instances` object per image. The `Instances`
                object contains "pred_boxes" and "pred_classes" which are
                known boxes in the image.
                The inference will then skip the detection of bounding boxes,
                and only predict other per-ROI outputs.
            do_postprocess (bool): whether to apply post-processing on the outputs.

        Returns:
            When do_postprocess=True, same as in :meth:`forward`.
            Otherwise, a list[Instances] containing raw network outputs.
        """
        assert not self.training

        images = self.preprocess_image(batched_inputs)
        features = self.backbone(images.tensor)

        if detected_instances is None:
            if self.proposal_generator:
                proposals, _ = self.proposal_generator(images, features, None)
            else:
                assert "proposals" in batched_inputs[0]
                proposals = [x["proposals"].to(self.device) for x in batched_inputs]

            results, _ = self.roi_heads(images, features, proposals, None)
        else:
            detected_instances = [x.to(self.device) for x in detected_instances]
            features = self.roi_heads.forward_with_given_boxes_(features, detected_instances)

        if do_postprocess and detected_instances is None:
            return MyRCNN._postprocess(results, batched_inputs, images.image_sizes)
        else:
            return features

    def preprocess_image(self, batched_inputs):
        """
        Normalize, pad and batch the input images.
        """
        images = [x["image"].to(self.device) for x in batched_inputs]
        images = [(x - self.pixel_mean) / self.pixel_std for x in images]
        images = ImageList.from_tensors(images, self.backbone.size_divisibility)
        return images

    @staticmethod
    def _postprocess(instances, batched_inputs, image_sizes):
        """
        Rescale the output instances to the target size.
        """
        # note: private function; subject to changes
        processed_results = []
        for results_per_image, input_per_image, image_size in zip(
            instances, batched_inputs, image_sizes
        ):
            height = input_per_image.get("height", image_size[0])
            width = input_per_image.get("width", image_size[1])
            r = detector_postprocess(results_per_image, height, width)
            processed_results.append({"instances": r})
        return processed_results

@ROI_HEADS_REGISTRY.register()
class MyROIHeads(ROIHeads):
    """
    It's "standard" in a sense that there is no ROI transform sharing
    or feature sharing between tasks.
    Each head independently processes the input features by each head's
    own pooler and head.

    This class is used by most models, such as FPN and C5.
    To implement more models, you can subclass it and implement a different
    :meth:`forward()` or a head.
    """

    @configurable
    def __init__(
        self,
        *,
        box_in_features: List[str],
        box_pooler: ROIPooler,
        box_head: nn.Module,
        box_predictor: nn.Module,
        mask_in_features: Optional[List[str]] = None,
        mask_pooler: Optional[ROIPooler] = None,
        mask_head: Optional[nn.Module] = None,
        keypoint_in_features: Optional[List[str]] = None,
        keypoint_pooler: Optional[ROIPooler] = None,
        keypoint_head: Optional[nn.Module] = None,
        train_on_pred_boxes: bool = False,
        **kwargs
    ):
        """
        NOTE: this interface is experimental.

        Args:
            box_in_features (list[str]): list of feature names to use for the box head.
            box_pooler (ROIPooler): pooler to extra region features for box head
            box_head (nn.Module): transform features to make box predictions
            box_predictor (nn.Module): make box predictions from the feature.
                Should have the same interface as :class:`FastRCNNOutputLayers`.
            mask_in_features (list[str]): list of feature names to use for the mask
                pooler or mask head. None if not using mask head.
            mask_pooler (ROIPooler): pooler to extract region features from image features.
                The mask head will then take region features to make predictions.
                If None, the mask head will directly take the dict of image features
                defined by `mask_in_features`
            mask_head (nn.Module): transform features to make mask predictions
            keypoint_in_features, keypoint_pooler, keypoint_head: similar to ``mask_*``.
            train_on_pred_boxes (bool): whether to use proposal boxes or
                predicted boxes from the box head to train other heads.
        """
        super().__init__(**kwargs)
        # keep self.in_features for backward compatibility
        self.in_features = self.box_in_features = box_in_features
        self.box_pooler = box_pooler
        self.box_head = box_head
        self.box_predictor = box_predictor

        self.mask_on = mask_in_features is not None
        if self.mask_on:
            self.mask_in_features = mask_in_features
            self.mask_pooler = mask_pooler
            self.mask_head = mask_head

        self.keypoint_on = keypoint_in_features is not None
        if self.keypoint_on:
            self.keypoint_in_features = keypoint_in_features
            self.keypoint_pooler = keypoint_pooler
            self.keypoint_head = keypoint_head

        self.train_on_pred_boxes = train_on_pred_boxes

    @classmethod
    def from_config(cls, cfg, input_shape):
        ret = super().from_config(cfg)
        ret["train_on_pred_boxes"] = cfg.MODEL.ROI_BOX_HEAD.TRAIN_ON_PRED_BOXES
        # Subclasses that have not been updated to use from_config style construction
        # may have overridden _init_*_head methods. In this case, those overridden methods
        # will not be classmethods and we need to avoid trying to call them here.
        # We test for this with ismethod which only returns True for bound methods of cls.
        # Such subclasses will need to handle calling their overridden _init_*_head methods.
        if inspect.ismethod(cls._init_box_head):
            ret.update(cls._init_box_head(cfg, input_shape))
        if inspect.ismethod(cls._init_mask_head):
            ret.update(cls._init_mask_head(cfg, input_shape))
        if inspect.ismethod(cls._init_keypoint_head):
            ret.update(cls._init_keypoint_head(cfg, input_shape))
        return ret

    @classmethod
    def _init_box_head(cls, cfg, input_shape):
        # fmt: off
        in_features       = cfg.MODEL.ROI_HEADS.IN_FEATURES
        pooler_resolution = cfg.MODEL.ROI_BOX_HEAD.POOLER_RESOLUTION
        pooler_scales     = tuple(1.0 / input_shape[k].stride for k in in_features)
        sampling_ratio    = cfg.MODEL.ROI_BOX_HEAD.POOLER_SAMPLING_RATIO
        pooler_type       = cfg.MODEL.ROI_BOX_HEAD.POOLER_TYPE
        # fmt: on

        # If StandardROIHeads is applied on multiple feature maps (as in FPN),
        # then we share the same predictors and therefore the channel counts must be the same
        in_channels = [input_shape[f].channels for f in in_features]
        # Check all channel counts are equal
        assert len(set(in_channels)) == 1, in_channels
        in_channels = in_channels[0]

        box_pooler = ROIPooler(
            output_size=pooler_resolution,
            scales=pooler_scales,
            sampling_ratio=sampling_ratio,
            pooler_type=pooler_type,
        )
        # Here we split "box head" and "box predictor", which is mainly due to historical reasons.
        # They are used together so the "box predictor" layers should be part of the "box head".
        # New subclasses of ROIHeads do not need "box predictor"s.
        box_head = build_box_head(
            cfg, ShapeSpec(channels=in_channels, height=pooler_resolution, width=pooler_resolution)
        )
        box_predictor = FastRCNNOutputLayers(cfg, box_head.output_shape)
        return {
            "box_in_features": in_features,
            "box_pooler": box_pooler,
            "box_head": box_head,
            "box_predictor": box_predictor,
        }

    @classmethod
    def _init_mask_head(cls, cfg, input_shape):
        if not cfg.MODEL.MASK_ON:
            return {}
        # fmt: off
        in_features       = cfg.MODEL.ROI_HEADS.IN_FEATURES
        pooler_resolution = cfg.MODEL.ROI_MASK_HEAD.POOLER_RESOLUTION
        pooler_scales     = tuple(1.0 / input_shape[k].stride for k in in_features)
        sampling_ratio    = cfg.MODEL.ROI_MASK_HEAD.POOLER_SAMPLING_RATIO
        pooler_type       = cfg.MODEL.ROI_MASK_HEAD.POOLER_TYPE
        # fmt: on

        in_channels = [input_shape[f].channels for f in in_features][0]

        ret = {"mask_in_features": in_features}
        ret["mask_pooler"] = (
            ROIPooler(
                output_size=pooler_resolution,
                scales=pooler_scales,
                sampling_ratio=sampling_ratio,
                pooler_type=pooler_type,
            )
            if pooler_type
            else None
        )
        if pooler_type:
            shape = ShapeSpec(
                channels=in_channels, width=pooler_resolution, height=pooler_resolution
            )
        else:
            shape = {f: input_shape[f] for f in in_features}
        ret["mask_head"] = build_mask_head(cfg, shape)
        return ret

    @classmethod
    def _init_keypoint_head(cls, cfg, input_shape):
        if not cfg.MODEL.KEYPOINT_ON:
            return {}
        # fmt: off
        in_features       = cfg.MODEL.ROI_HEADS.IN_FEATURES
        pooler_resolution = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_RESOLUTION
        pooler_scales     = tuple(1.0 / input_shape[k].stride for k in in_features)  # noqa
        sampling_ratio    = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_SAMPLING_RATIO
        pooler_type       = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_TYPE
        # fmt: on

        in_channels = [input_shape[f].channels for f in in_features][0]

        ret = {"keypoint_in_features": in_features}
        ret["keypoint_pooler"] = (
            ROIPooler(
                output_size=pooler_resolution,
                scales=pooler_scales,
                sampling_ratio=sampling_ratio,
                pooler_type=pooler_type,
            )
            if pooler_type
            else None
        )
        if pooler_type:
            shape = ShapeSpec(
                channels=in_channels, width=pooler_resolution, height=pooler_resolution
            )
        else:
            shape = {f: input_shape[f] for f in in_features}
        ret["keypoint_head"] = build_keypoint_head(cfg, shape)
        return ret

    def forward(
        self,
        images: ImageList,
        features: Dict[str, torch.Tensor],
        proposals: List[Instances],
        targets: Optional[List[Instances]] = None,
    ) -> Tuple[List[Instances], Dict[str, torch.Tensor]]:
        """
        See :class:`ROIHeads.forward`.
        """
        del images
        if self.training:
            assert not torch.jit.is_scripting()
            assert targets, "'targets' argument is required during training"
            proposals = self.label_and_sample_proposals(proposals, targets)
        del targets

        if self.training:
            assert not torch.jit.is_scripting()
            losses = self._forward_box(features, proposals)
            # Usually the original proposals used by the box head are used by the mask, keypoint
            # heads. But when `self.train_on_pred_boxes is True`, proposals will contain boxes
            # predicted by the box head.
            losses.update(self._forward_mask(features, proposals))
            losses.update(self._forward_keypoint(features, proposals))
            return proposals, losses
        else:
            pred_instances = self._forward_box(features, proposals)
            # During inference cascaded prediction is used: the mask and keypoints heads are only
            # applied to the top scoring box detections.
            pred_instances = self.forward_with_given_boxes(features, pred_instances)
            return pred_instances, {}

    def forward_with_given_boxes_(
        self, features: Dict[str, torch.Tensor], instances: List[Instances]
    ) -> List[Instances]:
        """
        Use the given boxes in `instances` to produce other (non-box) per-ROI outputs.

        This is useful for downstream tasks where a box is known, but need to obtain
        other attributes (outputs of other heads).
        Test-time augmentation also uses this.

        Args:
            features: same as in `forward()`
            instances (list[Instances]): instances to predict other outputs. Expect the keys
                "pred_boxes" and "pred_classes" to exist.

        Returns:
            instances (list[Instances]):
                the same `Instances` objects, with extra
                fields such as `pred_masks` or `pred_keypoints`.
        """
        assert not self.training
        assert instances[0].has("pred_boxes") and instances[0].has("pred_classes")

        features = self._forward_feat(features, instances)
        return features

    def forward_with_given_boxes(
        self, features: Dict[str, torch.Tensor], instances: List[Instances]
    ) -> List[Instances]:
        """
        Use the given boxes in `instances` to produce other (non-box) per-ROI outputs.

        This is useful for downstream tasks where a box is known, but need to obtain
        other attributes (outputs of other heads).
        Test-time augmentation also uses this.

        Args:
            features: same as in `forward()`
            instances (list[Instances]): instances to predict other outputs. Expect the keys
                "pred_boxes" and "pred_classes" to exist.

        Returns:
            instances (list[Instances]):
                the same `Instances` objects, with extra
                fields such as `pred_masks` or `pred_keypoints`.
        """
        assert not self.training
        assert instances[0].has("pred_boxes") and instances[0].has("pred_classes")

        instances = self._forward_mask(features, instances)
        instances = self._forward_keypoint(features, instances)
        return instances

    def _forward_box(self, features: Dict[str, torch.Tensor], proposals: List[Instances]):
        """
        Forward logic of the box prediction branch. If `self.train_on_pred_boxes is True`,
            the function puts predicted boxes in the `proposal_boxes` field of `proposals` argument.

        Args:
            features (dict[str, Tensor]): mapping from feature map names to tensor.
                Same as in :meth:`ROIHeads.forward`.
            proposals (list[Instances]): the per-image object proposals with
                their matching ground truth.
                Each has fields "proposal_boxes", and "objectness_logits",
                "gt_classes", "gt_boxes".

        Returns:
            In training, a dict of losses.
            In inference, a list of `Instances`, the predicted instances.
        """
        features = [features[f] for f in self.box_in_features]
        box_features = self.box_pooler(features, [x.proposal_boxes for x in proposals])
        box_features = self.box_head(box_features)
        predictions = self.box_predictor(box_features)
        del box_features

        if self.training:
            assert not torch.jit.is_scripting()
            losses = self.box_predictor.losses(predictions, proposals)
            # proposals is modified in-place below, so losses must be computed first.
            if self.train_on_pred_boxes:
                with torch.no_grad():
                    pred_boxes = self.box_predictor.predict_boxes_for_gt_classes(
                        predictions, proposals
                    )
                    for proposals_per_image, pred_boxes_per_image in zip(proposals, pred_boxes):
                        proposals_per_image.proposal_boxes = Boxes(pred_boxes_per_image)
            return losses
        else:
            pred_instances, _ = self.box_predictor.inference(predictions, proposals)
            return pred_instances

    def _forward_mask(self, features: Dict[str, torch.Tensor], instances: List[Instances]):
        """
        Forward logic of the mask prediction branch.

        Args:
            features (dict[str, Tensor]): mapping from feature map names to tensor.
                Same as in :meth:`ROIHeads.forward`.
            instances (list[Instances]): the per-image instances to train/predict masks.
                In training, they can be the proposals.
                In inference, they can be the boxes predicted by R-CNN box head.

        Returns:
            In training, a dict of losses.
            In inference, update `instances` with new fields "pred_masks" and return it.
        """
        if not self.mask_on:
            # https://github.com/pytorch/pytorch/issues/43942
            if self.training:
                assert not torch.jit.is_scripting()
                return {}
            else:
                return instances

        # https://github.com/pytorch/pytorch/issues/46703
        assert hasattr(self, "mask_head")

        if self.training:
            assert not torch.jit.is_scripting()
            # head is only trained on positive proposals.
            instances, _ = select_foreground_proposals(instances, self.num_classes)

        if self.mask_pooler is not None:
            features = [features[f] for f in self.mask_in_features]
            boxes = [x.proposal_boxes if self.training else x.pred_boxes for x in instances]
            features = self.mask_pooler(features, boxes)
        else:
            # https://github.com/pytorch/pytorch/issues/41448
            features = dict([(f, features[f]) for f in self.mask_in_features])
        return self.mask_head(features, instances)

    def _forward_feat(self, features: Dict[str, torch.Tensor], instances: List[Instances]):
        """
        Forward logic of the mask prediction branch.

        Args:
            features (dict[str, Tensor]): mapping from feature map names to tensor.
                Same as in :meth:`ROIHeads.forward`.
            instances (list[Instances]): the per-image instances to train/predict masks.
                In training, they can be the proposals.
                In inference, they can be the boxes predicted by R-CNN box head.

        Returns:
            In training, a dict of losses.
            In inference, update `instances` with new fields "pred_masks" and return it.
        """
        if not self.mask_on:
            # https://github.com/pytorch/pytorch/issues/43942
            if self.training:
                assert not torch.jit.is_scripting()
                return {}
            else:
                return instances

        # https://github.com/pytorch/pytorch/issues/46703
        assert hasattr(self, "mask_head")

        if self.training:
            assert not torch.jit.is_scripting()
            # head is only trained on positive proposals.
            instances, _ = select_foreground_proposals(instances, self.num_classes)

        if self.mask_pooler is not None:
            features = [features[f] for f in self.mask_in_features]
            boxes = [x.proposal_boxes if self.training else x.pred_boxes for x in instances]
            features = self.mask_pooler(features, boxes)
        else:
            # https://github.com/pytorch/pytorch/issues/41448
            features = dict([(f, features[f]) for f in self.mask_in_features])
        return features

    def _forward_keypoint(self, features: Dict[str, torch.Tensor], instances: List[Instances]):
        """
        Forward logic of the keypoint prediction branch.

        Args:
            features (dict[str, Tensor]): mapping from feature map names to tensor.
                Same as in :meth:`ROIHeads.forward`.
            instances (list[Instances]): the per-image instances to train/predict keypoints.
                In training, they can be the proposals.
                In inference, they can be the boxes predicted by R-CNN box head.

        Returns:
            In training, a dict of losses.
            In inference, update `instances` with new fields "pred_keypoints" and return it.
        """
        if not self.keypoint_on:
            if self.training:
                assert not torch.jit.is_scripting()
                return {}
            else:
                return instances

        assert hasattr(self, "keypoint_head")

        if self.training:
            assert not torch.jit.is_scripting()
            # head is only trained on positive proposals with >=1 visible keypoints.
            instances, _ = select_foreground_proposals(instances, self.num_classes)
            instances = select_proposals_with_visible_keypoints(instances)

        if self.keypoint_pooler is not None:
            features = [features[f] for f in self.keypoint_in_features]
            boxes = [x.proposal_boxes if self.training else x.pred_boxes for x in instances]
            features = self.keypoint_pooler(features, boxes)
        else:
            features = dict([(f, features[f]) for f in self.keypoint_in_features])
        return self.keypoint_head(features, instances)


import math

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch import _softmax_backward_data as _softmax_backward_data
from torch.utils import checkpoint

class Bert(nn.Module):
    def __init__(self, config, classifier="basic", activation_checkpointing=False):
        super().__init__()
        self.embedding = Embedding(config)
        self.transformer = Encoder(config, activation_checkpointing)
        self.classifier = MaskClassifier(config, self.embedding.word_embedding.weight)
        if classifier != "basic":
            self.next_sentence_classifier = NextSentenceClassifier(config)
        else:
            self.next_sentence_classifier = None

    def get_contextualized(self, input_ids, attention_mask):
        static_embeddings, relative_embedding = self.embedding(input_ids)
        contextualized_embeddings = self.transformer(static_embeddings, attention_mask.unsqueeze(1).unsqueeze(2), relative_embedding)
        return contextualized_embeddings

    def forward(self, input_ids, attention_mask, masked_lm_labels=None):
        contextualized_embeddings = self.get_contextualized(input_ids, attention_mask)[-1]
        subword_prediction = self.classifier(contextualized_embeddings, masked_lm_labels)

        if self.next_sentence_classifier:
            next_sentence_prediction = self.next_sentence_classifier(contextualized_embeddings)
        else:
            next_sentence_prediction = None

        return subword_prediction, next_sentence_prediction

class Encoder(nn.Module):
    def __init__(self, config, activation_checkpointing=False):
        super().__init__()
        self.layers = nn.ModuleList([EncoderLayer(config) for _ in range(config.num_hidden_layers)])

        for i, layer in enumerate(self.layers):
            layer.mlp.mlp[1].weight.data *= math.sqrt(1.0 / (2.0 * (1 + i)))
            layer.mlp.mlp[-2].weight.data *= math.sqrt(1.0 / (2.0 * (1 + i)))

        self.activation_checkpointing = activation_checkpointing

    def forward(self, hidden_states, attention_mask, relative_embedding):
        hidden_states = [hidden_states]
        for layer in self.layers:
            if self.activation_checkpointing:
                hidden_states.append(
                    checkpoint.checkpoint(layer, hidden_states[-1], attention_mask, relative_embedding)
                )
            else:
                hidden_states.append(
                    layer(hidden_states[-1], attention_mask, relative_embedding)
                )

        return hidden_states

class MaskClassifier(nn.Module):
    def __init__(self, config, subword_embedding):
        super().__init__()
        self.nonlinearity = nn.Sequential(
            nn.LayerNorm(config.hidden_size, config.layer_norm_eps, elementwise_affine=False),
            nn.Linear(config.hidden_size, config.hidden_size),
            nn.GELU(),
            nn.Dropout(config.hidden_dropout_prob),
            nn.LayerNorm(config.hidden_size, config.layer_norm_eps, elementwise_affine=False),
            nn.Linear(subword_embedding.size(1), subword_embedding.size(0))
        )
        self.initialize(config.hidden_size, subword_embedding)

    def initialize(self, hidden_size, embedding):
        std = math.sqrt(2.0 / (5.0 * hidden_size))
        nn.init.trunc_normal_(self.nonlinearity[1].weight, mean=0.0, std=std, a=-2*std, b=2*std)
        self.nonlinearity[-1].weight = embedding
        self.nonlinearity[1].bias.data.zero_()
        self.nonlinearity[-1].bias.data.zero_()

    def forward(self, x, masked_lm_labels=None):
        if masked_lm_labels is not None:
            x = torch.index_select(x.flatten(0, 1), 0, torch.nonzero(masked_lm_labels.flatten() != -100).squeeze())
        x = self.nonlinearity(x)
        return x

class NextSentenceClassifier(nn.Module):
    def __init__(self, config):
        super().__init__()
        self.nonlinearity = nn.Sequential(
            nn.LayerNorm(config.hidden_size, config.layer_norm_eps, elementwise_affine=False),
            nn.Linear(config.hidden_size, config.hidden_size),
            nn.GELU(),
            nn.Dropout(config.hidden_dropout_prob),
            nn.LayerNorm(config.hidden_size, config.layer_norm_eps, elementwise_affine=False),
            nn.Linear(config.hidden_size, 1)
        )
        self.initialize(config.hidden_size)

    def initialize(self, hidden_size):
        std = math.sqrt(2.0 / (5.0 * hidden_size))
        nn.init.trunc_normal_(self.nonlinearity[1].weight, mean=0.0, std=std, a=-2*std, b=2*std)
        nn.init.trunc_normal_(self.nonlinearity[-1].weight, mean=0.0, std=std, a=-2*std, b=2*std)
        self.nonlinearity[1].bias.data.zero_()
        self.nonlinearity[-1].bias.data.zero_()

    def forward(self, x):
        x = self.nonlinearity(x[0, :, :]).squeeze(-1)
        return x

class EncoderLayer(nn.Module):
    def __init__(self, config):
        super().__init__()
        self.attention = Attention(config)
        self.mlp = FeedForward(config)

    def forward(self, x, padding_mask, relative_embedding):
        x = x + self.attention(x, padding_mask, relative_embedding)
        x = x + self.mlp(x)
        return x

class GeGLU(nn.Module):
    def forward(self, x):
        x, gate = x.chunk(2, dim=-1)
        x = x * F.gelu(gate, approximate='tanh')
        return x

class FeedForward(nn.Module):
    def __init__(self, config):
        super().__init__()
        self.mlp = nn.Sequential(
            nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps, elementwise_affine=False),
            nn.Linear(config.hidden_size, 2*config.intermediate_size, bias=False),
            GeGLU(),
            nn.LayerNorm(config.intermediate_size, eps=config.layer_norm_eps, elementwise_affine=False),
            nn.Linear(config.intermediate_size, config.hidden_size, bias=False),
            nn.Dropout(config.hidden_dropout_prob)
        )
        self.initialize(config.hidden_size)

    def initialize(self, hidden_size):
        std = math.sqrt(2.0 / (5.0 * hidden_size))
        nn.init.trunc_normal_(self.mlp[1].weight, mean=0.0, std=std, a=-2*std, b=2*std)
        nn.init.trunc_normal_(self.mlp[-2].weight, mean=0.0, std=std, a=-2*std, b=2*std)

    def forward(self, x):
        return self.mlp(x)

class MaskedSoftmax(torch.autograd.Function):
    @staticmethod
    def forward(self, x, mask, dim):
        self.dim = dim
        x.masked_fill_(mask, float('-inf'))
        x = torch.softmax(x, self.dim)
        x.masked_fill_(mask, 0.0)
        self.save_for_backward(x)
        return x

    @staticmethod
    def backward(self, grad_output):
        output, = self.saved_tensors
        inputGrad = _softmax_backward_data(grad_output, output, self.dim, output.dtype)
        return inputGrad, None, None

class Attention(nn.Module):
    def __init__(self, config):
        super().__init__()

        if config.hidden_size % config.num_attention_heads != 0:
            raise ValueError(f"The hidden size {config.hidden_size} is not a multiple of the number of attention heads {config.num_attention_heads}")

        self.hidden_size = config.hidden_size
        self.num_heads = config.num_attention_heads
        self.head_size = config.hidden_size // config.num_attention_heads

        self.in_proj_qk = nn.Linear(config.hidden_size, 2*config.hidden_size, bias=True)
        self.in_proj_v = nn.Linear(config.hidden_size, config.hidden_size, bias=True)
        self.out_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=True)

        self.pre_layer_norm = nn.LayerNorm(config.hidden_size, config.layer_norm_eps, elementwise_affine=False)
        self.post_layer_norm = nn.LayerNorm(config.hidden_size, config.layer_norm_eps, elementwise_affine=True)

        position_indices = torch.arange(config.max_position_embeddings, dtype=torch.long).unsqueeze(1) \
            - torch.arange(config.max_position_embeddings, dtype=torch.long).unsqueeze(0)
        position_indices = self.make_log_bucket_position(position_indices, config.position_bucket_size, config.max_position_embeddings)
        position_indices = config.position_bucket_size - 1 + position_indices
        self.register_buffer("position_indices", position_indices, persistent=True)

        self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
        self.scale = 1.0 / math.sqrt(3 * self.head_size)
        self.initialize()

    def make_log_bucket_position(self, relative_pos, bucket_size, max_position):
        sign = torch.sign(relative_pos)
        mid = bucket_size // 2
        abs_pos = torch.where((relative_pos < mid) & (relative_pos > -mid), mid - 1, torch.abs(relative_pos))
        log_pos = torch.ceil(torch.log(abs_pos / mid) / math.log((max_position-1) / mid) * (mid - 1)).int() + mid
        bucket_pos = torch.where(abs_pos <= mid, relative_pos, log_pos * sign).long()
        return bucket_pos

    def initialize(self):
        std = math.sqrt(2.0 / (5.0 * self.hidden_size))
        nn.init.trunc_normal_(self.in_proj_qk.weight, mean=0.0, std=std, a=-2*std, b=2*std)
        nn.init.trunc_normal_(self.in_proj_v.weight, mean=0.0, std=std, a=-2*std, b=2*std)
        nn.init.trunc_normal_(self.out_proj.weight, mean=0.0, std=std, a=-2*std, b=2*std)
        self.in_proj_qk.bias.data.zero_()
        self.in_proj_v.bias.data.zero_()
        self.out_proj.bias.data.zero_()

    def compute_attention_scores(self, hidden_states, relative_embedding):
        key_len, batch_size, _ = hidden_states.size()
        query_len = key_len

        hidden_states = self.pre_layer_norm(hidden_states)

        query, key = self.in_proj_qk(hidden_states).chunk(2, dim=2)  # shape: [T, B, D]
        value = self.in_proj_v(hidden_states)  # shape: [T, B, D]

        pos = self.in_proj_qk(self.dropout(relative_embedding))  # shape: [2T-1, 2D]
        pos = F.embedding(self.position_indices[:query_len, :key_len], pos)  # shape: [T, T, 2D]
        pos = pos.view(query_len, key_len, self.num_heads, 2*self.head_size)
        query_pos, key_pos = pos.chunk(2, dim=3)

        query = query.reshape(query_len, batch_size * self.num_heads, self.head_size).transpose(0, 1)
        key = key.reshape(key_len, batch_size * self.num_heads, self.head_size).transpose(0, 1)
        value = value.view(key_len, batch_size * self.num_heads, self.head_size).transpose(0, 1)

        attention_scores = torch.bmm(query, key.transpose(1, 2) * self.scale)

        query = query.view(batch_size, self.num_heads, query_len, self.head_size)
        key = key.view(batch_size, self.num_heads, query_len, self.head_size)
        attention_scores = attention_scores.view(batch_size, self.num_heads, query_len, key_len)
        attention_scores.add_(torch.einsum("bhqd,qkhd->bhqk", query, key_pos * self.scale))
        attention_scores.add_(torch.einsum("bhkd,qkhd->bhqk", key * self.scale, query_pos))

        return attention_scores, value

    def compute_output(self, attention_probs, value):
        attention_probs = self.dropout(attention_probs)
        context = torch.bmm(attention_probs.flatten(0, 1), value)  # shape: [B*H, Q, D]
        context = context.transpose(0, 1).reshape(context.size(1), -1, self.hidden_size)  # shape: [Q, B, H*D]
        context = self.out_proj(context)
        context = self.post_layer_norm(context)
        context = self.dropout(context)
        return context

    def forward(self, hidden_states, attention_mask, relative_embedding):
        attention_scores, value = self.compute_attention_scores(hidden_states, relative_embedding)
        attention_probs = MaskedSoftmax.apply(attention_scores, attention_mask, -1)
        return self.compute_output(attention_probs, value)

class Embedding(nn.Module):
    def __init__(self, config):
        super().__init__()
        self.hidden_size = config.hidden_size

        self.word_embedding = nn.Embedding(config.vocab_size, config.hidden_size)
        self.word_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps, elementwise_affine=False)
        self.dropout = nn.Dropout(config.hidden_dropout_prob)

        self.relative_embedding = nn.Parameter(torch.empty(2 * config.position_bucket_size - 1, config.hidden_size))
        self.relative_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)

        self.initialize()

    def initialize(self):
        std = math.sqrt(2.0 / (5.0 * self.hidden_size))
        nn.init.trunc_normal_(self.relative_embedding, mean=0.0, std=std, a=-2*std, b=2*std)
        nn.init.trunc_normal_(self.word_embedding.weight, mean=0.0, std=std, a=-2*std, b=2*std)

    def forward(self, input_ids):
        word_embedding = self.dropout(self.word_layer_norm(self.word_embedding(input_ids)))
        relative_embeddings = self.relative_layer_norm(self.relative_embedding)
        return word_embedding, relative_embeddings


"""neuron_on_iris.py: show performance of a neuron on iris dataset"""
import matplotlib.pyplot as plt
import numpy as np
import logging
from random import seed
from learning_perceptron import Neuron
from useful.math_functions import sigmoid
from useful.preprocess_dataset import import_data, split_set
from useful.results import confusion_matrix, accuracy, recall

FIG_SIZE = (20, 20)
TRAIN_SIZE = 0.8
LR = 0.5

np.random.seed(123)
seed(123)

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)

    # Initialize neuron
    neuron = Neuron("On iris", 4, sigmoid, LR)

    # iris dataset
    dataset = import_data("../../data/iris.data").T[0:100].T

    dataset[4][0:50] = 1.0
    dataset[4][50:100] = 0.0

    train_set, test_set = split_set(dataset, TRAIN_SIZE)

    epochs = []
    accuracies = []
    recalls = []

    for x1, x2, x3, x4, label in train_set.T.tolist():
        epochs.append(
            neuron.train([x1, x2, x3, x4], label)
        )
        prediction = []
        labels = []
        for y1, y2, y3, y4, label2 in test_set.T.tolist():
            prediction.append(neuron.feed([y1, y2, y3, y4]))
            labels.append(label2)

        c_m = confusion_matrix(np.array(prediction), np.array(labels))
        accuracies.append(accuracy(c_m))
        recalls.append(recall(c_m)[0])

    fig, ax = plt.subplots(figsize=FIG_SIZE)
    ax.plot(epochs, accuracies, label="Accuracy", linewidth=3.5)
    ax.plot(epochs, recalls, "--", label="Recall", linewidth=2.0)
    ax.set_xlabel("Epochs", fontsize=20)
    ax.set_ylabel("Measure", fontsize=20)
    ax.set_title("Sigmoid neuron on Iris Dataset\n", fontsize=30)
    ax.legend(fontsize=20)
    ax.grid()

    plt.savefig("../results/neuron_on_iris.png")


import traceback
import csv
import pkg_resources

from db_adapter.logger import logger

def add_obs_to_d03_grid_mappings_for_rainfall(pool, grid_interpolation, obs_to_d03_map_path, active_obs_path):

    """
    Add observational stations grid mappings to the database
    :param pool:  database connection pool
    :param grid_interpolation: grid interpolation method
    :param obs_to_d03_map_path: path to file containing curw rainfall observational stations to d03 stations mapping
    :param active_obs_path: path to file containing all active curw rainfall observation stations
    :return: True if the insertion is successful, else False
    """
    # [obs_grid_id,d03_1_id,d03_1_dist,d03_2_id,d03_2_dist,d03_3_id,d03_3_dist]
    with open(obs_to_d03_map_path, 'r') as f1:
        obs_d03_mapping=[line for line in csv.reader(f1)][1:]

    # [hash_id,station_id,station_name,latitude,longitude]
    with open(active_obs_path, 'r') as f2:
        obs_stations=[line for line in csv.reader(f2)][1:]

    obs_dict = {}

    for i in range(len(obs_stations)):
        station_id = obs_stations[i][1]
        station_name = obs_stations[i][2]
        obs_dict[station_id] = [station_name]

    grid_mappings_list = []

    for index in range(len(obs_d03_mapping)):
        obs_id = obs_d03_mapping[index][0]
        grid_mapping = ['rainfall_{}_{}_{}'.format(obs_id, obs_dict.get(obs_id)[0], grid_interpolation),
                        obs_d03_mapping[index][1], obs_d03_mapping[index][3],
                        obs_d03_mapping[index][5], obs_d03_mapping[index][7]]
        grid_mappings_list.append(tuple(grid_mapping))

    connection = pool.connection()
    try:
        with connection.cursor() as cursor:
            sql_statement = "INSERT INTO `grid_map_obs` (`grid_id`, `d03_1`, `d03_2`, `d03_3`, `d03_4`)" \
                            " VALUES ( %s, %s, %s, %s, %s) " \
                            "ON DUPLICATE KEY UPDATE `d03_1`=VALUES(`d03_1`), `d03_2`=VALUES(`d03_2`), " \
                            "`d03_3`=VALUES(`d03_3`), `d03_4`=VALUES(`d03_4`);"
            row_count = cursor.executemany(sql_statement, grid_mappings_list)
        connection.commit()
        return row_count
    except Exception as exception:
        connection.rollback()
        error_message = "Insertion of flo2d grid mappings failed."
        logger.error(error_message)
        traceback.print_exc()
        return False
    finally:
        if connection is not None:
            connection.close()

def get_obs_to_d03_grid_mappings_for_rainfall(pool, grid_interpolation):

    """
    Retrieve obs to d03 grid mappings
    :param pool: database connection pool
    :param grid_interpolation: grid interpolation method
    :return: dictionary with grid ids as keys and corresponding obs1, obs2, obs3 station ids as a list
    """

    obs_grid_mappings = {}

    connection = pool.connection()
    try:
        with connection.cursor() as cursor:
            sql_statement = "SELECT `grid_id`,`d03_1`,`d03_2`,`d03_3`,`d03_4` FROM `grid_map_obs` " \
                            "WHERE `grid_id` like %s ESCAPE '$'"
            row_count = cursor.execute(sql_statement, "rainfall$_%$_{}".format(grid_interpolation))
            if row_count > 0:
                results = cursor.fetchall()
                for dict in results:
                    obs_grid_mappings[dict.get("grid_id")] = [dict.get("d03_1"), dict.get("d03_2"),
                                                              dict.get("d03_3"), dict.get("d03_4")]
                return obs_grid_mappings
            else:
                return None
    except Exception as exception:
        error_message = "Retrieving flo2d to obs grid mappings failed"
        logger.error(error_message)
        traceback.print_exc()
        raise exception
    finally:
        if connection is not None:
            connection.close()


#!/usr/bin/env python3

import pandas as pd
import sys

colors = { True: 'red', False: 'blue' }

df = pd.read_csv(sys.argv[1]).sort_values(by=['weekend','hour'])

df_week = df.iloc[0:24].rename(columns = {'sum(free_bases)': 'laboral'})

df_weekend = df.iloc[24:48].rename(columns = {'sum(free_bases)':'finde'})

plot_week = df_week.plot(x='hour')
plot = df_weekend.plot(x='hour', ax=plot_week)

plot.get_figure().savefig(sys.argv[1].split('.')[0]+'.png')


import math
from sys import stdin

def main():
    N = int(stdin.readline())
    # 時刻 t をkeyにしてsunukeの出現を記録
    sunuke_dict = {}
    times = []
    for _ in range(N):
        T, X, A, = map(int, stdin.readline().split())
        sunuke_dict[T] = (X, A)
        times.append(T)

    # dp[i][j]: 時刻 i にて、j の位置にいるときの最大値
    dp = [[-math.inf]*5 for _ in range(times[-1]+1)]  # 不可能なマスは -∞ とする

    dp[0][0] = 0
    for i in range(1, times[-1]+1):
        for j in range(min(i+1, 5)):
            dp[i][j] = 0

    for i in range(1, times[-1]+1):
        for j in range(5):
            if j == 0:
                dp[i][0] = max(dp[i-1][0], dp[i-1][1])
            elif j == 4:
                dp[i][4] = max(dp[i-1][4], dp[i-1][3])
            else:
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-1], dp[i-1][j+1])
        if i in sunuke_dict:
            dp[i][sunuke_dict[i][0]] += sunuke_dict[i][1]

    # for row in dp:
    #     print(row)
    print(max(dp[-1]))

if __name__ == '__main__':
    main()


#lambda / anonymous functions in python :

#square of a number :

'''
lambda function used only when we
have to evaluate only 1 expression
in a function.
'''
func = lambda a:a*a
print(func(5))

add = lambda a,b:a+b
print(add(2,4))

#filter evens and perfect squares from list

from math import ceil
from math import sqrt
from math import floor

lst = [2,4,6,9,11,12,13,14,16]

even_numbers = list(filter(lambda a:a%2==0,lst))
print(*even_numbers)

perfect_squares = list(filter(lambda i:ceil(sqrt(i))==int(sqrt(i)),lst))
print(perfect_squares)

#lambda with map:
'''
map is used when we want to map our values to something else:
lime we can double all values in perfect_squares
'''
double_perfect = list(map(lambda a : a*2,perfect_squares))
print(double_perfect)

#lambda with reduce :
'''
reduce is used when we want to reduce our value
to a single value, like we want to sum our
double_perfect list
'''
from functools import reduce
sum = reduce(lambda a,b:a+b, double_perfect)
print(sum)


import torch_geometric
import torch
import numpy as np
import pandas as pd
import os

from models import HeteroGNN
from dataset import TMDBDataset

task_id = os.getenv("TASK_ID")

hidden_sizes = [8, 16, 24]
dropouts = [0.0, 0.3, 0.5]
lrs = [0.1, 0.03, 0.01]

graph_features = ["overview", "keywords"]

def main():
    global task_id
    global hidden_sizes
    global dropouts
    global lrs
    global graph_features

    task_id = int(task_id)
    print(f"Task id: {task_id}")

    hidden_sizes_idx = task_id // (len(dropouts) * len(lrs) * len(graph_features))
    dropout_idx = (task_id // (len(lrs) * len(graph_features))) % len(dropouts)
    lr_idx = (task_id // len(graph_features)) % len(lrs)

    graph_features_idx = task_id % len(graph_features)

    hidden_size = hidden_sizes[hidden_sizes_idx]
    dropout = dropouts[dropout_idx]
    lr = lrs[lr_idx]
    graph_features = graph_features[graph_features_idx]

    train_model(hidden_size, dropout, lr, graph_features)

def train_model(hidden_size, dropout, lr, graph_features):
    df = TMDBDataset(
        root="./tmp",
        node_feature_method="counter",
        node_feature_params={"min_df": 0.1 if graph_features == "overview" else 0.015},
        node_feature_column_source=graph_features,
        add_additional_node_features=True,
        edge_weight_column_source="cast",
        jaccard_distance_threshold=0,
        graph_type="heterogeneous",
    )

    print(f"Training with hidden size {hidden_size}, dropout {dropout}, lr {lr}")
    graph = df[0]
    graph["movies"].y = np.log(graph["movies"].y)

    split = torch_geometric.transforms.RandomNodeSplit(num_val=0, num_test=0.2)
    graph = split(graph)

    model = HeteroGNN(hidden_channels=hidden_size, out_channels=1, num_layers=1, dropout=dropout)
    model.to(torch.float64)

    optimizer = torch.optim.AdamW(model.parameters(), lr=lr)
    loss_fn = torch.nn.MSELoss()

    train_mse = []
    test_mse = []

    for epoch in range(250):
        optimizer.zero_grad()
        out = model(graph.x_dict, graph.edge_index_dict)
        train_mask = graph["movies"].train_mask
        loss = loss_fn(out[train_mask].ravel(), graph["movies"].y[train_mask])
        loss.backward()
        optimizer.step()
        train_mse.append(loss.item())

        test_mask = graph["movies"].test_mask
        test_mse_val = loss_fn(out[test_mask].ravel(), graph["movies"].y[test_mask]).item()
        test_mse.append(test_mse_val)

    pd.DataFrame(
        {
            "architecture": hidden_size,
            "dropout": dropout,
            "lr": lr,
            "node_features": graph_features,
            "train_mse": train_mse,
            "test_mse": test_mse,
        }
    ).to_csv(
        f"results/hetero_nf={graph_features}_size={hidden_size}_dropout={dropout}_lr={lr}.csv",
        index=False,
    )

if __name__ == "__main__":
    main()