from numbers import Integral
from pathlib import Path
from typing import Any, Callable, Dict, Optional, Union

import numpy as np
from PIL import Image
from torchvision.datasets.utils import download_and_extract_archive
from typing_extensions import Literal

from ._cifar10_base import _CIFAR10Base
from ._utils import md5_check

__all__ = ["CIFAR10C", "CIFAR100C"]

PathLike = Union[str, Path]
Corruptions = Literal[
    "brightness",
    "contrast",
    "defocus_blur",
    "elastic_transform",
    "fog",
    "frost",
    "gaussian_blur",
    "gaussian_noise",
    "glass_blur",
    "impulse_noise",
    "jpeg_compression",
    "motion_blur",
    "pixelate",
    "saturate",
    "shot_noise",
    "snow",
    "spatter",
    "speckle_noise",
    "zoom_blur",
]

Severity = Literal[1, 2, 3, 4, 5]

class CIFAR10C(_CIFAR10Base):
    """
    A CIFAR-10-based test dataset for benchmarking neural network robustness to common
    corruptions [1]_. For each corruption and for each severity (`1-5`), the
    dataset consists of the 10,000 test images from CIFAR-10 with that corruption
    applied to those images.

    References
    ----------
    .. [1] https://zenodo.org/record/2535967#.YnAe_9rMKbg
    """

    url = "https://zenodo.org/record/2535967/files/CIFAR-10-C.tar"
    filename = "CIFAR-10-C.tar"
    tar_md5: str = "56bf5dcef84df0e2308c6dcbcbbd8499"
    base_folder: str = "CIFAR-10-C"

    _file_to_md5: Dict[str, str] = {
        "brightness": "0a81ef75e0b523c3383219c330a85d48",
        "contrast": "3c8262171c51307f916c30a3308235a8",
        "defocus_blur": "7d1322666342a0702b1957e92f6254bc",
        "elastic_transform": "9421657c6cd452429cf6ce96cc412b5f",
        "fog": "7b397314b5670f825465fbcd1f6e9ccd",
        "frost": "31f6ab3bce1d9934abfb0cc13656f141",
        "gaussian_blur": "c33370155bc9b055fb4a89113d3c559d",
        "gaussian_noise": "ecaf8b9a2399ffeda7680934c33405fd",
        "glass_blur": "7361fb4019269e02dbf6925f083e8629",
        "impulse_noise": "2090e01c83519ec51427e65116af6b1a",
        "jpeg_compression": "2b9cc4c864e0193bb64db8d7728f8187",
        "labels": "c439b113295ed5254878798ffe28fd54",
        "motion_blur": "fffa5f852ff7ad299cfe8a7643f090f4",
        "pixelate": "0f14f7e2db14288304e1de10df16832f",
        "saturate": "1cfae0964219c5102abbb883e538cc56",
        "shot_noise": "3a7239bb118894f013d9bf1984be7f11",
        "snow": "bb238de8555123da9c282dea23bd6e55",
        "spatter": "8a5a3903a7f8f65b59501a6093b4311e",
        "speckle_noise": "ef00b87611792b00df09c0b0237a1e30",
        "zoom_blur": "6ea8e63f1c5cdee1517533840641641b",
    }

    all_corruptions = (
        "brightness",
        "contrast",
        "defocus_blur",
        "elastic_transform",
        "fog",
        "frost",
        "gaussian_blur",
        "gaussian_noise",
        "glass_blur",
        "impulse_noise",
        "jpeg_compression",
        "motion_blur",
        "pixelate",
        "saturate",
        "shot_noise",
        "snow",
        "spatter",
        "speckle_noise",
        "zoom_blur",
    )
    noise_corruptions = (
        "gaussian_noise",
        "impulse_noise",
        "shot_noise",
    )
    blur_corruptions = (
        "defocus_blur",
        "glass_blur",
        "motion_blur",
        "zoom_blur",
    )
    weather_corruptions = (
        "brightness",
        "fog",
        "frost",
        "snow",
    )
    digital_corruptions = (
        "contrast",
        "elastic_transform",
        "jpeg_compression",
        "pixelate",
    )

    # not included in augmix results
    extra_corruptions = (
        "gaussian_blur",
        "saturate",
        "spatter",
        "speckle_noise",
    )

    def __init__(
        self,
        root: PathLike,
        corruption: Corruptions,
        severity: Severity,
        transform: Optional[Callable[[Image.Image], Any]] = None,
        target_transform: Optional[Callable[[int], Any]] = None,
        download: bool = False,
    ) -> None:
        """
        Parameters
        ----------
        root : PathLike
            Root directory of dataset where directory
            ``CIFAR-10-C`` exists or will be saved to if download is set to True.

        corruption : str
            The type of corruption, e.g., "fog". See `CIFAR10C.all_corruptions()` for a full list of corruptions.

        severity : Literal[1, 2, 3, 4, 5]
            The severity-level of the corruption, ranging from 1 to 5.

        transform :  Optional[Callable[[Image], Any]]
            A function/transform that takes in a PIL image
            and returns a transformed version. E.g., ``transforms.RandomCrop``

        target_transform : Optional[Callable]
            A function/transform that takes in a target
            and returns a transformed version.

        download : bool, optional (default=False)
            If true, downloads the dataset from the internet and puts it in root directory.
            If dataset is already downloaded, it is not downloaded again."""

        super().__init__(
            root=str(root), transform=transform, target_transform=target_transform
        )

        self._root = (Path(self.root) / self.base_folder).resolve()
        assert corruption in self._file_to_md5
        self.corruption = corruption

        if download:
            self.download()

        if not self._check_integrity():
            raise RuntimeError(
                "Dataset not found or corrupted."
                + " You can use download=True to download it"
            )

        if not isinstance(severity, (int, Integral)) and 1 <= severity <= 5:
            raise ValueError(f"`severity` must be an integer in [1, 5]. Got {severity}")

        severity -= 1  # type: ignore

        mmap = np.load(self._root / (corruption + ".npy"), mmap_mode="r")
        size = len(mmap) // 5

        # shape-(N, H, W, C)
        self.data = np.array(mmap[severity * size : (severity + 1) * size])
        self.targets = np.load(self._root / "labels.npy")

    def _check_integrity(self) -> bool:
        img_path = self._root / (self.corruption + ".npy")
        labels_path = self._root / "labels.npy"

        if not img_path.is_file() and not labels_path.is_file():
            return False

        img_md5 = md5_check(img_path)
        label_md5 = md5_check(labels_path)

        return (
            img_md5 == self._file_to_md5[self.corruption]
            and label_md5 == self._file_to_md5["labels"]
        )

    def download(self) -> None:
        if self._check_integrity():
            print("Files already downloaded and verified")
            return
        download_and_extract_archive(
            self.url, self.root, filename=self.filename, md5=self.tar_md5
        )

    def extra_repr(self) -> str:
        return "Split: Test"

class CIFAR100C(CIFAR10C):
    """
    A CIFAR-100-based test dataset for benchmarking neural network robustness to common
    corruptions [1]_. For each corruption and for each severity (`1-5`), the
    dataset consists of the 10,000 test images from CIFAR-100 with that corruption
    applied to those images.

    Parameters
    ----------
    root : PathLike
        Root directory of dataset where directory
        ``CIFAR-100-C`` exists or will be saved to if download is set to True.

    corruption : str
        The type of corruption, e.g., "fog". See `CIFAR100C.all_corruptions()` for a full
        list of corruptions.

    severity : Literal[1, 2, 3, 4, 5]
        The severity-level of the corruption, ranging from 1 to 5.

    transform :  Optional[Callable[[Image], Any]]
        A function/transform that takes in an PIL image
        and returns a transformed version. E.g., ``transforms.RandomCrop``

    target_transform : Optional[Callable]
        A function/transform that takes in a target
        and returns a transformed version.

    download: bool, optional (default=False)
        If true, downloads the dataset from the internet and puts it in root directory.
        If dataset is already downloaded, it is not downloaded again.

    References
    ----------
    .. [1] https://zenodo.org/record/2535967#.YnAe_9rMKbg
    """

    url = "https://zenodo.org/record/3555552/files/CIFAR-100-C.tar"
    filename = "CIFAR-100-C.tar"
    tar_md5: str = "11f0ed0f1191edbf9fa23466ae6021d3"
    base_folder: str = "CIFAR-100-C"

    _file_to_md5: Dict[str, str] = {
        "brightness": "f22d7195aecd6abb541e27fca230c171",
        "contrast": "322bb385f1d05154ee197ca16535f71e",
        "defocus_blur": "d923e3d9c585a27f0956e2f2ad832564",
        "elastic_transform": "a0792bd6581f6810878be71acedfc65a",
        "fog": "4efc7ebd5e82b028bdbe13048e3ea564",
        "frost": "3a39c6823bdfaa0bf8b12fe7004b8117",
        "gaussian_blur": "5204ba0d557839772ef5a4196a052c3e",
        "gaussian_noise": "ecc4d366eac432bdf25c024086f5e97d",
        "glass_blur": "0bf384f38e5ccbf8dd479d9059b913e1",
        "impulse_noise": "3b3c210ddfa0b5cb918ff4537a429fef",
        "jpeg_compression": "c851b7f1324e1d2ffddeb76920576d11",
        "labels": "bb4026e9ce52996b95f439544568cdb2",
        "motion_blur": "732a7e2e54152ff97c742d4c388c5516",
        "pixelate": "96c00c60f144539e14cffb02ddbd0640",
        "saturate": "c0697e9fdd646916a61e9c312c77bf6b",
        "shot_noise": "b0a1fa6e1e465a747c1b204b1914048a",
        "snow": "0237be164583af146b7b144e73b43465",
        "spatter": "12ccf41d62564d36e1f6a6ada5022728",
        "speckle_noise": "e3f215b1a0f9fd9fd6f0d1cf94a7ce99",
        "zoom_blur": "0204613400c034a81c4830d5df81cb82",
    }

    classes = (
        "apple",
        "aquarium_fish",
        "baby",
        "bear",
        "beaver",
        "bed",
        "bee",
        "beetle",
        "bicycle",
        "bottle",
        "bowl",
        "boy",
        "bridge",
        "bus",
        "butterfly",
        "camel",
        "can",
        "castle",
        "caterpillar",
        "cattle",
        "chair",
        "chimpanzee",
        "clock",
        "cloud",
        "cockroach",
        "couch",
        "crab",
        "crocodile",
        "cup",
        "dinosaur",
        "dolphin",
        "elephant",
        "flatfish",
        "forest",
        "fox",
        "girl",
        "hamster",
        "house",
        "kangaroo",
        "keyboard",
        "lamp",
        "lawn_mower",
        "leopard",
        "lion",
        "lizard",
        "lobster",
        "man",
        "maple_tree",
        "motorcycle",
        "mountain",
        "mouse",
        "mushroom",
        "oak_tree",
        "orange",
        "orchid",
        "otter",
        "palm_tree",
        "pear",
        "pickup_truck",
        "pine_tree",
        "plain",
        "plate",
        "poppy",
        "porcupine",
        "possum",
        "rabbit",
        "raccoon",
        "ray",
        "road",
        "rocket",
        "rose",
        "sea",
        "seal",
        "shark",
        "shrew",
        "skunk",
        "skyscraper",
        "snail",
        "snake",
        "spider",
        "squirrel",
        "streetcar",
        "sunflower",
        "sweet_pepper",
        "table",
        "tank",
        "telephone",
        "television",
        "tiger",
        "tractor",
        "train",
        "trout",
        "tulip",
        "turtle",
        "wardrobe",
        "whale",
        "willow_tree",
        "wolf",
        "woman",
        "worm",
    )


"""It Hangs in the Balance"""
from typing import Iterator

def get_smallest_partitions(
    packages: list[int], goal: int, start: int = 0, smallest: int = None
) -> Iterator[list[int]]:
    smallest = len(packages) / 4 if smallest is None else smallest
    for index, package in enumerate(packages[start:], start):
        if package > goal:
            break
        if package == goal:
            yield [index]
            smallest = 1
            continue
        if smallest <= 1:
            break
        for sub_group in get_smallest_partitions(packages, goal - package, index + 1, smallest - 1):
            if smallest >= 1 + len(sub_group):
                smallest = 1 + len(sub_group)
                yield [index, *sub_group]

def product(factors: list[int]):
    p = 1
    for factor in factors:
        p *= factor
    return p

def get_smallest_partition_lowest_entanglement(packages, remaining, partitions: int) -> int:
    assert remaining[0] % partitions == 0
    partition_size = remaining[0] // partitions
    parts = {}
    for part in get_smallest_partitions(packages, partition_size):
        if len(part) not in parts:
            parts[len(part)] = []
        parts[len(part)].append(part)
    smallest_partitions = parts[min(parts)]
    entanglements = [product([packages[p] for p in part]) for part in smallest_partitions]
    return min(entanglements)

def solve(text: str) -> Iterator:
    packages = sorted([int(p) for p in text.strip().splitlines()])
    remaining = [sum(packages[i:]) for i in range(len(packages))]
    yield get_smallest_partition_lowest_entanglement(packages, remaining, 3)
    yield get_smallest_partition_lowest_entanglement(packages, remaining, 4)


import pandas as pd
import numpy as np

#load wine data set, reading only Alcohol and Malic acid information
df = pd.io.parsers.read_csv(
    'Data/wine.data',
     header=None,
     usecols=[0,1,2]
    )

df.columns=['Class label', 'Alcohol', 'Malic acid']

#Alcohol (percent/volumne) and Malic acid (g/l) are measured on different scales
#print(df.head()) #DataFrame

from sklearn import preprocessing

#set Mean and Std Deviation to Standardization Scaler instance
std_scale = preprocessing.StandardScaler().fit(df[['Alcohol', 'Malic acid']])
#scale data frame according to set Mean and Std Deviation parameters, using Standardization Scaler instance
df_std = std_scale.transform(df[['Alcohol', 'Malic acid']])

#set min and max values from Data Frame to MinMaxScaler instance
minmax_scale = preprocessing.MinMaxScaler().fit(df[['Alcohol', 'Malic acid']])
#scale data frame according to set min and max values, using Min Max Scaler instance
df_minmax = minmax_scale.transform(df[['Alcohol', 'Malic acid']])

print(df_std) #converted to numpy array
#Mean of data set lies at 0 now
print('mean of Alcohol, using Standardization Scaler = {:.2f}'.format(df_std[:,0].mean()))
print('mean of Malic Acid, using Standardization Scaler = {:.2f}'.format(df_std[:,1].mean()))

print('mean of Alcohol, using MinMax Scaler = {:.2f}'.format(df_minmax[:,0].mean())) #means are not set to 0 by transformation
print('mean of Malic Acid, using MinMax Scaler = {:.2f}'.format(df_minmax[:,1].mean())) #means are not set to 0 by transformation

#Min-Max standardizes all values to fall between 1 and 0

print('Min-value after min-max scaling:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_minmax[:,0].min(), df_minmax[:,1].min()))
print('\nMax-value after min-max scaling:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_minmax[:,0].max(), df_minmax[:,1].max()))

#plotting graphs

import matplotlib.pyplot as plt

def plot():
    plt.figure(figsize=(10,10)) #size of the graph

    plt.scatter(df['Alcohol'], df['Malic acid'], color='green', label='input scale', alpha=0.5) #input

    plt.scatter(df_std[:,0], df_std[:,1], color='red', label='Standardized [$N  (\mu=0, \; \sigma=1)$]', alpha=0.3) #standardization

    plt.scatter(df_minmax[:,0], df_minmax[:,1], color='blue', label='min-max scaled [min=0, max=1]', alpha=0.3) #normalization

    plt.title('Alcohol and Malic Acid content of the wine dataset')
    plt.xlabel('Alcohol')
    plt.ylabel('Malic Acid')
    plt.legend(loc='upper left')
    plt.grid()
    #plt.tight_layout()

plot()
plt.show()

#plots using input, Normalized input and Standardized input to differentiate the three classes

fig, ax = plt.subplots(3, figsize=(6,14))

for a,d,l in zip(range(len(ax)),
               (df[['Alcohol', 'Malic acid']].values, df_std, df_minmax), #values for d, array of graph data
               ('Input scale',
                'Standardized [$N  (\mu=0, \; \sigma=1)$]',
                'min-max scaled [min=0, max=1]')            #values for l, label for the graph
                ):
    for i,c in zip(range(1,4), ('red', 'blue', 'green')):  #looping over the three classes, for individual graph type
        ax[a].scatter(d[df['Class label'].values == i, 0], #setting value of alcohol amount corresponding to class of wine on x axis
                  d[df['Class label'].values == i, 1], #ssetting value of malic acid amount corresponding to class of wine to y axis
                  alpha=0.5,
                  color=c,
                  label='Class %s' %i
                  )
    ax[a].set_title(l)
    ax[a].set_xlabel('Alcohol')
    ax[a].set_ylabel('Malic Acid')
    ax[a].legend(loc='upper left')
    ax[a].grid()

plt.tight_layout()

plt.show()


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

import cv2
import numpy as np
from matplotlib import pyplot as plt
import functions as f

import sys
sys.path.append('MIDI/src/midiutil')

from MidiFile3 import MIDIFile

tabla_sol = [77,76,74,72,71,69,67,65,64,62,60,59,57,55,53,52,50]
kernel = np.ones((2,2),np.uint8)
MyMIDI = MIDIFile(1)

def line_separator(img,color):
    sx,sy = np.size(img,0),np.size(img,1)
    c = 0
    ca =[]
    for i in range(0,sx):
        temp = False
        for j in range(0,sy):
            if(img[i][j] != color):
                temp = True
        if temp == True:
            c = c+1
        elif(c != 0):
            ca.append([c,i-c,i])
            c = 0
    return ca

def ar_line_separator(ar,color):
    ans = []
    for i in range(0,len(ar)):
        ans.append(line_separator(ar[i],255))
    return ans

def separator_blocks(img,cord):
    images = []
    for i in range(0,np.size(cord,0)):
        #For each one
        csize = cord[i][0]
        sy = np.size(img,1)
        cstart = cord[i][1]
        temp = np.zeros([csize,sy],dtype=np.uint8)
        for n in range(0,csize):
            for m in range(0,sy):
                temp[n][m] = img[n + cstart][m]
        temp = agrandar(temp,30,30)
        images.append(temp)
    return images

def ar_separator_blocks(ar,cords):
    ans = []
    for i in range(0,len(ar)):
        ans.append(separator_blocks(ar[i],cords[i]))

    return ans
def EliminateLines(img):
    im = np.copy(img)
    sx = int(im.shape[0])
    sy = int(im.shape[1])
    #Another Tresshold
    for i in range(0,sx):
        for j in range(0,sy):
            if(im[i][j]>=210):
                im[i][j] = 255
            else:
                im[i][j] = 0
    im = ~im
    imgFinal = np.copy(im)
    (rows, cols) = im.shape
    estructura = np.array([[1],
              [1],
             [1]])
    #Falta por convertir a manual
    imgFinal = cv2.erode(imgFinal, estructura, iterations = 1);
    imgFinal = cv2.dilate(imgFinal, estructura, iterations = 1);
    imgFinal = cv2.bitwise_not(imgFinal)
    return imgFinal

"""
test = f.loadimg("test.png")
f.show(test)
test = f.to_grey(test)
test = cv2.adaptiveThreshold(test,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,15,-2)
f.saveimg(test)
data = line_separator(test)
result = separator_blocks(test,data)
#mg(test)
"""
#Demo1
#Demo

def get_body(image):
    gray = cv2.medianBlur(image, 5)
    dst2 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
    return dst2

def transpose_all(ar):
    for i in range(0,np.size(ar,0)):
        ar[i] = cv2.transpose(ar[i])

    return ar

def transponse_arr_all(ar):
    for i in range(0,len(ar)):
        ar[i]= transpose_all(ar[i])
    return ar

#test = f.tresshold(test,100)

#test = cv2.adaptiveThreshold(test,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,15,-2)

"""
test = f.loadimg("test2.jpg")
test = f.to_grey(test)
f.saveimg(test,"imagen.png")
f.show(test)

clear = EliminateLines(test)
clear = f.tresshold(clear,50)
data = line_separator(test,255)

result_1 = separator_blocks(clear,data)
result_2 = transpose_all(result_1)
result_3 = ar_line_separator(result_2,255)
result_4 = ar_separator_blocks(result_2,result_3)
result_5 = transponse_arr_all(result_4)
"""

def agrandar(image,pixeles,n):
    sx,sy = np.size(image,0), np.size(image,1)
    img = np.ones([ sx+ pixeles + n,sy + pixeles + n],dtype = np.uint8) * 255
    for i in range(0,sx):
        for j in range(0,sy):
            img[i + 1][j + 1] = image[i][j]
    return img

def show_circles(image):
    img = np.copy(image)
    img = f.tresshold(img,200)
    #img = cv2.resize(img,[np.size(img,0)*2,np.size(img,1)*2])
    cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
    circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,1,param1=1,param2=7,minRadius=1,maxRadius=40)
    circles = np.uint8(np.around(circles))
    for i in circles[0,:]:

       cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3,0)
    f.showc(cimg)
    pass

def delete_borders(image):
    data = line_separator(np.transpose(agrandar(image,2,2)),255)
    data = data[0]
    new_image = np.ones([np.size(image,0),data[0]],dtype = np.uint8) * 255
    for i in range(0,np.size(image,0)):
        for j in  range(0,data[0]):
            new_image[i][j] = image[i][j+data[1]]
    return new_image

def fcorchea(image):
    e = False
    total = 0
    image = agrandar(image,2,2)
    image = cv2.dilate(image,kernel)
    image = delete_borders(image)
    l1,l2,l3,l4 = 0,0,0,0
    sx, sy = np.size(image,0), np.size(image,1)
    for i in range(0,int(sx/2)):
        for j in range(0,int(sy/2)):
            if(image[i][j] < 10):
                l1 = l1 + 1
        for j in range(int(sy/2),sy):
            if(image[i][j] < 10):
                l2 = l2 + 1
    for i in range(int(sx/2),sx):
        for j in range(0,int(sy/2)):
            if(image[i][j] < 10):
                l3 = l3 + 1
                image[i][j] = 0
        for j in range(int(sy/2),sy):
            if(image[i][j] < 10):
                l4 = l4 + 1

    answe = [l1,l2,l3,l4]
    total = l1 + l2 + l3 + l4
    answe = np.sort(answe)
    sup = answe[3]
    inf = answe[0]
    if(answe[0] < 5):
        sup = answe[3]
        inf = answe[1]
        med = answe[2]
        val = sup/max(1,inf)
        if(val > 3):
            e = True
    elif((inf/sup)<1.3 and (inf/sup)>0.8):
        e = False
    if(answe[1] <5):
        e = False
    return e

def Erosion(im,pixel,mascara):
    val = False
    for i in range(0,1):
        for j in range(0,mascara.shape[0]):
            if im[pixel[0]+i][pixel[1]+j]==mascara[j]:
                val = True
            else:
                val = False
                break
        if(val == False):
            break
    if(val == False):
        im[pixel[0]][pixel[1]] = 255

def Dilatacion(im,pixel,mascara):
    for i in range(0,1):
        for j in range(0,mascara.shape[0]):
            im[pixel[0]+i][pixel[1]+j]=mascara[j]

def BorrarLineas(img, mascara):
    im = np.copy(img)
    sx = int(im.shape[0])
    sy = int(im.shape[1])
    for i in range(0,sx):
        for j in range(0,sy):
            if(im[i][j]>=210):
                im[i][j] = 255
            else:
                im[i][j] = 0
    for i in range(0,im.shape[0]):
        for j in range(0,im.shape[1]):
            if(im[i][j]==0 and i+4<=im.shape[0] and j+4<=im.shape[1]):
                pixel = [i,j]
                Erosion(im,pixel,mascara)

    im2 = np.copy(im)
    for i in range(0,im.shape[0]):
        for j in range(0,im.shape[1]):
            if(im2[i][j]==0 and i+4<=im.shape[0] and j+4<=im.shape[1]):
                pixel = [i,j]
                Dilatacion(im,pixel,mascara)
    return im

def eliminar_repetidas(arr):
    ans = np.copy(arr)
    to_delete = []
    rango = 3
    sz = np.size(arr,0)
    for i in range(sz):
        for n in range(i + 1,sz):
            a = abs(arr[i][0] - arr[n][0])
            b = abs(arr[i][1] - arr[n][1])
            if((a < rango) and (b < rango)):
                to_delete.append(n)
    to_delete = np.unique(to_delete)
    ans= np.delete(arr,to_delete,0)
    return ans

def templates(imag, templ, templPos, tipo):
    imagen_gray = f.to_grey(imag)
    w, h = templ.shape[::-1]
    res = cv2.matchTemplate(imagen_gray, templ ,cv2.TM_CCOEFF_NORMED)
    threshold = 0.7
    loc = np.where(res >= threshold)

    for pt in zip(*loc[::-1]):
        cv2.rectangle(imag, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
        temp = [pt[0],pt[1],tipo,w,h] #1 es cambiado por tipo
        templPos.append(temp)

    return imag, templPos

def ConseguirLineas(imag):
    masca = np.zeros([int(np.size(imag,1)/2)],dtype = np.uint8)
    #masca = np.array([(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)])
    imag = f.to_grey(imag)
    imag = BorrarLineas(imag,masca)
    f.saveimg(imag,"lineas.png")
    lineaPos = np.zeros([20])
    lineaCon = 0
    adi = 0
    LineasPos = []
    for i in range(0,imag.shape[0]):
        if(imag[i][100]+adi==0):
            lineaPos[lineaCon] = i
            lineaCon += 1
            adi=2
            LineasPos.append(i)
        else:
            adi=0

    lineaInicial = LineasPos[0]
    dist = LineasPos[1]-LineasPos[0]

    return lineaInicial, dist

def check_corchea(img,posx,dist):
    value = False
    sx = np.size(img,0)
    sy = int(dist)
    temp = np.ones([sx,sy],dtype = np.uint8)
    for i in range(0,sx):
        for j in range(0,sy):
            temp[i][j] = img[i][posx + j]
    temp = agrandar(temp,1,1)

    temp = delete_borders(temp)
    temp = np.transpose(delete_borders(np.transpose(temp)))
    value = fcorchea(temp)
    return value

def change_to_corc(arr,image,black):
    for i in range(0,np.size(arr,0)):
        if(check_corchea(image,arr[i][0],arr[i][3]*1.4)):
            arr[i][2] = 5
    pass

def decide_position(arr,lin,size):
    for i in range(0,np.size(arr,0)):
        temp = ((arr[i][1] - lin + 2))/size
        next_temp = ((arr[i][1]+arr[i][3] - lin))/size
        if(np.floor(next_temp) == np.ceil(temp)):#se le da un margen de error
            arr[i][4] = 2*(np.floor(temp)) + 1
        else:
            arr[i][4] = np.floor(temp)*2 + 2

    pass

def newNote(time, duration, pitch):
    track = 0
    MyMIDI.addTrackName(track,time,"Sample Track")
    MyMIDI.addTempo(track,time, 120)
    channel = 0
    volume = 100
    MyMIDI.addNote(track,channel,pitch,time,duration,volume)

def make_midi(arr):
    time = 0
    for i in range(1,np.size(arr,0)):
        tempo = float(arr[i][2]) / 10.0

        frecuencia = tabla_sol[arr[i][4]]
        newNote(time,tempo,frecuencia)
        time = time + tempo
    pass

def song(f_lista):
    tiempo = 0
    newNote(0,f_lista[0][1],f_lista[0][0])
    for i in range(1,len(f_lista)):

        newNote(tiempo,f_lista[i][1],f_lista[i][0])
        tiempo = tiempo + f_lista[i-1][1]
    pass

def get_dataset(imagen):
    linea, distancia = ConseguirLineas(imagen)
    negra = cv2.imread('templates/b1.png',0)
    blanca = cv2.imread('templates/w1.png',0)
    blanca2 = cv2.imread('templates/w2.png',0)
    sol = cv2.imread('templates/sol.png',0)
    fa = cv2.imread('templates/clavefa.jpg',0)
    redonda = cv2.imread('templates/r1.png',0)
    redonda2 = cv2.imread('templates/r2.png',0)
    tata = f.to_grey(imagen)
    tata = EliminateLines(tata)
    NegraPos = []
    BlancaPos = []
    RedondaPos = []
    SolPos = []
    FaPos = []

    imagen, NegraPos = templates(imagen, negra, NegraPos,10)
    imagen, BlancaPos = templates(imagen, blanca, BlancaPos,20)
    imagen, BlancaPos = templates(imagen, blanca2, BlancaPos,20)
    imagen, SolPos = templates(imagen, sol, SolPos,50)
    imagen, RedondaPos = templates(imagen, redonda, RedondaPos, 40)
    imagen, RedondaPos = templates(imagen, redonda2, RedondaPos, 40)
    imagen, FaPos = templates(imagen, fa, FaPos,60)

    NegraPos = eliminar_repetidas(NegraPos)
    change_to_corc(NegraPos,tata,negra)
    BlancaPos = eliminar_repetidas(BlancaPos)
    SolPos = eliminar_repetidas(SolPos)
    NegraPos = sorted(NegraPos,key=lambda order:order[0],reverse = False)
    if(np.size(SolPos,0) > 0):
        dataset = np.concatenate((SolPos,NegraPos),axis = 0)
    if(np.size(BlancaPos,0) > 0):
        dataset = np.concatenate((dataset, BlancaPos),axis=0)

    dataset = np.array(sorted(dataset,key=lambda order:order[0],reverse = False))
    decide_position(dataset,linea,distancia)
    return dataset

def demo():

    image = cv2.imread("maria.jpg")
    tata = f.to_grey(image)
    tata = EliminateLines(tata)
    f.saveimg(tata,"qw.png")

    image = f.to_grey(image)
    clear = EliminateLines(image)
    clear = f.tresshold(clear,50)
    data = line_separator(clear,255)
    result = separator_blocks(image,data)
    datasets = []
    for i in range(0,np.size(result,0)):
        result[i] = agrandar(result[i],15,15)
        datasets.append(get_dataset(result[i]))

    for i in range(1,np.size(datasets,0)):
        dataset = np.concatenate((datasets[i-1],datasets[i]),axis = 0)
    #dataset = get_dataset(result[1])
    make_midi(dataset)
    binfile = open("FINAL2.mid", 'wb')
    MyMIDI.writeFile(binfile)
    binfile.close()

    cv2.imwrite('res2.png',image)

    pass

demo()


#the zero game: 21 coins
#Shereen Hassan 20170130
#AI game
n=21

while (n<=21):

    p1=int(input("Your turn, play:"))
    while (p1<1 or p1>3):
        print("Wrong number, choose between 1 and 3")
        p1=int(input("Your turn, play:"))
    if (p1>=1 and p1<=3):
        n=n-p1
        print ("n =",n)
    if (n==1):
        print("You WIN!")
        break

    if (n==5):
        n=n-1
    elif(n==6):
        n=n-2
    elif(n==7):
        n=n-3
    elif(n==2):
        n=n-1
    elif(n==3):
        n=n-2
    else:
        n=n-2
    if(n==1):
        print("You LOSE!")
        break

    print ("Computer played","n =",n)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 27 13:26:32 2023

@author: johnmorgan
"""

from heapq import *

# O(k) initial insert
# O((n - k) * (logk)
# O(k) space

def find_kth_largest(arr, k):
    minh = []
    index = 0
    while k > 0:
        heappush(minh, arr[index])
        index += 1
        k -= 1
    print(minh)
    for index in range(index, len(arr)):
        elem = arr[index]
        if elem > minh[0]:
            heappop(minh)
            heappush(minh, elem)
    return minh[0]

arr = [-1,-5,-9,-11,-5,-10,-3,-4,-1,-12,-13,-8]
k = 7
print(find_kth_largest(arr, k))


#!/usr/bin/env python
# coding: utf-8

# In[1]:

import pandas as pd
import numpy as np
import torch
from torch.utils.data import Dataset
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from torch.utils.data import DataLoader
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import pdb

# In[2]:

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# In[3]:

print(device)

# In[4]:

train_in = pd.read_csv('train_input.csv')
train_out = pd.read_csv('train_output.csv')

# In[5]:

train_in.head()

# In[6]:

train_out.head()

# In[35]:

class NumpyDataset(Dataset):

    def __init__(self, input_file_name, output_file_name, is_train=True):
        X_in = pd.read_csv(input_file_name)[:10000]
        X_in.drop(columns=['ID'], inplace=True)
        y_in = pd.read_csv(output_file_name)[:10000]
        y_in.drop(columns=['ID'], inplace=True)
        X_in['distance'] = y_in['distance']
        self.len = len(X_in)

        X_train, X_test = train_test_split(X_in, test_size=.01, random_state=1)

        if is_train:
            X = X_train
        else:
            X = X_test

        self.class_holder = dict()
        for i in range(1, 15):
            subsetX = X[X['distance'] == i].copy()
            subsetX.drop(columns=['distance'], inplace=True)
            self.class_holder[i] = subsetX.to_numpy()

    def __getitem__(self, index):

        choice_idx = np.random.choice(range(1, 15))

        x = self.class_holder[choice_idx]
        while len(x) == 0:
            choice_idx = np.random.choice(range(1, 15))
            x = self.class_holder[choice_idx]

        x_choice = x[np.random.choice(range(len(x)))]

        return x_choice, choice_idx

    def __len__(self):
        return self.len

# In[ ]:

# In[ ]:

# In[36]:

train_dataset = NumpyDataset('train_input.csv', 'train_output.csv')
trainloader = DataLoader(train_dataset, batch_size=64, shuffle=False)
valid_dataset = NumpyDataset('train_input.csv', 'train_output.csv', is_train=False)
testloader = DataLoader(valid_dataset, batch_size=64)

# In[22]:

class ResnetModel(nn.Module):
    def __init__(self, state_dim: int, one_hot_depth: int, h1_dim: int, resnet_dim: int, num_resnet_blocks: int,
                 out_dim: int, batch_norm: bool):
        super().__init__()
        self.one_hot_depth: int = one_hot_depth
        self.state_dim: int = state_dim
        self.blocks = nn.ModuleList()
        self.num_resnet_blocks: int = num_resnet_blocks
        self.batch_norm = batch_norm

        # first two hidden layers
        if one_hot_depth > 0:
            self.fc1 = nn.Linear(self.state_dim * self.one_hot_depth, h1_dim)
        else:
            self.fc1 = nn.Linear(self.state_dim, h1_dim)

        if self.batch_norm:
            self.bn1 = nn.BatchNorm1d(h1_dim)

        self.fc2 = nn.Linear(h1_dim, resnet_dim)

        if self.batch_norm:
            self.bn2 = nn.BatchNorm1d(resnet_dim)

        # resnet blocks
        for block_num in range(self.num_resnet_blocks):
            if self.batch_norm:
                res_fc1 = nn.Linear(resnet_dim, resnet_dim)
                res_bn1 = nn.BatchNorm1d(resnet_dim)
                res_fc2 = nn.Linear(resnet_dim, resnet_dim)
                res_bn2 = nn.BatchNorm1d(resnet_dim)
                self.blocks.append(nn.ModuleList([res_fc1, res_bn1, res_fc2, res_bn2]))
            else:
                res_fc1 = nn.Linear(resnet_dim, resnet_dim)
                res_fc2 = nn.Linear(resnet_dim, resnet_dim)
                self.blocks.append(nn.ModuleList([res_fc1, res_fc2]))

        # output
        self.fc_out = nn.Linear(resnet_dim, out_dim)

        self.dummy = nn.Linear(self.state_dim * self.one_hot_depth, out_dim, bias=True)

    def forward(self, states_nnet):
        x = states_nnet

        # preprocess input
        if self.one_hot_depth > 0:
            x = F.one_hot(x.long(), self.one_hot_depth)
            x = x.float()
            x = x.view(-1, self.state_dim * self.one_hot_depth)
        else:
            x = x.float()

        # first two hidden layers
        x = self.fc1(x)
        if self.batch_norm:
            x = self.bn1(x)

        x = F.relu(x)
        x = self.fc2(x)
        if self.batch_norm:
            x = self.bn2(x)

        x = F.relu(x)

        # resnet blocks
        for block_num in range(self.num_resnet_blocks):
            res_inp = x
            if self.batch_norm:
                x = self.blocks[block_num][0](x)
                x = self.blocks[block_num][1](x)
                x = F.relu(x)
                x = self.blocks[block_num][2](x)
                x = self.blocks[block_num][3](x)
            else:
                x = self.blocks[block_num][0](x)
                x = F.relu(x)
                x = self.blocks[block_num][1](x)

            x = F.relu(x + res_inp)

        # output
        x = self.fc_out(x)
#         x = F.one_hot(x.long(), self.one_hot_depth)
#         x = x.view(-1, self.state_dim * self.one_hot_depth)
#         x = x.float()
#         x= self.dummy(x)+11
        return x

# In[23]:

net = ResnetModel(24, 6, 1000, 100, 4, 1, True)
net = net.to(device)

# In[24]:

# loss
criterion = nn.MSELoss()
#critetion= nn.L1Loss()
# optimizer
optimizer = optim.Adam(net.parameters(), lr=0.0001)

# In[25]:

# class LogisticRegression(torch.nn.Module):
#     def __init__(self, input_dim, output_dim):
#         super(LogisticRegression, self).__init__()
#         self.linear = torch.nn.Linear(input_dim, output_dim)

#     def forward(self, x):
#         outputs = self.linear(x.float())
#         return outputs.float()

# In[26]:

# net = LogisticRegression(24, 1)
# criterion = torch.nn.MSELoss()
# optimizer = torch.optim.SGD(net.parameters(), lr=0.0001)
# net = net.to(device)

# In[27]:

# for x, y in trainloader:
#     print(x-1, x.shape)
#     print(y, y.shape)
#     break
# outputs = net(x-1)
# print(outputs, outputs.shape)

# In[28]:

def train(net, trainloader):
    i = 0
    for epoch in range(10):  # no. of epochs
        running_loss = 0
        for i, data in enumerate(trainloader):
            # data and labels to GPU if available

            inputs, labels = data[0].to(device, non_blocking=True) - 1, data[1].to(device, non_blocking=True)
#             print(inputs.shape, labels.shape)
            # pdb.set_trace()

            # set the parameter gradients to zero
            optimizer.zero_grad()
            outputs = net(inputs).float()
#             print(outputs.shape)
            loss = criterion(outputs.view(-1).float(), labels.view(-1).float())

            # propagate the loss backward
            loss.backward()
            # update the gradients
            optimizer.step()

            running_loss += loss.item()

            if not i % 500 and i > 0:
                print(loss.item())
#                 print(running_loss / i)

            i += 1
        print('[Epoch %d] loss: %.3f' %
              (epoch + 1, running_loss / len(trainloader)))
#               (epoch + 1, running_loss / len(trainloader)))

    print('Done Training')

# In[29]:

def test(net, testloader):
    correct = 0
    total = 0
    with torch.no_grad():
        for data in testloader:
            inputs, labels = data[0].to(device, non_blocking=True) - 1, data[1].to(device, non_blocking=True)
            outputs = net(inputs)
            # pdb.set_trace()
#             _, predicted = torch.max(outputs.data, 1)
#             print(outputs.data.shape)
#             print(predicted.shape)
            total += labels.size(0)
            correct += (torch.round(outputs.data.reshape(-1)) == labels).sum().item()
    print('Accuracy of the network on test set: %0.3f %%' % (100 * correct / total))

# In[39]:

train(net, trainloader)

# In[40]:

test(net, trainloader)

# In[41]:

test(net, testloader)

# In[ ]:

# In[ ]:


# -*- coding: utf-8 -*-
"""
Created on Sun Dec 30 12:28:54 2018

@author: truthless
"""

import random
import torch
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
from DataManager import GO
from Dgl_Graph import Graph
from SparseGraphAttention import SGraphAttention

# device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device = torch.device("cuda")

g = Graph().get_graph()

class TopicRNN_SGAT(nn.Module):

    def __init__(self, model, rnn_type, word_vector, nvoc, nvoc_nonstop, nembed, nhid, nhid_infer,
                 ntopic, n_entity, nodes_rep, adj, gcn_dropout=0.5, teacher_forcing=0.5, nlayers=1, dropout=0.05):
        super(TopicRNN_SGAT, self).__init__()

        self.edge_number = 0
        self.nhid = nhid  # H
        self.nhid_infer = nhid_infer  # E
        self.ntopic = ntopic  # K
        self.nvoc = nvoc  # C
        self.nvoc_nonstop = nvoc_nonstop  # C-
        self.nembed = nembed  # V
        self.teacher_forcing = teacher_forcing
        self.encoder = Encoder(nvoc, nembed, nhid, rnn_cell=rnn_type, variable_lengths=True, embedding=word_vector)

        self.fc = nn.Linear(nvoc_nonstop, nhid_infer)
        self.fc_mu = nn.Linear(nhid_infer, nhid_infer)
        self.fc_sigma = nn.Linear(nhid_infer, nhid_infer)
        self.fc_theta = nn.Linear(nhid_infer, ntopic)
        # just use a fully-connected layer to replace gcn
        self.fc_replace_gcn = nn.Linear(nembed, nhid)
        # convert the hidden state to generate a query vector to query at the KG
        self.fc_query = nn.Linear(nembed, nhid)

        if rnn_type in ['LSTM', 'GRU']:
            self.rnn_decoder = getattr(nn, rnn_type)(nembed, nembed, nlayers, dropout=dropout)
            self.rnn_context = getattr(nn, rnn_type)(nhid, nhid, nlayers, dropout=dropout)
        else:
            raise ValueError("rnn_type should be GRU or LSTM! {0}".format(rnn_type))
        self.fc_stop_word = nn.Linear(nembed, 2)
        self.text_decoder = nn.Linear(nembed, nvoc)
        self.topic_decoder = nn.Linear(ntopic, nvoc)

        self.encoder_mem = EncoderMemNN(self.nvoc, self.nembed, 10, 0, 1) #10:hop

        self.n_entity = n_entity
        self.adj = adj.cuda()
        self.nodes_rep = torch.LongTensor(nodes_rep).cuda()
        init = "uniform"

        self.gc1 = SGraphAttention(g, nembed, nhid, 0.02, 5)
        self.gc2 = SGraphAttention(g, nhid, nhid, 0.02, 5)

        self.gcn_dropout = gcn_dropout
        self.gcn_normalize = False

        self.model = model

    def get_nodes_embed(self):
        # note self.nodes_rep[0] corresponds to the node "none"
        nodes_embed = self.encoder.embedding(self.nodes_rep)
        nodes_embed = torch.max(nodes_embed, dim=1)[0]
        # nodes_embed = torch.mean(nodes_embed, dim=1)

        mode = "gcn_no_activation"  # "gcn", "no_gcn", "gcn_no_activation", "gcn_no_dropout", "gcn_no_drop_no_acti"
        mode = self.model

        if mode == "gcn":
            nodes_embed, edges = self.gc1.forawrd(nodes_embed)
            nodes_embed = F.leaky_relu(nodes_embed)
            nodes_embed = F.dropout(nodes_embed, self.gcn_dropout)
            nodes_embed, edges = self.gc2.forawrd(nodes_embed)
            nodes_embed = F.leaky_relu(nodes_embed)
        if mode == "no_gcn":
            nodes_embed = self.fc_replace_gcn(nodes_embed)
        if mode == "gcn_no_activation":
            edges= "__ALL__"
            nodes_embed, edges, edge_numbers1 = self.gc1.forawrd(nodes_embed, edges,skip=0)
            nodes_embed = F.dropout(nodes_embed, self.gcn_dropout)
            nodes_embed, edges, edge_numbers2 = self.gc2.forawrd(nodes_embed, edges,skip=1)
            self.edge_number = edge_numbers2
        if mode == "gcn_no_dropout":
            nodes_embed, edges, edge_numbers = self.gc1.forawrd(nodes_embed)
            nodes_embed = F.leaky_relu(nodes_embed)
            nodes_embed, edges, edge_numbers = self.gc2.forawrd(nodes_embed)
            nodes_embed = F.leaky_relu(nodes_embed)
            self.edge_number += edge_numbers
        if mode == "gcn_no_drop_no_acti":
            nodes_embed, edges = self.gc1.forawrd(nodes_embed)
            nodes_embed, edges = self.gc2.forawrd(nodes_embed)

        return nodes_embed

    def forward(self, x, x_len, y, y_len, x_tf, use_teacher_forcing=None):
        """
        Parameters
        ----------
        x : (batch, sequence length)
        x_len : (batch)
        x_stop : (batch, sequence length)
        x_tf: (batch, nonstop vocabulary size)
        y : (batch, target sequence length)
        y_len : (batch)
        """
        batch_size = x.shape[0]
        hidden = self.encoder_mem(x).unsqueeze(0)
        mu, log_sigma = self.encode(x_tf)  # (batch, E), (batch, E)
        # Compute noisy topic proportions given Gaussian parameters.
        Z = self.reparameterize(mu, log_sigma)  # (batch, E)
        theta = F.softmax(self.fc_theta(Z), dim=1)  # (batch, K)

        target_max_len = max(y_len)
        outputs = torch.zeros_like(y).long().to(device=device)
        word_probs = Variable(torch.zeros(batch_size, target_max_len, self.nvoc)).to(device=device)
        indicator_probs = Variable(torch.zeros(batch_size, target_max_len, 2)).to(device=device)
        entity_probs = Variable(torch.zeros(batch_size, target_max_len, self.n_entity + 1)).to(device=device)

        if use_teacher_forcing is None:
            use_teacher_forcing = random.random() < self.teacher_forcing
        token_input = Variable(torch.LongTensor([GO] * batch_size)).to(device=device)
        rnn_input = self.encoder.embedding(token_input)  # (batch, V)

        for t in range(target_max_len):
            rnn_input = rnn_input.unsqueeze(0)
            rnn_output, hidden = self.rnn_decoder(rnn_input, hidden)
            rnn_output = rnn_output.squeeze(0)  # (batch, H)

            logits = self.text_decoder(rnn_output)  # (batch, C)

            stopword_logits = torch.sigmoid(self.fc_stop_word(rnn_output))  # (batch, 2)
            stopword_predictions = torch.argmax(stopword_logits, dim=-1).unsqueeze(-1)

            topic_additions = self.topic_decoder(theta)  # (batch, C)
            topic_additions[:, :4] = 0  # Padding & Unknowns will be treated as stops.
            topic_mask = (1 - stopword_predictions).expand(-1, self.nvoc)
            topic_additions = topic_additions * topic_mask.float()

            word_logits = logits + topic_additions

            results = torch.argmax(word_logits, dim=-1).detach()
            outputs[:, t] = results

            word_probs[:, t, :] = word_logits
            indicator_probs[:, t, :] = stopword_logits

            if self.model != "TopicRNN":
                # start: entity selection
                nodes_embed = self.get_nodes_embed()  # [314, nhid]
                nodes_embed = nodes_embed.squeeze(1)
                nodes_embed = nodes_embed.squeeze(1)
                zero_node = torch.zeros([1, nodes_embed.shape[1]]).cuda()
                nodes_embed = torch.cat([zero_node, nodes_embed], dim=0)  # [315, nhid]

                # query = self.fc_query(hidden)
                query = hidden
                tmp_hidden = query.squeeze(0).unsqueeze(1).expand(-1, nodes_embed.shape[0],
                                                                  -1)
                nodes_embed = nodes_embed.unsqueeze(0).expand(tmp_hidden.shape)
                entity_prob = torch.sum(tmp_hidden * nodes_embed, dim=2)
                entity_probs[:, t, :] = entity_prob
                # end: entity selection

            if use_teacher_forcing:
                rnn_input = self.encoder.embedding(y[:, t])  # (batch, V)
            else:
                rnn_input = self.encoder.embedding(results)

        return outputs, word_probs, indicator_probs, mu, log_sigma, entity_probs

    def encode(self, x):
        h = F.relu(self.fc(x))  # (batch, E)
        return self.fc_mu(h), self.fc_sigma(h)

    def reparameterize(self, mu, logvar):
        std = torch.exp(0.5 * logvar)
        eps = torch.randn_like(std).to(device=device)
        return eps.mul(std).add_(mu)

class Encoder(nn.Module):
    def __init__(self, vocab_size, embed_size, hidden_size, input_dropout_p=0, dropout_p=0, n_layers=1,
                 rnn_cell='GRU', variable_lengths=False, embedding=None, update_embedding=True):
        super(Encoder, self).__init__()

        self.vocab_size = vocab_size
        self.hidden_size = hidden_size
        self.n_layers = n_layers
        self.input_dropout = nn.Dropout(p=input_dropout_p)
        if rnn_cell == 'LSTM':
            self.rnn_cell = nn.LSTM
        elif rnn_cell == 'GRU':
            self.rnn_cell = nn.GRU
        else:
            raise ValueError("Unsupported RNN Cell: {0}".format(rnn_cell))

        self.variable_lengths = variable_lengths
        self.embedding = nn.Embedding(vocab_size, embed_size)
        if embedding is not None:
            self.embedding.weight = nn.Parameter(embedding)
        self.embedding.weight.requires_grad = update_embedding
        self.rnn = self.rnn_cell(embed_size, hidden_size, n_layers, batch_first=True, dropout=dropout_p)

    def forward(self, input_var, input_lengths=None):
        """
        Applies a multi-layer RNN to an input sequence.
        Args:
            input_var (batch, seq_len): tensor containing the features of the input sequence.
            input_lengths (list of int, optional): A list that contains the lengths of sequences
              in the mini-batch
        Returns: output, hidden
            - **output** (batch, seq_len, hidden_size): variable containing the encoded features of
              the input sequence
            - **hidden** (num_layers * num_directions, batch, hidden_size): variable containing the
              features in the hidden state h
        """
        if self.variable_lengths:
            sort_index = torch.sort(-input_lengths)[1]
            unsort_index = torch.sort(sort_index)[1]
            input_var = input_var[sort_index]
            input_lengths = input_lengths[sort_index]
        embedded = self.embedding(input_var)
        embedded = self.input_dropout(embedded)
        if self.variable_lengths:
            embedded = pack_padded_sequence(embedded, input_lengths.cpu(), batch_first=True)
        output, hidden = self.rnn(embedded)
        if self.rnn_cell == nn.LSTM:
            hidden = hidden[0]
        if self.variable_lengths:
            hidden = torch.transpose(hidden, 0, 1)[unsort_index]
            hidden = torch.transpose(hidden, 0, 1)
            output, _ = pad_packed_sequence(output, batch_first=True)
            output = output[unsort_index]
        return output, hidden

class EncoderMemNN(nn.Module):
    def __init__(self, vocab, embedding_dim, hop, dropout, unk_mask):
        super(EncoderMemNN, self).__init__()
        self.num_vocab = vocab  # 577
        self.max_hops = hop  # 1
        self.embedding_dim = embedding_dim  # 64
        self.dropout = dropout  # 0.5
        self.unk_mask = unk_mask  # 1
        for hop in range(self.max_hops + 1):
            C = nn.Embedding(self.num_vocab, embedding_dim, padding_idx=0)
            C.weight.data.normal_(0, 0.1)
            self.add_module("C_{}".format(hop), C)
        self.C = AttrProxy(self, "C_")
        self.softmax = nn.Softmax(dim=1)

    def get_state(self, bsz):
        """Get cell states and hidden states."""
        return Variable(torch.zeros(bsz, self.embedding_dim))

    def forward(self, story):
        story_size = story.size()  # b * m * 3
        if self.unk_mask:
            if (self.training):
                ones = np.ones((story_size[0], story_size[1], story_size[2]))
                rand_mask = np.random.binomial([np.ones((story_size[0], story_size[1]))], 1 - self.dropout)[
                    0]  # Draw samples from a binomial distribution
                ones[:, :, 0] = ones[:, :, 0] * rand_mask
                a = Variable(torch.Tensor(ones))
                story = story * a.long().to('cuda')
        u = [self.get_state(story.size(0))]
        for hop in range(self.max_hops):
            embed_A = self.C[hop](story.contiguous().view(story.size(0),
                                                          -1).long())  # b * (m * s) * eif (os.cpu_count() > 8)  [batch_size,*,batch_size]
            embed_A = embed_A.view(story_size + (embed_A.size(-1),))  # b * m * s * e
            m_A = torch.sum(embed_A, 2).squeeze(2)  # b * m * e
            u_temp = u[-1].unsqueeze(1).expand_as(m_A)  # query

            prob = self.softmax(torch.sum(m_A * u_temp.to('cuda'), 2))
            embed_C = self.C[hop + 1](story.contiguous().view(story.size(0), -1).long())
            embed_C = embed_C.view(story_size + (embed_C.size(-1),))
            m_C = torch.sum(embed_C, 2).squeeze(2)

            prob = prob.unsqueeze(2).expand_as(m_C)
            o_k = torch.sum(m_C * prob, 1)  # output
            u_k = u[-1].to('cuda') + o_k  # query
            u.append(u_k)

        return u_k

class AttrProxy(object):
    """
    Translates index lookups into attribute lookups.
    To implement some trick which able to use list of nn.Module in a nn.Module
    see https://discuss.pytorch.org/t/list-of-nn-module-in-a-nn-module/219/2
    """

    def __init__(self, module, prefix):
        self.module = module
        self.prefix = prefix

    def __getitem__(self, i):
        return getattr(self.module, self.prefix + str(i))


from django.shortcuts import render,redirect

from .models import ReaderModel
from .forms import AddReaderForm
from django.http.response import HttpResponse

# Create your views here.

def SubscribeView(request):
    if request.method == 'POST':
        form = AddReaderForm(request.POST)
        if form.is_valid():
            f_name = form.cleaned_data['RName']
            f_number = form.cleaned_data['RNumber']
            f_gender = form.cleaned_data['Gender']
            f_city = form.cleaned_data['City']
            f_contactnumber = form.cleaned_data['ContactNumber']
            f_subscription = form.cleaned_data['Subscription']
            if f_subscription == "Month":
                f_charges = 100
            else:
                f_charges = 1000
            model_obj = ReaderModel(
                RName=f_name,
                RNumber=f_number,
                Gender=f_gender,
                City=f_city,
                ContactNumber=f_contactnumber,
                Subscription=f_subscription,
                Charges=f_charges
            )
            model_obj.save()
            # return HttpResponse('
This is Subscribe View
')
            return redirect('display_readers')
    else:
        form = AddReaderForm
    return render(request, 'subscribe.html', {'form':form})

def DisplayReadersView(request):
    post = ReaderModel.objects.all()[:10]
    cont = {
        'data': post,
    }
    return render(request, 'displayReaders.html', context=cont)
    # return HttpResponse('
This is DisplayReadersView View
')


import numpy as np
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

def func(m, x, r, t):

    if x > r:
        return t

    return max(0, m - 1)

def MHI(filepath, ext, t ,r = 30.0, b = False):

    Ip = None
    FD = None
    i = 1
    while True:

        In = None

        if i < 10 and b == True:
            In = cv2.imread(filepath + "0" + str(i) + "." + ext)
        else:
            In = cv2.imread(filepath + str(i) + "." + ext)

        i += 1

        if In is None:
            FD = (FD / t) * 255.0
            return FD.astype(np.uint8)

        if len(In.shape) == 3:
            In = cv2.cvtColor(In, cv2.COLOR_BGR2GRAY)

        if i == 2:
            FD = np.zeros(In.shape, dtype= np.double)
        else:
            diff = abs(In.astype(np.double) - Ip.astype(np.double))
            FD = np.vectorize(func)(FD, diff, r, t)

        Ip = In

##Q2##

pirate = MHI("../pirate/frame", "png", 12)
course = MHI("../course/frame", "png", 40)
femme = MHI("../femme/frame", "png", 22)
action = MHI("../action/seq2_0", "png", 25, b = True)

cv2.imwrite("../.results/images/pirate_MHI.png", pirate)
cv2.imwrite("../.results/images/course_MHI.png", course)
cv2.imwrite("../.results/images/femme_MHI.png", femme)
cv2.imwrite("../.results/images/action_MHI.png", action)

fig = plt.figure(figsize = (12,7))
columns = 2
rows = 2

fig.add_subplot(rows, columns, 1)
plt.imshow(pirate, cmap='Greys_r', interpolation='nearest')
plt.axis('off')
plt.title('pirate_MHI')

fig.add_subplot(rows, columns, 2)
plt.imshow(course, cmap='Greys_r', interpolation='nearest')
plt.axis('off')
plt.title('course_MHI')

fig.add_subplot(rows, columns, 3)
plt.imshow(femme, cmap='Greys_r', interpolation='nearest')
plt.axis('off')
plt.title('femme_MHI')

fig.add_subplot(rows, columns, 4)
plt.imshow(action, cmap='Greys_r', interpolation='nearest')
plt.axis('off')
plt.title('action_MHI')

plt.show()


import numpy as np
from keras.layers import LSTM, Dense ,RepeatVector, Dropout, TimeDistributed
from keras import optimizers
from keras.models import Sequential
from sgan.data.trajectories import TrajectoryDataset
import matplotlib.pyplot as plt
from keras.models import load_model
from sgan.utils import relative_to_abs
import torch
import os
from sgan.losses import displacement_error, final_displacement_error
from keras.layers import embeddings

os.environ["CUDA_VISIBLE_DEVICES"]="1"

datasetss= TrajectoryDataset(data_dir="/home/asyed/sgan/scripts/datasets/univ/train" , obs_len=8, pred_len=12, skip=1, threshold=0.002,
        min_ped=1, delim='\t')

test= TrajectoryDataset(data_dir="/home/asyed/sgan/scripts/datasets/univ/test", obs_len=8, pred_len=12, skip=1, threshold=0.002,
        min_ped=1, delim='\t')

input_data= datasetss.obs_traj_rel.permute(0,2,1).numpy()
output_data= datasetss.pred_traj_rel.permute(0,2,1).numpy()

test_x= test.obs_traj_rel.permute(0,2,1).numpy()
test_y = test.pred_traj_rel.permute(0,2,1).numpy()

test_x_abs= test.obs_traj.permute(0,2,1).numpy()
test_y_abs=test.pred_traj.permute(0,2,1).numpy()
#
hidden_neurons= 128
# # # #
model= Sequential()
model.add(Dense(64, input_shape=(None,2),activation="linear"))
model.add(LSTM(input_shape=(8,64), output_dim= hidden_neurons, return_sequences= False))
model.add(RepeatVector(12))
model.add(LSTM( output_dim= hidden_neurons, return_sequences= True))
model.add(Dropout(0.3))
model.add(TimeDistributed(Dense(2,activation= "linear")))
optim= optimizers.adam(lr=0.001)
model.compile(loss="mse", optimizer=optim, metrics=["accuracy"])

model.fit(input_data, output_data,
                  validation_split=0.15,
                  epochs=50,
                  batch_size=64,
                  shuffle=True)
        # model.reset_states()

# history = model.fit(x, y, validation_data=(x_test, y_test), epochs=100, callbacks=callbacks_list)

model.save("lstm_univ_em.h5")
new_model= load_model("lstm_univ_em.h5")
pred=new_model.predict(test_x,batch_size=64)
predict= torch.from_numpy(pred)
predict= predict.permute(0,2,1)
prediction= predict.permute(0,2,1).numpy()

a=relative_to_abs(datasetss.obs_traj_rel.permute(2,0,1),datasetss.obs_traj.permute(2,0,1)[0])
# print(a)

# print(predict[1:3].permute(2,0,1))
# print(datasetss.pred_traj[1:3].permute(2,0,1)[0])
# print(datasetss.obs_traj[1])

# print(datasetss.obs_traj_rel[1:3].permute(2,0,1))
# print(datasetss.obs_traj[1:3].permute(2,0,1)[0])

abs_traj=relative_to_abs(predict.permute(2,0,1),test.pred_traj.permute(2,0,1)[0])
pred_traj= abs_traj.permute(1,0,2).numpy()
# print(pred_traj[1:4])
# print(datasetss.obs_traj[1:3])
# print(a)
# print(a.permute(1,0,2))

for i in range(110,115):
    plt.plot(pred_traj[i][:,0], pred_traj[i][:,1], "r+")
    plt.plot(test_x_abs[i][:,0], test_x_abs[i][:,1], "b+")
    plt.plot(test_y_abs[i][:,0], test_y_abs[i][:,1], "g+")

plt.show()
pred_traj_tensor=torch.from_numpy(pred_traj)
gt_tensor=torch.from_numpy(test_y_abs)
ade=displacement_error(pred_traj_tensor.permute(1,0,2),gt_tensor.permute(1,0,2),mode="sum")
# print(ade)
ade_res = (ade[0].detach()) / (len(pred_traj) * 12)
print(ade_res)
fde= final_displacement_error(pred_traj_tensor.permute(1,0,2)[-1],gt_tensor.permute(1,0,2)[-1],mode="sum")
fde_res= (fde[0].detach()) / (len(pred_traj))
# print(predict.permute(2,0,1))
# print(test.pred_traj.permute(2,0,1))
print(fde_res)

print(test_y_abs.shape)
print(pred_traj_tensor.shape)


import numpy as np
from tmm1d import tmm1d
import time

class Parameters:
    pass

def main():
    DEV = Parameters()

    ## Device Parameters
    DEV.er1 = 1.4 # permitivity reflection interface
    DEV.er2 = 1.8 # permitivity transmission interface
    DEV.ur1 = 1.2 # permeability reflection interface
    DEV.ur2 = 1.6 # permeability transmission interface
    DEV.ER = np.array([2,1]) # permitivity of the device layers (you can add any amout of layers you want)
    DEV.UR = np.array([1,3]) # permeability of device layers (you can add any amount of layers you want)
    DEV.L = np.array([0.25,0.5]) * 2.7 # Length of the layers

    ## Source Parameters
    SRC = Parameters()
    SRC.ptm = (1j)/np.sqrt(2) # Amplitude of the TM polarization
    SRC.pte = 1 / np.sqrt(2) # Amplitude of the TE polarization
    SRC.phi = 23 # Azimuthal angle of incidence (Degrees)
    SRC.theta = 57 # Elevation angle of incidence (Degrees)
    SRC.lam0 = 2.7 # Free space wavelength
    print(SRC.lam0)

    start_time = time.time()
    DAT = tmm1d(DEV, SRC)
    print('--- %s seconds ---' %(time.time() - start_time))

    print('REF: ', DAT.REF)
    print('TRN: ', DAT.TRN)

    print('S11:\n', DAT.s11)
    print('S12:\n', DAT.s12)
    print('S21:\n', DAT.s21)
    print('S22:\n', DAT.s22)

if __name__ == "__main__":
    main()


k = int(input())
rooms = list(map(int,input().split()))
a = set()
b = set()
for i in rooms:
    if i not in a:
        a.add(i)
        b.add(i)
    else:
        b.discard(i)
x = (list(b))
print(x[0])


from enums import BlockState, MemOperation, BlockSource, Protocol
from tracker import CoreTracker

"""
CacheConfig: structure for cache configuration
"""
class CacheConfig:
    def __init__(self, size: int, associativity: int, block_size: int, word_size: int, protocol: Protocol) -> None:
        self.size = size
        self.associativity = associativity
        self.block_size = block_size
        self.word_size = word_size
        self.protocol = protocol

"""
CacheBlock: Represents a cache block with size {block_size} and has {block_size / word_size} entries
- Each cache block has a state (MESI)
- Each block keeps track of whether it is least recently used (lru)
"""
class CacheBlock:
    def __init__(self, block_size: int, word_size: int) -> None:
        self.state = BlockState.INVALID     # We can consider INVALID as not occupied
        self.last_used = 0                  # Gets updated for every load/store operation. For LRU implementation
        self.tag = 0                        # Address tag

        entry_num = int(block_size / word_size)  # default: 32 / 4 = 8
        self.entries = []
        for i in range(0, entry_num):
            self.entries.append(0)

    def is_invalid(self):
        return self.state == BlockState.INVALID

    def is_shared(self):
        return self.state == BlockState.SHARED

    def is_private(self):
        return self.state == BlockState.EXCLUSIVE or self.state == BlockState.MODIFIED

    def set_last_used(self, new_last_used: int):
        self.last_used = new_last_used

    """
    Simulate cache's state machine for MESI / DRAGON
    """
    def get_next_state(self, op: MemOperation, source: BlockSource) -> BlockState:
        ##################### Invalidation-based protocol
        if op == MemOperation.PR_INVALIDATE_LOAD:
            if self.state == BlockState.INVALID and source == BlockSource.MEMORY:
                return BlockState.EXCLUSIVE
            elif self.state == BlockState.INVALID and source == BlockSource.REMOTE_CACHE:
                return BlockState.SHARED
        elif op == MemOperation.PR_INVALIDATE_STORE:
            return BlockState.MODIFIED
        elif op == MemOperation.BUS_INVALIDATE_LOAD:
            if self.state == BlockState.EXCLUSIVE or self.state == BlockState.MODIFIED:
                return BlockState.SHARED
        ##################### MOESI protocol
        elif op == MemOperation.BUS_MOESI_LOAD:
            if self.state == BlockState.EXCLUSIVE:
                return BlockState.SHARED
            elif self.state == BlockState.MODIFIED:
                return BlockState.OWNED
        elif op == MemOperation.BUS_LOAD_EXCLUSIVE:
            return BlockState.INVALID
        ##################### Update-based protocol
        elif op == MemOperation.PR_LOAD_MISS:
            if self.state == BlockState.INVALID and source == BlockSource.MEMORY:
                return BlockState.EXCLUSIVE
            elif self.state == BlockState.INVALID and source == BlockSource.REMOTE_CACHE:
                return BlockState.SHARED_CLEAN
        elif op == MemOperation.PR_STORE_MISS:
            if source == BlockSource.MEMORY:
                return BlockState.MODIFIED
            elif source == BlockSource.REMOTE_CACHE:
                return BlockState.SHARED_MODIFIED
        elif op == MemOperation.PR_UPDATE_STORE:
            if self.state == BlockState.EXCLUSIVE:
                return BlockState.MODIFIED
            elif self.state == BlockState.SHARED_CLEAN:
                return BlockState.SHARED_MODIFIED       # Achieve ownership
        elif op == MemOperation.BUS_UPDATE_LOAD:
            if self.state == BlockState.EXCLUSIVE:
                return BlockState.SHARED_CLEAN
            elif self.state == BlockState.MODIFIED:
                return BlockState.MODIFIED
        elif op == MemOperation.BUS_UPDATE_UPDATE:
            if self.state == BlockState.SHARED_MODIFIED:
                return BlockState.SHARED_CLEAN          # Give up ownership

        return self.state

"""
Cache: Represents an L1 Cache
- Cache has {size / block_size} cache blocks. They are divided into { associativity } sets of {size / block_sizse / associativity} blocks
- Cache should use LRU protocol
"""
class Cache:
    def __init__(self, id: int, cache_config: CacheConfig, tracker: CoreTracker) -> None:
        self.config = cache_config
        self.id = id
        self.tracker = tracker

        # For LRU implementation. Each cache block receives a new last_used each load/store
        self.num_operation = 0

        self.blocks = []
        num_sets = int(self.config.size / self.config.block_size / self.config.associativity)
        for set in range(0, num_sets):
            # 64 sets of 2 cache blocks
            self.blocks.append([])
            for _ in range(0, self.config.associativity):
                self.blocks[set].append(CacheBlock(self.config.block_size, self.config.word_size))

    """
    A hit happens when blocks[cache_index] returns a set of blocks, in which one has tag === given tag AND that block is not invalid
    Returns index of block in the given set
    """
    def find_block(self, tag, cache_index) -> int:
        for block_id, block in enumerate(self.blocks[cache_index]):
            if block.tag == tag and not block.is_invalid():
                return block_id

        return -1

    """
    processor_load: load instruction issued by processor
        If hit: report hit to processor. Set block's last used to num_operation.
        If miss: Report miss to processor
        num_operation++
    """
    def processor_load(self, tag, cache_index, offset) -> BlockState:
        # self.log(f'Handling processor load at tag {tag}, index {cache_index} and offset {offset}')
        hit_block = self.find_block(tag, cache_index)
        if hit_block != -1: # Hit!
            self.blocks[cache_index][hit_block].last_used = self.num_operation
            self.num_operation = self.num_operation + 1
            # Track hit and access
            self.tracker.track_hit()
            self.tracker.incr_data_access(state=self.blocks[cache_index][hit_block].state)
            return self.blocks[cache_index][hit_block].state

        self.tracker.incr_miss()
        self.num_operation = self.num_operation + 1
        return BlockState.INVALID

    """
    processor_store: store instruction issued by processor
        If hit: report hit to processor. Use state machine to change state accordingly.
        If miss: Handle LRU accordingly. Report miss to processor.
        Set block's last used to num_operation. num_operation++
    """
    def processor_invalidate_store(self, tag, cache_index, offset):
        hit_block = self.find_block(tag, cache_index)
        if hit_block != -1: # Hit!
            target_block = self.blocks[cache_index][hit_block]
            target_block.last_used = self.num_operation
            self.num_operation = self.num_operation + 1

            # Store old state to return (shared, modified, exclusive)
            old_state = target_block.state

            # hit store logic
            target_block.state = target_block.get_next_state(op=MemOperation.PR_INVALIDATE_STORE, source=BlockSource.LOCAL_CACHE)

            # Track hit
            self.tracker.track_hit()
            self.tracker.incr_data_access(old_state)
            return old_state

        self.tracker.incr_miss()
        self.num_operation = self.num_operation + 1
        return BlockState.INVALID

    def processor_update_store(self, tag, cache_index, offset):
        hit_block = self.find_block(tag, cache_index)
        if hit_block != -1: # Hit!
            target_block = self.blocks[cache_index][hit_block]
            target_block.last_used = self.num_operation
            self.num_operation = self.num_operation + 1

            # Store old state to return (exclusive, shared_clean, shared_modified, dirty)
            old_state = target_block.state

            # hit store logic
            target_block.state = target_block.get_next_state(op=MemOperation.PR_UPDATE_STORE, source=BlockSource.LOCAL_CACHE)

            # Track hit
            self.tracker.track_hit()
            self.tracker.incr_data_access(old_state)
            return old_state

        self.tracker.incr_miss()
        self.num_operation = self.num_operation + 1
        return BlockState.INVALID

    """
    pr_read_miss: bus_load but a different new state
    """
    def bus_update_load(self, tag, cache_index, offset):
        block_index = self.find_block(tag, cache_index)
        if block_index == -1:
            return False

        block = self.blocks[cache_index][block_index]
        self.tracker.incr_data_access(block.state)
        block.state = block.get_next_state(op=MemOperation.BUS_UPDATE_LOAD, source=BlockSource.REMOTE_CACHE)
        block.last_used = self.num_operation

        self.num_operation += 1
        return True

    """
    bus_load: Another remote cache is asking to read a block that you might have
        If you have it: return True. Use state machine to change state accordingly.
        If you don't: return False. No state change
    """
    def bus_invalidate_load(self, tag, cache_index, offset):
        # self.log(f'Handling bus load at tag {tag}, index {cache_index} and offset {offset}')
        block_index = self.find_block(tag, cache_index)
        if block_index == -1:
            return False

        block = self.blocks[cache_index][block_index]
        self.tracker.incr_data_access(block.state)
        block.state = block.get_next_state(op=MemOperation.BUS_INVALIDATE_LOAD, source=BlockSource.REMOTE_CACHE)
        block.last_used = self.num_operation

        self.num_operation += 1
        return True

    def bus_invalidate_load_exclusive(self, tag, cache_index, offset):
        # self.log(f'Handling bus load exclusive at tag {tag}, index {cache_index} and offset {offset}')
        block_index = self.find_block(tag, cache_index)
        if block_index == -1:
            return False

        block = self.blocks[cache_index][block_index]

        # self.tracker.incr_data_access(block.state) # Invalidation not counted as access
        block.last_used = self.num_operation
        block.state = block.get_next_state(op=MemOperation.BUS_LOAD_EXCLUSIVE, source=BlockSource.REMOTE_CACHE)

        self.num_operation += 1
        return True

    def bus_moesi_invalidate_load(self, tag, cache_index, offset):
        # self.log(f'Handling bus moesi invalidate load at tag {tag}, index {cache_index} and offset {offset}')
        block_index = self.find_block(tag, cache_index)
        if block_index == -1:
            return False

        block = self.blocks[cache_index][block_index]
        self.tracker.incr_data_access(block.state)
        block.state = block.get_next_state(op=MemOperation.BUS_MOESI_LOAD, source=BlockSource.REMOTE_CACHE)
        block.last_used = self.num_operation

        self.num_operation += 1
        return True

    def flush(self, tag, cache_index, offset, wrote_back):
        print("----- Flushing")
        block_index = self.find_block(tag, cache_index)
        if block_index == -1:
            return False

        block = self.blocks[cache_index][block_index]
        if self.config.protocol == Protocol.MOESI and block.state == BlockState.OWNED:
            self.tracker.track_evict()

        if self.config.protocol == Protocol.MESI and (block.state == BlockState.MODIFIED or block.state == BlockState.SHARED) and not wrote_back: # block is written back to memory as it is invalidated. Has to.
            self.tracker.track_evict()

        block.state = BlockState.INVALID
        block.last_used = self.num_operation
        return not wrote_back

    """
    receive_block_from_bus: Adds new block to cache. Handle LRU if needed.
    Let cache block decide its own next state
    """
    def receive_block_from_bus(self, source: BlockSource, op: MemOperation, tag, cache_index, offset):
        target_blk = None
        # Find invalid cache block to insert itself there
        for block in self.blocks[cache_index]:
            if block.is_invalid():
                target_blk = block
                break

        # If no invalid blocks found, find lru block
        if target_blk == None:
            min_last_used = 2 ** 31 + (2 ** 31 - 1)
            for block in self.blocks[cache_index]:
                if block.last_used < min_last_used:
                    target_blk = block
                    min_last_used = block.last_used

            # Invalidate chosen block
            # self.log(f'Evicting block with tag {target_blk.tag}')
            self.tracker.track_evict()
            target_blk.state = BlockState.INVALID

        # Load block into cache
        target_blk.tag = tag
        target_blk.last_used = self.num_operation

        # Set new state
        target_blk.state = target_blk.get_next_state(op=op, source=source)
        self.num_operation = self.num_operation + 1

        # Track stall time
        if source == BlockSource.REMOTE_CACHE:
            self.tracker.track_load_words_from_remote_cache(words=int(self.config.block_size / self.config.word_size))
        elif source == BlockSource.MEMORY:
            self.tracker.track_load_from_mem()

    def receive_word_from_bus(self, source: BlockSource, op: MemOperation, tag, cache_index, offset):
        blk_index = self.find_block(tag=tag, cache_index=cache_index)
        if blk_index == -1:
            return

        target_blk = self.blocks[cache_index][blk_index]

        # Set last_used
        target_blk.last_used = self.num_operation

        # Set new state
        target_blk.state = target_blk.get_next_state(op=op, source=source)
        self.num_operation = self.num_operation + 1

        # Track stall time
        self.tracker.track_load_words_from_remote_cache(words=1)

    def log(self, message: str):
        print(f'CACHE {self.id}: {message}')


# August 4th 2018
# Author: Samuel Salemi
# University of Guelph Masters Graduate
# This is a directory module

def main(directories):
    parentDir = "E:/Documents/University/Masters/Sandbox/Project"
    paramsDir = parentDir + "/genericSettings"
    genericDir = parentDir + "/model"
    resultsDir = parentDir + "/results"
    subID = "subject01"
    subResultsDir = resultsDir + "/" + subID
    ikResultsDir = subResultsDir + "/ik"
    idResultsDir = subResultsDir + "/id"
    soResultsDir = subResultsDir + "/so"
    rraResultsDir = subResultsDir + "/rra"
    cmcResultsDir = subResultsDir + "/cmc"
    jrResultsDir = subResultsDir + "/jr"
    return(parentDir, paramsDir, genericDir, resultsDir, subID, subResultsDir, ikResultsDir,idResultsDir, soResultsDir, rraResultsDir, cmcResultsDir, jrResultsDir)


"""
Задача 5.2
Создать текстовый файл (не программно),
сохранить в нем несколько строк,
выполнить подсчет количества строк,
количества слов в каждой строке.
"""

my_file = 'Task_5.2.txt'

with open(my_file, 'r', encoding='utf-8') as data:
    stroces = [line for line in data]
    print(f'в документе {my_file}: {len(stroces)} строки')
    num_stroke = 0
    for stroce in stroces:
        num_stroke += 1
        print(f'В строке {num_stroke}: {len(stroce.split())} слова')


import numpy as np

from python_prototypes.graph import AdjacencyListGraph as Graph
from python_prototypes.graph import AdjacencyListVertex

def get_small_world_network(n):
    G = Graph()
    edges = 0
    vertices = np.empty(n, dtype=AdjacencyListVertex)
    for i in range(n):
        vertices[i] = G.add_vertex()
    for v in vertices:
        out_edges = np.random.choice(n, np.random.randint(0, np.log2(n)), replace=False)
        for j in out_edges:
            v.add_edge(j)
            vertices[j].add_edge(v.id)
            edges += 2
    return G, edges

def parse_edge_list(input_file):
    G = Graph()
    f = open(input_file)
    x = f.readlines()
    n, m = x[0].strip().split()
    s, t = x[1].strip().split()
    n = int(n);
    m = int(m);
    s = int(s);
    t = int(t)
    data = np.genfromtxt(input_file, skip_header=2, dtype=np.int)
    capacity = np.zeros((n, n), dtype=np.int)
    for _ in range(n):
        G.add_vertex()
    for source, dst, edge_cap in data:
        if G.connected(source, dst):
            capacity[source, dst] += edge_cap
        else:
            G[source].add_edge(dst)
            G[dst].add_edge(source)
            capacity[source, dst] = edge_cap

    return G, s, t, capacity, n, m


import pandas as pd
import json

df = pd.read_excel('public_use-industry-skills-needs.xlsx', 'Industry Skills Needs')

# print(df.isic_section_name.unique())
def data_collection():
    industry_names = df.industry_name.unique()

    sections = {'Mining and quarrying' : 'Mining',
                'Manufacturing' : 'Manufacturing',
                'Information and communication' : 'Info',
                'Financial and insurance activities' : 'Finacial',
                'Professional scientific and technical activities':'Scientific-Technical',
                'Arts, entertainment and recreation':'Arts'}

    # industry_name_dict = {}
    # count = 0
    # for item in industry_names:
    #     industry_name_dict[item] = count
    #     count += 1

    # print(industry_name_dict)
    skill_group_names = df['skill_group_name']
    skill_group_names_dict = {}
    for skill in skill_group_names:
        if skill not in skill_group_names_dict:
            skill_group_names_dict[skill] = 1
        else:
            skill_group_names_dict[skill] += 1

    # print(skill_group_names_dict)

    skill_rank = {}
    for ind in df.index:
        if df['skill_group_name'][ind] not in skill_rank:
            skill_rank[df['skill_group_name'][ind]] = df['skill_group_rank'][ind]
        else:
            skill_rank[df['skill_group_name'][ind]] += df['skill_group_rank'][ind]

    for skill in skill_rank:
        skill_rank[skill] /= skill_group_names_dict[skill]

    # print(skill_rank)

    # with open('skill_name_ranks.json', 'w') as f:
    #     json.dump(skill_rank, f, indent=2)

    # with open('skill_name_frequencies.json', 'w') as f:
    #     json.dump(skill_group_names_dict,f, indent=2)
    with open('skill_name_frequencies.json','r') as f:
        freq = json.load(f)
    with open('skill_name_ranks.json','r') as f:
        ranks = json.load(f)

    print(freq)

def industry_names():
    names = df.industry_name.unique()
    industry_name_options = {}
    for name in names:
        industry_name_options[name] = name #creating this dictionary for the dropdown options

    options = []
    for k in industry_name_options:
        options.append({'label':k,'value':k})

    with open('dropdown_options.json', 'w') as f:
        json.dump(options,f,indent=2)

industry_names()


n,m = map(int, input().split())

# 2n人の選手の、それぞれの出し手
A = []
for i in range(2*n):
	A.append(input())

# print(A[0][0])

# 必要なのは
# 1.各ラウンドの対戦相手を決定すること
# 2.対戦相手との勝負の結果を記録するMap
# 3.対戦相手との勝負の結果を決定する条件分岐

result = {i:0 for i in range(2*n)}

for i in range(m):
	res = sorted(result.items(), key=lambda x:x[1], reverse=True)
	r_list = list(result.keys())
	for k in range(1, n+1):
		# 対戦相手を確定する(index調整のため-1)
		p1 = res[2*k-1][0]
		p2 = res[2*k-2][0]

		# 対戦を行う
		p1_GCP = A[p1][i]
		p2_GCP = A[p2][i]
		if p1_GCP == 'G':
			if p2_GCP == 'C':
				result[p1] += 1
			elif p2_GCP == 'P':
				result[p2] += 1
		elif p1_GCP == 'C':
			if p2_GCP == 'P':
				result[p1] += 1
			elif p2_GCP == 'G':
				result[p2] += 1
		elif p1_GCP == 'P':
			if p2_GCP == 'G':
				result[p1] += 1
			elif p2_GCP == 'C':
				result[p2] += 1

res = sorted(result.items(), key=lambda x:x[1], reverse=True)
for i in range(2*n):
	print(res[i][0]+1)

# result = sorted(result.items(), key=lambda x:x[1], reverse=True)
# r_list = list(result.keys())
# print(r_list)

# print(result)


'''
Scrapes google scholar search results and returns a numpy array of the
first 10 results with the relevent information (authors, title, absract etc.)
=============================================================================
Author: Mitchell Baum
=============================================================================
'''
import requests
from bs4 import BeautifulSoup
import numpy
import re

'''Article class for storing scraped information. Contains as_list method which returns the information as a list and as_dict which returns a dict'''
class article:
    def __init__(self, no, embayment, bsObj):

        self.no             = no
        self.embayment      = embayment
        self.title          = bsObj.find('h3', {'class':'gs_rt'}).text
        (self.auth,         #TODO: this method using split does not work when an author has a '-' in their name maybe use ' - '??
        self.dateyear,
        self.publication)   = bsObj.find('div', {'class':'gs_a'}).text.split('-')
        self.abstract       = bsObj.find('div', {'class':'gs_rs'}).text
        self.citations      = bsObj.find('div', {'class': 'gs_fl'}).find(text=re.compile("^Cited by"))
        self.link           = bsObj.find('h3', {'class':'gs_rt'}).find('a', href = True)['href']

    '''Method which returns the information as a list with all the information stored in the class'''
    def as_array(self):
        x = numpy.array([[
            self.no,
            self.embayment,
            self.title,
            self.auth,
            self.dateyear,
            self.publication,
            self.abstract,
            self.citations,
            self.link
        ]])
        return x

    '''Converts article information to a dict and returns it'''

    def dictionary(self):
        x = dict({
        'Id':self.no,
        'Embayment':self.embayment,
        'Article':self.title,
        'Author/s':self.auth,
        'Year':self.dateyear,
        'Publication':self.publication,
        'Abstract':self.abstract,
        'Citations':self.citations,
        'Link':self.link
        })

        return x

'''A url class for converting user input into a url which can be requested using requests or urllib etc.'''
class url:

    def __init__(self, query, url="https://scholar.google.com.au/scholar?start={}&q="):

        '''Formats the input embayment and search terms to create the url for the search'''
        queryTerms = query.strip().split(' ')
        separator ='+'
        prefix = url.format('00')

        self.prefix = prefix
        self.suffix = "&hl=en&as_sdt=0,5"
        self.terms  = separator.join(queryTerms)
        self.url    = self.prefix + self.terms + self.suffix

'''Class which takes in a url as an argument, requests it using requests,
then converts it into a beautiful soup object, and returns the <body></body> section'''
class bsSchol:

    def __init__(self, url):
        self.html = requests.get(url, headers = {"User-Agent":"Mozilla/5.0"})
        self.soup = BeautifulSoup(self.html.content, "html.parser")
        self.body = self.soup.find("div", {"id":"gs_res_ccl_mid"})
        self.results = self.body.findAll("div", {"class":"gs_ri"})

def scholarScrape():

    '''Asking for user input for scholar search'''
    embayment_query     = input("\n\nSearch:\n")
    extra_query_terms   = input("\n\nExtra Search Terms:\n")
    query               = embayment_query + " " + extra_query_terms
    search_url          = url(query)
    search_bsObj        = bsSchol(search_url.url)

    article_array = numpy.array([[
        "id",
        "Embayment",
        "Article Title",
        "Author/s",
        "Year",
        "Publication",
        "Abstract",
        "Citations",
        "Link"]])

    number = 0

    for i in search_bsObj.results:
        entry = article(
            number,
            embayment_query,
            i)
        number += number

        article_array = numpy.append(article_array, entry.as_array(), axis=0)

    return article_array


from django.shortcuts import render,redirect
from django.contrib.auth.models import User
from django.contrib.auth import authenticate,login,logout
from .models import *

# Create your views here.

def About(request):
	return render(request,'about.html')

def Contact(request):
	return render(request,'contact.html')

def Index(request):
	if not request.user.is_staff:
		return redirect('login')
	return render(request,'index.html')

def LogIn(request):
	error = ""
	if request.method=='POST':
		u = request.POST['uname']
		p = request.POST['pwd']
		user = authenticate(username=u,password=p)
		try:
			if user.is_staff:
				login(request,user)
				error="no"
			else:
				error="yes"
		except:
			error = "yes"
	d = {'error':error}
	return render(request,'login.html',d)

def Logout_Admin(request):
	if not request.user.is_staff:
		return redirect('login')
	logout(request)
	return redirect('login')

def View_Student(request):
    if not request.user.is_staff:
        return redirect('login')
    stud = Student.objects.all()
    d = {"stud":stud}
    return render(request,'view_student.html',d)

def Add_Student(request):
    error=""
    if not request.user.is_staff:
        return redirect('login')
    if request.method == 'POST':
        n = request.POST['name']
        g = request.POST['gender']
        ag = request.POST['age']
        c = request.POST['mobile']
        ad = request.POST['address']
        em = request.POST['email']
        try:
            Student.objects.create(name=n, gender=g,mobile=c,address=ad,age=ag,emailid=em)
            error="no"
        except:
            error="yes"
    d={'error':error}
    return render(request,'add_student.html',d)

def Delete_Student(request,pid):
	if not request.user.is_staff:
		return redirect('login')
	student = Student.objects.get(id=pid)
	student.delete()
	return redirect('view_student')


# Draws an off-screen buffer and display it in the corner of the view.
import bpy
from bgl import *

class OffScreenDraw(bpy.types.Operator):
    bl_idname = "view3d.offscreen_draw"
    bl_label = "View3D Offscreen Draw"

    _handle_calc = None
    _handle_draw = None
    is_enabled = False

    # manage draw handler
    @staticmethod
    def draw_callback_px(self, context):
        scene = context.scene
        aspect_ratio = scene.render.resolution_x / scene.render.resolution_y

        self._update_offscreen(context, self._offscreen)
        self._opengl_draw(context, self._texture, aspect_ratio, 0.2)

    @staticmethod
    def handle_add(self, context):
        OffScreenDraw._handle_draw = bpy.types.SpaceView3D.draw_handler_add(
                self.draw_callback_px, (self, context),
                'WINDOW', 'POST_PIXEL',
                )

    @staticmethod
    def handle_remove():
        if OffScreenDraw._handle_draw is not None:
            bpy.types.SpaceView3D.draw_handler_remove(OffScreenDraw._handle_draw, 'WINDOW')

        OffScreenDraw._handle_draw = None

    # off-screen buffer
    @staticmethod
    def _setup_offscreen(context):
        import gpu
        scene = context.scene
        aspect_ratio = scene.render.resolution_x / scene.render.resolution_y

        try:
            offscreen = gpu.offscreen.new(512, int(512 / aspect_ratio))
        except Exception as e:
            print(e)
            offscreen = None

        return offscreen

    @staticmethod
    def _update_offscreen(context, offscreen):
        scene = context.scene
        render = scene.render
        camera = scene.camera

        modelview_matrix = camera.matrix_world.inverted()
        projection_matrix = camera.calc_matrix_camera(
                render.resolution_x,
                render.resolution_y,
                render.pixel_aspect_x,
                render.pixel_aspect_y,
                )

        offscreen.draw_view3d(
                scene,
                context.space_data,
                context.region,
                projection_matrix,
                modelview_matrix,
                )

    @staticmethod
    def _opengl_draw(context, texture, aspect_ratio, scale):
        """
        OpenGL code to draw a rectangle in the viewport
        """

        glDisable(GL_DEPTH_TEST)

        # view setup
        glMatrixMode(GL_PROJECTION)
        glPushMatrix()
        glLoadIdentity()

        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()

        glOrtho(-1, 1, -1, 1, -15, 15)
        gluLookAt(0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)

        act_tex = Buffer(GL_INT, 1)
        glGetIntegerv(GL_TEXTURE_2D, act_tex)

        viewport = Buffer(GL_INT, 4)
        glGetIntegerv(GL_VIEWPORT, viewport)

        width = int(scale * viewport[2])
        height = int(width / aspect_ratio)

        glViewport(viewport[0], viewport[1], width, height)
        glScissor(viewport[0], viewport[1], width, height)

        # draw routine
        glEnable(GL_TEXTURE_2D)
        glActiveTexture(GL_TEXTURE0)

        glBindTexture(GL_TEXTURE_2D, texture)

        texco = [(1, 1), (0, 1), (0, 0), (1, 0)]
        verco = [(1.0, 1.0), (-1.0, 1.0), (-1.0, -1.0), (1.0, -1.0)]

        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)

        glColor4f(1.0, 1.0, 1.0, 1.0)

        glBegin(GL_QUADS)
        for i in range(4):
            glTexCoord3f(texco[i][0], texco[i][1], 0.0)
            glVertex2f(verco[i][0], verco[i][1])
        glEnd()

        # restoring settings
        glBindTexture(GL_TEXTURE_2D, act_tex[0])

        glDisable(GL_TEXTURE_2D)

        # reset view
        glMatrixMode(GL_PROJECTION)
        glPopMatrix()

        glMatrixMode(GL_MODELVIEW)
        glPopMatrix()

        glViewport(viewport[0], viewport[1], viewport[2], viewport[3])
        glScissor(viewport[0], viewport[1], viewport[2], viewport[3])

    # operator functions
    @classmethod
    def poll(cls, context):
        return context.area.type == 'VIEW_3D'

    def modal(self, context, event):
        if context.area:
            context.area.tag_redraw()

        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        if OffScreenDraw.is_enabled:
            self.cancel(context)

            return {'FINISHED'}

        else:
            self._offscreen = OffScreenDraw._setup_offscreen(context)
            if self._offscreen:
                self._texture = self._offscreen.color_texture
            else:
                self.report({'ERROR'}, "Error initializing offscreen buffer. More details in the console")
                return {'CANCELLED'}

            OffScreenDraw.handle_add(self, context)
            OffScreenDraw.is_enabled = True

            if context.area:
                context.area.tag_redraw()

            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}

    def cancel(self, context):
        OffScreenDraw.handle_remove()
        OffScreenDraw.is_enabled = False

        if context.area:
            context.area.tag_redraw()

def register():
    bpy.utils.register_class(OffScreenDraw)

def unregister():
    bpy.utils.unregister_class(OffScreenDraw)

if __name__ == "__main__":
    register()


from flask import jsonify

def remove_friends_by_friend_id(user_id, friend_id, connection):
    DELETE_FRIEND_BY_FRIEND_ID = """
    DELETE FROM friendships WHERE user_id = %s AND friend_id = %s
    RETURNING *;
    """
    with connection:
        with connection.cursor() as cursor:
            cursor.execute(DELETE_FRIEND_BY_FRIEND_ID, (user_id, friend_id,))
            deleted_friend = cursor.fetchone()

            if deleted_friend:
                return jsonify({'message': 'Friendship deleted successfully'})
            else:
                return jsonify({'message': 'Friendship not found'})


num=int(input("enter the number: "))
itter=[]
iterr=[]
def fibo(l):
    if l==0: return 0
    elif l==1: return 0
    elif l==2: return 1
    else:
        for i in range(l):
            curren=fibo(l-1)+fibo(l-2)
            itter.append(curren)

    return curren

def fibonacci(n):
    a=1
    b=1
    if n<=0: return 0
    if n==1: return 1
    if n==2: return 1
    else:
        for i in range(n-2):
            c=a+b
            a=b
            b=c
    return b

for i in range(num):
    print(fibonacci(i),end='')
    # print(i,end='')


from typing import Callable, Set, List
import numpy as np

class VotingRules:

    def borda_count(candidates: Set[object], ranking_functions: List[Callable], weights: List[float]):
        """Borda count implementation

        Args:
            candidates (Union[List[Solution], List[int]]): Either List of Solutions or List of location_ids
            ranking_functions (List[Callable]): Either solution ranking functions or location ranking functions from each rider
            kwargs: Additional arguments that is supplied to the runtime ranking functions

        Returns:
            winner [Solution | int]: Winner candidate (either a Solution or location_id) according to voting rule
        """
        num_of_candidates = len(candidates)
        scores = {candidate: 0 for candidate in candidates}

        for ranking_function, weight in zip(ranking_functions, weights):
            ranked_candidates = ranking_function(candidates)
            for rank_index, candidate in enumerate(ranked_candidates):
                scores[candidate] += weight*((num_of_candidates - 1) - rank_index)

        # Use np.random to account for the fact that there could be ties
        best_candidate = max(scores, key=scores.get)
        best_score = scores[best_candidate]
        indifferent_candidates = \
            [candidate for candidate in candidates if scores[candidate] == best_score]

        return np.random.choice(indifferent_candidates)

    def popularity(candidates: Set[object], ranking_functions: List[Callable], weights: List[float]):

        scores = {candidate: 0 for candidate in candidates}

        for ranking_function, weight in zip(ranking_functions, weights):
            ranked_candidates = ranking_function(candidates)
            first_choice = ranked_candidates[0]
            scores[first_choice] += 1*weight
        # Use np.random to account for ties
        best_candidate = max(scores, key=scores.get)
        best_score = scores[best_candidate]
        indifferent_candidates = \
            [candidate for candidate in candidates if scores[candidate] == best_score]

        return np.random.choice(indifferent_candidates)

    def harmonic(candidates: Set[object], ranking_functions: List[Callable], weights: List[float]):
        scores = {candidate: 0 for candidate in candidates}

        for ranking_function, weight in zip(ranking_functions, weights):
            ranked_candidates = ranking_function(candidates)
            for rank_index, candidate in enumerate(ranked_candidates):
                scores[candidate] += weight * (1/(rank_index+1)) # practically the main change between harmonic and borda

        # Use np.random to account for the fact that there could be ties
        best_candidate = max(scores, key=scores.get)
        best_score = scores[best_candidate]
        indifferent_candidates = \
            [candidate for candidate in candidates if scores[candidate] == best_score]

        return np.random.choice(indifferent_candidates)

    def instant_runoff(candidates: Set[object], ranking_functions: List[Callable], weights: List[float]):
        """
        the voting rule runs in |candidates| rounds. At each round, the least supported candidate is eliminated
        I have not implemented a weighted version, as I cannot see how do we use them.
        :param ranking_functions:
        :param
        :return:
        """

        Eliminated = set([])
        ranked_candidates = []

        for ranking_function in ranking_functions:
            ranked_candidates.append(ranking_function(candidates))

        while len(Eliminated) < len(candidates) - 1:
            scores = {candidate: 0 for candidate in candidates if candidate not in Eliminated}
            for ordering, weight in zip(ranked_candidates, weights):
                not_eliminated_ordering = [i for i in ordering if i not in Eliminated]
                first_choice = not_eliminated_ordering[0]
                scores[first_choice] += 1 * weight
            worst_candidate = min(scores, key=scores.get)
            worst_score = scores[worst_candidate]

            indifferent_candidates = [candidate for candidate in candidates.difference(Eliminated) if scores[candidate] == worst_score]
            # choose randomly one of the candidates with the lowest score to be eliminated
            Eliminated.add(np.random.choice(indifferent_candidates))
        return candidates.difference(Eliminated).pop()