from typing import Any, Tuple, Optional, List

import pytorch_lightning as pl

from torch import Tensor
from torch.optim import SGD, Optimizer, Adam
from torch.optim.lr_scheduler import MultiStepLR

from .config.kdfinetune import Config
from src.data import get_partial_datamodule, BaseDataModule
from .utils import (
    get_loss_function,
    compute_accuracy,
    evaluate_benign_accuracy,
    evaluate_backdoor_success_rate
)
from .kdbackdoor import KDBackdoorModel

_config = Config()

class KDFinetuneModel(pl.LightningModule):
    name: str = "kdfinetune"

    def __init__(
        self, *,
        kd_checkpoint_path: str,
        train_partial_rate: float = _config.train_partial_rate,
        test_partial_rate: float = _config.test_partial_rate,
        loss_function: str = _config.loss_function,
        lr: float = _config.lr,
        momentum: float = _config.momentum,
        weight_decay: float = _config.weight_decay,
        epochs: int = _config.epochs,
        milestones: List[int] = _config.milestones,
        gamma: float = _config.gamma,
        **datamodule_kwargs
    ) -> None:
        super().__init__()

        self.save_hyperparameters()

        kd_model = KDBackdoorModel.load_from_checkpoint(kd_checkpoint_path)
        self._network = kd_model._teacher_network
        self._backdoor = kd_model._backdoor_network
        self._target_label = kd_model.hparams.target_label
        self._datamodule = get_partial_datamodule(
            kd_model.datamodule,
            train_partial_rate=train_partial_rate,
            test_partial_rate=test_partial_rate,
            **datamodule_kwargs
        )

        self._loss_function = get_loss_function(loss_function)

    def forward(self, x: Tensor) -> Any:
        return self._network(x)

    def training_step(self, batch: Tuple[Tensor, Tensor], batch_idx: int) -> Any:
        x, y = batch
        pred_y = self._network(x)
        loss = self._loss_function(pred_y, y)
        acc = compute_accuracy(pred_y, y)

        self.log_dict({
            "finetune_train_loss": loss,
            "finetune_train_acc": acc
        }, on_epoch=True)

        return loss

    def on_train_epoch_end(self, unused: Optional = None) -> None:
        test_acc = evaluate_benign_accuracy(
            model=self._network,
            dataloader=self.datamodule.test_dataloader(),
            device=self.device
        )
        self.log_dict({
            "finetune_test_acc": test_acc
        }, on_step=False, on_epoch=True)

        self.log_dict({
            "finetune_teacher_backdoor_success_rate": evaluate_backdoor_success_rate(
                model=self._network,
                backdoor=self._backdoor,
                dataloader=self.datamodule.test_dataloader(),
                target_label=self._target_label,
                device=self.device
            )
        })

    def configure_optimizers(self) -> Optimizer:
        optimizer = SGD(
            self._network.parameters(),
            lr=self.hparams.lr,
            momentum=self.hparams.momentum,
            weight_decay=self.hparams.weight_decay
        )
        scheduler = MultiStepLR(
            optimizer,
            milestones=self.hparams.milestones,
            gamma=self.hparams.gamma
        )

        return [optimizer], [scheduler]

    @property
    def datamodule(self) -> BaseDataModule:
        return self._datamodule


"""
Given an array of integers nums sorted in ascending
order, find the starting and ending position of a
given target value. If target is not found in the
array, return [-1, -1].
Follow up: Could you write an algorithm with
O(log n) runtime complexity?
"""

def searchRange(self, nums: List[int], target: int):
    def findStart(nums, target):
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if target > nums[mid]:
                left = mid + 1
            else:
                right = mid - 1
        return left

    def findEnd(nums, target):
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if target >= nums[mid]:
                left = mid + 1
            else:
                right = mid - 1
        return right
    start, end = findStart(nums, target), \
        findEnd(nums, target)
    if start <= end:
        return [start, end]
    return [-1, -1]

print(searchRange([5, 7, 7, 8, 8, 10], 6))
print(searchRange([5, 7, 7, 8, 8, 10], 8))
print(searchRange([], 0))
print("The arrays above should be [-1, -1], \
    [3, 4], and [-1, -1]")


from .._impl import mx
import sys
import traceback
import atexit

# Stores accesses to internal symbols
_internal_accesses = set()
# Whether an exit handler was already installed
_exit_handler_set = False

class ModuleInterceptor:
    def __init__(self, thisname, targetname, allowed_internal_reads, allowed_writes=None):
        self.__dict__["_thisname"] = thisname
        self.__dict__["_allowed_internal_reads"] = allowed_internal_reads or []
        self.__dict__["_allowed_writes"] = allowed_writes or []
        self.__dict__["_thismodule"] = sys.modules[thisname]
        self.__dict__["_othermodule"] = sys.modules[targetname]

    def _get_target(self, name, is_set: bool):
        if name.startswith("__"):
            return self.__dict__["_thismodule"]

        mem_name = f"{self.__dict__['_thisname']}.{name}"

        if name.startswith("_"):
            if not is_set and name not in self.__dict__["_allowed_internal_reads"]:
                mx.abort(f"Disallowed read of internal symbol detected: {mem_name}")

            _internal_accesses.add(mem_name)
            stack = traceback.extract_stack()
            mx.logv(f"Access to internal symbol detected ({'write' if is_set else 'read'}): {mem_name}")
            mx.logvv("".join(stack.format()))

        if is_set and name not in self.__dict__["_allowed_writes"]:
            mx.abort(f"Disallowed write to {mem_name}")

        return self.__dict__["_othermodule"]

    def __setattr__(self, name, value):
        target = self._get_target(name, True)
        setattr(target, name, value)

    def __getattr__(self, name):
        target = self._get_target(name, False)
        return getattr(target, name)

def _exit_handler():
    if _internal_accesses:
        mx.logv(f"The following internal mx symbols were accessed: {', '.join(_internal_accesses)}")

def redirect(thisname: str, allowed_internal_reads: [str] = None, allowed_writes: [str] = None):
    """
    Redirects all attribute accesses on the ``thisname`` module to the
    ``mx._impl.{thisname}`` module.

    The only exception are builtins (names starting with two underscores).

    Produces warnings for accesses to internal symbols (which should not be accessed from the outside) that are not
    explicitly allowed in ``allowed_internal_reads``.

    Produces errors for writes to symbols (we should not rely on setting arbitrary symbols from the outside) that are
    not explicitly allowed in ``allowed_writes``.

    At the end (using an exit handler :func:_exit_handler:), the final list of these symbols is printed.

    :param: allowed_writes: List of symbols that are allowed to be set. All other assignments will produce an error.
    """
    global _exit_handler_set

    sys.modules[thisname] = ModuleInterceptor(thisname, "mx._impl." + thisname, allowed_internal_reads, allowed_writes)

    if not _exit_handler_set:
        atexit.register(_exit_handler)
        _exit_handler_set = True


import socket

def main():
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(("127.0.0.1", 8000))
    while True:
        msg = input("Inserisci un numero di cui fare la tabellina: ('exit' per uscire) ")
        client.sendall(msg.encode("utf-8"))
        if msg.lower() == "exit": # se scrivo exit esco
            client.close()
            break
        else:
            operazione = 0
            while operazione != "ERRORE" and operazione != "FINITO": #se ho inserito un input sbagliato o ho finito l atabellina esco
                response = client.recv(4096).decode("utf-8")
                print(f"Risultato {operazione} ricevuto: {response}")
                if response[:6] != "ERRORE": # se non ho ricevuto errore, quindi ho inserito correttamente l'input
                    if operazione >= 10: #perché la tabellina ha da 0 a 10 operazioni
                        operazione = "FINITO" #ho finito la tabellina
                    else:
                        operazione+=1 #continuo la tabellina
                else:
                    operazione = "ERRORE" # ho sbagliato a scrivere l'input

if __name__ == "__main__":
    main()


import pandas as pd
import numpy as np
#import matplotlib.pyplot as plt

class Criminal:
    jail="COUNTY JAIL"

    def __init__(self,name):
        self.name=name
        # if self.name = "John":
    def GetcriminalList(self):
        data={
            "Name": ['John', 'Ithan','Pekk','Sherlock','Tyrion','Mike',
         'Will','Steve','Dustin','Jonathan','Silverdeev','Majnu Bhai','Selmon Bhoi','Sanjay Dutt'],

            "Charge": ['Murder','Kidnapping','Tax Evasion','Blackmail','Child Abuse',
           'Cybercrime','Fraud','Hit and Run','Terrorism','Robbery','Smuggling','Paintings Smuggler','Animal Abuse,Hit and Run',
           'Carrying concealed weapon'],

            "Offense Date": ['20/09/2012', '10/01/2015', '11/09/2010','01/01/2020','30/03/2011',
                 '12/12/2015','10/10/2010','09/04/2017','10/03/2005','20/09/2019','20/10/2013','15/09/2013','10/12/2010','15/02/2010'],

            "Disposed": ['20/09/2019', '10/01/2019', '11/09/2022','01/01/2023','30/03/2025',
                 '12/12/2022','10/10/2026','09/04/2024','10/03/2029','20/09/2030','20/10/2035','15/03/2024','20/03/2022','12/12/2022'],

            "Confinement type": ['COUNTY JAIL','COUNTY JAIL','COUNTY JAIL','COUNTY JAIL','COUNTY JAIL','COUNTY JAIL',
                     'COUNTY JAIL','COUNTY JAIL','COUNTY JAIL','COUNTY JAIL','COUNTY JAIL','TIHAR JAIL','TIHAR JAIL','TIHAR JAIL']

        }
        df = pd.DataFrame(data, index = ["case no.1", "case no.2", "case no.3","case no.4","case no.5","case no.6",
                                 "case no.7","case no.8","case no.9","case no.10","case no.11","case no.12","case no.13","case no.14"])
        print(df)

    def case01(self,name):
        data1={
            "Name" : ['John'],
            "Charge":['Murder'],
            "Offense Date":['20/09/2012'],
            "Dispose":['20/09/2019'],
            "Confinement type":['COUNTY JAIL']
        }
        df1 = pd.DataFrame(data1, index = ["case no.1"])
        print(df1)

    def case02(self,name):
        data2={
            "Name" : ['Ithan'],
            "Charge":['Kidnapping'],
            "Offense Date":['10/01/2015'],
            "Dispose":['10/01/2019'],
            "Confinement type":['COUNTY JAIL']
        }
        df2 = pd.DataFrame(data2, index = ["case no.2"])
        print(df2)

    def case03(self,name):
        data3={
            "Name" : ['Pekk'],
            "Charge":['Tax Evasion'],
            "Offense Date":['11/09/2010'],
            "Dispose":['11/09/2022'],
            "Confinement type":['COUNTY JAIL']
        }
        df3 = pd.DataFrame(data3, index = ["case no.3"])
        print(df3)

    def case04(self,name):
        data4={
            "Name" : ['Sherlok'],
            "Charge":['Blackmail'],
            "Offense Date":['01/01/2020'],
            "Dispose":['01/01/2023'],
            "Confinement type":['COUNTY JAIL']
        }
        df4 = pd.DataFrame(data4, index = ["case no.4"])
        print(df4)

    def case05(self,name):
        data5={
            "Name" : ['Tyrion'],
            "Charge":['Child Abuse'],
            "Offense Date":['30/03/2011'],
            "Dispose":['30/03/2025'],
            "Confinement type":['COUNTY JAIL']
        }
        df5 = pd.DataFrame(data5, index = ["case no.5"])
        print(df5)

    def case06(self,name):
        data6={
            "Name" : ['Mike'],
            "Charge":['Cybercrime'],
            "Offense Date":['12/12/2015'],
            "Dispose":['12/12/2022'],
            "Confinement type":['COUNTY JAIL']
        }
        df6 = pd.DataFrame(data6, index = ["case no.6"])
        print(df6)

    def case07(self,name):
        data7={
            "Name" : ['Will'],
            "Charge":['Fraud'],
            "Offense Date":['10/10/2010'],
            "Dispose":['10/10/2026'],
            "Confinement type":['COUNTY JAIL']
        }
        df7 = pd.DataFrame(data7, index = ["case no.7"])
        print(df7)

    def case08(self,name):
        data8={
            "Name" : ['Steve'],
            "Charge":['Hit and Run'],
            "Offense Date":['09/04/2017'],
            "Dispose":['09/04/2024'],
            "Confinement type":['COUNTY JAIL']
        }
        df8 = pd.DataFrame(data8, index = ["case no.8"])
        print(df8)

    def case09(self,name):
        data9={
            "Name" : ['Dustin'],
            "Charge":['Terrorism'],
            "Offense Date":['10/03/2005'],
            "Dispose":['10/03/2029'],
            "Confinement type":['COUNTY JAIL']
        }
        df9 = pd.DataFrame(data9, index = ["case no.9"])
        print(df9)

    def case10(self,name):
        data10={
            "Name" : ['Jonathan'],
            "Charge":['Robbery'],
            "Offense Date":['20/09/2019'],
            "Dispose":['20/09/2030'],
            "Confinement type":['COUNTY JAIL']
        }
        df10 = pd.DataFrame(data10, index = ["case no.10"])
        print(df10)

    def case11(self,name):
        data11={
            "Name" : ['Silverdeev'],
            "Charge":['Smuggling'],
            "Offense Date":['20/10/2013'],
            "Dispose":['20/10/2035'],
            "Confinement type":['COUNTY JAIL']
        }
        df11 = pd.DataFrame(data11, index = ["case no.11"])
        print(df11)

    def case12(self,name):
        data12={
            "Name" : ['Majnu Bhai'],
            "Charge":['Paintings Smuggler'],
            "Offense Date":['15/09/2013'],
            "Dispose":['15/03/2024'],
            "Confinement type":['TIHAR JAIL']
        }
        df12 = pd.DataFrame(data12, index = ["case no.12"])
        print(df12)

    def case13(self,name):
        data13={
            "Name" : ['Selmon Bhoi'],
            "Charge":['Animal Abuse,Hit and Run'],
            "Offense Date":['10/12/2010'],
            "Dispose":['20/03/2022'],
            "Confinement type":['TIHAR JAIL']
        }
        df13 = pd.DataFrame(data13, index = ["case no.13"])
        print(df13)

    def case14(self,name):
        data14={
            "Name" : ['Sanjay Dutt'],
            "Charge":['Carrying concealed weapon'],
            "Offense Date":['15/02/2010'],
            "Dispose":['12/12/2022'],
            "Confinement type":['TIHAR JAIL']
        }
        df14 = pd.DataFrame(data14, index = ["case no.14"])
        print(df14)

if __name__ == '__main__':
    dummy = Criminal("dummy1")

    while(True):
        print("Welcome to Criminal Record Database")
        print("1. Display Full list")
        print("2. Display namewise")

        user_choice = input()
        if user_choice not in ['1','2']:
            print("Please enter a valid option")
            continue

        else:
            user_choice = int(user_choice)

        if user_choice == 1:
            dummy.GetcriminalList()

        elif user_choice == 2:
            criminal = input("Enter the name :")
            if criminal=="John":
                dummy.case01(criminal)

            elif criminal=="Ithan":
                dummy.case02(criminal)

            elif criminal=="Pekk":
                dummy.case03(criminal)

            elif criminal=="Sherlok":
                dummy.case04(criminal)

            elif criminal=="Tyrion":
                dummy.case05(criminal)

            elif criminal=="Mike":
                dummy.case06(criminal)

            elif criminal=="Will":
                dummy.case07(criminal)

            elif criminal=="Steve":
                dummy.case08(criminal)

            elif criminal=="Dustin":
                dummy.case09(criminal)

            elif criminal=="Jonathan":
                dummy.case10(criminal)

            elif criminal=="Silverdeev":
                dummy.case11(criminal)

            elif criminal=="Majnu Bhai":
                dummy.case12(criminal)

            elif criminal=="Selmon Bhoi":
                dummy.case13(criminal)

            elif criminal=="Sanjay Dutt":
                dummy.case14(criminal)

        print("Press q to quit and c to continue")
        user_choice2 = ""
        while(user_choice2!="c" and user_choice2!="q"):
            user_choice2 = input()
            if user_choice2 not in ['q','c']:
                print("Please enter a valid option")
            continue

        else:
            user_choice = int(user_choice)
            if user_choice2 == "q":
                exit()

            elif user_choice2 == "c":
                continue


import numpy as np
import matplotlib.pyplot as plt

def sigmoid(Z):
    return 1/(1 + np.exp(-Z))

def logistic_model(X, Y):
    alpha = 0.1
    n_epoch = 100
    n, m = X.shape
    W = np.zeros(n)
    b = 0

    for i in range(n_epoch):
        Z = W.dot(X) + b
        p = sigmoid(Z)
        W = W - alpha * (1/m) * np.sum(X * (p - Y), axis=1)
        b = b - alpha * (1/m) * np.sum(p - Y)

        J = -(1/m) * np.sum(Y * np.log(p + 1e-8) + (1 - Y) * np.log(1 - p + 1e-8))
        print('epoch =', i, ', cost =', J)

    def model(X):
        return W.dot(X) + b > 0

    return model

def random_weights(n):
    W = np.tan(np.random.rand(n) * 2 * np.pi)
    b = np.random.rand() * 10 - 5

    return W, b

def random_sample(W, b, m, n):
    X = np.random.rand(n, m) * 20 - 10
    Y = W.dot(X) + b > 0

    X += np.random.randn(n, m) * 5

    return X, Y

m = 50
n = 2
axis = [-20, 20, -20, 20]

W, b = random_weights(n)
X, Y = random_sample(W, b, m, 2)

x1 = -15
x2 = 15
y1 = -1/W[1] * (W[0] * x1 + b)
y2 = -1/W[1] * (W[0] * x2 + b)

plt.figure('Truth')
plt.plot(X[0,:][Y == 0], X[1,:][Y == 0], 'rx')
plt.plot(X[0,:][Y == 1], X[1,:][Y == 1], 'bo')
plt.plot([x1, x2], [y1, y2], 'k')
plt.axis(axis)
plt.title('Truth')

model = logistic_model(X, Y)

Y_pred = model(X)

plt.figure('Predicted')
plt.plot(X[0,:][Y_pred == 0], X[1,:][Y_pred == 0], 'rx')
plt.plot(X[0,:][Y_pred == 1], X[1,:][Y_pred == 1], 'bo')
plt.axis(axis)
plt.title('Predicted')


import RPi.GPIO as IoPort
import time
import os
import TcpWork
import SndProt
import RcvProt
#key input
def KeyInput(key):
    if IoPort.input(key) == False:
        return False
    time.sleep(0.1)
    while True:
        if IoPort.input(key) == True:
            break
    time.sleep(0.1)
    return True
#key num
key22 = 22
key27 = 27
#set
IoPort.setmode(IoPort.BCM)
IoPort.setwarnings(False)
IoPort.setup(key22,IoPort.IN)
IoPort.setup(key27,IoPort.IN)
#object
Tcp = TcpWork.TcpWork()
rcvFile = RcvProt.RcvProt()
sndFile = SndProt.SndProt()

Tcp.Connect('192.168.1.53',20001)
print("Connected")
Tcp.Blocking(0)

while True:
    if KeyInput(key22)==True:
        sndmsg = input('message : ')
        Tcp.SendStr(sndmsg)

    if KeyInput(key27)==True:
        FileName = input("Input File Name : ")
        if os.path.isfile(FileName) == False:
            print(FileName,' is not file name. Try Again!!!')
            continue
        fle = open(FileName,'rb')
        btfile = fle.read()
        fle.close()
        bDta = sndFile.pFileSend(FileName,btfile)
        Tcp.Send(bDta)

    btrcv = Tcp.Receive()
    if btrcv == None:
        continue
    for bt in btrcv:
        rcvFile.ByteTrace(bt)
    if len(rcvFile.lst)>1:
        str1 = ''
        for bt in rcvFile.lst:
            str1 = str1 + chr(bt)
        print (str1)
        rcvFile.lst.clear()